Search Unity

Trying to convert a custom shader to URP

Discussion in 'Universal Render Pipeline' started by Sora092, Jan 25, 2021.

  1. Sora092

    Sora092

    Joined:
    Jul 27, 2020
    Posts:
    1
    Recently I've been following Sebastian Lague's tutorials on his procedual terrain. Since he based his shader for rendering textures onto the mesh on the SRP and my project depends on URP, I have to convert it to URP.
    I've been tinkering around with ShaderGraphs and found a starting point for the custom shader but still, nothing. I'm kind of at a dead end and have to get it working.

    The only thing I get is that when I manually set the "layers" value to the amount of layers, is that I am able to edit the albedo of this layer. But it just sets the base color. Not the texture. This color also only gets applied below a specific height in world space

    These are the codes and graphs:

    Setting values; Same code for both shaders:

    Code (CSharp):
    1.    public void ApplyToMaterial(Material material)
    2.     {
    3.         material.SetFloat("layerCount", layers.Length);
    4.         material.SetColorArray("baseColours", layers.Select(x => x.tint).ToArray());
    5.         material.SetFloatArray("baseStartHeights", layers.Select(x => x.startHeight).ToArray());
    6.         material.SetFloatArray("baseBlends", layers.Select(x => x.blendStrength).ToArray());
    7.         material.SetFloatArray("baseColourStrength", layers.Select(x => x.tintStrength).ToArray());
    8.         material.SetFloatArray("baseTextureScales", layers.Select(x => x.textureScale).ToArray());
    9.         Texture2DArray texturesArray = GenerateTextureArray(layers.Select(x => x.texture).ToArray());
    10.         material.SetTexture("textures", texturesArray);
    11.  
    12.         UpdateMeshHeights(material, savedMinHeight, savedMaxHeight);
    13.     }
    14.  
    15.     public void UpdateMeshHeights(Material material, float minHeight, float maxHeight)
    16.     {
    17.         savedMaxHeight = maxHeight;
    18.         savedMinHeight = minHeight;
    19.         material.SetFloat("min", minHeight);
    20.         material.SetFloat("height", maxHeight);
    21.     }
    22.  
    Original Shader (texture is calles baseTexture here):

    Code (CSharp):
    1. Shader "Custom/Terrain" {
    2.     Properties{
    3.         testTexture("Texture", 2D) = "white"{}
    4.         testScale("Scale", Float) = 1
    5.  
    6.     }
    7.         SubShader{
    8.             Tags { "RenderType" = "Opaque" }
    9.             LOD 200
    10.  
    11.             CGPROGRAM
    12.             // Physically based Standard lighting model, and enable shadows on all light types
    13.             #pragma surface surf Standard fullforwardshadows
    14.  
    15.             // Use shader model 3.0 target, to get nicer looking lighting
    16.             #pragma target 3.0
    17.  
    18.             const static int maxLayerCount = 8;
    19.             const static float epsilon = 1E-4;
    20.  
    21.             int layerCount;
    22.             float3 baseColours[maxLayerCount];
    23.             float baseStartHeights[maxLayerCount];
    24.             float baseBlends[maxLayerCount];
    25.             float baseColourStrength[maxLayerCount];
    26.             float baseTextureScales[maxLayerCount];
    27.  
    28.             float minHeight;
    29.             float maxHeight;
    30.  
    31.             sampler2D testTexture;
    32.             float testScale;
    33.  
    34.             UNITY_DECLARE_TEX2DARRAY(baseTextures);
    35.  
    36.             struct Input {
    37.                 float3 worldPos;
    38.                 float3 worldNormal;
    39.             };
    40.  
    41.             float inverseLerp(float a, float b, float value) {
    42.                 return saturate((value - a) / (b - a));
    43.             }
    44.  
    45.             float3 triplanar(float3 worldPos, float scale, float3 blendAxes, int textureIndex) {
    46.                 float3 scaledWorldPos = worldPos / scale;
    47.                 float3 xProjection = UNITY_SAMPLE_TEX2DARRAY(baseTextures, float3(scaledWorldPos.y, scaledWorldPos.z, textureIndex)) * blendAxes.x;
    48.                 float3 yProjection = UNITY_SAMPLE_TEX2DARRAY(baseTextures, float3(scaledWorldPos.x, scaledWorldPos.z, textureIndex)) * blendAxes.y;
    49.                 float3 zProjection = UNITY_SAMPLE_TEX2DARRAY(baseTextures, float3(scaledWorldPos.x, scaledWorldPos.y, textureIndex)) * blendAxes.z;
    50.                 return xProjection + yProjection + zProjection;
    51.             }
    52.  
    53.             void surf(Input IN, inout SurfaceOutputStandard o) {
    54.                 float heightPercent = inverseLerp(minHeight,maxHeight, IN.worldPos.y);
    55.                 float3 blendAxes = abs(IN.worldNormal);
    56.                 blendAxes /= blendAxes.x + blendAxes.y + blendAxes.z;
    57.  
    58.  
    59.                 for (int i = 0; i < layerCount; i++) {
    60.                     float drawStrength = inverseLerp(-baseBlends[i] / 2 - epsilon, baseBlends[i] / 2, heightPercent - baseStartHeights[i]);
    61.  
    62.                     float3 baseColour = baseColours[i] * baseColourStrength[i];
    63.                     float3 textureColour = triplanar(IN.worldPos, baseTextureScales[i], blendAxes, i) * (1 - baseColourStrength[i]);
    64.  
    65.                     o.Albedo = o.Albedo * (1 - drawStrength) + (baseColour + textureColour) * drawStrength;
    66.                 }
    67.             }
    68.  
    69.  
    70.             ENDCG
    71.         }
    72.             FallBack "Diffuse"
    73. }
    74.  
    The modified shader:

    Code (CSharp):
    1. const static int maxLayerCount = 8;
    2. const static float epsilon = 1E-4;
    3.  
    4. float layerCount;
    5. float3 baseColours[maxLayerCount];
    6. float baseStartHeights[maxLayerCount];
    7. float baseBlends[maxLayerCount];
    8. float baseColourStrength[maxLayerCount];
    9. float baseTextureScales[maxLayerCount];
    10.  
    11. float3 triplanar(float3 worldPos, float scale, float3 blendAxes, Texture2DArray textures, SamplerState ss, int textureIndex) {
    12.     float3 scaledWorldPos = worldPos / scale;
    13.     float3 xProjection = SAMPLE_TEXTURE2D_ARRAY(textures, ss, float2(scaledWorldPos.y, scaledWorldPos.z), textureIndex) * blendAxes.x;
    14.     float3 yProjection = SAMPLE_TEXTURE2D_ARRAY(textures, ss, float2(scaledWorldPos.x, scaledWorldPos.z), textureIndex) * blendAxes.y;
    15.     float3 zProjection = SAMPLE_TEXTURE2D_ARRAY(textures, ss, float2(scaledWorldPos.x, scaledWorldPos.y), textureIndex) * blendAxes.z;
    16.     return xProjection + yProjection + zProjection;
    17. }
    18.  
    19. float inverseLerp(float a, float b, float c)
    20. {
    21.     return saturate((c - a) / (b - a));
    22. }
    23.  
    24. void layer_terrain_float(float3 worldPos, float heightPercent, float3 worldNormal, Texture2DArray textures, SamplerState ss, int layerCount, out float3 albedo) {
    25.     float3 blendAxes = abs(worldNormal);
    26.     blendAxes /= blendAxes.x + blendAxes.y + blendAxes.z;
    27.  
    28.     albedo = 0.0f;
    29.  
    30.     for (int i = 0; i < layerCount; i++) {
    31.         float drawStrength = inverseLerp(-baseBlends[i] / 2 - epsilon, baseBlends[i] / 2, heightPercent - baseStartHeights[i]);
    32.  
    33.         float3 baseColour = baseColours[i] * baseColourStrength[i];
    34.         float3 textureColour = triplanar(worldPos, baseTextureScales[i], blendAxes, textures, ss, i) * (1 - baseColourStrength[i]);
    35.  
    36.         albedo = albedo * (1 - drawStrength) + (baseColour + textureColour) * drawStrength;
    37.     }
    38. }
    And my ShaderGraph:



    Help would be really appreciated!
     
    Last edited: Jan 27, 2021
  2. UltimateVenom

    UltimateVenom

    Joined:
    Aug 7, 2021
    Posts:
    3
    Did you ever work this out? I find myself in the same predicament and everything I do seems to be a dead end for one reason or another.
     
    Last edited: Oct 4, 2021