#笔记-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得出
例程很简单,可用改例程扩展为海边浪花等shader效果
源码c#添加到camera组件下
using UnityEngine;
using System.Collections;
using UnityEditor;
[ExecuteInEditMode]
public class RenderDepthMap : MonoBehaviour
{
private Camera cam;
void Start()
{
cam = GetComponent<Camera>();
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/