카테고리 없음
12_Normal [2/2]
컴맹학자
2021. 7. 3. 21:46
728x90
노말백터를 이용한 음영 표현 (ADSE)
Ambient : 주변 조명 인한 색 ex) 태양
Diffuse : 기본 물체의 색깔
Specular : 정반사광 (정구형태)
Emissive : 외각선
Lambert 조명 (Diffuse)
기존 지형 노말벡터와 조명의 노말벡터와 내적을 해서 cos가 1에 가까우면 밝게 반대로는 어둡게
11_Terrain.fx 수정
더보기
matrix World, View, Projection;
struct VertexInput
{
float4 Position : Position;
};
//-------------------------------------------------------
//Simple Terrain Color [원본]
//-------------------------------------------------------
struct VertexOutput
{
float4 Position : SV_Position;
};
RasterizerState RS
{
FillMode = WireFrame;
};
VertexOutput VS(VertexInput input)
{
VertexOutput output;
output.Position = mul(input.Position, World);
output.Position = mul(output.Position, View);
output.Position = mul(output.Position, Projection);
return output;
}
float4 PS(VertexOutput input) : SV_Target
{
return float4(1, 0, 0, 1);
}
//-------------------------------------------------------
//GetHeight Color [원본에 색상칠해줄꺼]
//-------------------------------------------------------
struct VertexOutput_GetHeight
{
float4 Position : SV_Position;
float4 Color : Color;
};
//높이값에 따른 색상 처리하는곳
float4 GetHeightColor(float y)
{
if(y > 20.0f)
return float4(1, 0, 0, 1);
if(y > 10.0f)
return float4(0, 1, 0, 1);
if(y > 5.0f)
return float4(0, 0, 1, 1);
return float4(1, 1, 1, 1);
}
VertexOutput_GetHeight VS_GetHeightColor(VertexInput input)
{
VertexOutput_GetHeight output;
output.Position = mul(input.Position, World);
output.Color = GetHeightColor(output.Position.y); //넣는곳에 따라 처리방법이 다름
output.Position = mul(output.Position, View);
output.Position = mul(output.Position, Projection);
return output;
}
float4 PS_GetHeightColor(VertexOutput_GetHeight input) : SV_Target
{
return input.Color;
}
//-------------------------------------------------------
//Lambert Color (법선 벡터로 색상 입힘)
//-------------------------------------------------------
struct VertexInput_Normal
{
float4 Position : Position;
float3 Normal : Normal;
};
struct VertexOutput_Normal
{
float4 Position : SV_Position;
float3 Normal : Normal;
float4 Color : Color;
};
VertexOutput_Normal VS_Lambert(VertexInput_Normal input)
{
VertexOutput_Normal output;
output.Position = mul(input.Position, World);
output.Color = GetHeightColor(output.Position.y);
output.Position = mul(output.Position, View);
output.Position = mul(output.Position, Projection);
//법선벡터도 월드 위치에 따라 움직이게만듬
output.Normal =mul(input.Normal, (float3x3) World);
return output;
}
float3 LightDirection = float3(-1, -1, +1);
float4 PS_Lambert(VertexOutput_Normal input) : SV_Target
{
float3 normal = normalize(input.Normal); // 월드값(VS) 값이 다시 압축이됨
//내적(벡터방향, 바라보는 방향) 1 ~ -1 / 1에 가까우면 밝아짐
float Ndot = dot(normal, normalize(-LightDirection));
return input.Color * Ndot;
}
float4 PS_HelfLambert(VertexOutput_Normal input) : SV_Target
{
//음영 반값
float3 normal = normalize(input.Normal);
float Ndot = dot(normal, normalize(-LightDirection)) * 0.5f + 0.5f;
return input.Color * Ndot;
}
technique11 T0
{
pass P0
{
SetVertexShader(CompileShader(vs_5_0, VS()));
SetPixelShader(CompileShader(ps_5_0, PS()));
}
pass P1
{
SetRasterizerState(RS);
SetVertexShader(CompileShader(vs_5_0, VS()));
SetPixelShader(CompileShader(ps_5_0, PS()));
}
pass P2
{
SetVertexShader(CompileShader(vs_5_0, VS_GetHeightColor()));
SetPixelShader(CompileShader(ps_5_0, PS_GetHeightColor()));
}
pass P3
{
SetVertexShader(CompileShader(vs_5_0, VS_Lambert()));
SetPixelShader(CompileShader(ps_5_0, PS_Lambert()));
}
pass P4
{
SetVertexShader(CompileShader(vs_5_0, VS_Lambert()));
SetPixelShader(CompileShader(ps_5_0, PS_HelfLambert()));
}
}
TerrainDemo.cpp (수정)
더보기
void TerrainDemo::Update()
{
static UINT Pass = 0; //Pass의 마지막값
ImGui::InputInt("Pass", (int*)&Pass);
Pass %= shader->PassCount();
terrain->Pass() = Pass;
static Vector3 LightDirection = Vector3(-1, -1, 1);
ImGui::SliderFloat3("LightDirection", (float*)&LightDirection, -1, 1);
shader->AsVector("LightDirection")->SetFloatVector(LightDirection);
terrain->Update();
}
실행
Lambert
장점 : 음영을 사용 할 수 있게됨
단점 : 극단적으로 어둡고 밝음
HelfLambert
장점 : Lambert 의 단점을 보완 해서 사용
단점 : 지점토 형식 (카툰렌더링 쪽에서 사용)