问题总结-AlphaTest在forward管线生成DepthNormalsTexture的问题

Posted wolf96

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了问题总结-AlphaTest在forward管线生成DepthNormalsTexture的问题相关的知识,希望对你有一定的参考价值。

在Forward管线中,如果后期需要用到法线贴图,

需要将相机depthTextureMode 的Flag设置为DepthNormals

在相机面板可以确认

这样的话会把物体走一遍"Hidden/Internal-DepthNormalsTexture"来渲染出一张屏幕的Normal和Depth

"Hidden/Internal-DepthNormalsTexture"有很多pass,第一个是画不透明,第二个是画AlphaTest物体

画AlphaTest物体会需要传入_MainTex来确认alpha,还有_Cutoff参数,并且RenderType需要为"RenderType"="TransparentCutout",不满足上面两个条件就会走不透明的pass,这样被clip的部分也会画到法线图片上,就会出错

看下面的代码可以知道,pass分成了不透明,AlphaTest,还有地形相关的pass,clip是在fragment shader中做的,所以需要这些参数

Unity.cginc中

#define DECODE_EYEDEPTH(i) LinearEyeDepth(i)

#define COMPUTE_EYEDEPTH(o) o = -UnityObjectToViewPos( v.vertex ).z

#define COMPUTE_DEPTH_01 -(UnityObjectToViewPos( v.vertex ).z * _ProjectionParams.w)

#define COMPUTE_VIEW_NORMAL normalize(mul((float3x3)UNITY_MATRIX_IT_MV, v.normal))

输出法线原理是vertex shader中将顶点法线由模型空间变为世界空间,再在fragment shader中输出

输出深度的原理是将Z(相机空间深度)*w(1/farPlane)得出归一化深度

但是有一个疑问这两个的shader参数是怎么同步的呢?

Shader "Hidden/Internal-DepthNormalsTexture" 

Properties 

    _MainTex ("", 2D) = "white" 

    _Cutoff ("", Float) = 0.5

    _Color ("", Color) = (1,1,1,1)




SubShader 

    Tags  "RenderType"="Opaque" 

    Pass 

CGPROGRAM

#pragma vertex vert

#pragma fragment frag

#include "UnityCG.cginc"

struct v2f 

    float4 pos : SV_POSITION;

    float4 nz : TEXCOORD0;

    UNITY_VERTEX_OUTPUT_STEREO

;

v2f vert( appdata_base v ) 

    v2f o;

    UNITY_SETUP_INSTANCE_ID(v);

    UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);

    o.pos = UnityObjectToClipPos(v.vertex);

    o.nz.xyz = COMPUTE_VIEW_NORMAL;

    o.nz.w = COMPUTE_DEPTH_01;

    return o;



fixed4 frag(v2f i) : SV_Target 

    return EncodeDepthNormal (i.nz.w, i.nz.xyz);



ENDCG

    




SubShader 

    Tags  "RenderType"="TransparentCutout" 

    Pass 

CGPROGRAM

#pragma vertex vert

#pragma fragment frag

#include "UnityCG.cginc"

struct v2f 

    float4 pos : SV_POSITION;

    float2 uv : TEXCOORD0;

    float4 nz : TEXCOORD1;

    UNITY_VERTEX_OUTPUT_STEREO

;

uniform float4 _MainTex_ST;

v2f vert( appdata_base v ) 

    v2f o;

    UNITY_SETUP_INSTANCE_ID(v);

    UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);

    o.pos = UnityObjectToClipPos(v.vertex);

    o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);

    o.nz.xyz = COMPUTE_VIEW_NORMAL;

    o.nz.w = COMPUTE_DEPTH_01;

    return o;



uniform sampler2D _MainTex;

uniform fixed _Cutoff;

uniform fixed4 _Color;

fixed4 frag(v2f i) : SV_Target 

    fixed4 texcol = tex2D( _MainTex, i.uv );

    clip( texcol.a*_Color.a - _Cutoff );

    return EncodeDepthNormal (i.nz.w, i.nz.xyz);



ENDCG

    




SubShader 

    Tags  "RenderType"="TreeBark" 

    Pass 

CGPROGRAM

#pragma vertex vert

#pragma fragment frag

#include "UnityCG.cginc"

#include "Lighting.cginc"

#include "UnityBuiltin3xTreeLibrary.cginc"

struct v2f 

    float4 pos : SV_POSITION;

    float2 uv : TEXCOORD0;

    float4 nz : TEXCOORD1;

    UNITY_VERTEX_OUTPUT_STEREO

;

v2f vert( appdata_full v ) 

    v2f o;

    UNITY_SETUP_INSTANCE_ID(v);

    UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);

    TreeVertBark(v);


    o.pos = UnityObjectToClipPos(v.vertex);

    o.uv = v.texcoord.xy;

    o.nz.xyz = COMPUTE_VIEW_NORMAL;

    o.nz.w = COMPUTE_DEPTH_01;

    return o;



