유니티 쉐이더 - 블린퐁

블린 퐁은 퐁쉐이딩을 간단화한 공식이다.

 

퐁 쉐이딩은 다루지 않을 예정이니 간단하게 말하고 넘어가면

 

"내가 보는 방향으로부터 반사된 방향에 조명이 잇으면 그 부분의 하이라이트가 가장 높다"

라는 것이 퐁 쉐이딩의 이론이다.

 

그래서 퐁 쉐이딩은 넘어가고

 

블린 퐁 쉐이딩이라니는 퐁쉐이딩을 간단화한 공식은

H = normalize(lightDir+viewDir):이다 ( 벡터의 방향은 위의 그림과같음 )

 

빛의 강도는

float specLightPower = pow(saturate(dot(H,surface의 NomalVector)),원하는 강도); 이고

빛의 표현은 이렇게 해주면되고

float3 specColor = specColor(입력값)*specLightPower;

 

float4 finalColor = float4(디퓨즈 컬러 + specColor,surface의 알파값);

 

을 해주면 된다.

 

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
Shader "Custom/BlinPhong"
{
    Properties
    {
        _MainTex ("Albedo (RGB)", 2D) = "white" {}
        _BumpMap("NormalMap",2D) = "bump"{}
        _SpecCol("Specular Color", Color) = (1,1,1,1)
        _SpecPow("Specular Pow",Range(10,100)) = 100
    }
            SubShader
            {
                Tags { "RenderType" = "Opaque" }
                LOD 200
 
                CGPROGRAM
            // Physically based Standard lighting model, and enable shadows on all light types
            #pragma surface surf Test
 
            // Use shader model 3.0 target, to get nicer looking lighting
            #pragma target 3.0
            
        sampler2D _MainTex;
        sampler2D _BumpMap;
        struct Input
        {
            float2 uv_MainTex;
            float2 uv_BumpMap;
        };
        float4 _SpecCol;
        float _SpecPow;
 
        void surf (Input IN, inout SurfaceOutput o)
        {
            fixed4 c = tex2D (_MainTex, IN.uv_MainTex);
            o.Normal = UnpackNormal(tex2D(_BumpMap, IN.uv_BumpMap));
            o.Albedo = c.rgb;
            o.Alpha = c.a;
        }
        float4 LightingTest(SurfaceOutput s, float3 lightDir, float3 viewDir,float atten)
        {
            float nDot = saturate(dot(s.Normal, lightDir));
            float4 diffuse;
            diffuse.rgb= nDot * s.Albedo*_LightColor0.rgb*atten;
            
            float3 h = normalize(lightDir + viewDir);
            float specDot = saturate(dot(h,s.Normal));
            specDot = pow(specDot, _SpecPow);
            float3 specColor = specDot* _SpecCol.rgb;
 
            float4 final;
            final.rgb = diffuse.rgb + specColor.rgb;
            final.a = s.Alpha;
 
            return final;
        }
        ENDCG
    }
    FallBack "Diffuse"
}
 
http://colorscripter.com/info#e" target="_blank" style="color:#e5e5e5text-decoration:none">Colored by Color Scripter
 
그래서 코딩을 하면 이런식으로 코딩할 수 있다.
참고로 Surface 쉐이딩을 할때,
커스텀 라이팅을 쓰려면 
pragma 부분에 surf 다음에 원하는 이름을 넣고, 커스텀 라이팅 함수이름을
Lighting+prgma부분에서 지정한 이름 을 넣어주면 된다.

그리고 매개변수는 항상 정해져있고 ( 갯수에 따라 다른게 오버로딩 된다)

아래를 가보면 정확하게 알 수 있다.

https://docs.unity3d.com/kr/2018.4/Manual/SL-SurfaceShaderLighting.html

 

 

 

아래는 완성된 스페큘러 + 디퓨즈

 

 

 

  Comments,     Trackbacks