Painterly real-time rendering | Useless Game Dev
Vložit
- čas přidán 22. 08. 2024
- Join me in this disastrous adventure as I try to make a real-time painterly rendering filter for a video game, there will be brushes, there will be compute shaders, there will be tears. Fun times all around.
More reading/watching on this subject:
- Interactive Painterly Stylization of Images, Videos and 3D Animations: gfx.cs.princet...
- GDC Talk A Living Painting: The Rendering and Art of 11-11 Memories Retold: • A Living Painting: The...
- Game Dev Guide on getting started with compute shaders: • Getting Started with C...
- Painterly Rendering in Blender: • Turning 3D Models into...
Music:
"Wholesome" Kevin MacLeod (incompetech.com)
Licensed under Creative Commons: By Attribution 4.0 License
creativecommons...
"Beauty Flow" Kevin MacLeod (incompetech.com)
Licensed under Creative Commons: By Attribution 4.0 License
creativecommons...
"Wallpaper" Kevin MacLeod (incompetech.com)
Licensed under Creative Commons: By Attribution 4.0 License
creativecommons...
"Montauk Point" Kevin MacLeod (incompetech.com)
Licensed under Creative Commons: By Attribution 4.0 License
creativecommons...
Other Credits:
- 3D assets by Kenney: kenney.itch.io...
Support the channel on Patreon to get extra content, and access to the source code of all projects!
/ uselessgamedev
Follow me on Twitter, not that I tweet that often: / uselessgamedev
Kappa Avatar art by Boskoop www.artstation...
And as always, have a good one!
#Painterly #Rendering #Unity #GameDev #IndieDev #devlog
I imagine the balance between temporal coherence and artistic style is the biggest challenge.
Yes, that's a big point in the GDC talk. Their final style doesn't even look that painterly at time but I guess that's the price you have to pay for consistency and readability
I like the approach of splitting the image up into different layers of detail. It's kind of reminiscent of the actual painting process where you'd start with midtones blocking out the rough shape and then paint over them for the details. As always great video!
A really nice looking effect! I study color and the first time I realized that I could actually turn the values I used day to day into number values to do math with, it certainly opened up a whole different layer of understanding what I chose as one of my majors :D
May not have been your target, but I love the look of the scene repainting after the camera moves. Would be great for a game that encourages slowing down and taking time to observe.
I think this shader could work really well when paired with a depth texture. You could use large, maybe even softer, brush strokes for the background, and increase the fidelity of the strokes for foreground objects.
As always, phenomenal video! Thank you for sharing
genius
Dude you are probably the best video game channel on CZcams and that's saying a lot given the thousands of copycat, trash clickbait unoriginal buffoons that post on here. Thank you for all your hard work and you deserve 100x more subscribers
First! This is genius! I love your vids, continue like this :)
This is such a cool effect! I think the way it struggles when moving at the end would actually be fantastic for a dream sequence of some kind in a game. Great stuff as always!
This is incredible for only a few weeks of work! Definitely inspired me to start exploring compute shaders.
This is exactly what I was looking for! One thing that might make moving the camera less painful to the senses it to break up the painting into smaller pieces that are angled to the world geometry, which can stay inplace for a while. Distant objects could be combined into one painting while the closest objects get a little painting each. When the view changes enough a redraw and re-combining may be necessary.
I hope this makes sense...
I have zero experience with shades, but for finding the angle: Could you use a depth map, then have the strokes try to minimize the difference in depth beneath them. For example a long stroke on the horizon if placed vertically would have a huge difference in depth from top to bottom but placed horizontally it would have very little difference. love your videos btw and I'm glad you are keeping up with them ♥!!
That's an interesting idea but maybe it would work even better using the normals? With a 3d rotation?
using a sobel filter to find image directionality is really close to a solution I see a lot of shader devs using:
if you take the results of a sobel filter (X gradient and Y gradient), you can rearrange it into what is called a structure tensor:
X^2, XY
XY, Y^2
for which the eigenvectors describe the perpendicular and parallel directions of that texel's gradient, and the eigenvalues correspond to the magnitude of those directions.
Acerola's video on Kuwahara Filters uses this technique, which is where I first learned about it
Interesting. Thanks I'll check it out!
amazing! this marks a new era in game/interactive art dev
Glad to see you didnt stop making videos, love your work
Heyyy I have been watching you for months now and you know what? I will stop just watching and start doing! I'm starting with this one and I'll make a small narrative game with it! Thanks for inspiring me!
Oh no please keep watching
Jk have fun experimenting it's very fun
Good luck!
HSFAGFIAGFIUA. dw I'll still keep watching and since I'll be taking ideas from your stuff probably more so now
Yeah. I've seen that talk way back and it got me thinking... It could be maybe used to something else entirely? IDK what, but it's applying "shader look", but in 3D... Random example would be smoke effects. IDK if it would be better or worse than normal smoke effects, blood splatter effects, etc. but it would surely be unique.
Love that you are toying with it :)
Far from useless! I found this extremely interesting and I appreciate the work you put into this
Love those videos.
Really like the artistic aspect of those rendering methods.
Continue the good work ^^
The process of splitting the image into different layers of detail, and then moving those patches around, reminds me of how video compression works. I wonder if Fourier analysis would be helpful at all for this application...
I really adore your experiments and find them really inspiring. Thank you for sharing you explorations.
Thanks that's very nice!
I recently saw a video by Cody Gindy who used a complely different approach to get a painterly look in blender. It's his only video so far, but the results are very impressive. His method relies on painting over object space normal maps and the base colour, then using realistic lighting. This effectively clamps the normals to discrete values in the shape of brush strokes, but the strokes interact with the lighting. I think it should be possible to use this for real time rendering in games as well. Maybe your next project?
I love this!! Such a cool effect!
Anybody remember an obscure old proc gen MMORPG called Love from way back in 2010? That had a nice painterly shader, I always wanted to see more games take it up.
Loved the way you built off the sobel filter from the previous video. The explanation of compute shaders was good as well. Ive always heard of the cpu being a university student, and the gpu being a classroom of middleschoolers. Who would get done a task faster depends on the complexity of calculations
That's a nice analogy! Although I assume the GPU is just as "smart" and capable as the CPU, so it's probably more akin to a class of university students except they have to wait for everyone to synchronize after every word they write
You did really well with the filter, even if you weren't able to get it to update as quickly as you would have liked.
something else to consider is painted normal maps, like the absolute normal for the vert not the change from the surface. basically you paint brush strokes of flat areas, which then react to light normally. i saw it done by hand, but that could probably be done automatically, and each brush stroke could have a random value in a map used for color offsets and other stuff. it wouldn't stick off of stuff, but it would at least make each object already look a lot closer to the style, and then maybe hand placed (or again using code to figure out where the strokes are to place on the surface) quads which contain a brush stroke texture that sticks off of it.
The way I know to make a painterly look is the kuwahara filter
Its more blurring the image in a way that resembles a brushstroke than placing a stroke but achieve a similar effect
(I am not a programmer) A potential solution that immediately comes to mind for me is heavy usage of shader mapping. I think using a depth map (or z buffer??) + an outline map (like in cell shaded games) + a detail map, you can create the effect you might want. The outlines can define the edges of objects and let the shader know where to stop painting to make sure that detail is retained, and you can tell objects apart even at a distance! It can also define the 'paint strokes' to make with your brush! Maybe you can try making the strokes follow the outline and offset to the center of the object to create a more 'painted' look and less 'paint splat' look. You can then use the depth data to draw the strokes from furthest to nearest in order to make sure proper depth is retained. Then, with the detail map, you can let the shader know when to draw with smaller strokes when you need more detail. The idea of using the depth data to create less detail for further objects is cool! The biggest thing in my eyes causing this to fail when in motion is the use of noise. Also! It may be okay to leave gaps in the shader, make the shader transparent and draw it over your scene in order to fill in any gaps and add a little detail back into the image. Again, not a programmer, so I apologize if I got anything wrong, I just had some thoughts that I hope might help!
Awesome video, thanks for sharing! Now i really want to try implement it!
Looks beautiful! Great work :D
I really shouldn’t watch these videos. They are so cool, I try to recreate this and spend like a month on it instead of actually making any progress on games
That's precisely why they're here though, so you can sort of live the experiment through me without having to actually get your hands dirty
this guy is awesome
Owww that's quite frustrating that you weren't able to go further, but that's right I totally understand your time limit. IMHO, you shall keep digging this rabbit hole a bit, it was very uncommon to watch and think about.
And take care of yourself, don't over load 😉
Amazing video
how useless could a gamedev be if his avatar IS A GODDAMN KAPPA :D I LOVE KAPPAS
It also kinda reminds me of impressionism - which got me the idea that you could try slightly randomizing the hue of each stroke to give it even more live and counter some of the sterile nature that cg renders often have
I do this not with the hue but the brightness. There's about a 10% random range on brightness otherwise the brown table in the fruit basket scene would be completely uniform. Hue is nice suggestion though maybe I should have done both
@@uselessgamedev awesome!
It's very impressive. I think someone can make new cartoon artstyle shader with this idea
Sujet intéressant et magnifiquement traité
Genial
I wanted to do this task once, as well.
I actually like the effect of just the small strokes at 6:36.
Maybe because it is consistent between frames.
Now, I haven't finished the video yet, UGD, but I think to make this effect really worth using in a widely-distributed game, I think you should make the math for how the strokes are placed very accurate, and based upon the geometry of the surface, so that no matter where you are looking from, the texture always stays in place.
This way, it wouldn't move around as you move around, and it would be beautiful to look at.
Now, I don't know if my comment will offend you, because maybe this is difficult to do and you don't want to do it. I don't know. But I think it would make for a beautiful effect.
But what you made in the video (at 6:36, because I have to leave at the moment) is cool!
Great job, and Good luck! 🙂
That looks pretty cool, and I like the larger strokes. The only thing that needs improving is when you move the camera. Definitely something to consider as I try to decide the art style for my own game as I'm definitely not going to want realistic graphics.
Im a 2d artist and i think it looks really awesome! I also really like the repainting effwct when the camera moves, but ofcourse that would make it unusable for most games
But it looks reeaaly nice!
If you can find a way to turn each R G B into a vector flow field which flows from high intensity to low intensity, then you can add and average these flow fields together to get the final ve toe flow field and use that to determine the brush angle.
Yes that would be ideal but I have no idea how to do this. Maybe something with gradient?
1911 has a similar art style. I like te concept a lot but I wish things would remain static when the camera or actors in view arent moving. I think it would be much more beautiful if only motion caused the painting to kind of twinkle like that, then once stationary again, the image is static again.
trop joli trop beau
Awesome video! You should team up with youtuber Acerola for a video! I think it would be a super cool collaboration.
For the last problem, couldn't you use the motion field of the pixels to shift everything and not need to redraw that much ?
Yes, that's what 11-11 does, from what they say in the GDC talk, apparently Unity's motion vectors is enough for what they need. However it does require keeping track of every stroke and their parameters to shift them, which I don't do
Id love to see a followup to this in 6 years when its done
Maybe the easy way to make the strokes persist is to do decals/particles. Like the camera initially shoots raycasts and you place particle with the appropriate color of what you hit at the world location (or maybe attached to it so the base object could be moved together with decals). That would be a completely different implementation without doing post-processing of the base image, but something to consider :)
Yes either way storing the list of strokes/particles would help moving them in the next frame instead of reprocessing everything from scratch!
Here's an idea: create a screenspace normal map by deriving it from the depth buffer, then use that to get the direction of the stroke.
That's a good idea yeah, with a 3D rotation maybe even. You don't even need to derive it from depth, unity does provide the world normal map
Here is another version, just sample around a pixel, using a sampling pattern randomly or base on thebpixel values, and pick the best pixel according to some rules, for examples take the highest luminosity and apply to current pixel. The end.
Sequel, do it but with rejection rules aka do nothing, and per mip map before blending down. No need for complex shader.
Instructions unclear, got a stroke.
this really looks good 👍
Maybe another way to improve the effect as the camera moves is to use world space noise instead of screen space. If your shader was the material for each object in the world, then the calculations you do would be pegged to its position and be preserved regardless of the camera angle.
Not certain it would work. Regardless, nice video!
What if you use multiple cameras, each rendering a desired layer with this effect?
It might be the solution for moving and every stroke getting blended and blurred together.
bro knows how to make me click on a video.
I think you might be able to get a more cohesive look (not temporally, but just in general) if you were to have some sort of directionality affect the way the brush strokes are drawn. You can probably modify sobel edge detection for this and use R and G as direction components depending on where the edges are detected. There'd be some overhead to be sure, but you'd get some more defined edges which could help the composition a whole bunch
Hmm I'm not sure I see what you mean because what you're describing is exactly what I do for brush stroke orientation
@@uselessgamedev There is a VERY distinct possibility I missed something in the video. I was swapping between devices and youtube's playback resume can be a bit flaky. Sorry about that!
edit: I rewatched the video from start to finish and you sure did! Now I'm even extra sorry, I left one of THOSE types of comments
Ha no worries!
I wonder if you could do a rendertexture "skymap" that keeps traks of surroundings :D
What if you morphed the screen space UV to follow edges, similar to how the pinch/expand tool works in photoshop? That way, the paint blobs will conform to the shape of objects.
Interesting. I could probably do a displacement along the sobel vector. Thanks for the suggestion!
Orientation of strokes could take into account normal screenspace.
And if you can figure out a way to create these screenspace textures on your own, you could use make some kind of "focus texture" for objects that's lighter in important areas that it can read off.
Interesting idea, thanks!
Art
I have one question/idea. Making an outline shader that looks more pencil drawn. A bit jagged, not entirely even, maybe animated? Every single outline shader/toon shader I've seen does them perfectly even and smooth, to the point where I don't know if it's possible to do it differently
Yeah if only there was a video about jagged outlines on this very channel :O
Although something I don't show in the video is the "not entirely even" / damaged feature which I did add but didn't look so good
dreams ps4 used a fleck graphics system developed by sony in the early 2000s, assigning alpha "stroke" quads to define the objects (and a secondary 2d "paint" object). really lovely, works to excellent effect, but the entire dreams experience was dominated by Mm staff being all witchy and hating folks not fitting their agenda.
Super interesting, would a Kuwahara filter be more appropriate for the affect you're going for? Despite the performance hit.
Not sure. It's just a different effect
And what it's look if instead of pos processing the effect, you use this to bake the textures, mave doing a second mesh with the brushs in front of the normal mesh
kewl
I dont think you would need to make the 'brushstrokes' consistent much, if at all. It lends credibility to the illusion of the moving image being a series of paintings, which would have different strokes. You can see this in the movie Loving Vincent, which was actually made by oil painting thousands of Van Gogh-esque animation frames. Maybe the needs of a game would require something more stable, maybe for twitch reflex hit box stuff, but as an aesthetic I actually like it more than something silky-smooth.
I think the techniques you used with the hand drawn video could prove to be useful here to draw some details, your approach I think was a little better there I think because you did combine different techniques, the edge detection, crosshatching, gradients together.
I saw a very interesting videos of guys trying to do this in blender, with much better results.
they also tried couple of different techniques.
One that caught my attention, as a smart, ingenious, slightly cheaty way of simulating paint was to distort the normal map(they smudged the normal map in photoshop). So we do not REDRAW the 3D scene. We draw in the 3D objects and on top of these objects. czcams.com/video/s8N00rjil_4/video.html
This looked cool on still frames if you ignored the sharp edges of objects. To fix that we could generate billboard sprites on just the edges of objects with paint splats. Properly angled and curved if possible. Lastly we could fix somewhat the temporal problems by playing around with animating the painted normal maps, when the camera moves and every 2 or 3 frames.
I would gladly work together with somebody on this, but I am a shader illiterate. I have no idea how shaders work, visual or text, But I will learn them eventually.
Hi, may I ask why not use Fresnel to get the exact angle of the object to paint?
This is a screen space shader I don't have access to this information. I probably could put the info (either fresnel itself or just 3D stuff) in a texture and then use it in the screen space shader but as is I didn't have it
boids!
how to learn this computational texturing ? and will it work in unreal
The feature surely exists in Unreal however I don't know Unreal so I can't point you to resources to learn
this would be cool if you didin't have a hotbar or anything,
and you just follow where the painting has higher detail to go to reach your goal, like the painting details are your compass. and then you could have a level where everything is the same detail as in you've reached your goal, now what. or some philosophical shit like that
yes, that or just depth of field blur/focus to emphasize where to go. There's a lot of possibilities to explore
Is the same possible in UE5? 🤨
Sure! I don't see why not
this looks like oil pastles
So you're telling me you are not a turtle in real life?
I am! If you ever see a human it's all AI
Reprojection?
Why not just add the strokes to the textures themselves? Simpler, more performant and looks better
This is a good idea but I wanted the scruffy outlines