管理着色器Alpha和深度

时间:2018-04-13 06:59:15

标签: unity3d shader alpha depth

我有一个对象。我正在申请一架飞机。这个平面定义了我希望看到哪些像素,另一个必须是不可见的。

这是另一个观点的对象。我们看到他的左边是切割物体。

Here it's the object with an other point of view. We see the object is cut on his left.

这是从平面角度看的物体。飞机已经切割了一些物体。但是我们看到这些部分总是在这里,因为它们隐藏了对象的其他部分。

Here is the object see from the plane point of view. The plane has already cut some part of the object. But we see that these parts are always here because they hide the other part of the object.

最大的问题是我不能在运行时动态更改对象的不透明度,而不会将alpha pragma放到我的着色器代码中。但是这个alpha pragma打破了我的所有对象与一些工件,因为Unity无法管理Fade& ZDepth。我的意思是当你有一个不透明的着色器时,它与同一个着色器不同,但是使用了pragma alpha。 (编辑器中没有alpha变化或其他)。

以下是将alpha pragma放入我的着色器代码中的结果示例。

Here is an example of result to just put alpha pragma in my shader code.

我只想要一个“不透明”的对象(我的CutPlane可以很好地使用它),但也动态地改变了不透明度。

如果有人有想法:)谢谢

编辑:着色器代码

Shader "Custom/Clipping" {


    Properties {
      _Conversion ("Conversion (RGB)", 2D) = "white" {}     
      _MainTex ("Main Texture", 2D) = "white" {}            
      _NormalxValue("Normal X Value", Float) = 1        
      _Glossiness ("Smoothness", Range(0,1)) = 0.5          
      _Metallic ("Metallic", Range(0,1)) = 0.0      
      _Color ("Color", Color) = (0.5,0.5,0.5,1)
    }
    SubShader {
      Tags { "Queue" = "Transparent"  "RenderType" = "TransparentCutout" "DisableBatching" = "True" }
      LOD 200

      Cull Off

     Pass {
        ZWrite On
        ColorMask 0

        CGPROGRAM
        #pragma vertex vert
        #pragma fragment frag
        #include "UnityCG.cginc"

        struct v2f {
            float4 pos : SV_POSITION;
        };

        v2f vert (appdata_base v)
        {
            v2f o;
            o.pos = UnityObjectToClipPos (v.vertex); //o.pos = 0 ==> no Depth

            //Here I know that if I put o.pos = 0; Zbuffer is desactivate.
            return o;
        }

        half4 frag (v2f i) : COLOR
        {
            return half4 (0,0,0,0);
        }

       ENDCG  
    }


      CGPROGRAM

      #pragma surface surf Standard alpha
      #pragma target 3.0

      struct Input {
          float2 uv_MainTex;    
          float2 uv_BumpMap;        
          float2 uv_Conversion;     
          float3 worldPos;          
      };    

      half _Glossiness;
      half _Metallic;
      half _ConvertDistance;
      half _ConvertEmission; 
      fixed4 _Color;

      ////////////////////// 
      /// <Cut Area
      //////////////////////
      float3 _PlaneNormal;

      //Plane variables
      float _xValue;
      float _yValue;
      float _zValue;

      float _NormalxValue;
      float _NormalyValue;
      float _NormalzValue;
      ////////////////////// 
      /// Cut Area />
      //////////////////////

      ////////////////////// 
      /// <Interest Area (sphere)
      //////////////////////

      sampler2D _MainTex;
      sampler2D _BumpMap;
      sampler2D _Conversion;

      void surf (Input IN, inout SurfaceOutputStandard o) {

        _ConvertDistance = 0.4;
        _ConvertEmission = 0.45;
        _PlaneNormal = float3(_NormalxValue,_NormalyValue,_NormalzValue);
        _PlaneNormal = normalize(_PlaneNormal);

        // Calculate distance from object to plane
        half dist = (IN.worldPos.x * _PlaneNormal.x) + (IN.worldPos.y * _PlaneNormal.y) + (IN.worldPos.z * _PlaneNormal.z)
                    - (_xValue * _PlaneNormal.x) - (_yValue * _PlaneNormal.y) - (_zValue * _PlaneNormal.z) 
            / sqrt( pow(_PlaneNormal.x, 2) + pow(_PlaneNormal.y, 2) + pow(_PlaneNormal.z,2));

        float convert_mask = dist / _ConvertDistance;

        if(any(dist < 0))
        {
            discard;
        }
        ///////////////////////////////////////////////////////

        o.Albedo = _Color;
        o.Metallic = _Metallic;
        o.Smoothness = _Glossiness;
        o.Alpha = _Color.a;   

      }
       ENDCG
    } 
    // Si pas de subshader possible - On appelle un shader Diffuse.
    Fallback "Diffuse"
  }

1 个答案:

答案 0 :(得分:0)

我正在回答我自己的问题,以防有人遇到同样的问题。

问题是我使用我的对象的wolrdPosition计算我的切割平面的颜色,而对于ZBuffer,我使用ClipPos位置做了相同的操作。

在顶点函数中添加此行:

o.worldPos =  mul(unity_ObjectToWorld, v.vertex);

并用它来计算。不要使用

给出的ClipPos
o.pos = UnityObjectToClipPos (v.vertex);