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
question from:
https://stackoverflow.com/questions/65928612/need-help-converting-a-custom-shader-to-urp