팀프로젝트/R&D

2020.06.28. Shader_오브젝트 뒤에 가려진 물체 렌더링

dev_sr 2020. 6. 28. 14:54

이 코드보고 리뷰해보려고 공부한건데 아직 공부 못한 부분이 많아서 잘 모르겠음

 

 

1. 팬텀 쉐이더

 

출처:

 

z buffer test 를 조작해서 phantom shader 를 만들어 보자

[ 서론 ] 유튜브를 배회하다 우연히 본 동영상. 보다시피 돈주고 사야하는 Asset임. 공식적인 명칭인지는 모르겠지만 팬텀 쉐이더 (phantom shader) 를 오늘 한번 만들어 보겠음. [ 본론 ] 1.어떻게 구현�

egloos.zum.com

 

 

 

동영상에 보이는 것처럼 물체 뒤로 가면 색이 들어간 유령처럼 반투명해짐

Stencil 버퍼와 rim lighting 방법을 이용했다고 함 

_PhantomPower 변수를 조절해서 불투명 <-> 반투명 조절할 수 있음

 

*이것저것 만져봐서 원래 원작자가 올려주셨던 코드랑 좀 다를 수 있음

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
/*
    2014.12.27
    copyright(c) 2014.12.27
    all rights reserved by Little Wing Soft
*/
 
Shader "lwsoft/phantom" 
{
   Properties
    {
        _Color ("Main Color", Color) = (1,1,1,1)
        [perrenderdata]_MainTex ("Base (RGB)", 2D) = "white" {}
        _PhantomColor ("Phantom Color", Color) = (1,1,1,1)
        _PhantomPower ("Phantom Power", Float) = 1
        
    }
   
    SubShader
    {
        //Pass: character 
        stencil
        {
          ref 20
          comp Always
          
          pass replace
          
        }
        Tags { "Queue" = "Geometry+1" "RenderType" = "Opaque" }
 
        CGPROGRAM
        #pragma surface surf BlinnPhong 
        
       
        uniform float4 _Color;
        uniform float4 _Indicator;
        uniform sampler2D _MainTex;
         
        struct Input
        {
            float2 uv_MainTex;
            float3 viewDir;
        };
       
        void surf (Input IN, inout SurfaceOutput o)
        {
            o.Albedo = tex2D ( _MainTex, IN.uv_MainTex).rgb * _Color;
        }
        ENDCG
 
        // Pass: Phantom
        stencil
        {
          ref 20
          comp notequal
          
          pass replace
          zfail incrsat
        }
 
      ZWrite On
      ZTest Always
      
      Blend SrcAlpha OneMinusSrcAlpha
     
      CGPROGRAM
      #include "UnityCG.cginc"
      #pragma surface surf BlinnPhong
      uniform float4 _Color;
      uniform fixed  _PhantomPower;
      uniform fixed4 _PhantomColor;
      uniform sampler2D _MainTex;
      
      
      struct Input
      {
          float2 uv_MainTex;
          float3 viewDir;
          float3 worldNormal;
      };
     
      void surf (Input IN, inout SurfaceOutput o)
      {
            
            half rim = 1.0 - saturate(dot (normalize(IN.viewDir), IN.worldNormal ));
              fixed3 rim_final = _PhantomColor.rgb * pow (rim, _PhantomPower);
         
              o.Emission = rim_final.rgb ; 
              o.Alpha = rim * _PhantomColor.a;
      }
      ENDCG  
 
 
       
    }
 
 
   
    Fallback "Diffuse"0
 
}

 

 

버튼 누를 때마다

모델의 메테리얼을 바꿔서 벽 뒤에 가렸을 때 반투명 되는 처리를 on/off 로 제어해보고 싶었는데

안됨

방법이 이게 아닌가봄

-----------------------------------------

수정) 그냥 메테리얼에 넣으면 바뀜

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEditor;
 
public class App : MonoBehaviour
{
 
    public Button btn;
    public Material origin;
    public Material change;
    public GameObject model;
 
    private bool isFunctionON;  //벽에 가렸을 때 보여주는 기능을 키고 끌것인가
 
    void Start()
    {
        this.btn.onClick.AddListener(() =>
        {
            if(!this.isFunctionON)  //꺼졌을 때 누르면 켜라
            {
                this.model.GetComponent<SkinnedMeshRenderer>().material = this.change;
                this.isFunctionON = true;
            }
 
            if (this.isFunctionON)  //꺼졌을 때 누르면 켜라
            {
                this.model.GetComponent<SkinnedMeshRenderer>().material = this.origin;
                this.isFunctionON = false;
            }
 
 
        });
    }
 
  
}
 

 

 

 

2. Unlit으로 구현한 Shader

 

 

출처:

 

 

팬텀처럼 반투명해지는 건 아니고 색만 변함

쉐이더를 만들 때 Standard가 아니라 Unlit으로 만듦

 

Pass를 두개를 써서

처음엔 Depth를 무시하고 무조건 그리고

두번째엔 정상적으로 그리는 원리

 

설명을 들어도 지금은 모르는 코드가 많아서 상세하겐 모르겠음

 

 

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
Shader "Unlit/AlwaysVisible"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
        _Color("Always Visible Color",Color) = (0,0,0,0)
    }
    SubShader
    {
        Tags { "Queue"="Transparent" }
        LOD 200
 
 
        Pass
        {
            Cull off
            Zwrite off
 
            ZTest Always
 
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            
 
            #include "UnityCG.cginc"
 
 
            struct appdata
            {
                float4 vertex : POSITION;
 
            };
 
            struct v2f
            {
 
                float4 vertex : SV_POSITION;
            };
 
            float4 _Color;
 
            v2f vert(appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                return o;
            }
 
            fixed4 frag(v2f i) : SV_Target
            {
                return _Color;
            }
 
            
            ENDCG
 
        }
 
 
        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
 
            #include "UnityCG.cginc"
 
            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };
 
            struct v2f
            {
                float2 uv : TEXCOORD0;
                float4 vertex : SV_POSITION;
            };
 
            sampler2D _MainTex;
            float4 _MainTex_ST;
 
            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = TRANSFORM_TEX(v.uv, _MainTex);
                return o;
            }
 
            fixed4 frag (v2f i) : SV_Target
            {
                // sample the texture
                fixed4 col = tex2D(_MainTex, i.uv);
                return col;
            }
            ENDCG
        }
 
        
    }
}