Unity Shaderlab 人造阴影(1)

创建正交相机,从光源视角渲染场景到全局纹理

1.新建场景,放置plane与若干物体,添加方向光,关闭其阴影。

upload successful

upload successful

2.新建脚本DepthTextureCamera.cs,附加到光源节点。

upload successful
脚本大致作用,动态创建正交相机,与光源节点transform完全一致,调用其Render,渲染至RenderTexture,仅保留深度信息。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class DepthTextureCamera : MonoBehaviour
{
//正交相机对象
Camera depthCamera;
//shader,正交相机渲染时使用,仅保留深度信息
Shader depthTextureShader;
//全局纹理
RenderTexture depthTexture;

// Start is called before the first frame update
private void Start()
{
depthCamera = new GameObject().AddComponent<Camera>();
depthCamera.name = "DepthCamera";
depthCamera.depth = 2;
depthCamera.clearFlags = CameraClearFlags.SolidColor;
depthCamera.backgroundColor = new Color(0, 0, 0, 0);
depthCamera.aspect = 1;
depthCamera.transform.position = this.transform.position;
depthCamera.transform.rotation = this.transform.rotation;
depthCamera.transform.parent = this.transform;
depthCamera.orthographic = true;
depthCamera.orthographicSize = 20;
//阴影贴图分辨率
       depthTexture = new RenderTexture(512, 512, 0);
depthTexture.wrapMode = TextureWrapMode.Clamp;
depthCamera.targetTexture = depthTexture;
depthCamera.enabled = false;
depthTextureShader = Shader.Find("ShadowMap/DepthTextureShader");
}

// Update is called once per frame
void Update()
{
  //每帧刷新纹理
       depthCamera.RenderWithShader(depthTextureShader, "RenderType");
Shader.SetGlobalTexture("_DepthTexture", depthTexture);
}
}

DepthTextureShader内容也很简单,只保留z坐标信息,保存成像素点数据。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
Shader "ShadowMap/DepthTextureShader"
{
SubShader
{
Tags { "RenderType"="Opaque" }
LOD 100

Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag

#include "UnityCG.cginc"

struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};

struct v2f
{
float2 uv : TEXCOORD0;
float4 vertex : SV_POSITION;
float2 depth : TEXCOORD1;
};

sampler2D _MainTex;
float4 _MainTex_ST;

v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
o.depth = o.vertex.zw;
return o;
}

fixed4 frag (v2f i) : SV_Target
{
          //这里的xy对应顶点函数的zw,z/w齐次坐标坐标转为正交坐标
               float depth = i.depth.x/i.depth.y;
               fixed4 col = EncodeFloatRGBA(depth);//浮点数保存为RGBA值
               return col;
}
ENDCG
}
}
}

运行,打开Window->Analysis->Frame Debugger.

upload successful

能看到这个图,就是成功了。