【问题标题】:Outline shader break after upgrading to Unity 5.5升级到 Unity 5.5 后轮廓着色器中断
【发布时间】:2017-03-06 11:38:13
【问题描述】:

着色器在 iPad Air 上的 unity 5.4 上运行良好,但升级到 unity 5.5 后,它打破了轮廓,但 alpha 仍在运行。

此对象着色器支持纹理和 alpha

Shader "TFTM/Outline/Basic-Alpha" {
 Properties {
     _Color ("Main Color", Color) = (.5,.5,.5,1)
     _MainTex ("Base (RGB)", 2D) = "white" {}
 }


SubShader {
     Tags { "RenderType"="Opaque" "Queue"="Transparent" }
     Pass {
         Name "BASE"
         Blend SrcAlpha OneMinusSrcAlpha
         //Blend DstColor SrcColor
         CGPROGRAM
         #pragma vertex vert
         #pragma fragment frag
         #pragma fragmentoption ARB_precision_hint_fastest 
         #include "UnityCG.cginc"
         sampler2D _MainTex;
         float4 _MainTex_ST;
         float4 _Color;
         struct appdata {
             float4 vertex : POSITION;
             float2 texcoord : TEXCOORD0;
             float3 normal : NORMAL;
         };

         struct v2f {
             float4 pos : POSITION;
             float2 texcoord : TEXCOORD0;
         };
         v2f vert (appdata v)
         {
             v2f o;
             o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
             o.texcoord = TRANSFORM_TEX(v.texcoord, _MainTex);
             return o;
         }
         float4 frag (v2f i) : COLOR
         {
             float4 col = _Color * tex2D(_MainTex, i.texcoord);
             return float4(2.0f * col.rgb, col.a);
         }
         ENDCG            
     }
 } 
 SubShader {
     Tags { "RenderType"="Opaque" "Queue"="Transparent"}
     Pass {
         Name "BASE"
         SetTexture [_MainTex] {
             constantColor [_Color]
             Combine texture * constant
         } 
     }
 } 

 Fallback "VertexLit"
 }

这个shader做轮廓,2 pass,先在shader上面画,再画轮廓,然后剔除前面。

Shader "TFTM/Outline/Basic Outline-Alpha" {
     Properties {
         _Color ("Main Color", Color) = (.5,.5,.5,1)
         _OutlineColor ("Outline Color", Color) = (0,0,0,1)
         _Outline ("Outline width", Range (0, 0.02)) = 0
         _MainTex ("Base (RGB)", 2D) = "white" { }
     }

 CGINCLUDE
 #include "UnityCG.cginc"

 struct appdata {
     float4 vertex : POSITION;
     float3 normal : NORMAL;
 };
 struct v2f {
     float4 pos : POSITION;
     float4 color : COLOR;
 };

 uniform float _Outline;
 uniform float4 _OutlineColor;

 v2f vert(appdata v) {
     v2f o;
     o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
     float3 norm   = mul ((float3x3)UNITY_MATRIX_IT_MV, v.normal);
     float2 offset = TransformViewToProjection(norm.xy);
     o.pos.xy += offset * o.pos.z * _Outline;
     o.color = _OutlineColor;
     return o;
 }
 ENDCG
 SubShader {
     Tags { "RenderType"="Opaque" "Queue"="Transparent" }
     UsePass "TFTM/Outline/Basic-Alpha/BASE"
     Pass {
         Name "OUTLINE"
         Tags { "LightMode" = "Always" }
         Cull Front
         ZWrite On
         ColorMask RGB
         Blend DstColor SrcColor // 2x Multiplicative
         CGPROGRAM
         #pragma vertex vert
         #pragma fragment frag
         half4 frag(v2f i) :COLOR { return i.color ; }
         ENDCG
     }
 }

 SubShader {
     Tags { "RenderType"="Opaque" "Queue"="Transparent"}
     UsePass "TFTM/Outline/Basic-Alpha/BASE"
     Pass {
         Name "OUTLINE"
         Tags { "LightMode" = "Always" }
         Cull Front
         ZWrite On
         ColorMask RGB
         Blend DstColor SrcColor // 2x Multiplicative
         CGPROGRAM
         #pragma vertex vert
         #pragma exclude_renderers shaderonly
         ENDCG
         SetTexture [_MainTex] { combine primary }
     }
 }

 Fallback "TFTM/Outline/Basic-Alpha"
 }

【问题讨论】:

  • 不是 100% 确定,但更改日志提到:Shaders: Per-rendertarget blend modes. New shader syntax: "Blend N Src Dst", "BlendOp N Op", "ColorMask Mask N", where N is the render target index (0..7). This feature works on DX11/12, GLCore, Metal, PS4. 这可能会影响着色器。
  • 是的,我听说过 unity 5.5 更改日志,但经过我不知道它是否会影响上面的着色器。
  • 考虑到上面引用的更改提到了混合的语法更改,您似乎确实使用了几次,我认为它确实如此。再说一次,我不是着色器中的英雄。
  • 我昨天解决了这个问题,但我会再次解决,因为最好解决真正的问题。
  • 如果你修复了它,你应该将它作为答案发布,以便将来有同样问题的其他人也能得到帮助。

标签: unity3d fragment-shader


【解决方案1】:

我通过将 api 渲染更改为 OpenGL ES 3 而不是 Metal 来修复它,但当然现在它只是一个临时修复。

【讨论】:

    【解决方案2】:
    o.pos.xy += offset * o.pos.z * _Outline;
    

    o.pos.z 因平台而异。 https://docs.unity3d.com/Manual/SL-PlatformDifferences.html

    因此,您不能使用它来缩放轮廓。

    o.pos.z 的目的是保持轮廓大小不变,无论距离如何。

    现在,我们想要的是基于相机 z 轴的缩放值。

    float eye_depth;
    // This depth is based on camera's z axis
    COMPUTE_EYEDEPTH(eye_depth);
    // Divided by near plane. This is similar triangle math.
    float eye_depth_scale = eye_depth/_ProjectionParams.y; 
    o.pos.xy += offset * eye_depth_scale * _Outline; 
    

    如果太远,您可能需要限制 eye_depth 以防止缩放轮廓。

    【讨论】:

    猜你喜欢
    • 2018-03-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-25
    • 1970-01-01
    相关资源
    最近更新 更多