Hi
I know the answer to “can I make a shader with shadows, zwrite and alpha”, that is tricky, if not impossible.
However I do not want exactly that.
What I am working on is a tile based system with textures that transition into each other using transition alphas.
My idea is that normally, a tile will only have a single texture, but sometimes, it needs several, when there is a transition, so when there is a transition, I was thinking that I should be able to just duplicate the tile mesh so that there are two meshes occupying the exact same space, but they have different materials. The lowest prioritized texture/material one will be rendered before the second one by specifying the render queue, the lowest prioritized mesh should simply show the texture. The second material/texture should be be alpha-blended with anything rendered before it (e.g the lowest prioritized texture/material).
Note that this does not rely in any way on that the transparent objects are rendered in back to front order.
What I am asking for essentially is a diffuse shader which just blends in another way with the previously rendered pixels.
Preferably it should be doable in deferred rendering, I notice that when I add “alpha” to the “#pragma surface” line, it refuses to use the deferred rendering path.
The below shader blends correctly, but does not have any shadows and does not have ZWrite enabled.
I have tried editing the compiled shaders, enabling ZWrite and changing blending modes and similar, but nothing have worked so far. I can get some features, but if I can get, for example correct blending and ZWrite, then shadows are suddenly not working.
Shader "TerrainTransition"
{
properties
{
_MainTex ("Base Texture", 2D) = "white"{}
_SplatControl ("Splat Map", 2D) = "white"{}
_Emission ("Emission", Float) = 0.1
}
subshader
{
Tags { "RenderType" = "Opaque" }
ZTest LEqual
ZWrite On
CGPROGRAM
//#pragma surface surf Lambert vertex:vert alpha
#pragma surface surf Lambert alpha addshadow
#pragma target 3.0
#pragma exclude_renderers flash
#pragma exclude_renderers d3d11
sampler2D _MainTex;
sampler2D _SplatControl;
fixed _Emission;
struct Input
{
half2 uv_MainTex;
half2 uv2_SplatControl;
};
void surf (Input IN, inout SurfaceOutput o)
{
fixed4 t0 = tex2D ( _MainTex, IN.uv_MainTex );
fixed4 splat_control = tex2D ( _SplatControl, IN.uv2_SplatControl );
o.Albedo = t0.rgb; // + splat_control.rgb*0.1;
o.Alpha = splat_control.r;
o.Emission = t0.rgb * _Emission;
}
ENDCG
}
Fallback "Diffuse"
}
The below image shows how the current blending looks. Two planes with different materials are blended together. The grass material has a render queue set so that it is rendered after the dirt material. The dirt plane is completely opaque (but using the same shader as the grass material).
[19818-screen+shot+2013-12-27+at+22.29.11.png|19818]
Notes:
- Z sorting is not needed ( handled using render queues since I know the correct ordering at creation time )
- Shadows are required, but they can completely ignore the alpha ( I don’t think there is a way for them to respect it anyway, but it doesn’t matter ).
- ZWrite is required
- A cutout shader is not sufficient because they have hard edges ( I need smooth blending )
- I am not totally sure on when unity decides that a shader cannot run in deferred mode, but it would be nice if the shader could run in deferred mode.
Thanks in advance!
- Aron Granberg