Hello everyone, I recently finished Sebastian Lague’s procedural terrain generation playlist. To be honest, because I’m kind of a beginner of this whole procedural thing, I couln’t understand most of the code. I played it ariund a little and decided to add a world bending effect with a surface shader code I found on the internet for a planet-like look. I don’t actually know how shaders work but I managed to merge the shader code I found with the custom shader Sebastian created in the series and it worked but there is a problem.
The code works but because of the bending effect, the height values are much below their orginal values without the effect. As a result, the textures are not working as intended. For example, the far sides of the map is just all water and the textures shift from water to grass as the player moves.
It’s my understanding that the shader first curves the world and then adds the textures. Is there a way to reverse this?
For context, this is without the world bending effect:
[198338-upload-2022-8-3-21-35-25r.png*_|198338]
And this is with the world bending effect:
[198339-upload-2022-8-3-21-37-29r.png*_|198339]
This is the world bending shader code I found:
Shader "playmint/curved/curved"
{
Properties
{
_Color("Main Colour", Color) = (1,1,1,1)
_MainTex("Base (RGB)", 2D) = "white" {}
}
SubShader
{
Tags { "RenderType" = "Opaque" }
LOD 200
CGPROGRAM
#pragma surface surf Lambert vertex:vert addshadow
// Global Shader values
uniform float2 _BendAmount;
uniform float3 _BendOrigin;
uniform float _BendFalloff;
sampler2D _MainTex;
fixed4 _Color;
struct Input
{
float2 uv_MainTex;
};
float4 Curve(float4 v)
{
//HACK: Considerably reduce amount of Bend
_BendAmount *= .0001;
float4 world = mul(unity_ObjectToWorld, v);
float dist = length(world.xz - _BendOrigin.xz);
dist = max(0, dist - _BendFalloff);
// Distance squared
dist = dist * dist;
world.xy += dist * _BendAmount;
return mul(unity_WorldToObject, world);
}
void vert(inout appdata_full v)
{
v.vertex = Curve(v.vertex);
}
void surf(Input IN, inout SurfaceOutput o)
{
fixed4 c = tex2D(_MainTex, IN.uv_MainTex) * _Color;
o.Albedo = c.rgb;
o.Alpha = c.a;
}
ENDCG
}
Fallback "Mobile/Diffuse"
}
And this is the shader code from attempted merge:
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 vertex:vert addshadow // vert add
// 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;
// Global Shader values
uniform float2 _BendAmount;
uniform float3 _BendOrigin;
uniform float _BendFalloff;
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;
}
float4 Curve(float4 v)
{
//HACK: Considerably reduce amount of Bend
_BendAmount *= .0001;
float4 world = mul(unity_ObjectToWorld, v);
float dist = length(world.xz - _BendOrigin.xz);
dist = max(0, dist - _BendFalloff);
// Distance squared
dist = dist * dist;
world.xy += dist * _BendAmount;
return mul(unity_WorldToObject, world);
}
void vert(inout appdata_full v)
{
v.vertex = Curve(v.vertex);
}
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<em>/2 - epsilon, baseBlends_/2, heightPercent - baseStartHeights*);*_</em>
float3 baseColour = baseColours * baseColourStrength*;*
float3 textureColour = triplanar(IN.worldPos, baseTextureScales_, blendAxes, i) * (1-baseColourStrength*);*_
o.Albedo = o.Albedo * (1-drawStrength) + (baseColour+textureColour) * drawStrength;
}
}
ENDCG
}
FallBack “Diffuse”
}
As I said, Sebastian’s code felt a bit hard for me to understand and I have near zero experience with shaders. I would like to ask if there is a way to fix this problem.
*
*