2016-02-23 18 views
12

Tôi đang cố viết một bóng đổ cho sự thống nhất sẽ làm nổi bật các phần chồng chéo của các mắt lưới. Nó sẽ làm việc cho một đối tượng chồng chéo chính nó cũng như nhiều đối tượng.Unity Shader làm nổi bật chồng lên nhau

Kết quả sẽ giống như hình ảnh đính kèm. enter image description here

Đầu tiên tôi đã cố gắng thực hiện điều này với phát hiện va chạm nhưng tôi nghĩ rằng cách tốt nhất là viết bóng đổ.

Tôi không quen thuộc với các trình đổ bóng nên nếu có ai có thể giúp tôi, tôi sẽ biết ơn.

Tôi nghĩ rằng nó có thể được thực hiện bằng cách sử dụng shaders stencil như ở đây http://docs.unity3d.com/Manual/SL-Stencil.html nhưng shader này chỉ hiển thị giao điểm của hai đối tượng mà không cần render toàn bộ đối tượng.

Tôi cũng thấy đổ bóng dựa trên Depth (https://chrismflynn.wordpress.com/2012/09/06/fun-with-shaders-and-the-depth-buffer/) nhưng điều này cũng làm việc trên hai đối tượng và không hoạt động trên một lưới trùng tự

Về @Zze bình luận với ý tưởng về hai đèo tôi có bây giờ hai shaders . Và nó hoạt động trên hai đối tượng khi có một đối tượng và một đối tượng khác có thứ hai.

Có lẽ ai cũng có thể giúp tôi cách kết hợp nó thành một trình đổ bóng cũng sẽ hoạt động trong đối tượng sẽ chồng lên nhau?

ShaderOne

Shader "Custom/ShaderOne" 
{ 
    SubShader { 
     Tags { "RenderType"="Opaque" "Queue"="Geometry"} 
     Pass { 
      Stencil { 
       Ref 2 
       Comp always 
       Pass keep 
       Fail decrWrap 
       ZFail keep 
      } 

      CGPROGRAM 
      #pragma vertex vert 
      #pragma fragment frag 
      struct appdata { 
       float4 vertex : POSITION; 
      }; 
      struct v2f { 
       float4 pos : SV_POSITION; 
      }; 
      v2f vert(appdata v) { 
       v2f o; 
       o.pos = mul(UNITY_MATRIX_MVP, v.vertex); 
       return o; 
      } 
      half4 frag(v2f i) : SV_Target { 
       return half4(0,1,0,1); 
      } 
      ENDCG 
     } 
     Pass { 
      Stencil { 
       Ref 2 
       Comp equal 
      } 

      CGPROGRAM 
      #pragma vertex vert 
      #pragma fragment frag 
      struct appdata { 
       float4 vertex : POSITION; 
      }; 
      struct v2f { 
       float4 pos : SV_POSITION; 
      }; 
      v2f vert(appdata v) { 
       v2f o; 
       o.pos = mul(UNITY_MATRIX_MVP, v.vertex); 
       return o; 
      } 
      half4 frag(v2f i) : SV_Target { 
       return half4(0,0,1,1); 
      } 
      ENDCG 
     } 

    } 
} 

ShaderTwo

Shader "Custom/ShaderTwo" 
{ 
    SubShader { 
     Tags { "RenderType"="Opaque" "Queue"="Geometry"} 
     Pass { 
      Stencil { 
       Ref 2 
       Comp always 
       Pass replace 
       ZFail keep 
      } 

      CGPROGRAM 
      #pragma vertex vert 
      #pragma fragment frag 
      struct appdata { 
       float4 vertex : POSITION; 
      }; 
      struct v2f { 
       float4 pos : SV_POSITION; 
      }; 
      v2f vert(appdata v) { 
       v2f o; 
       o.pos = mul(UNITY_MATRIX_MVP, v.vertex); 
       return o; 
      } 
      half4 frag(v2f i) : SV_Target { 
       return half4(1,0,0,1); 
      } 
      ENDCG 
     } 
    } 
} 

Kết quả trông giống như một hình ảnh gắn liền enter image description here

+0

Nếu shader stencil làm cho các điểm giao nhau, thì tại sao bạn không làm một Shader với 2 đường chuyền, những người đầu tiên thu hút bình thường và sau đó bắt chước thứ hai là kết quả của sự đổ bóng stencil? – Zze

+0

Bạn có thể muốn xem khái niệm lột sâu. Xem [tại đây] (http: //www.opengl-tutorial.org/trung bình-hướng dẫn/hướng dẫn-10-minh bạch /) và [ở đây] (http://www.eng.utah.edu/~cs5610/handouts/order_independent_transparency.pdf). Bạn cũng dự định có bao nhiêu đồ vật. Nếu không nhiều bạn có thể muốn hiển thị từng đối tượng cho một kết cấu và sau đó kết hợp chúng như một bộ đệm tích lũy. – mrVoid

+0

@mrVoid Tôi nghĩ rằng kiểm tra độ sâu sẽ hoạt động trong tình huống này chỉ với chế độ xem trên máy ảnh - nhưng khi nào thì quan điểm này sẽ không hoạt động? Tôi bị đau đầu vì điều này. có lẽ bạn có thể cung cấp cho tôi một số ví dụ về việc sử dụng nó với mã mẫu? – seek

Trả lời

2

Vấn đề này có thể được giải quyết với sự giúp đỡ của Stencil đệm và một, hai-pass đổ bóng. Ý tưởng là như sau:

  • Vượt qua đầu tiên so sánh giá trị trong bộ đệm stencil với 0. Trong cả hai trường hợp (vượt qua/thất bại) tăng giá trị trong bộ đệm.
  • Lần vượt qua thứ hai so sánh giá trị trong bộ đệm stencil với 1. Nếu giá trị tham chiếu 1 nhỏ hơn, chúng tôi vượt qua và làm nổi bật pixel trùng lặp.

Bạn có thể muốn thêm đèo rằng cũng giống như thứ hai, nhưng với giá trị tham khảo khác nhau để làm nổi bật các khu vực chồng lấn hai lần, ba lần, vv

Trong ký hiệu shaderlab Unity, nó nên có một cái gì đó như thế:

Pass 
    { 
     Stencil { 
      Ref 0 
      Comp Equal 
      Pass IncrSat 
      Fail IncrSat 
     } 

     // Shader for not overlapping regions goes here. 
    } 

    Pass 
    { 
     Stencil { 
      Ref 1 
      Comp Less 
     } 

     // Shader for one-time overlapping regions goes here. 
    } 

    Pass 
    { 
     Stencil { 
      Ref 2 
      Comp Less 
     } 

     // Shader for two-time overlapping regions goes here. 
    } 

Ví dụ:

enter image description here

Shader:

Shader "Unlit/Stencil" 
{ 
    Properties 
    { 
     _MainTex ("Texture", 2D) = "white" {} 
    } 
    SubShader 
    { 
     Tags { "RenderType"="Opaque" } 
     LOD 100 

     Pass 
     { 
      Stencil { 
       Ref 0 
       Comp Equal 
       Pass IncrSat 
       Fail IncrSat 
      } 

      CGPROGRAM 
      #pragma vertex vert 
      #pragma fragment frag 

      #include "UnityCG.cginc" 

      struct appdata 
      { 
       float4 vertex : POSITION; 
      }; 

      struct v2f 
      { 
       float4 vertex : SV_POSITION; 
      }; 

      v2f vert (appdata v) 
      { 
       v2f o; 
       o.vertex = mul(UNITY_MATRIX_MVP, v.vertex); 
       return o; 
      } 

      fixed4 frag (v2f i) : SV_Target 
      { 
       fixed4 col = fixed4(0.0, 0.0, 1.0, 1.0); 
       return col; 
      } 
      ENDCG 
     } 

     Pass 
     { 
      Stencil { 
       Ref 1 
       Comp Less 
      } 

      CGPROGRAM 
      #pragma vertex vert 
      #pragma fragment frag 

      #include "UnityCG.cginc" 

      struct appdata 
      { 
       float4 vertex : POSITION; 
      }; 

      struct v2f 
      { 
       float4 vertex : SV_POSITION; 
      }; 

      v2f vert (appdata v) 
      { 
       v2f o; 
       o.vertex = mul(UNITY_MATRIX_MVP, v.vertex); 
       return o; 
      } 

      fixed4 frag (v2f i) : SV_Target 
      { 
       fixed4 col = fixed4(1.0, 1.0, 0.0, 1.0); 
       return col; 
      } 
      ENDCG 
     } 

     Pass 
     { 
      Stencil { 
       Ref 2 
       Comp Less 
      } 

      CGPROGRAM 
      #pragma vertex vert 
      #pragma fragment frag 

      #include "UnityCG.cginc" 

      struct appdata 
      { 
       float4 vertex : POSITION; 
      }; 

      struct v2f 
      { 
       float4 vertex : SV_POSITION; 
      }; 

      v2f vert (appdata v) 
      { 
       v2f o; 
       o.vertex = mul(UNITY_MATRIX_MVP, v.vertex); 
       return o; 
      } 

      fixed4 frag (v2f i) : SV_Target 
      { 
       fixed4 col = fixed4(1.0, 0.0, 0.0, 1.0); 
       return col; 
      } 
      ENDCG 
     } 
    } 
} 
+0

Hoạt động tuyệt vời !. Đó là chính xác những gì tôi đang tìm kiếm. Vui lòng cho tôi biết trình đổ bóng này được hiển thị ở đầu những người khác, có thể thêm Hàng đợi vào điều này không? Và điều khác là nó có thể làm điều này cho hai mặt cũng? – seek

+2

> Vui lòng cho tôi biết trình đổ bóng này được hiển thị trên đầu trang của những người khác, có thể thêm Hàng đợi vào điều này không? Không chắc chắn rằng tôi đã hiểu chính xác câu hỏi. Bạn có thể thay thế shader trong mỗi Pass với riêng bạn, để có được các shaders khác nhau cho các vùng chồng chéo và không chồng chéo. Bạn có thể hiển thị nó trên đầu trang của những người khác bằng cách sử dụng Hàng đợi. Bạn cũng có thể hiển thị hai mặt. Bạn chỉ cần thiết lập 'Cull Off'. – Podgorskiy

+0

Tôi có nghĩa là tôi có các đối tượng khác trên hiện trường sẽ được hiển thị trên đầu đối tượng này với trình đổ bóng của bạn. – seek

Các vấn đề liên quan