Half-Lambert란 갑자기 음영이 검게 떨어지는 단점을 보완하게 위해 벨브에서 발표한 Lambert라이팅의 수정공식으로,
물리적으로는 옳지 않으나 가볍고 게임속 음영을 보기편하게 하는 공식이다
딱봐도 게임할땐 오른쪽이 더 보기 편해보인다
float4 Lighting_MyLambert(SurfaceOutput s, float3 lightDir, float atten)
{
float ndot = dot(s.Normal, lightDir) * 0.5 + 0.5;
float4 final = saturate(ndot) + 0.5;
return final;
}
적용하는 방법은 매우 간단하다. ndot에 들어가는 값에 (* 0.5 + 0.5) 만 넣어주면 된다
전후 차이이다. 확실히 더 자연스럽고 보기좋게 바뀐것을 알 수 있다
float4 Lighting_MyLambert(SurfaceOutput s, float3 lightDir, float atten)
{
float ndot = dot(s.Normal, lightDir) * 0.5 + 0.5;
float4 final = pow(ndot,3);
return final;
}
반대 공식도 있다. Half-Lambert 공식은 빛이 거의 180도 영향을 끼치게 하기에
이 정도를 조금 줄이기 위해서는 결과물에 제곱을 해줄수 있다 *pow(X,n) = X의 n제곱
16-8일차 - Lambert 커스텀 라이트
우선 간단하게 텍스쳐 하나 받아 출력하게 한다 Shader "Custom/NewSurfaceShader" { Properties { _MainTex ("Albedo (RGB)", 2D) = "white" {} } SubShader { Tags { "RenderType"="Opaque" } CGPROGRAM #pragma surface surf _MyLambert noambient //
sangeun00.tistory.com
이렇게 Lambert와 Half-Lambert의 기본공식을 만들어밨지만 윗글에도 적어둔것처럼 조명의 색상이나 강도등이
텍스쳐에 전혀 적용되지 않은 모습들을 확인할 수 있다. 이번엔 그것들을 전부 해결하며 Lambert라이트를 완성해보겠다
Shader "Custom/NewSurfaceShader"
{
Properties
{
_MainTex ("Albedo (RGB)", 2D) = "white" {}
_BumpMap ("Albedo (RGB)", 2D) = "bump" {}
}
SubShader
{
Tags { "RenderType"="Opaque" }
CGPROGRAM
#pragma surface surf _MyLambert noambient // 환경광 제거
sampler2D _MainTex;
sampler2D _BumpMap;
struct Input
{
float2 uv_MainTex;
float2 uv_BumpMap;
};
void surf (Input IN, inout SurfaceOutput o) // Lambert쓸거면 output 이후로 지우자
{
fixed4 c = tex2D(_MainTex, IN.uv_MainTex);
//Normal Map
fixed4 d = tex2D(_BumpMap, IN.uv_BumpMap);
fixed3 normal = UnpackNormal (d);
o.Normal = normal;
o.Albedo = c.rgb;
}
float4 Lighting_MyLambert(SurfaceOutput s, float3 lightDir, float atten)
{
//Lambert
float ndot = dot(s.Normal, lightDir) * 0.5 + 0.5;
float4 final = pow(ndot,2);
return final;
}
ENDCG
}
FallBack "Diffuse"
}
우선 노멀맵을 하나 추가하여 출력하도록 하자
float4 Lighting_MyLambert(SurfaceOutput s, float3 lightDir, float atten)
{
//Lambert
float ndot = dot(s.Normal, lightDir);
float4 final;
final.rgb = ndot * s.Albedo * _LightColor0.rgb * atten;
final.a = s.Alpha;
return final;
}
텍스쳐와 조명색상, 감쇠를 연산하여 조명을 완성했다
조명의 색상과 감쇠효과를 얻기 위해 가장 중요한건 이 한줄이다
final.rgb = ndot * s.Albedo * _LightColor0.rgb * atten;
우선 final 변수는 위에서 float4 형식으로 선언해주었다
final.rgb = ndot * s.Albedo * _LightColor0.rgb * atten;
ndot = dot(s.Normal, lightDir) 즉 노멀벡터와 라이트벡터를 내적 연산해주는 값이 들어간 변수이다
즉 조명과 노멀의 각도를 표현
final.rgb = ndot * s.Albedo * _LightColor0.rgb * atten;
Albedo로 입력받은 텍스쳐. SurfaceOutput이 s로 들어왔으니 s.Albedo이다
final.rgb = ndot * s.Albedo * _LightColor0.rgb * atten;
조명의 색상이나 강도를 내장하여 가져올수 있는 변수.
이 변수를 곱한후 조명의 색상이나 강도를 변화시키면 그대로 반영이 된다
final.rgb = ndot * s.Albedo * _LightColor0.rgb * atten;
atten은 그림자를 받거나 거리가 멀어지면서 점점 조명이 흐려지는 라이트의 거리별 감쇠현상을 나타냄
즉 atten을 계산하지 않는다면 그림자에 관한것들이 대부분 사라지게 된다
물론 Direction Light에서는 큰 차이를 느낄수 없지만
Point Light에서는 멀수록 어두워지는 효과등이 전부 atten의 역할이다
final.rgb = ndot * s.Albedo * _LightColor0.rgb * atten;
'유니티 > 게임그래픽' 카테고리의 다른 글
홀로그램 (0) | 2024.02.24 |
---|---|
Fresnel(프레넬) & Rim 라이트 (0) | 2024.02.22 |
Vertex Color 응용 (0) | 2024.02.22 |
Lambert 커스텀 라이트 (0) | 2024.02.21 |
디지털 라이트 이론 & Vector (0) | 2024.02.21 |