I have the following basic shader that I wrote for my terrain:
Shader "Terrain/Terrain" {
Properties {
// BASIC
_TerrainSize ("Terrain Size", Float) = 0.0
_TerrainWorldOrigin ("Terrain World Origin", Vector) = (0.0, 0.0, 0.0, 0.0)
// OPTIONS
_SplatEdgeFalloff ("Splatmap Edge Falloff", Range(0,1)) = 0.0
_CliffEdgeFalloff ("Cliff Edge Falloff", Range (0,1)) = 0.9
// MAPS
_MapSplat ("Splat Map", 2D) = "white" {}
// TEXTURES
_TexCliff ("Cliff Texture", 2D) = "white" {}
_Tex1 ("Texture 1", 2D) = "white" {}
_Tex2 ("Texture 2", 2D) = "white" {}
_Tex3 ("Texture 3", 2D) = "white" {}
_Tex4 ("Texture 4", 2D) = "white" {}
// BLEND SETTINGS
_BlendTex1 ("Texture 1 Blend", Range(0,1)) = 0.9
_BlendTex2 ("Texture 2 Blend", Range(0,1)) = 0.8
_BlendTex3 ("Texture 3 Blend", Range(0,1)) = 0.7
_BlendTex4 ("Texture 4 Blend", Range(0,1)) = 0.7
}
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
// triplanar library for far better blending
#include "triplanar.cginc"
sampler2D _MapSplat;
sampler2D _TexCliff;
sampler2D _Tex1;
sampler2D _Tex2;
sampler2D _Tex3;
sampler2D _Tex4;
float _BlendTex1;
float _BlendTex2;
float _BlendTex3;
float _BlendTex4;
float _SplatEdgeFalloff;
float _CliffEdgeFalloff;
struct Input {
float3 worldPos;
float3 worldNormal;
float2 uv_MapSplat;
};
// FUNCTIONS
float normalize01(float min, float max, float val) {
return (val - min) * (1 / (max - min));
}
// Checks to see if we shoudl blend into the next texture, and does so. otherwise
// returns currentColor
float4 edgeBlend(float4 currentColor, sampler2D blendTex, float splatSample, float blendDiff, float3 worldPos, float3 worldNormal) {
if(splatSample < blendDiff) {
float difference = blendDiff - splatSample;
return lerp(
currentColor,
tex2DTriPlanar(blendTex, worldPos, worldNormal),
normalize01(0.0, _SplatEdgeFalloff, difference)
);
}
return currentColor;
}
// END FUNCTIONS
void surf (Input IN, inout SurfaceOutputStandard o) {
o.Alpha = 1.0;
// Sample Splatmap
float4 splatSampleRaw = tex2D(_MapSplat, IN.uv_MapSplat);
float splatSample = splatSampleRaw.r;
// test range
float blendDiff = 0.0;
sampler2D nextTex;
if(splatSample >= _BlendTex1) {
o.Albedo = edgeBlend (
tex2DTriPlanar(_Tex1, IN.worldPos, IN.worldNormal),
_Tex2,
splatSample,
_BlendTex1 + _SplatEdgeFalloff,
IN.worldPos,
IN.worldNormal
);
} else if(splatSample >= _BlendTex2) {
o.Albedo = edgeBlend (
tex2DTriPlanar(_Tex2, IN.worldPos, IN.worldNormal),
_Tex3,
splatSample,
_BlendTex2 + _SplatEdgeFalloff,
IN.worldPos,
IN.worldNormal
);
} else if(splatSample >= _BlendTex3) {
o.Albedo = edgeBlend (
tex2DTriPlanar(_Tex3, IN.worldPos, IN.worldNormal),
_Tex4,
splatSample,
_BlendTex3 + _SplatEdgeFalloff,
IN.worldPos,
IN.worldNormal
);
} else if(splatSample >= _BlendTex4) {
o.Albedo = tex2DTriPlanar(_Tex4, IN.worldPos, IN.worldNormal);
} else {
o.Albedo = half3(0.0, 0.0, 0.0);
}
// should we blend in some cliff?
float cliffTest = dot(IN.worldNormal, half3(0.0, 1.0, 0.0));
if(cliffTest < _CliffEdgeFalloff) {
// TODO: our lerp data is bad... I think,. we are oversaturating. revist formular for lerp amount
float difference = saturate(_CliffEdgeFalloff - cliffTest);
o.Albedo = lerp (
o.Albedo,
tex2DTriPlanar(_TexCliff, IN.worldPos, IN.worldNormal),
saturate(normalize01(0.0, 1 - _CliffEdgeFalloff, difference))
);
}
}
ENDCG
}
FallBack "Diffuse"
}
And these are the contents of triplanar.cginc:
#ifndef __triplanar_hlsl_
#define __triplanar_hlsl_
// returns a color that is blended with larger samples of itself. used to
// reduce the appearance of tiling
fixed4 tex2DTiled(sampler2D tex, float2 uv) {
return tex2D(tex, uv) * tex2D(tex, uv * -0.1) * tex2D(tex, uv * -0.01) * 4;
}
fixed4 tex2DTriPlanar(sampler2D tex, float3 coords, float3 norm) {
float3 blending = abs(norm);
blending = normalize(max(blending, 0.00001));
float b = (blending.x + blending.y + blending.z);
blending /= float3(b, b, b);
fixed4 xaxis = tex2DTiled(tex, coords.yz);
fixed4 yaxis = tex2DTiled(tex, coords.xz);
fixed4 zaxis = tex2DTiled(tex, coords.xy);
// blend the results of the 3 planar projections.
fixed4 retVal = xaxis * blending.x + yaxis * blending.y + zaxis * blending.z;
return retVal;
}
// returns color value based on 3 textures, and perlin noise
fixed4 tex2DBlend(sampler2D tA, sampler2D tB, sampler2D tC, float2 uv, float noise) {
fixed4 cA = tex2DTiled(tA, uv);
fixed4 cB = tex2DTiled(tB, uv);
fixed4 cC = tex2DTiled(tC, uv);
fixed4 c = lerp(cA, cB, noise);
fixed4 c2 = lerp(cA, cC, 1 - noise);
return lerp(c, c2, 0.5);
}
fixed4 tex2DBlendTriPlanar(sampler2D tA, sampler2D tB, sampler2D tC, float3 coords, float3 norm, float noise) {
fixed4 cA = tex2DTriPlanar(tA, coords, norm);
fixed4 cB = tex2DTriPlanar(tB, coords, norm);
fixed4 cC = tex2DTriPlanar(tC, coords, norm);
fixed4 c = lerp(cA, cB, noise);
fixed4 c2 = lerp(cA, cC, 1 - noise);
return lerp(c, c2, 0.5);
}
#endif
This is causing performance issues with Render.TransparentGeometry. Since I’ll never be rendering transparent areas in the terrain, I would like to switch to a different, simpler lighting model.
I tried to simply change the pragma to:
#pragma surface surf Lambert
But then I got a plethora of compile errors (and unhelpful ones).
How could I take this shader and alter it such that there is no alpha blending pass (which is what I think is happening)?
EDIT: I wanted to add that when I load the scene and do not move the camera, my FPS is around 200. When I pan my camera, the FPS drops to around 15 - 20, before settling back at 200 after I stop moving Very confused as to why this is happening.