Hi,
How can I blend multiple textures in a shader if there are only 16 texture samplers and multipass blending of opaque geometry doesn’t work in deferred mode?
What I tried:
-
A single “uber” surface shader: a sampler for albedo, normal+height and specular+metal+roughtness+selfillum
The result is: “not enough texture samplers” for 5 layers: 15 + splat + build in samplers. -
A multipass surface shader:
-
clip(alpha - 0.5) in each layer’s surface shader:
Result: no blending, only hard cutoff -
o.Alpha = alpha; as output of surface shader:
-
without “alpha” in pragma
Result: nothing happens -
with “alpha” in pragma
Result: the entire layer doesn’t render at all, no matter what blend mode -
Blend One One
Result: sortof works, but need to know (1-alpha) in the other layer ahead of time to correctly blend, so with the heightmap per layer, i would need to sample all other heightmaps in each pass. Getting close to the limit of the single shader again. And i imagine that would be just way to expensive anyway to be usable.
Tags{
"RenderType" = "Transparent" // doesn't change much
"Queue" = "Geometry"
}
LOD 200
Blend SrcAlpha OneMinusSrcAlpha // completly ignored unless it's One One
CGPROGRAM
#pragma surface surf Standard
#pragma target 3.0
sampler2D _layer0_Albedo;
sampler2D _layer0_NormalHeight;
uniform float4 _layer0_Albedo_ST;
sampler2D _Splat1Tex;
sampler2D _Splat2Tex;
float _TerrainWidth;
float _TerrainHeight;
struct Input {
float3 worldPos;
};
void surf (Input IN, inout SurfaceOutputStandard o) {
float3 color = tex2D(_layer0_Albedo, TRANSFORM_TEX(IN.worldPos.xz,_layer0_Albedo));
float4 normalBlend = tex2D(_layer0_NormalHeight, TRANSFORM_TEX(IN.worldPos.xz,_layer0_Albedo));
o.Albedo = color;
o.Alpha = 0.5f;
}
ENDCG
CGPROGRAM
#pragma surface surf Standard
// Use shader model 3.0 target, to get nicer looking lighting
#pragma target 3.0
sampler2D _layer1_Albedo;
sampler2D _layer1_NormalHeight;
uniform float4 _layer1_Albedo_ST;
sampler2D _Splat1Tex;
sampler2D _Splat2Tex;
float _TerrainWidth;
float _TerrainHeight;
struct Input {
float3 worldPos;
};
void surf (Input IN, inout SurfaceOutputStandard o) {
float3 coords = IN.worldPos;
coords.x -= _TerrainWidth/2;
coords.z -= _TerrainHeight/2;
float splat = tex2D(_Splat1Tex, coords.xz /float2(_TerrainWidth, _TerrainHeight)).r;
float4 normalBlend = tex2D(_layer1_NormalHeight, TRANSFORM_TEX(IN.worldPos.xz,_layer1_Albedo));
//clip(splat-normalBlend.a); // this is the only thing i can get working, far from an ideal blend.
float3 color = tex2D(_layer1_Albedo, TRANSFORM_TEX(IN.worldPos.xz,_layer1_Albedo));
o.Albedo = color;
o.Alpha = splat; // completly ignored, acts as 1 without #pragma alpha, acts as 0 with it.
}
ENDCG
// AND SO ON AND SO ON...