Shader - Lambert
차례대로 Standard, CustomLambert, HalfLambert
1. Standard
Shader "Custom/lambert"
{
Properties
{
_MainTex("Main Texture", 2D) = "white"{}
_NormalMap("NormalMap", 2D) = "bump" {}
_Color("Color", Color) = (1,1,1,1)
}
SubShader
{
Tags { "RenderType"="Opaque" }
CGPROGRAM
#pragma surface surf Standard
#pragma target 3.0
sampler2D _MainTex;
sampler2D _NormalMap;
float4 _Color;
struct Input
{
float4 color : COLOR;
float2 uv_MainTex;
float2 uv_NormalMap;
};
void surf (Input IN, inout SurfaceOutputStandard o)
{
float4 c = tex2D(_MainTex, IN.uv_MainTex);
float4 d = tex2D(_NormalMap, IN.uv_NormalMap);
o.Normal = UnpackNormal (d);
o.Albedo = c.rgb * _Color;
o.Alpha = c.a;
}
// 빛을 만든다
ENDCG
}
FallBack "Diffuse"
}
2. CustomLambert
Shader "Custom/customLambert"
{
Properties
{
_MainTex("Main Texture", 2D) = "white"{}
_NormalMap("NormalMap", 2D) = "bump" {}
_Color("Color", Color) = (1,1,1,1)
}
SubShader
{
Tags { "RenderType"="Opaque" }
CGPROGRAM
#pragma surface surf _MyLambert
#pragma target 3.0
sampler2D _MainTex;
sampler2D _NormalMap;
float4 _Color;
struct Input
{
float4 color : COLOR;
float2 uv_MainTex;
float2 uv_NormalMap;
};
void surf (Input IN, inout SurfaceOutput o)
{
float4 c = tex2D(_MainTex, IN.uv_MainTex);
float4 d = tex2D(_NormalMap, IN.uv_NormalMap);
o.Normal = UnpackNormal (d);
o.Albedo = c.rgb * _Color;
o.Alpha = c.a;
}
// 빛을 만든다
float4 Lighting_MyLambert(SurfaceOutput s, float3 lightDir, float atten)
{
float4 final;
float ndot1 = dot(s.Normal, lightDir);
final.rgb = ndot1 * s.Albedo.rgb;
final.a = s.Alpha;
return final;
}
ENDCG
}
FallBack "Diffuse"
}
2-2. CustomLambert
Shader "Custom/customLambert"
{
Properties
{
_NormalMap("Normal Map",2D) = "bump"{}
}
SubShader
{
Tags { "RenderType"="Opaque" }
CGPROGRAM
#pragma surface surf _MyLambert noambient;
#pragma target 3.0
sampler2D _NormalMap;
struct Input
{
float4 color : COLOR;
float2 uv_NormalMap;
};
void surf (Input IN, inout SurfaceOutput o)
{
float4 c = tex2D(_NormalMap, IN.uv_NormalMap);
o.Normal = UnpackNormal (c);
o.Albedo = 1;
}
float4 Lighting_MyLambert(SurfaceOutput s, float3 lightDir, float atten)
{
float4 final;
//return float4(1,0,0,1);
//노멀벡터와 조명벡터를 내적해라
float ndot1 = dot(s.Normal, lightDir);
final = saturate(ndot1);
return final;
}
ENDCG
}
FallBack "Diffuse"
}
3. HalfLambert
Shader "Custom/customLambert2"
{
Properties
{
_MainTex("Main Texture", 2D) = "white"{}
_NormalMap("NormalMap", 2D) = "bump" {}
_Color("Color", Color) = (1,1,1,1)
}
SubShader
{
Tags { "RenderType"="Opaque" }
CGPROGRAM
#pragma surface surf _MyLambert
#pragma target 3.0
sampler2D _MainTex;
sampler2D _NormalMap;
float4 _Color;
struct Input
{
float4 color : COLOR;
float2 uv_MainTex;
float2 uv_NormalMap;
};
void surf (Input IN, inout SurfaceOutput o)
{
float4 c = tex2D(_MainTex, IN.uv_MainTex);
float4 d = tex2D(_NormalMap, IN.uv_NormalMap);
o.Normal = UnpackNormal (d);
o.Albedo = c.rgb * _Color;
o.Alpha = c.a;
}
// 빛을 만든다
float4 Lighting_MyLambert(SurfaceOutput s, float3 lightDir, float atten)
{
float4 final;
float ndot1 = dot(s.Normal, lightDir)* 0.5 + 0.5;
final = pow(ndot1, 3);
final.rgb = ndot1 * s.Albedo.rgb * _LightColor0.rgb * atten;
final.a = s.Alpha;
return final;
}
ENDCG
}
FallBack "Diffuse"
}
CustomLambert의 기본형
1. #pragma surface surf _MyLambert
2. void surf (Input IN, inout SurfaceOutput o)
3. float4 Lighting_MyLambert(SurfaceOutput s, float3 lightDir, float atten)
{
;
return float4(1, 0, 0 , 1);
}
우선 이 3가지로 스탠다드를 바꿔주고 메서드를 만들어준다.
이때 매개변수는 변경하거나 수정할 수 없으며 주어진 대로 사용해야 한다.
float3 lightDir
조명 방향의 벡터
단, 조명을 편하게 사용하기 위해 뒤집혀지고 길이가 1인 단위 벡터 상태
float atten(uation) - 감쇠
그림자를 받거나 거리가 멀어지면 점점 조명이 흐려지는 라이트의 거리별 현상
dot : 노멀 벡터와 라이트 벡터를 내적 연산해주는 함수
우리는 o.Normal에 값을 넣지 않았지만 s.Normal의 값을 가져올 수 있다.
lightDir은 vertex에서 바라보는 조명의 방향을 뒤집은 조명 벡터이므로 두 벡터를 단순히 내적하면 cos값이 나온다.
나중에 ambient light 또는 추가라이트를 비출 때 이 음수는 문제를 일으킬수 있는데
이(0아래는 전부 0으로 잘라주는)를 해결해주는 함수 saturate, max가 있다.
이 함수들을 사용하면 빨간선처럼 0보다 작은수는 0으로 지정해준다.
HalfLambert
* 0.5 + 0.5는 마법의 숫자이다.
이 공식은 -1 ~ 1까지의 숫자를 0에서 1까지의 범위로 만들어준다.
그 결과 cos라인을 끌어 올려주어 부드러운 결과 값이 나온다.
조명의 색상 or 감쇠를 이용할 수 있다.
ex) final.rgb = ndotl * s.Albedo * _LightColor0.rgb * atten;
https://docs.unity3d.com/kr/2021.3/Manual/SL-UnityShaderVariables.html
빌트인 셰이더 변수 - Unity 매뉴얼
Unity의 빌트인 포함 파일에는 셰이더에 대한 전역 변수(예: 현재 오브젝트의 변환 매트릭스, 광원 파라미터, 현재 시간 등)가 포함되어 있습니다. 이러한 셰이더 프로그램에서 이러한 전역 변수
docs.unity3d.com
이에 따라 조명의 색깔을 변경하고 거리에 따른 그림자를 조절할 수 있다.