fixed4 frag( v2f i ) : SV_Target 

    return EncodeDepthNormal (i.nz.w, i.nz.xyz);



ENDCG

    




SubShader 

    Tags  "RenderType"="TreeLeaf" 

    Pass 

CGPROGRAM

#pragma vertex vert

#pragma fragment frag

#include "UnityCG.cginc"

#include "Lighting.cginc"

#include "UnityBuiltin3xTreeLibrary.cginc"

struct v2f 

    float4 pos : SV_POSITION;

    float2 uv : TEXCOORD0;

    float4 nz : TEXCOORD1;

    UNITY_VERTEX_OUTPUT_STEREO

;

v2f vert( appdata_full v ) 

    v2f o;

    UNITY_SETUP_INSTANCE_ID(v);

    UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);

    TreeVertLeaf(v);


    o.pos = UnityObjectToClipPos(v.vertex);

    o.uv = v.texcoord.xy;

    o.nz.xyz = COMPUTE_VIEW_NORMAL;

    o.nz.w = COMPUTE_DEPTH_01;

    return o;



uniform sampler2D _MainTex;

uniform fixed _Cutoff;

fixed4 frag( v2f i ) : SV_Target 

    half alpha = tex2D(_MainTex, i.uv).a;


    clip (alpha - _Cutoff);

    return EncodeDepthNormal (i.nz.w, i.nz.xyz);



ENDCG

    




SubShader 

    Tags  "RenderType"="TreeOpaque" "DisableBatching"="True" 

    Pass 

CGPROGRAM

#pragma vertex vert

#pragma fragment frag

#include "UnityCG.cginc"

#include "TerrainEngine.cginc"

struct v2f 

    float4 pos : SV_POSITION;

    float4 nz : TEXCOORD0;

    UNITY_VERTEX_OUTPUT_STEREO

;

struct appdata 

    float4 vertex : POSITION;

    float3 normal : NORMAL;

    fixed4 color : COLOR;

    UNITY_VERTEX_INPUT_INSTANCE_ID

;

v2f vert( appdata v ) 

    v2f o;

    UNITY_SETUP_INSTANCE_ID(v);

    UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);

    TerrainAnimateTree(v.vertex, v.color.w);

    o.pos = UnityObjectToClipPos(v.vertex);

    o.nz.xyz = COMPUTE_VIEW_NORMAL;

    o.nz.w = COMPUTE_DEPTH_01;

    return o;



fixed4 frag(v2f i) : SV_Target 

    return EncodeDepthNormal (i.nz.w, i.nz.xyz);



ENDCG

    




SubShader 

    Tags  "RenderType"="TreeTransparentCutout" "DisableBatching"="True" 

    Pass 

        Cull Back

CGPROGRAM

#pragma vertex vert

#pragma fragment frag

#include "UnityCG.cginc"

#include "TerrainEngine.cginc"


struct v2f 

    float4 pos : SV_POSITION;

    float2 uv : TEXCOORD0;

    float4 nz : TEXCOORD1;

    UNITY_VERTEX_OUTPUT_STEREO

;

struct appdata 

    float4 vertex : POSITION;

    float3 normal : NORMAL;

    fixed4 color : COLOR;

    float4 texcoord : TEXCOORD0;

    UNITY_VERTEX_INPUT_INSTANCE_ID

;

v2f vert( appdata v ) 

    v2f o;

    UNITY_SETUP_INSTANCE_ID(v);

    UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);

    TerrainAnimateTree(v.vertex, v.color.w);

    o.pos = UnityObjectToClipPos(v.vertex);

    o.uv = v.texcoord.xy;

    o.nz.xyz = COMPUTE_VIEW_NORMAL;

    o.nz.w = COMPUTE_DEPTH_01;

    return o;



uniform sampler2D _MainTex;

uniform fixed _Cutoff;

fixed4 frag(v2f i) : SV_Target 

    half alpha = tex2D(_MainTex, i.uv).a;


    clip (alpha - _Cutoff);

    return EncodeDepthNormal (i.nz.w, i.nz.xyz);



ENDCG

    

    Pass 

        Cull Front

CGPROGRAM

#pragma vertex vert

#pragma fragment frag

#include "UnityCG.cginc"

#include "TerrainEngine.cginc"


struct v2f 

    float4 pos : SV_POSITION;

    float2 uv : TEXCOORD0;

    float4 nz : TEXCOORD1;

    UNITY_VERTEX_OUTPUT_STEREO

;

struct appdata 

    float4 vertex : POSITION;

    float3 normal : NORMAL;

    fixed4 color : COLOR;

    float4 texcoord : TEXCOORD0;

    UNITY_VERTEX_INPUT_INSTANCE_ID

;

v2f vert( appdata v ) 

    v2f o;

    UNITY_SETUP_INSTANCE_ID(v);

    UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);

    TerrainAnimateTree(v.vertex, v.color.w);

    o.pos = UnityObjectToClipPos(v.vertex);

    o.uv = v.texcoord.xy;

    o.nz.xyz = -COMPUTE_VIEW_NORMAL;

    o.nz.w = COMPUTE_DEPTH_01;

    return o;



