diff --git a/frontend/libs/markdown-content/src/lib/content/news/world-models-for-film.md b/frontend/libs/markdown-content/src/lib/content/news/world-models-for-film.md index 1a1efd6c3c..509a41e2bd 100644 --- a/frontend/libs/markdown-content/src/lib/content/news/world-models-for-film.md +++ b/frontend/libs/markdown-content/src/lib/content/news/world-models-for-film.md @@ -1,6 +1,6 @@ --- title: Less Slop: World Models for Consistent AI Filmmaking -abstract: How to use World Models and 3D Rendering to Get Consistent AI Film Locations and better AI Films +abstract: How to use World Models and 3D Rendering to Get Consistent AI Film Locations and better AI Films. date: 2026-01-30 --- @@ -35,7 +35,7 @@ continuity. We've figured out how to overcome this problem. And in the spirit of "Show, Don't Tell", let me show you what we've discovered. You'll intuit how this technique works immediately: -@youtube(wJCJYdGdpHg) +@youtube(kzvQMdg66Go) Now let me break down the rationale and the technique... @@ -179,7 +179,17 @@ Then prompt, followed by a 4K upscale (with a few more fixes): # World Models Make This Easy -The real star of this workflow is image-to-Gaussian Splat models, such as World Labs' Marble or Apple's Sharp. You can very quickly create a pleasing image of an intracate set in MidJourney, edit it in Nano Banana, then turn it into a fully navigable 3D scene. +The real stars of the modern 3D compositing workflow are image-to-Gaussian Splat models, such as World Labs' Marble or Apple's Sharp. + +You can very quickly create a pleasing image of an intracate set in MidJourney, edit it in Nano Banana, +then turn it into a fully navigable 3D scene. This gives your characters room to move, your camera places +to go, and your location opportunities to shine. + +@loop_autoplay(https://pub-f7441936e5804042a1ea2bdc92e4dc71.r2.dev/Fantasy_Gif_One.mp4) +@loop_autoplay(https://pub-f7441936e5804042a1ea2bdc92e4dc71.r2.dev/Beach_Gif_One.mp4) +@loop_autoplay(https://pub-f7441936e5804042a1ea2bdc92e4dc71.r2.dev/SciFi_Gif_One.mp4) + +Finally, we have set pieces. And they're easy to build and iterate on. # Combining Techniques @@ -187,6 +197,13 @@ You can use MidJourney to quickly generate brilliant scenes with high detail and This is less like "prompting" and more like "crafting", with lots of different visual tools used in quick succession and coordination. +Need something? Generate it, turn it into 3D, edit, manipulate it. Stick it into something else. Rinse, cycle, repeat. Highly tangible, +like an artist molding clay - except now we're moving closer to the speed of thoughts. + +We're still being largely intentional. If there's something we want to see, we now have the tool to make it real. It's *What You See Is What You Get*. + +We're painting with pictures. We're not prompters, but rather auteurs of crafting. + # ArtCraft: Free and Open 3D Filmmaking ArtCraft is a crafting engine and is available in its entirety on [Github (please star us!)](https://github.com/storytold/artcraft) diff --git a/frontend/libs/markdown-content/src/lib/utils/markdown.ts b/frontend/libs/markdown-content/src/lib/utils/markdown.ts index 8627ca38ea..a50469bc47 100644 --- a/frontend/libs/markdown-content/src/lib/utils/markdown.ts +++ b/frontend/libs/markdown-content/src/lib/utils/markdown.ts @@ -65,6 +65,12 @@ export const markdownToHtml = ( return `
`; }; + // Render a looping autoplay video embed (muted required for autoplay) + const renderLoopAutoplayVideoEmbed = (url: string): string => { + const safeUrl = normalizeLink(url); + return `
`; + }; + // Get video MIME type from URL const getVideoMimeType = (url: string): string => { const lowerUrl = url.toLowerCase().split("?")[0]; @@ -203,6 +209,15 @@ export const markdownToHtml = ( continue; } + // Looping autoplay video embed: @loop_autoplay(url) + const loopAutoplayMatch = ltrim.match(/^@loop_autoplay\(([^)]+)\)\s*$/); + if (loopAutoplayMatch) { + flushParagraph(); + closeListIfOpen(); + htmlParts.push(renderLoopAutoplayVideoEmbed(loopAutoplayMatch[1])); + continue; + } + // Image/GIF embed: @image(url, size) or @gif(url, size) const imageMatch = ltrim.match( /^@(image|gif)\(([^,)]+)(?:,\s*([^)]+))?\)\s*$/,