Search Unity

Question Help needed with raymarching grass

Discussion in 'Shaders' started by topitsky, Mar 21, 2023.

  1. topitsky

    topitsky

    Joined:
    Jan 12, 2016
    Posts:
    100
    Hey, I've been experimenting with this type of grass rendering:
    upload_2023-3-21_12-22-59.png
    hope that paint gives the idea across. Basically I'm trying to do a fur kind of rendering without the stacked alpha planes. The top down texture stores height information about the grass, and every iteration we march towards the final depth and check if that pos is "under" the grass. I've been able to get some results with this dirty piece of code:
    Code (CSharp):
    1. float4 g1 = tex2D(_GrassMap, uv);
    2.                 float steps = 256;
    3.                 float3 forward = UNITY_MATRIX_V[2].xyz;
    4.  
    5.                 float3 fwd = forward * far / steps;
    6.                 float3 pos = g1.xyz;
    7.  
    8.                 //return pos.y;
    9.                 float final = 0;
    10.                 float diff = 0;
    11.                 bool hit2 = false;
    12.  
    13.                 for(int j = 0; j < steps; j++)
    14.                 {
    15.                     float4 ip = mul(_MirrorVP, float4(pos,1));
    16.                     float4 gs = tex2D(_GrassMapMirror, ComputeScreenPos(ip));
    17.  
    18.                     float4 gpos = float4(gs.xyz,0);
    19.                     gpos.y += gs.a * 12.0 * ry;
    20.  
    21.                     if(gpos.y <= pos.y && hit2 == false)
    22.                     {
    23.                         final = j;
    24.                         diff = abs(gpos.y - pos.y);
    25.                         hit2 = true;
    26.                     }
    27.                  
    28.                     pos -= fwd;
    29.                 }
    30.  
    31.                 return smoothstep(0,steps,final);
    Basically I have the "normal" camera that is grassmap, and then the grassmapmirror which is a topdown view, then I march through the scene and lookup the topdown texture. Both of the textures are "world pos textures", that is RGB contains the world xyz. The code here is going backwards, I've been experimenting with all directions in order to get something to show on screen, but clearly there is something I'm not understanding as the perspective is warped. I suspect it has something to do with composing the ray in a wrong way.

    upload_2023-3-21_12-27-9.png

    upload_2023-3-21_12-27-31.png

    There is probably something I'm missing about the orthographic view perspective, or the rendering idea itself doesnt offer sufficient information. Every piece of help is appreciated.

    PS. This code is running as a post processing shader as my old screenspace grass method was done that way. I realize this might be wiser to do inside a "regular mesh shader".
     
  2. burningmime

    burningmime

    Joined:
    Jan 25, 2014
    Posts:
    845
    You may want to take a look at this; it's a similar idea but keeps data from multiple angles in a 3D texture then lerps between the layers to estimate results:
    https://gamedev.ru/code/articles/grass_raycast (English: https://gamedev-ru.translate.goog/code/articles/grass_raycast?_x_tr_sl=auto&_x_tr_tl=en&_x_tr_hl=en )

    If you want to keep with the current rendering method, I'd ditch the world space positions stuff (those can be recalculated from the matrix + depth buffer anyways, so you're just sending more data and risking precision issues). Just store the height (normalized somehow) from the top-down camera into a height map, then do the raycast steps from Parallax Occlusion Mapping ( https://catlikecoding.com/unity/tutorials/rendering/part-20/ ), and replace the offsetting with whatever you need for your grass, since at that point you have a height offset and a normal.
     
  3. topitsky

    topitsky

    Joined:
    Jan 12, 2016
    Posts:
    100
    That article was actually my inspiration. Nevertheless, I was actually able to make my tech work, I was just composing the ray in a wrong way:
    upload_2023-3-22_12-31-32.png

    It sorts correctly now and has right height, just have to go about making it look prettier. Also, there's a huge amount of raytracing steps 512, I'll have to see if I can use the hull extrusion method to save on those steps, only start raytracing at points where its needed, and instead of going from camera to depth, well go from "max grass height at this pixel" to depth.

    PS. Interesting, so I'm effectively doing parallax raymarching here?
     
    Last edited: Mar 22, 2023