우선 간단하게 텍스쳐 하나 받아 출력하게 한다
Shader "Custom/NewSurfaceShader"
{
Properties
{
_MainTex ("Albedo (RGB)", 2D) = "white" {}
}
SubShader
{
Tags { "RenderType"="Opaque" }
CGPROGRAM
#pragma surface surf _MyLambert noambient // 환경광 제거
sampler2D _MainTex;
struct Input
{
float2 uv_MainTex;
};
void surf (Input IN, inout SurfaceOutput o) // Lambert쓸거면 output 이후로 지우자
{
fixed4 c = tex2D(_MainTex, IN.uv_MainTex);
o.Albedo = c.rgb;
}
float4 Lighting_MyLambert(SurfaceOutput s, float3 lightDir, float atten)
{
return float4(1,0,0,1);
}
ENDCG
}
FallBack "Diffuse"
}

하지만 여기서 처음 보는 부분이 있다
//반환타입 float4는 최종 color
//Custom Light 만들때 반드시 Lightning<라이트 모델이름> ex) Lightning_MyLambert
float4 Lighting_MyLambert(SurfaceOutput s, float3 lightDir, float atten)
{
return float4(1,0,0,1);
}
= > 여기서 _MyLambert가 라이팅 이름이다
#pragma surface surf _MyLambert noambient
이게 커스텀 라이트 함수의 기본형이다. 반환타입은 float4이고 이 반환값은 최종 color를 의미한다
float4 Lighting_MyLambert(SurfaceOutput s, float3 lightDir, float atten)
{
return float4(1, 0, 0, 1);
}
여기서 주의할건 커스텀 라이트 이름앞에 Lighting을 붙여줘야 라이트 함수로 받아들인다
float4 Lighting_MyLambert(SurfaceOutput s, float3 lightDir, float atten)
{
return float4(1, 0, 0, 1);
}
변경하거나 수정할 수 없다. 주어진대로 사용해야 한다.
매개변수 SurfaceOutput s 의 값은 surf 함수에서 계산된 후 전달된 구조체 인스턴스이다
매개변수 float3 lightDir 는 Vertex에서 바라보는 조명의 방향을 뒤집은 조명 벡터이다. 길이가 1인 단위벡터이다
매개변수 float atten 는 그림자를 받거나 거리가 멀어지면서 점점 조명이 흐려지는 라이트의 거리별 감쇠현상을 나타낸다
float4 Lighting_MyLambert(SurfaceOutput s, float3 lightDir, float atten)
{
return float4(1, 0, 0, 1);
}

위 코드는 말 그대로 (1,0,0,1) 값을 출력하도록 만드는 단순한 코드이며
이제 dot 함수를 사용하여 노멀벡터와 라이트벡터를 내적 연산을 해주자
float4 Lighting_MyLambert(SurfaceOutput s, float3 lightDir, float atten)
{
float ndot = dot(s.Normal, lightDir);
return ndot;
}
이전 surf 함수에서 o.Normal에 아무값도 넣지 않았으나 기본값이 있는 s.Normal의 값을 가져올 수 있다

이게 Lambert 라이트의 기본형이다

하지만 지금은 보다시피 조명의 색상도 받지 못하며 내적연산한 값이 1 ~ -1이기에
후에 ambient light나 추가 라이트를 비출때 이 음수가 문제를 불러일으킬 수 있다
이것을 방지하기 위해 0 밑의 값은 전부 0으로 잘라버려야 하는데
이러한 기능을 가진 함수는 saturate, max가 있다

이번엔 staturate함수를 사용하여 바꿔보겠다
float4 Lighting_MyLambert(SurfaceOutput s, float3 lightDir, float atten)
{
float ndot = dot(s.Normal, lightDir);
float4 final = saturate(ndot) + 0.5;
return final;
}

솔직히 이 과정에서 쓰이는 코싸인, 벡터를 내적한다던가 하는것들은 아직 이해되지 않는다
하지만 우선 이런 상황에서 이런 함수가 쓰인다는것, 그리고 커스텀 라이팅 만드는법만 익히고 넘어가자
'유니티 > 게임그래픽' 카테고리의 다른 글
Half-Lambert (0) | 2024.02.22 |
---|---|
Vertex Color 응용 (0) | 2024.02.22 |
디지털 라이트 이론 & Vector (0) | 2024.02.21 |
Lambert & Blinn Phong (0) | 2024.02.21 |
NormalMap (1) | 2024.02.21 |