- 커스텀 라이트를 만들기 위해 라이팅 이름을
Test
로 설정했다.#pragma surface surf Test noambient
- 위 이름에 적합한
LightingTest()
라이팅 함수를 추가한다.
Lighting + (라이트이름) 구조를 지켜서 라이팅 함수로 만들어야한다.float4 LightingTest(SurfaceOutput s, float3 lightDir, float atten) { return float4(1, 0, 0, 0); //아직 붉은 결과물만 출력한다. }
- 최종적으로 화면에 컬러를 출력할 것이기 때문에
float4
의 반환값을 가진다.- 매개변수는 Properties에서 만들어서 변수로 받아오는 값빼고는 미리 정해져 있어 수정할 수 없다.
LightingTest()
함수의 매개변수1. SurfaceOutput s
surf()
에서 o.Albedo
나 o.Normal
에 넣은 값들은 그냥 Standard나 Lambert, BlinnPhong 라이팅 함수를 거쳤다면, 현재는 우리가 만든 LightingTest()
라이팅 함수를 거치는 것이다.LightingTest()
커스텀 라이팅 함수에서는 surf()
에서 o.Albedo
로 집어넣었던 값을 s.Albedo
로 꺼내서 쓸 수 있다.2. float3 lightDir
3. float atten
ndot1
- 노멀 벡터와 라이트 벡터의 내적을 연산한 값- 버텍스에서 노멀값을 평범하게 받아와있는 상태라서 s.Normal이라고 받아도 제대로 노멀값이 들어온다.
float4 LightingTest(SurfaceOutput s, float3 lightDir, float atten) { float ndot1 = dot(s.Normal, lightDir); return ndot1; }
-1
~1
)에 따라 음영이 계산된 상태
saturate(값)
: 0보다 낮은 값은 0으로, 1보다 높은 값은 1로 잘라준다.float ndot1 = saturate(dot(s.Normal, lightDir));
max(값, 값)
: 두 값 중 큰 값을 내보내며, 한쪽의 값을 0으로 설정하면 0 이하인 값은 나오지 않는다.float ndot1 = max(0, dot(s.Normal, lightDir));
return ndot1 + 0.5;
로 수정한 모습이다. (함수를 적용하지 않아 내적값이 -1까지 있을 때는 0.5를 더했음에도 불구하고 검은 면이 보인다.)☑️ Half-Lambert
- 하프라이프에서 사용된 Lambert 라이팅의 수정 공식
- 기존 Lambert 라이트의 cos그래프 연산 특성상 밝다가 갑자기 검게 음영이 떨어지는 단점을 보완
- 물리적으로 옳지 않지만, 가볍고 보기좋다. (쉐이더는 보기 좋은게 우선!)
기존 라이트 결과물 (Half-Lambert의 극명한 결과를 위해 조명 각도만 수정한 상태)
위에서 적용시켜준 saturate()
함수를 없애고, Half-Lambert공식을 넣는다.
float ndot1 = dot(s.Normal, lightDir) * 0.5 + 0.5;
//마법의 숫자 '* 0.5 + 0.5'
//-1부터 1까지의 숫자를 0에서 1까지의 범위로 맵핑한다.
return pow(ndot1, 3); //세제곱
final
- 반환값을 위한 float4 변수s.Albedo
- Albedo로 입력받은 텍스쳐_LightColor0.rgb
- 내장변수를 이용해 조명의 색상과 강도를 가져옴atten
- 빛의 감쇠현상 (아래에서 추가설명)//[2.Lambert 라이트 연산 만들기]의 코드에서 이어서 수정 float4 LightingTest(SurfaceOutput s, float3 lightDir, float atten) { float ndot1 = saturate(dot(s.Normal, lightDir)); float4 final; final.rgb = n.dot1 * s.Albedo * _LightColor0.rgb * atten; final.a = s.Alpha; return ndot1; }
//#pragma surface surf Test noambient (수정 전)
#pragma surface surf Test
📝최종 코드
Shader "Custom/LambertShader" { Properties { _MainTex ("Albedo (RGB)", 2D) = "white" {} _BumpMap ("NormalMap", 2D) = "bump"{} } SubShader { Tags { "RenderType"="Opaque" } CGPROGRAM #pragma surface surf Test sampler2D _MainTex; sampler2D _BumpMap; struct Input { float2 uv_MainTex; float2 uv_BumpMap; }; void surf (Input IN, inout SurfaceOutput o) { fixed4 c = tex2D (_MainTex, IN.uv_MainTex); o.Albedo = c.rgb; o.Normal = UnpackNormal(tex2D(_BumpMap, IN.uv_BumpMap)); o.Alpha = c.a; } float4 LightingTest(SurfaceOutput s, float3 lightDir, float atten) { float ndot1 = dot(s.Normal, lightDir) * 0.5 + 0.5; float4 final; final.rgb = ndot1 * s.Albedo * _LightColor0.rgb * atten; final.a = s.Alpha; return pow(final, 2.5); } ENDCG } FallBack "Diffuse" }