Unity shader开启透明通道,开启Z缓存,渲染前后问题。

1回答

Unity shader开启透明通道,开启Z缓存,渲染前后问题。

提问者 30040852 2017-10-25 1k浏览
shader 开启了 Alpha,由于边缘显示教乱开启了Z缓存,之后在同一个模型中有前后结构的时候,出现遮罩闪烁,就是刚遮挡一点的时候不显示后面的,遮挡到一半的时候后面的突然出现,看起来很不舒服。请问大神们 这个问题应该如何解决?

shader如下:
Properties
{
_Color("Color", Color) = (1,1,1,1)
_MainTex("Albedo (RGB)", 2D) = "white" {}
    _AlphaScale("AlphaScale",Range(0,1)) = 1.0
_Emissive("Emissive",Color) = (0,0,0,0)
_EmissiveValue("EmissiveValue",Range(0,1)) = 0.0
}

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

Pass
{
Lighting Off
ZTest On
Zwrite On
ColorMask 0
}

Pass
{
Tags{ "LightMode" = "ForwardBase" }
Zwrite Off
Cull Off
Blend SrcAlpha OneMinusSrcAlpha

CGPROGRAM

#pragma vertex vert
#pragma fragment frag

#include "UnityCG.cginc"
#include "Lighting.cginc"

        fixed4 _Color;
    fixed4 _Emissive;

    sampler2D _MainTex;
float4 _MainTex_ST;
float _AlphaScale;
float _EmissiveValue;

struct a2v
{
float4 vertex:POSITION;
float3 normal:NORMAL;
float4 texcoord:TEXCOORD0;
};

struct v2f
{
float4 pos:SV_POSITION;
float3 worldPos:TEXCOORD0;
float3 worldNormal:TEXCOORD1;
float3 viewDir : TEXCOORD3;
float2 uv:TEXCOORD2;
};

v2f vert(a2v v)
{
v2f o;
o.pos = mul(UNITY_MATRIX_MVP,v.vertex);
o.worldNormal = UnityObjectToWorldNormal(v.normal);
o.worldPos = mul(_Object2World,v.vertex).xyz;
o.uv = TRANSFORM_TEX(v.texcoord,_MainTex);

return o;
}
fixed4 frag(v2f i) : COLOR
{
float3 worldLightDir = normalize(UnityWorldSpaceLightDir(i.worldPos));
float3 worldNormal = normalize(i.worldNormal);
float3 viewNormal = normalize(i.viewDir);

fixed4 texColor = tex2D(_MainTex,i.uv);
fixed3 albedo = texColor.rgb * _Color.rgb;
fixed3 diffuse = _LightColor0.rgb * albedo * pow(saturate(dot(worldNormal, worldLightDir)), _AlphaScale) _Emissive * _EmissiveValue;

fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz * albedo;

return fixed4(ambient diffuse, texColor.a * _AlphaScale);
}
ENDCG
}
}

FallBack "Diffuse"

快来消灭0回答吧

{{ dataList.answer_count | view-format }}回答
  • 南神 2017-10-25 16:10
    面试也经常提到,就是透明物体渲染顺序的问题。
    (1)两个物体的话可以更改Render Queue来避免。例如:两个plane,cube等等
    (2)一个物体的自遮挡问题,基本就是一个pass深度测试,并写入;一个pass利用缓存中的深度值来绘制。
    深度写入pass:就是根据ZTest 设定好的条件,比如说默认的LEqual,就是比较重叠部分距离相机的距离,小于等于该片元缓冲中的值,就替换掉缓冲中的值。这样就会找到模型最表层的深度,即表面(和ShadowMap类似,就相当于一个灰度图)。
    绘制pass:只比较与缓冲中的值(上一个pass留下的),不写入。设定好比较的ZTest参数,就能达到各样的效果。

    1评论
  • {{ answer.user.NickName }} {{ answer.profession }} {{ answer.created_at | time-format }}
    专家回答
    {{{ answer.answer }}}
    {{ answer.answer_count | view-format }}评论
加载中... 查看更多回答