【问题标题】:Unity3d mobile shader transparency issueUnity3d移动着色器透明度问题
【发布时间】:2023-04-03 18:18:01
【问题描述】:

在 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 &lt; _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
     }
    }
   }

【问题讨论】:

    标签: unity3d shader transparency alphablending depth-testing


    【解决方案1】:
    1. 着色器未点亮,因为您使用常规 CG 着色器而不是 Surface 着色器,其目的是方便地在场景后面提供照明。解决方案:从表面着色器模板重新开始
    2. 没有利用 Alpha 混合,因为(col.a &lt; _Cutoff) 始终为真或假,没有中间值,它始终完全显示或完全隐藏。最重要的是,您编写该条件的方式可能会在着色器中生成一些动态分支,请尝试使用静态分支而不是 float newOpacity = (col.a &lt; _Cutoff) ? 0.0 : 1.0;(在这种情况下,执行的代码始终相同,只有值发生变化,这通常对 perfs 更好) .
    3. 着色器有 2 个通道,这将阻止以后进行批处理,这对性能非常不利。一个是填充 Zbuffer,另一个是进行 alpha 混合(2 个操作并不真正兼容)。 prepass 不能正常工作,因为它用原始网格填充缓冲区,而没有来自纹理的透明度信息。 当然你可以修改第一个 pass 来做到这一点,但是你看的结果for 本质上只是一个非常简单的 Surface 着色器开启了 alpha 测试

    您可以在此处阅读 Unity 公开的语义以控制 Surface 着色器中的 Alpha 测试:https://docs.unity3d.com/Manual/SL-SurfaceShaders.html,特别是该部分:

    alphatest:VariableName - 启用 alpha 剪切透明度。隔断 value 位于带有 VariableName 的浮点变量中。你可能还会 想使用 addshadow 指令来生成正确的阴影投射器 通过。

    或者,您可以将 clip() 方法与 addshadow 结合使用,很可能沿用 clip(col.a - 0.5);

    【讨论】:

    • 嗨@Brice,1. 表面着色器在移动reference 中有很大的性能成本。这就是我坚持使用常规着色器的原因。 2. 如何编写代码以利用常规着色器中的 alpha 混合?如果你有示例我可以参考 =) 3. 我使用 2 次传递,因为如果我不写到 zbuffer,渲染顺序似乎是错误的,正如这里提到的 link。我们如何解决这个问题?
    • 我之前做过 abit 研究,clip() 函数和 alpha 测试在移动设备中的成本很高,因为它们无法利用延迟渲染。 2 次通过优于 alpha 测试,如“有效使用隐藏表面去除”下的 here 所述
    • 我根据您的建议用新代码更新了我的帖子,但遇到了同样的问题
    • 嗨。您没有在问题中提及有关移动或延迟的任何内容,在这种情况下,您是对的,它具有重大影响:) 这完全取决于您的用例,不幸的是,我对此一无所知。透明度和排序是一个大话题,没有万能的解决方案。
    • 嗨@Brice,抱歉没有提到移动设备。我更新了标题。您知道我可以在哪里寻找适合我的问题的不同解决方案吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-16
    • 1970-01-01
    • 2013-02-20
    • 2021-06-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多