Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
117 views
in Technique[技术] by (71.8m points)

c# - Need help converting a custom shader to URP

For the last few days I've been following Sebastian Lague's videos about procedual generation. Since my project is based on URP and the custom shader responsible for rendering textures upon the mesh is just written for SRP I have to do an conversion. I've been tinkering around with shader graphs and found a possible solution for the conversion. But still, neither the tint nor the textures are getting rendered. I will add both codes: The one original and the attempted coversion.

Edit: The only thing I got from tinkering a little more is that when I manually set the "layers" value in the shadergraph, it allows me to go and change the base color of said layer. Still, it only affects the one single layer, doesn't apply any textures and only works under a certein y value in global space

This is the code for setting the variables. The same for both:

public void ApplyToMaterial(Material material)
     {
         material.SetInt("layerCount", layers.Length);
         material.SetColorArray("baseColours", layers.Select(x => x.tint).ToArray());
         material.SetFloatArray("baseStartHeights", layers.Select(x => x.startHeight).ToArray());
         material.SetFloatArray("baseBlends", layers.Select(x => x.blendStrength).ToArray());
         material.SetFloatArray("baseColourStrength", layers.Select(x => x.tintStrength).ToArray());
         material.SetFloatArray("baseTextureScales", layers.Select(x => x.textureScale).ToArray());
         Texture2DArray texturesArray = GenerateTextureArray(layers.Select(x => x.texture).ToArray());
         material.SetTexture("baseTextures", texturesArray);
 
         UpdateMeshHeights(material, savedMinHeight, savedMaxHeight);
     }
 
     public void UpdateMeshHeights(Material material, float minHeight, float maxHeight)
     {
         savedMaxHeight = maxHeight;
         savedMinHeight = minHeight;
 
         material.SetFloat("minHeight", minHeight);
         material.SetFloat("maxHeight", maxHeight);
     }

The original shader:

 Shader "Custom/Terrain" {
     Properties{
         testTexture("Texture", 2D) = "white"{}
         testScale("Scale", Float) = 1
 
     }
         SubShader{
             Tags { "RenderType" = "Opaque" }
             LOD 200
 
             CGPROGRAM
             // Physically based Standard lighting model, and enable shadows on all light types
             #pragma surface surf Standard fullforwardshadows
 
             // Use shader model 3.0 target, to get nicer looking lighting
             #pragma target 3.0
 
             const static int maxLayerCount = 8;
             const static float epsilon = 1E-4;
 
             int layerCount;
             float3 baseColours[maxLayerCount];
             float baseStartHeights[maxLayerCount];
             float baseBlends[maxLayerCount];
             float baseColourStrength[maxLayerCount];
             float baseTextureScales[maxLayerCount];
 
             float minHeight;
             float maxHeight;
 
             sampler2D testTexture;
             float testScale;
 
             UNITY_DECLARE_TEX2DARRAY(baseTextures);
 
             struct Input {
                 float3 worldPos;
                 float3 worldNormal;
             };
 
             float inverseLerp(float a, float b, float value) {
                 return saturate((value - a) / (b - a));
             }
 
             float3 triplanar(float3 worldPos, float scale, float3 blendAxes, int textureIndex) {
                 float3 scaledWorldPos = worldPos / scale;
                 float3 xProjection = UNITY_SAMPLE_TEX2DARRAY(baseTextures, float3(scaledWorldPos.y, scaledWorldPos.z, textureIndex)) * blendAxes.x;
                 float3 yProjection = UNITY_SAMPLE_TEX2DARRAY(baseTextures, float3(scaledWorldPos.x, scaledWorldPos.z, textureIndex)) * blendAxes.y;
                 float3 zProjection = UNITY_SAMPLE_TEX2DARRAY(baseTextures, float3(scaledWorldPos.x, scaledWorldPos.y, textureIndex)) * blendAxes.z;
                 return xProjection + yProjection + zProjection;
             }
 
             void surf(Input IN, inout SurfaceOutputStandard o) {
                 float heightPercent = inverseLerp(minHeight,maxHeight, IN.worldPos.y);
                 float3 blendAxes = abs(IN.worldNormal);
                 blendAxes /= blendAxes.x + blendAxes.y + blendAxes.z;
 
 
                 for (int i = 0; i < layerCount; i++) {
                     float drawStrength = inverseLerp(-baseBlends[i] / 2 - epsilon, baseBlends[i] / 2, heightPercent - baseStartHeights[i]);
 
                     float3 baseColour = baseColours[i] * baseColourStrength[i];
                     float3 textureColour = triplanar(IN.worldPos, baseTextureScales[i], blendAxes, i) * (1 - baseColourStrength[i]);
 
                     o.Albedo = o.Albedo * (1 - drawStrength) + (baseColour + textureColour) * drawStrength;
                 }
             }
 
 
             ENDCG
         }
             FallBack "Diffuse"
 }

The attempt plus the shader graph:

const static int maxLayerCount = 8;
 const static float epsilon = 1E-4;
 
 float layerCount;
 float3 baseColours[maxLayerCount];
 float baseStartHeights[maxLayerCount];
 float baseBlends[maxLayerCount];
 float baseColourStrength[maxLayerCount];
 float baseTextureScales[maxLayerCount];
 
 float3 triplanar(float3 worldPos, float scale, float3 blendAxes, Texture2DArray textures, SamplerState ss, int textureIndex) {
     float3 scaledWorldPos = worldPos / scale;
     float3 xProjection = SAMPLE_TEXTURE2D_ARRAY(textures, ss, float2(scaledWorldPos.y, scaledWorldPos.z), textureIndex) * blendAxes.x;
     float3 yProjection = SAMPLE_TEXTURE2D_ARRAY(textures, ss, float2(scaledWorldPos.x, scaledWorldPos.z), textureIndex) * blendAxes.y;
     float3 zProjection = SAMPLE_TEXTURE2D_ARRAY(textures, ss, float2(scaledWorldPos.x, scaledWorldPos.y), textureIndex) * blendAxes.z;
     return xProjection + yProjection + zProjection;
 }
 
 float inverseLerp(float a, float b, float c)
 {
     return saturate((c - a) / (b - a));
 }
 
 void layer_terrain_float(float3 worldPos, float heightPercent, float3 worldNormal, Texture2DArray textures, SamplerState ss, int layerCount, out float3 albedo) {
     float3 blendAxes = abs(worldNormal);
     blendAxes /= blendAxes.x + blendAxes.y + blendAxes.z;
 
     albedo = 0.0f;
 
     for (int i = 0; i < layerCount; i++) {
         float drawStrength = inverseLerp(-baseBlends[i] / 2 - epsilon, baseBlends[i] / 2, heightPercent - baseStartHeights[i]);
 
         float3 baseColour = baseColours[i] * baseColourStrength[i];
         float3 textureColour = triplanar(worldPos, baseTextureScales[i], blendAxes, textures, ss, i) * (1 - baseColourStrength[i]);
 
         albedo = albedo * (1 - drawStrength) + (baseColour + textureColour) * drawStrength;
     }
 }

I am banging my head against a wall here for a few days straight. So help would be really appreciated

The Shadergraph

question from:https://stackoverflow.com/questions/65928612/need-help-converting-a-custom-shader-to-urp

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)
Waitting for answers

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...