問題總結-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

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章