0506 쉐이더 라이트닝 연산

2021. 5. 6. 11:23unity/쉐이더

환경광을 없애기

 

노멀 벡터와 빛의 벡터가 90도를 이룰 때 노멀 벡터가 가장 어둡고, 서로 마주보고 있을 때 가장 밝다.

물리 벡터 : 방향+크키

수 벡터 : 위치

각각의 버텍스에도 벡터를 가지고 있다.
노멀벡터 - 조명벡터 = 밝기가 계산된다. (-1이면 가장 어두움)

빛 벡터와 노멀 벡터가 만나서 이루는 각을 이용해 밝기 연산을 한다. 90도일때 가장 어둡고, 그보다 높은 각도의 방향들은 어둡게 표현된다.

docs.unity3d.com/Manual/SL-SurfaceShaders.html

 

Unity - Manual: Writing Surface Shaders

Vertex and fragment shader examples for the Built-in Render Pipeline Surface Shaders and rendering paths Writing Surface Shaders In the Built-in Render Pipelne, Surface Shaders are a streamlined way of writing shadersA program that runs on the GPU. More in

docs.unity3d.com

 

커스텀 라이팅 메서드를 만들 때 주의사항 : 라이팅 메서드 안에선 빛의 벡터가 반대로 뒤집혀서 들어온다. (조명의 벡터는 단위벡터 : 값이 0,1,-1)

라이트 이름 설정 : Test
Lighting + Test 이름으로 함수 선언
반환타입은 float4
매개 변수 (SurfaceOutput s, 
   float3 lightDir //조명의 단위 벡터, 
   float atten //빛의 감쇠)

램버트 공식 : saturate(표면 벡터와 조명 벡터를 내적)
//saturate는 optional
0~1까지를 표현,
그 값을 반환

void surf (Input IN, inout SurfaceOutput o)
        {
            fixed4 c = tex2D (_MainTex, IN.uv_MainTex);
            o.Albedo = c.rgb;
            o.Alpha = c.a;
        }

        float4 LightingTest(SurfaceOutput s, float3 lightDir, float atten) 
        {
            //return float4 (1, 0, 0, 1);
            float ndotl = dot(s.Normal, lightDir);
            return ndotl;
        }
        ENDCG

CG API 0보다 작은 값은 0, 1보다 큰 값은 1로 만들어준다.

 

왼쪽 :  일반 램버트 , 왼쪽: 하프 램버트 수식 적용 ( *0.5 + 0.5)

 float4 LightingTest(SurfaceOutput s, float3 lightDir, float atten) 
        {
            //Lambert
            //saturate: 0~1 사이로 잘라준다.
            //float ndotl = max (0,dot(s.Normal, lightDir));
            float ndotl = saturate(dot(s.Normal, lightDir));
            
            //hal-Lambert
            float ndotl = dot(s.Normal, lightDir) * 0.5 + 0.5;
            return ndotl;
        }
        ENDCG

 

 

하프 램버트 공식 : 표면벡터와 조명 벡터를 내적 0.5*0.5
라이트 함수 내에서 SurfaceOutput 구조체 값 사용 가능
ex ) s.Albedo

_LightColor0.rgb : 조명의 색상이나 강도가 저장된 내장변수
빛의 감쇠는 Directional Light보다 Point Light에서 확인할 수 있다.
당연한 거지만 _LightColor0.rgb 변수를 빼면 빛의 색상이 적용되지 않는다.

float4 LightingTest (SurfaceOutput s, float3 lightDir, float atten)
        {
            float ndotl = (dot(s.Normal, lightDir)*0.5+0.5);

            float4 final;
            final.rgb = ndotl * s.Albedo * _LightColor0.rgb * atten;
            final.a = s.Alpha;
            return final;
        }
        ENDCG