笔记-UnityShader-深度图

#笔记-UnityShader-深度图
格式以后改

shader初学者,最近在学习[Lin Reid的shader文章][1],因为刚接触UnityShader,还是遇到了各种问题,在此做个记录,供参考

[3DWater教程][2]其中应用到了深度depth texture的技术,教程写的很细致,但过程中还是遇到了一些问题

例程中,maincamera设置DepthTextureMode.Depth texture模式;创建一个plane平面使用shader;创建一个默认的3Dcude与平面相交;相交被遮挡部分显示深度图像

1.由于使用DepthTextureMode.Depth texture深度采样,Queue<=2500时,相机对图形深度进行采样,默认的Queue = Geometry(2000),同样会绘制入深度图中,导致plane无法显示预期效果,可使用Queue = Transparent(3000)修复

2.shader代码中使用ComputeScreenPos(o.vertex)获取屏幕坐标,其中未进行齐次变换,则纹理采样时需进行齐次变换
tex2D(_CameraDepthTexture,i.screenPos,xyi.screenPos.w)
或直接使用
SAMPLE_DEPTH_TEXTURE_PROJ(_CameraDepthTexture, UNITY_PROJ_COORD(i.screenPos))
SAMPLE_DEPTH_TEXTURE_PROJ宏里面有对应齐次变换的封装

3.深度纹理采样获取的深度值是非线性的,因此需要Linear01Depth或LinearEyeDepth函数进行处理
Linear01Depth将返回z/F(F为远平面)[0,1]区间的值而LinearEyeDepth将返回z[0,F]

4.下一步将被遮挡部分显示渐变
float foamLine = 1 - saturate(_DepthFactor * (depth - i.screenPos.w))
调节_DepthFactor 值可调节显示被遮挡部分的深度
depth - i.screenPos.w仍不明白其缘由,其中depth需由LinearEyeDepth得出

笔记-UnityShader-深度图_第1张图片

例程很简单,可用改例程扩展为海边浪花等shader效果

源码c#添加到camera组件下

using UnityEngine;
using System.Collections;
using UnityEditor;

[ExecuteInEditMode]
public class RenderDepthMap : MonoBehaviour
{
    private Camera cam;

    void Start()
    {
        cam = GetComponent();
        cam.depthTextureMode = DepthTextureMode.Depth;//开启相机深度
    }
}

Shader代码,添加给plane(水面)组件

Shader "Example/3DWater"
{
	Properties
	{
		_DepthFactor("Depth Factor", float) = 1.0
	}

	SubShader
	{
		Tags{"Queue"="Transparent" "RenderType"="Transparent"}

		Pass
		{
			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag

			#include "UnityCG.cginc"

			struct v2f
			{
				float4 screenPos : TEXCOORD1;
				float4 vertex : SV_POSITION;
			};

			float _DepthFactor;
			sampler2D _CameraDepthTexture;

			v2f vert(appdata_base v)
			{
				v2f o;
				o.vertex = UnityObjectToClipPos(v.vertex);
				o.screenPos = ComputeScreenPos(o.vertex);
				return o;
			}

			fixed4 frag(v2f i) : COLOR
			{
				float depthSample = SAMPLE_DEPTH_TEXTURE_PROJ(_CameraDepthTexture, UNITY_PROJ_COORD(i.screenPos));
				//将深度还原回z坐标(viewspace下的-z坐标)
				float depth = LinearEyeDepth(depthSample);
				//i.screenPos.w = -viewpos.z
				float foamLine = 1 - saturate(_DepthFactor * (depth - i.screenPos.w));
				return foamLine;
			}

			ENDCG
		}
	}
	FallBack "Diffuse"
}

:被相交物体,如本例中的cube组件,需要有ShadowCaster通道,最简单FallBack "Diffuse"即可
[1]https://lindseyreidblog.wordpress.com/
[2]https://lindseyreidblog.wordpress.com/2017/12/15/simple-water-shader-in-unity/

你可能感兴趣的:(笔记,shader)