Search Unity

Snow deformation effect not translating across LODs

Discussion in 'Shaders' started by Mr_Admirals, Feb 3, 2019.

  1. Mr_Admirals

    Mr_Admirals

    Joined:
    May 13, 2017
    Posts:
    86
    Hey,

    I don't know if this is the right forum or not, but I'm running into an issue with my snow deformation pipeline. I figured I could get more bang for my buck by implementing a LOD system. The LOD system is in place, but unfortunately, despite each LOD mesh having the same material, they're not retaining the deformation information beyond LOD 0.

    Anyone have any insight into this?

    Here's my script that handles the render texture pipeline. I think the issue should be in here somewhere, but I can't figure it out.

    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. public class SnowRenderTexturePipeline : MonoBehaviour {
    4.  
    5.     public enum DownSampleMode { Off, Half, Quarter }
    6.  
    7.     public Texture displacementMap;
    8.     [Range(0, 1)]
    9.     public float displacement = 0.2f;
    10.     [Range(5, 64)]
    11.     public float tessellationEdgeLength = 16f;
    12.     public int resolutionX = 512;
    13.     public int resolutionY = 512;
    14.     public DownSampleMode downSampleMode = DownSampleMode.Off;
    15.     [Range(0, 8)]
    16.     public int blurIterations = 1;
    17.     public Shader snowShader;
    18.     public Shader blurShader;
    19.     public Shader normalizeShader;
    20.     public Texture snow;
    21.     public Color snowColor = Color.white;
    22.     public Texture ground;
    23.     public Color groundColor = Color.white;
    24.     public Texture2D normalMap;
    25.     public float bumpScale;
    26.     [Range(0,1)]
    27.     public float metallic = 0f;
    28.     [Range(0,1)]
    29.     public float smoothness = 0.5f;
    30.     public Texture2D detail;
    31.     public Texture2D detailNormals;
    32.     public float detailBumpScale;
    33.  
    34.     Material snowMat;
    35.     Material blurMat;
    36.     Material normalizeMat;
    37.  
    38.     RenderTexture objectDepth;
    39.     RenderTexture groundDepth;
    40.     RenderTexture depthTexture;
    41.     RenderTexture blurredDepthTexture;
    42.    
    43.     Camera objectCam;
    44.     public Camera groundCam;
    45.  
    46.     bool active = true;
    47.  
    48.     public void SetActive(bool flag)
    49.     {
    50.         active = flag;
    51.     }
    52.  
    53.     private void Start()
    54.     {
    55.         snowMat = new Material(snowShader);
    56.         snowMat.hideFlags = HideFlags.HideAndDontSave;
    57.         snowMat.SetTexture("_DispMap", displacementMap);
    58.         snowMat.SetFloat("_Displacement", displacement);
    59.         snowMat.SetFloat("_TessellationEdgeLength", tessellationEdgeLength);
    60.         snowMat.SetTexture("_SnowTex", snow);
    61.         snowMat.SetColor("_SnowColor", snowColor);
    62.         snowMat.SetTexture("_GroundTex", ground);
    63.         snowMat.SetColor("_GroundColor", groundColor);
    64.         snowMat.SetTexture("_NormalMap", normalMap);
    65.         snowMat.SetFloat("_BumpScale", bumpScale);
    66.         snowMat.SetFloat("_Metallic", metallic);
    67.         snowMat.SetFloat("_Smoothness", smoothness);
    68.         snowMat.SetTexture("_DetailTex", detail);
    69.         snowMat.SetTexture("_DetailNormalMap", detailNormals);
    70.         snowMat.SetFloat("_DetailBumpScale", detailBumpScale);
    71.         transform.parent.parent.GetComponent<Renderer>().material = snowMat;
    72.  
    73.         // If LODs 1 - 3 are attached to LOD 0...
    74.         if(transform.parent.parent.childCount > 1)
    75.         {
    76.             Debug.Log("Yes");
    77.             Transform tileTransform = transform.parent.parent;
    78.             tileTransform.GetChild(0).GetComponent<MeshRenderer>().material = snowMat;
    79.             tileTransform.GetChild(1).GetComponent<MeshRenderer>().material = snowMat;
    80.             tileTransform.GetChild(2).GetComponent<MeshRenderer>().material = snowMat;
    81.         }
    82.  
    83.         blurMat = new Material(blurShader);
    84.         blurMat.hideFlags = HideFlags.HideAndDontSave;
    85.         normalizeMat = new Material(normalizeShader);
    86.         normalizeMat.hideFlags = HideFlags.HideAndDontSave;
    87.  
    88.         depthTexture = new RenderTexture(resolutionX, resolutionY, 24, RenderTextureFormat.Depth);
    89.         objectDepth = new RenderTexture(depthTexture.width, depthTexture.height, 24, depthTexture.format);
    90.         groundDepth = new RenderTexture(depthTexture.width, depthTexture.height, 24, depthTexture.format);
    91.         blurredDepthTexture = new RenderTexture(depthTexture.width, depthTexture.height, 24, depthTexture.format);
    92.  
    93.         objectCam = GetComponent<Camera>();
    94.         objectCam.targetTexture = objectDepth;
    95.         groundCam.targetTexture = groundDepth;
    96.  
    97.         normalizeMat.SetTexture("_ObjectTex", objectDepth);
    98.         normalizeMat.SetTexture("_GroundTex", groundDepth);
    99.         normalizeMat.SetFloat("_Displacement", displacement);
    100.         normalizeMat.SetFloat("_NearClip", objectCam.nearClipPlane);
    101.         normalizeMat.SetFloat("_FarClip", objectCam.farClipPlane);
    102.     }
    103.  
    104.     void OnRenderImage(RenderTexture source, RenderTexture destination)
    105.     {
    106.         if(!active)
    107.         {
    108.             return;
    109.         }
    110.  
    111.         Graphics.Blit(groundDepth, depthTexture, normalizeMat);
    112.  
    113.         RenderTexture rt1, rt2;
    114.  
    115.         blurMat.SetTexture("_MyDepthTex", depthTexture);
    116.  
    117.         if (downSampleMode == DownSampleMode.Half)
    118.         {
    119.             rt1 = RenderTexture.GetTemporary(depthTexture.width / 2, depthTexture.height / 2, 24, depthTexture.format);
    120.             rt2 = RenderTexture.GetTemporary(depthTexture.width / 2, depthTexture.height / 2, 24, depthTexture.format);
    121.             Graphics.Blit(depthTexture, rt1, blurMat, 0);
    122.         }
    123.         else if (downSampleMode == DownSampleMode.Quarter)
    124.         {
    125.             rt1 = RenderTexture.GetTemporary(depthTexture.width / 4, depthTexture.height / 4, 24, depthTexture.format);
    126.             rt2 = RenderTexture.GetTemporary(depthTexture.width / 4, depthTexture.height / 4, 24, depthTexture.format);
    127.             Graphics.Blit(depthTexture, rt1, blurMat, 1);
    128.         }
    129.         else
    130.         {
    131.             rt1 = RenderTexture.GetTemporary(depthTexture.width, depthTexture.height, 24, depthTexture.format);
    132.             rt2 = RenderTexture.GetTemporary(depthTexture.width, depthTexture.height, 24, depthTexture.format);
    133.             Graphics.Blit(depthTexture, rt1, blurMat, 0);
    134.         }
    135.  
    136.         for (var i = 0; i < blurIterations; i++)
    137.         {
    138.             blurMat.SetTexture("_MyDepthTex", rt1);
    139.             Graphics.Blit(rt1, rt2, blurMat, 2);
    140.             blurMat.SetTexture("_MyDepthTex", rt2);
    141.             Graphics.Blit(rt2, rt1, blurMat, 3);
    142.         }
    143.  
    144.         blurMat.SetTexture("_MyDepthTex", rt1);
    145.         Graphics.Blit(rt1, blurredDepthTexture, blurMat, 0);
    146.         snowMat.SetTexture("_DispTex", blurredDepthTexture);
    147.  
    148.         RenderTexture.ReleaseTemporary(rt1);
    149.         RenderTexture.ReleaseTemporary(rt2);
    150.     }
    151. }
     
  2. Mr_Admirals

    Mr_Admirals

    Joined:
    May 13, 2017
    Posts:
    86
    Alright, I have an update. Still no luck, but I've identified it has something to do with the simplified meshes. I turned off the LOD system for the snow and made it so that the base mesh is swapped out for what would have been LOD 1. Now the snow doesn't work. So my current thinking is that something is up with the meshes that's making them incompatible.
     
  3. Mr_Admirals

    Mr_Admirals

    Joined:
    May 13, 2017
    Posts:
    86
    Another update: The depth maps are being captured properly on the meshes with no deformation occurring. But for some reason, the vertex and fragment shaders aren't working I guess? I also found out that for some reason, deformation only occurs on meshes with a certain pattern and vertex density, which is obviously not how the code works.

    Anyone have any insight at all on how to debug this issue?

    I can explain further how everything works and post more code as needed.
     
  4. Mr_Admirals

    Mr_Admirals

    Joined:
    May 13, 2017
    Posts:
    86
    Final update: I solved the issue!

    For the snow deformation, I pack two sets of texture coordinates into a single channel with a Vector4 (the texture coords, and the deformation coords). Similar to using Vector4's for a mesh's UV's, in the mesh simplifier you need to explicitly set them with the SetUV function call - which I was of course neglecting to do.