I want to bake static shadow of a terrain object into a texture. It’s sort like lightmap baking but much simpler. Here’s my step.
- Create a orthographic camera whose transform is at center of the terrain mesh and rotation equals to the directional light. And using bounds to calculate the camera’s size and far/near plane.
- Create a high-res render texture as the camera’s target texture.
- Render with replacement shader to draw depth, and get the result on the render texture.
- Only render the terrain using the same camera with a new shader, which collect shadows from previous render texture, and use uv coordinate as it’s output position (SV_POSITION) so that the result texture can be mapped with the original uv to the terrain.
It works quit well until I try to output the result into a texture. I can see the correct result on editor screen. However if I set a target texture to the camera, the texture got nothing on it, unless I set the output position to usual value like mul(UNITY_MATRIX_MVP, v.vertex). Can anyone explain me the reason?!
I also see the shadowgun’s render to texel sample project. But they bake texture in a different way. They first create the normal map and position map in texture space, and render the baking result just in texture space, using Graphic.Blit(). So their approach won’t meet my issue. Maybe unity just don’t let me do like that?
here’s the shader code fragment that I used to render the terrain in step 4.
v2f vert(vertex_data v)
{
v2f o;
UNITY_INITIALIZE_OUTPUT(v2f, o)
float4 pos = mul(UNITY_MATRIX_MVP, v.vertex);
o.pos = float4(v.uv * 2 - 1, 0, 1);//can't draw any thing to target texture
//o.pos = pos; //can see shadow result on render texture, but not in the uv layout that I want
o.screenCoord = ComputeScreenPos(pos).xy;
o.depth = (mul(UNITY_MATRIX_MV, v.vertex).z - _ProjectionParams.y) / (_ProjectionParams.z - _ProjectionParams.y);
return o;
}
sampler2D _LightDepth;
half4 frag(v2f i) : SV_Target
{
return sign(i.depth - tex2D(_LightDepth, i.screenCoord).r + 0.01);
}