Pixel Art Grass Shader V2

  Рет қаралды 60,553

t3ssel8r

t3ssel8r

3 жыл бұрын

Date of Recording: 2020-10-04
To avoid popping issues, grass is shaded directly, by transferring the world position and normal of the base terrain in 3D, which does not change frame-to-frame. GPU instancing is used for performance reasons. A random subset of the grass is given a separate sprite and a randomized color, to add visual interest.

Пікірлер: 45
@randyaguilar1920
@randyaguilar1920 3 жыл бұрын
This is awesome!
@minnimangaming7684
@minnimangaming7684 Жыл бұрын
hey love your work! I was wondering how you created the lighting effect. Is it a custom shader or how did you achieve this effect?
@TheAwesomeJMaestro
@TheAwesomeJMaestro Жыл бұрын
Hi, I really love all your videos, nice stuff! I've got a question about the grass receiving shadows if thats ok? I'm trying something similar and using the built-in pipeline, and passing terrain position, and normals for each instance through a buffer to the shader. How are you using the world terrain position to calculate the shadow colour for the whole sprite? My understanding is that in the ForwardBase pass that the main directional light is calculated in, there isn't a way to pass in a world position into any of the unity macros to calculate shadow attenuation - so just wondering how you managed to achieved this?
@wedman101
@wedman101 3 жыл бұрын
Greetings from Sweden! Btw, this is great! Would love a tutorial:)
@arthurg.5533
@arthurg.5533 2 жыл бұрын
I was wondering about your approach to pixelating the 3d models. I read up on Elliot Bentine's article on the topic, and implemented my own version based on his post-processing/dithering strategy. Do you use a similar method, or an entirely different approach? I would love to know, your visuals are so dang cool!
@t3ssel8r
@t3ssel8r 2 жыл бұрын
I just render to a low resolution RT. Elliot's method is more suited to games that have a mix of different resolution assets.
@arthurg.5533
@arthurg.5533 2 жыл бұрын
@@t3ssel8r is there a separate rt for each model, or is this for the entire scene?
@t3ssel8r
@t3ssel8r 2 жыл бұрын
whole scene
@arthurg.5533
@arthurg.5533 2 жыл бұрын
@@t3ssel8r I tried something similar at first, but found that locking objects to only moving pixel units at a time made them appear jittery, while not locking them made pixels swim. Did you find a way to get around this?
@t3ssel8r
@t3ssel8r 2 жыл бұрын
it's tricky to get right and there are many different things that affect it, including pixellation of entity movement, pixellation of camera movement, sub-pixel shifting of camera viewport, and of course pixel size. If you need individual sprites to slide across each other smoothly at different speeds, then of course you have no choice but pixellate separately.
@user-cw8hd7xn1i
@user-cw8hd7xn1i Жыл бұрын
what a beautiful....
@pfarnach
@pfarnach 3 жыл бұрын
This looks amazing! Would you mind talking about how you were able to instantiate so many grass sprites? It looks like they're packed together super densely. Is it a particle system, VFX graph or something? Using a particle system with GPU instancing turned on, I'm able to instantiate only ~100k sprites (quads) before the game starts choking, and the environment feels sparse. Really curious how you managed this. Keep up the good work!
@t3ssel8r
@t3ssel8r 3 жыл бұрын
there's a few different workable ideas. particle systems are one way, although you will want to pause the particle system so that they are not being recomputed every frame. You can also try using GPU instancing, or using the builtin terrain details system (which also uses GPU instancing). Since each mesh is so simple, I've also had success just pre-baking chunks into meshes.
@starbi
@starbi 3 жыл бұрын
I recreated this pretty closely and I used true GPU instancing with DrawMeshInstancedIndriect. I made a quad mesh with it's origin at the bottom center for correct billboarding, and applied a grass texture to it. When spawning the grass on startup, I read the terrains normals and heights at different points (like mentioned in the description) with the functions from TerrainData and pass them into the compute buffer. It works great with barely any framerate impact below 100k quads. DrawMeshInstancedIndirect does not have frustum culling. So if you want large terrains you probably have to implement that or load the grass in chunks or something like that.
@HiphopBurny
@HiphopBurny 2 жыл бұрын
@@starbi would you suggest using simple quads with opacity or actually geometry grass? What would be less demanding?
@arthurangenendt8959
@arthurangenendt8959 3 жыл бұрын
such a nice grass shader... been tryin to render something like that on blender for a while hahahaha
@jebaklesny2571
@jebaklesny2571 2 жыл бұрын
I am really curious how did you achive shadows like this. As I can see you pass something like spawn position to shader and then calculate light attenuation. I was not successful to calculate it to one point using Unity functions because I simply do not see any option to calculate other points than an actual fragment position. If I did not that in that way I would get half of the grass shaded which does not look like yours. And billboard effect would work strange. Do you really calculate everything on your own or use some other tricks?
@VoidplayLP
@VoidplayLP Жыл бұрын
I assume the grass takes its color value from the terrain it was placed on. This automatically makes it work with lighting
@simonthalen5674
@simonthalen5674 Жыл бұрын
Im having the same problem. Im using instanced indirect to draw sprites. I color it same as the terrain with a toonshader. However since i cannot access the shadow info in the vertex shader, just the fragment shader: Im getting half shaded grass and not per sprite shaded shadows. Did you find a solution?
@HiphopBurny
@HiphopBurny 2 жыл бұрын
Hello! I've been trying to make a similar pixel art shader in Unreal Engine, with deferred rendering. The issue with UE is a bug that orthographic camera won't render shadows. I was thinking about some custom shadow solution. What kind of shadows are you using? Is this the built in system for unity? Do you have anything in mind that could help me? Even a few keywords would help a lot to point me to the right direction.
@t3ssel8r
@t3ssel8r 2 жыл бұрын
shadow maps. maybe the bug in UE is with the calculation of the shadow view matrix. I don't know much about UE but you could compare a renderdoc capture of a perspective camera and an ortho camera to see what's different
@HiphopBurny
@HiphopBurny 2 жыл бұрын
@@t3ssel8r Thanks for suggesting, i will take a look!
@Andrew90046zero
@Andrew90046zero 2 жыл бұрын
So to achieve your pixel perfect, and deliberately force rendering at a specific resolution, and then scale up the render texture to the window? Or is there more that is going on?
@Andrew90046zero
@Andrew90046zero 2 жыл бұрын
It looks like others have recently been asking the same question.
@t3ssel8r
@t3ssel8r 2 жыл бұрын
it's essentially that, plus small adjustments to camera and viewport to make camera movements smooth
@laurens8069
@laurens8069 Жыл бұрын
Looks very cool! I read in the comments that you render to a low res render texture. I was just wondering how you display this texture on screen? I tried using URP and a custom RenderPass, but those only work for cameras, so you can't just display the rendertexture on the screen. So how did you do it?
@t3ssel8r
@t3ssel8r Жыл бұрын
you should be able to just call graphics.blit with a null target to draw to the viewport
@laurens8069
@laurens8069 Жыл бұрын
@@t3ssel8r I tried using Graphics.Blit with the RenderPipelineManager.endCameraRendering callback, but it still results in a black screen. I also tried it with RenderPipelineManager.endFrameRendering, but that causes recursive rendering and breaks unity all together. So where in the render pipeline should I call Graphics.Blit?
@t3ssel8r
@t3ssel8r Жыл бұрын
maybe in URP you need to use a command buffer as well? put the custom render pass on the camera that draws your scene, and do a commandbuffer.blit from there? set the camera's targetTexture to null, then you can blit to BuiltinRenderTextureType.CameraTarget. at least that's what I do in a custom SRP.
@laurens8069
@laurens8069 Жыл бұрын
​@@t3ssel8r I just tried it, and I did get some result. I can use a custom render pass just fine when the camera's target is set to null, but now it doesn't use a rendertexture anymore, and I can just pixelate the the camera's final result. I guess I will try out some more things. I take it you're using the default built-in renderer?
@t3ssel8r
@t3ssel8r Жыл бұрын
I'm using a custom SRP now, which is a little more flexible than URP, but I don't know exactly what the different limitations of the different render pipelines are, because the documentation is not very clear on these edge cases.
@Gabriaprile2001
@Gabriaprile2001 3 жыл бұрын
How do you achieve the grass like shapes of the lights and shadows?
@t3ssel8r
@t3ssel8r 3 жыл бұрын
the grass is made up of a bunch of grass-shaped sprites that are shaded with a single color equal to the color of the pixel at its base
@siriolongo612
@siriolongo612 2 жыл бұрын
@@t3ssel8r so are you able to combine the terrain's color, shading and shadows into a single color? I'm asking cause I'm trying to achieve the same effect on a shader by transfering normal and world position of the sprite to the shader in a MaterialPropertyBlock, but sampling the shadow map using the world position is giving me some weird artifacts that are visible around moving characters, where some of the sprites behind them appear dark even if not in a zone of shadow, and it becomes even more obvious when the characters move, cause some of the sprites behind them pop from light to dark and viceversa
@57Folhinha
@57Folhinha Жыл бұрын
how do i relpicate this grass
@mahmoudabdellahabdelhamidy8831
@mahmoudabdellahabdelhamidy8831 Жыл бұрын
What is your name app
@simonthalen5674
@simonthalen5674 2 жыл бұрын
Wait so no grab pass in the V2 shader? Trying to emulate...
@t3ssel8r
@t3ssel8r 2 жыл бұрын
I just use normal/position transfer instead and shade the sprites as if they were the terrain.
@flippykat9215
@flippykat9215 2 жыл бұрын
@@t3ssel8r How do you get the normals and the positions of the terrain?
@siriolongo612
@siriolongo612 2 жыл бұрын
@@flippykat9215 I believe from TerrainData when instancing them from c# code and pass them to the shader via materialpropertyblock
@antara7603
@antara7603 Жыл бұрын
Hi, im really a newbie and dont understand how to do pixelation shaders (but im obsessed with the way they look) , Is there any source/tutorial/article/guide ya´ll can send me to learn to do pixel shaders? ...I would really aprecciate the help. :3
@t3ssel8r
@t3ssel8r Жыл бұрын
Elliot Bentine has a medium article on the subject
@supercc66
@supercc66 2 жыл бұрын
what's the pixel camera was used??? please help
Giving Personality to Procedural Animations using Math
15:30
t3ssel8r
Рет қаралды 2,4 МЛН
Isometric Pixel Art Tutorial - Pixel Art Tips
8:03
Saultoons
Рет қаралды 184 М.
Sigma Girl Education #sigma #viral #comedy
00:16
CRAZY GREAPA
Рет қаралды 73 МЛН
Do you have a friend like this? 🤣#shorts
00:12
dednahype
Рет қаралды 44 МЛН
СҰЛТАН СҮЛЕЙМАНДАР | bayGUYS
24:46
bayGUYS
Рет қаралды 746 М.
Super sport🤯
00:15
Lexa_Merin
Рет қаралды 20 МЛН
How Are Games Rendering Fur?
28:51
Acerola
Рет қаралды 411 М.
Ender Pearls can accidentally kill you now and I love it.
8:07
Phoenix SC
Рет қаралды 610 М.
What Canvas Size Should you use for Pixel Art? (Pixel Art Tutorial)
7:28
I Got a 3D PIXEL ART Maker - Awful or Amazing?...
15:49
Jazza
Рет қаралды 3,5 МЛН
I simulated 40K blades of realtime grass with Python
6:42
DaFluffyPotato
Рет қаралды 76 М.
Notch Has A New Indie Game! (Minecraft Creator)
7:59
Thomas Brush
Рет қаралды 90 М.
Creating a Scene for my 3D Pixel Art Game
5:01
t3ssel8r
Рет қаралды 1,2 МЛН
I Tried Creating a Game Using Real-World Geographic Data
31:37
Sebastian Lague
Рет қаралды 6 МЛН
Pixel Art Grass Shader
0:42
t3ssel8r
Рет қаралды 39 М.
Sigma Girl Education #sigma #viral #comedy
00:16
CRAZY GREAPA
Рет қаралды 73 МЛН