ShaderLab 偏移不渲染一个多边形在另一个之上
ShaderLab offset not rendering one polygon above the other
我有两个着色器,UnlitRGBA 和 TransparentNoOverlap。他们如下:
UnlitRGBA.shaderlab
// Unity built-in shader source. Copyright (c) 2016 Unity Technologies. MIT license (see license.txt)
// modified by rbjacob101
Shader "Particles/Standard Unlit (RGBA)"
{
Properties
{
_MainTex("Albedo", 2D) = "white" {}
_Color("Color", Color) = (1,1,1,1)
_Cutoff("Alpha Cutoff", Range(0.0, 1.0)) = 0.5
_BumpScale("Scale", Float) = 1.0
_BumpMap("Normal Map", 2D) = "bump" {}
_EmissionColor("Color", Color) = (0,0,0)
_EmissionMap("Emission", 2D) = "white" {}
_DistortionStrength("Strength", Float) = 1.0
_DistortionBlend("Blend", Range(0.0, 1.0)) = 0.5
_SoftParticlesNearFadeDistance("Soft Particles Near Fade", Float) = 0.0
_SoftParticlesFarFadeDistance("Soft Particles Far Fade", Float) = 1.0
_CameraNearFadeDistance("Camera Near Fade", Float) = 1.0
_CameraFarFadeDistance("Camera Far Fade", Float) = 2.0
// Hidden properties
[HideInInspector] _Mode("__mode", Float) = 0.0
[HideInInspector] _ColorMode("__colormode", Float) = 0.0
[HideInInspector] _FlipbookMode("__flipbookmode", Float) = 0.0
[HideInInspector] _LightingEnabled("__lightingenabled", Float) = 0.0
[HideInInspector] _DistortionEnabled("__distortionenabled", Float) = 0.0
[HideInInspector] _EmissionEnabled("__emissionenabled", Float) = 0.0
[HideInInspector] _BlendOp("__blendop", Float) = 0.0
[HideInInspector] _SrcBlend("__src", Float) = 1.0
[HideInInspector] _DstBlend("__dst", Float) = 0.0
[HideInInspector] _ZWrite("__zw", Float) = 1.0
[HideInInspector] _Cull("__cull", Float) = 2.0
[HideInInspector] _SoftParticlesEnabled("__softparticlesenabled", Float) = 0.0
[HideInInspector] _CameraFadingEnabled("__camerafadingenabled", Float) = 0.0
[HideInInspector] _SoftParticleFadeParams("__softparticlefadeparams", Vector) = (0,0,0,0)
[HideInInspector] _CameraFadeParams("__camerafadeparams", Vector) = (0,0,0,0)
[HideInInspector] _ColorAddSubDiff("__coloraddsubdiff", Vector) = (0,0,0,0)
[HideInInspector] _DistortionStrengthScaled("__distortionstrengthscaled", Float) = 0.0
}
Category
{
SubShader
{
Tags{ "RenderType" = "Opaque" "IgnoreProjector" = "True" "PreviewType" = "Plane" "PerformanceChecks" = "False" }
BlendOp[_BlendOp]
Blend[_SrcBlend][_DstBlend]
ZWrite[_ZWrite]
Offset -1, -1
Cull[_Cull]
ColorMask RGBA
GrabPass
{
Tags{ "LightMode" = "Always" }
"_GrabTexture"
}
Pass
{
Name "ShadowCaster"
Tags{ "LightMode" = "ShadowCaster" }
BlendOp Add
Blend One Zero
ZWrite On
Cull Off
CGPROGRAM
#pragma target 2.5
#pragma shader_feature _ _ALPHATEST_ON _ALPHABLEND_ON _ALPHAPREMULTIPLY_ON _ALPHAMODULATE_ON
#pragma shader_feature _ _COLOROVERLAY_ON _COLORCOLOR_ON _COLORADDSUBDIFF_ON
#pragma shader_feature _REQUIRE_UV2
#pragma multi_compile_shadowcaster
#pragma multi_compile_instancing
#pragma instancing_options procedural:vertInstancingSetup
#pragma vertex vertParticleShadowCaster
#pragma fragment fragParticleShadowCaster
#include "UnityStandardParticleShadow.cginc"
ENDCG
}
Pass
{
Tags{ "LightMode" = "ForwardBase" }
CGPROGRAM
#pragma multi_compile __ SOFTPARTICLES_ON
#pragma multi_compile_fog
#pragma target 2.5
#pragma shader_feature _ _ALPHATEST_ON _ALPHABLEND_ON _ALPHAPREMULTIPLY_ON _ALPHAMODULATE_ON
#pragma shader_feature _ _COLOROVERLAY_ON _COLORCOLOR_ON _COLORADDSUBDIFF_ON
#pragma shader_feature _NORMALMAP
#pragma shader_feature _EMISSION
#pragma shader_feature _FADING_ON
#pragma shader_feature _REQUIRE_UV2
#pragma shader_feature EFFECT_BUMP
#pragma vertex vertParticleUnlit
#pragma fragment fragParticleUnlit
#pragma multi_compile_instancing
#pragma instancing_options procedural:vertInstancingSetup
#include "UnityStandardParticles.cginc"
ENDCG
}
}
}
Fallback "VertexLit"
CustomEditor "StandardParticlesShaderGUI"
}
TransparentNoOverlap.shader
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
/*
* Taken from:
* https://forum.unity.com/threads/transparent-depth-shader-good-for-ghosts.149511/
*/
Shader "Transparent/TransparentNoOverlap" {
Properties {
[PerRendererData]_Color ("Main Color", Color) = (1,1,1,1)
_MainTex ("Base (RGB) Trans (A)", 2D) = "white" {}
}
SubShader {
Tags {"RenderType"="Transparent" "Queue"="Transparent" "IgnoreProjector"="True"}
LOD 200
Pass {
Name "TRANSPARENT"
ZWrite On
ZTest LEqual
Blend SrcAlpha OneMinusSrcAlpha
ColorMask RGBA
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
fixed4 _Color;
struct v2f {
float4 pos : SV_POSITION;
};
v2f vert (appdata_base v)
{
v2f o;
o.pos = UnityObjectToClipPos (v.vertex);
return o;
}
half4 frag (v2f i) : COLOR
{
return _Color;
}
ENDCG
}
CGPROGRAM
#pragma surface surf Lambert alpha
#pragma debug
sampler2D _MainTex;
fixed4 _Color;
struct Input {
float2 uv_MainTex;
};
void surf (Input IN, inout SurfaceOutput o) {
fixed4 c = tex2D(_MainTex, IN.uv_MainTex) * _Color;
o.Albedo = c.rgba;
o.Alpha = c.a;
}
ENDCG
}
Fallback "Transparent/Diffuse"
}
我希望使用 UnlitRGBA 的材质始终在 TransparentNoOverlap 上渲染。为了达到这个结果我会怎么做?我尝试将 Offset -1, -1
或 Offset 0, -1
添加到 UnlitRGBA。当针对标准表面着色器对此进行测试时,它工作正常并且 UnlitRGBA 始终呈现在顶部。但是当使用 TransparentNoOverlap 渲染时,要么存在 z-fighting,要么 TransparentNoOverlap 总是渲染在顶部。为什么是这样?我想这可能与 ZTests 或 ZWrites 有关,但我最终不确定。
对于大量代码示例,我深表歉意...感谢您提供的任何帮助。
rbjacob
请注意,预期结果和设置略有歧义,因此可能有多种方法。
简单地说:Material 着色器 A(无光照)被 B(透明)覆盖,因为 B 是在它之后绘制的。 "Queue"="Transparent" 是在 B 中负责该效果的标志。
着色器 A 没有它,所以它使用默认的 "Geometry" 队列。 (你可以在这里阅读引擎盖下使用的索引值:https://docs.unity3d.com/Manual/SL-SubShaderTags.html)。
因此,在这方面,您可以明确指定队列索引,并确保它们符合您的预期行为。
这忽略了另一个方面:处理一个网格被另一个网格遮挡的 ZBuffer,使得它们实际上不依赖于该绘制顺序。可以根据深度测试丢弃像素,如果指定,深度可以按对象写入。 (https://docs.unity3d.com/Manual/SL-CullAndDepth.html)
网格显示 z-fighting 如果它们都写入和测试,并且是 co-planar(在同一位置)或缓冲区精度低,因此存储的值看起来像是。
假设你的mesh既要遮挡又要遮挡别人和自己,一种方法是设置B(Transparent)使用ZTest Less,这样它只出现当 A 根本不存在时,即使在 A 之后绘制,即使 co-planar with A.
我有两个着色器,UnlitRGBA 和 TransparentNoOverlap。他们如下:
UnlitRGBA.shaderlab
// Unity built-in shader source. Copyright (c) 2016 Unity Technologies. MIT license (see license.txt)
// modified by rbjacob101
Shader "Particles/Standard Unlit (RGBA)"
{
Properties
{
_MainTex("Albedo", 2D) = "white" {}
_Color("Color", Color) = (1,1,1,1)
_Cutoff("Alpha Cutoff", Range(0.0, 1.0)) = 0.5
_BumpScale("Scale", Float) = 1.0
_BumpMap("Normal Map", 2D) = "bump" {}
_EmissionColor("Color", Color) = (0,0,0)
_EmissionMap("Emission", 2D) = "white" {}
_DistortionStrength("Strength", Float) = 1.0
_DistortionBlend("Blend", Range(0.0, 1.0)) = 0.5
_SoftParticlesNearFadeDistance("Soft Particles Near Fade", Float) = 0.0
_SoftParticlesFarFadeDistance("Soft Particles Far Fade", Float) = 1.0
_CameraNearFadeDistance("Camera Near Fade", Float) = 1.0
_CameraFarFadeDistance("Camera Far Fade", Float) = 2.0
// Hidden properties
[HideInInspector] _Mode("__mode", Float) = 0.0
[HideInInspector] _ColorMode("__colormode", Float) = 0.0
[HideInInspector] _FlipbookMode("__flipbookmode", Float) = 0.0
[HideInInspector] _LightingEnabled("__lightingenabled", Float) = 0.0
[HideInInspector] _DistortionEnabled("__distortionenabled", Float) = 0.0
[HideInInspector] _EmissionEnabled("__emissionenabled", Float) = 0.0
[HideInInspector] _BlendOp("__blendop", Float) = 0.0
[HideInInspector] _SrcBlend("__src", Float) = 1.0
[HideInInspector] _DstBlend("__dst", Float) = 0.0
[HideInInspector] _ZWrite("__zw", Float) = 1.0
[HideInInspector] _Cull("__cull", Float) = 2.0
[HideInInspector] _SoftParticlesEnabled("__softparticlesenabled", Float) = 0.0
[HideInInspector] _CameraFadingEnabled("__camerafadingenabled", Float) = 0.0
[HideInInspector] _SoftParticleFadeParams("__softparticlefadeparams", Vector) = (0,0,0,0)
[HideInInspector] _CameraFadeParams("__camerafadeparams", Vector) = (0,0,0,0)
[HideInInspector] _ColorAddSubDiff("__coloraddsubdiff", Vector) = (0,0,0,0)
[HideInInspector] _DistortionStrengthScaled("__distortionstrengthscaled", Float) = 0.0
}
Category
{
SubShader
{
Tags{ "RenderType" = "Opaque" "IgnoreProjector" = "True" "PreviewType" = "Plane" "PerformanceChecks" = "False" }
BlendOp[_BlendOp]
Blend[_SrcBlend][_DstBlend]
ZWrite[_ZWrite]
Offset -1, -1
Cull[_Cull]
ColorMask RGBA
GrabPass
{
Tags{ "LightMode" = "Always" }
"_GrabTexture"
}
Pass
{
Name "ShadowCaster"
Tags{ "LightMode" = "ShadowCaster" }
BlendOp Add
Blend One Zero
ZWrite On
Cull Off
CGPROGRAM
#pragma target 2.5
#pragma shader_feature _ _ALPHATEST_ON _ALPHABLEND_ON _ALPHAPREMULTIPLY_ON _ALPHAMODULATE_ON
#pragma shader_feature _ _COLOROVERLAY_ON _COLORCOLOR_ON _COLORADDSUBDIFF_ON
#pragma shader_feature _REQUIRE_UV2
#pragma multi_compile_shadowcaster
#pragma multi_compile_instancing
#pragma instancing_options procedural:vertInstancingSetup
#pragma vertex vertParticleShadowCaster
#pragma fragment fragParticleShadowCaster
#include "UnityStandardParticleShadow.cginc"
ENDCG
}
Pass
{
Tags{ "LightMode" = "ForwardBase" }
CGPROGRAM
#pragma multi_compile __ SOFTPARTICLES_ON
#pragma multi_compile_fog
#pragma target 2.5
#pragma shader_feature _ _ALPHATEST_ON _ALPHABLEND_ON _ALPHAPREMULTIPLY_ON _ALPHAMODULATE_ON
#pragma shader_feature _ _COLOROVERLAY_ON _COLORCOLOR_ON _COLORADDSUBDIFF_ON
#pragma shader_feature _NORMALMAP
#pragma shader_feature _EMISSION
#pragma shader_feature _FADING_ON
#pragma shader_feature _REQUIRE_UV2
#pragma shader_feature EFFECT_BUMP
#pragma vertex vertParticleUnlit
#pragma fragment fragParticleUnlit
#pragma multi_compile_instancing
#pragma instancing_options procedural:vertInstancingSetup
#include "UnityStandardParticles.cginc"
ENDCG
}
}
}
Fallback "VertexLit"
CustomEditor "StandardParticlesShaderGUI"
}
TransparentNoOverlap.shader
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
/*
* Taken from:
* https://forum.unity.com/threads/transparent-depth-shader-good-for-ghosts.149511/
*/
Shader "Transparent/TransparentNoOverlap" {
Properties {
[PerRendererData]_Color ("Main Color", Color) = (1,1,1,1)
_MainTex ("Base (RGB) Trans (A)", 2D) = "white" {}
}
SubShader {
Tags {"RenderType"="Transparent" "Queue"="Transparent" "IgnoreProjector"="True"}
LOD 200
Pass {
Name "TRANSPARENT"
ZWrite On
ZTest LEqual
Blend SrcAlpha OneMinusSrcAlpha
ColorMask RGBA
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
fixed4 _Color;
struct v2f {
float4 pos : SV_POSITION;
};
v2f vert (appdata_base v)
{
v2f o;
o.pos = UnityObjectToClipPos (v.vertex);
return o;
}
half4 frag (v2f i) : COLOR
{
return _Color;
}
ENDCG
}
CGPROGRAM
#pragma surface surf Lambert alpha
#pragma debug
sampler2D _MainTex;
fixed4 _Color;
struct Input {
float2 uv_MainTex;
};
void surf (Input IN, inout SurfaceOutput o) {
fixed4 c = tex2D(_MainTex, IN.uv_MainTex) * _Color;
o.Albedo = c.rgba;
o.Alpha = c.a;
}
ENDCG
}
Fallback "Transparent/Diffuse"
}
我希望使用 UnlitRGBA 的材质始终在 TransparentNoOverlap 上渲染。为了达到这个结果我会怎么做?我尝试将 Offset -1, -1
或 Offset 0, -1
添加到 UnlitRGBA。当针对标准表面着色器对此进行测试时,它工作正常并且 UnlitRGBA 始终呈现在顶部。但是当使用 TransparentNoOverlap 渲染时,要么存在 z-fighting,要么 TransparentNoOverlap 总是渲染在顶部。为什么是这样?我想这可能与 ZTests 或 ZWrites 有关,但我最终不确定。
对于大量代码示例,我深表歉意...感谢您提供的任何帮助。
rbjacob
请注意,预期结果和设置略有歧义,因此可能有多种方法。
简单地说:Material 着色器 A(无光照)被 B(透明)覆盖,因为 B 是在它之后绘制的。 "Queue"="Transparent" 是在 B 中负责该效果的标志。 着色器 A 没有它,所以它使用默认的 "Geometry" 队列。 (你可以在这里阅读引擎盖下使用的索引值:https://docs.unity3d.com/Manual/SL-SubShaderTags.html)。 因此,在这方面,您可以明确指定队列索引,并确保它们符合您的预期行为。
这忽略了另一个方面:处理一个网格被另一个网格遮挡的 ZBuffer,使得它们实际上不依赖于该绘制顺序。可以根据深度测试丢弃像素,如果指定,深度可以按对象写入。 (https://docs.unity3d.com/Manual/SL-CullAndDepth.html)
网格显示 z-fighting 如果它们都写入和测试,并且是 co-planar(在同一位置)或缓冲区精度低,因此存储的值看起来像是。
假设你的mesh既要遮挡又要遮挡别人和自己,一种方法是设置B(Transparent)使用ZTest Less,这样它只出现当 A 根本不存在时,即使在 A 之后绘制,即使 co-planar with A.