在Unity3D(Unlit版本)中使用自定义着色器时,我的3D对象与alpha重叠:
它应该看起来像这样:
Shader "Custom/Shader1" {
Properties {
_Color ("Main Color", Color) = (1,1,1,1)
_MainTex ("Base (RGB) Trans (A)", 2D) = "white" {}
_Cutoff ("Alpha cutoff", Range(0,1)) = 0.5
}
SubShader {
Tags { "Queue"="Transparent" "RenderType"="Transparent" "IgnoreProjector"="True" }
Pass {
ZWrite On
ColorMask 0
}
Pass {
ZWrite Off // don't write to depth buffer
Blend SrcAlpha OneMinusSrcAlpha // use alpha blending
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
uniform float4 _Color; // define shader property for shaders
uniform sampler2D _MainTex;
uniform float _Cutoff;
struct vertexInput {
float4 vertex : POSITION;
float2 texcoord : TEXCOORD0;
};
struct vertexOutput {
float4 pos : SV_POSITION;
float2 tex : TEXCOORD0;
};
vertexOutput vert(vertexInput input) {
vertexOutput output;
output.tex = input.texcoord;
output.pos = UnityObjectToClipPos(input.vertex);
return output;
}
float4 frag(vertexOutput input) : COLOR {
float4 col = tex2D(_MainTex, input.tex) * _Color;
float newOpacity = 1.0;
if (col.a < _Cutoff) {
newOpacity = 0.0;
}
return float4(col.r, col.g, col.b, newOpacity);
}
ENDCG
}
}
}
我错过了什么吗?似乎透明度alpha重叠自己。
修改1
我删除了第一个传递,然后启用了Zbuffer并删除了if (col.a < _Cutoff)
并根据其纹理让它变为动态,但我仍然得到与第一个图像相同的结果。
Shader "Custom/Shader1" {
Properties {
_Color ("Main Color", Color) = (1,1,1,1)
_MainTex ("Base (RGB) Trans (A)", 2D) = "white" {}
_Cutoff ("Alpha cutoff", Range(0,1)) = 0.5
}
SubShader {
Tags { "Queue"="Transparent" "RenderType"="Transparent" "IgnoreProjector"="True" }
Pass {
ZWrite On
Blend SrcAlpha OneMinusSrcAlpha // use alpha blending
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
uniform float4 _Color; // define shader property for shaders
uniform sampler2D _MainTex;
uniform float _Cutoff;
struct vertexInput {
float4 vertex : POSITION;
float2 texcoord : TEXCOORD0;
};
struct vertexOutput {
float4 pos : SV_POSITION;
float2 tex : TEXCOORD0;
};
vertexOutput vert(vertexInput input) {
vertexOutput output;
output.tex = input.texcoord;
output.pos = UnityObjectToClipPos(input.vertex);
return output;
}
float4 frag(vertexOutput input) : COLOR {
float4 col = tex2D(_MainTex, input.tex) * _Color;
return col;
}
ENDCG
}
}
}
答案 0 :(得分:2)
(col.a < _Cutoff)
始终为真或假,没有中间值,它始终完全显示或完全隐藏。最重要的是,您编写该条件的方式可能会在着色器中生成一些动态分支,请尝试静态分支而不是float newOpacity = (col.a < _Cutoff) ? 0.0 : 1.0;
(在这种情况下,执行的代码始终相同,只有值更改通常更好用于perfs)。您可以阅读Unity公开的语义来控制Surface着色器中的alpha测试:https://docs.unity3d.com/Manual/SL-SurfaceShaders.html,特别是那部分:
alphatest:VariableName - 启用Alpha剪切透明度。隔断 value是一个带VariableName的float变量。你也可能 想要使用 addshadow 指令来生成适当的阴影施法者 通过。
或者,您可以将clip()方法与加入阴影结合使用,最有可能与clip(col.a - 0.5);