uniform sampler2D _MainTex;

uniform fixed _Cutoff;

fixed4 frag(v2f i) : SV_Target 

    fixed4 texcol = tex2D( _MainTex, i.uv );

    clip( texcol.a - _Cutoff );

    return EncodeDepthNormal (i.nz.w, i.nz.xyz);



ENDCG

    





SubShader 

    Tags  "RenderType"="TreeBillboard" 

    Pass 

        Cull Off

CGPROGRAM

#pragma vertex vert

#pragma fragment frag

#include "UnityCG.cginc"

#include "TerrainEngine.cginc"

struct v2f 

    float4 pos : SV_POSITION;

    float2 uv : TEXCOORD0;

    float4 nz : TEXCOORD1;

    UNITY_VERTEX_OUTPUT_STEREO

;

v2f vert (appdata_tree_billboard v) 

    v2f o;

    UNITY_SETUP_INSTANCE_ID(v);

    UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);

    TerrainBillboardTree(v.vertex, v.texcoord1.xy, v.texcoord.y);

    o.pos = UnityObjectToClipPos(v.vertex);

    o.uv.x = v.texcoord.x;

    o.uv.y = v.texcoord.y > 0;

    o.nz.xyz = float3(0,0,1);

    o.nz.w = COMPUTE_DEPTH_01;

    return o;



uniform sampler2D _MainTex;

fixed4 frag(v2f i) : SV_Target 

    fixed4 texcol = tex2D( _MainTex, i.uv );

    clip( texcol.a - 0.001 );

    return EncodeDepthNormal (i.nz.w, i.nz.xyz);



ENDCG

    




SubShader 

    Tags  "RenderType"="GrassBillboard" 

    Pass 

        Cull Off

CGPROGRAM

#pragma vertex vert

#pragma fragment frag

#include "UnityCG.cginc"

#include "TerrainEngine.cginc"


struct v2f 

    float4 pos : SV_POSITION;

    fixed4 color : COLOR;

    float2 uv : TEXCOORD0;

    float4 nz : TEXCOORD1;

    UNITY_VERTEX_OUTPUT_STEREO

;


v2f vert (appdata_full v) 

    v2f o;

    UNITY_SETUP_INSTANCE_ID(v);

    UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);

    WavingGrassBillboardVert (v);

    o.color = v.color;

    o.pos = UnityObjectToClipPos(v.vertex);

    o.uv = v.texcoord.xy;

    o.nz.xyz = COMPUTE_VIEW_NORMAL;

    o.nz.w = COMPUTE_DEPTH_01;

    return o;



uniform sampler2D _MainTex;

uniform fixed _Cutoff;

fixed4 frag(v2f i) : SV_Target 

    fixed4 texcol = tex2D( _MainTex, i.uv );

    fixed alpha = texcol.a * i.color.a;

    clip( alpha - _Cutoff );

    return EncodeDepthNormal (i.nz.w, i.nz.xyz);



ENDCG

    




SubShader 

    Tags  "RenderType"="Grass" 

    Pass 

        Cull Off

CGPROGRAM

#pragma vertex vert

#pragma fragment frag

#include "UnityCG.cginc"

#include "TerrainEngine.cginc"

struct v2f 

    float4 pos : SV_POSITION;

    fixed4 color : COLOR;

    float2 uv : TEXCOORD0;

    float4 nz : TEXCOORD1;

    UNITY_VERTEX_OUTPUT_STEREO

;


v2f vert (appdata_full v) 

    v2f o;

    UNITY_SETUP_INSTANCE_ID(v);

    UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);

    WavingGrassVert (v);

    o.color = v.color;

    o.pos = UnityObjectToClipPos(v.vertex);

    o.uv = v.texcoord;

    o.nz.xyz = COMPUTE_VIEW_NORMAL;

    o.nz.w = COMPUTE_DEPTH_01;

    return o;



uniform sampler2D _MainTex;

uniform fixed _Cutoff;

fixed4 frag(v2f i) : SV_Target 

    fixed4 texcol = tex2D( _MainTex, i.uv );

    fixed alpha = texcol.a * i.color.a;

    clip( alpha - _Cutoff );

    return EncodeDepthNormal (i.nz.w, i.nz.xyz);



ENDCG

    



Fallback Off

------by wolf96 2018/12/20

 

 

 

以上是关于问题总结-AlphaTest在forward管线生成DepthNormalsTexture的问题的主要内容,如果未能解决你的问题,请参考以下文章

[Unity Shader] 渲染管线流程

Unity Build-in管线shader移植到URP管线下

AlphaTest

GPU 渲染管线与着色器 大白话总结 ---- 一篇就够

基于mars3d海洋三维管线系统开发中期总结

基于cesium和mars3d海洋三维管线信息系统开发完工总结