DirectX Shader Programming Lambert 조명모델의 확장
Download
Report
Transcript DirectX Shader Programming Lambert 조명모델의 확장
지난주에 구현한 프로그램의 단점
조명계산을 하는 과정에서 월드 좌표계의 법
선 벡터를 받아오면서 연산을 2회함
로컬 좌표계에서 계산하는 방법으로 바꿀 수
있다면?
▪ Normal Vector의 연산을 로컬좌표계로 바꾸어 보자
▪ float N에 모델의 Normal 벡터를 대입하면 됨
I d I k 의 경우 바뀔 일이 없음
상수화 가능
환경광과 확산 반사광은 색의 강도만 다름
I color * (0.3 1.0 * ( N L))
과 같은 형태로 바꾸는 것도 가능
광원벡터 L의 w에 환경광의 강도가 포함
되어 있음
노멀 벡터를 입력받고
4방향벡터에 x,y,z에는 빛의 방향을,
W값에는 확산광 값을 넣어
메모리사용양과 계산양을 줄임
강한 빛이 반사된
부분에서 나타나는
하이라이트
하이라이트는 강한 빛이 닿는 부분에서 생
기는 강한 반사광을 의미
반영 반사광 (Specularity, 反影) 이라고 함
램버트 모델에서는 반
사광을 표현하지 못함
퐁 셰이딩은 반영 반사광을
정확히 표현함
빛이 물체에서 반사되었을 때, 시선이 입
사 방향과 가까울 수록 반사광이 강하게
보임
즉, 반사벡터 R을 구해서
R이 입사벡터 L과 가까울수록
강한 빛을 표현 하면 됨
반사 강도(n)에 따른 반응 변화는 위와 같음
n이 0에 가까울 수록 하이라이트 범위가 넓어짐
램버트 확산 조명에서 반영 반사항만 추가하
면됨
카메라의 위치를 EyePos라 하면 EyePos에서
정점 V로 향하는 벡터를 정규화해서 반사 벡
터를 계산
시점벡터는 뷰 좌표계의 원점을 사용하면 됨
I I a K a I d K d ( N L) I s K s ( L R)
램버트 조명
반영 반사광
반사벡터
n
버텍스 셰이더의 경우에는 폴리곤의 개수에
따라서 하이라이트 표현에 영향을 많이 받음
픽셀 셰이더는 법선 벡터 등의 입력변수를
마음대로 다룰 수 없음 버텍스 셰이더
에서 픽셀 셰이더로 값을 넘겨줄 때 입력
변수의 값을 함께 넘겨주는 방법을 사용
주로 텍스쳐 좌표를 입력 변수로 사용함
벡터로 변경이 가능하기 때문
struct VS_OUTPUT
{
float4 Pos
: POSITION;
float4 Color
: COLOR0;
float3 N : TEXCOORD0;
float3 Eye : TEXCOORD1;
};
텍스쳐좌표를 법선 벡터와 시점 벡터로 활용
// ------------------------------------------------------------// 장면렌더
// ------------------------------------------------------------VS_OUTPUT VS(
float4 Pos
: POSITION,
// 로컬위치좌표
float4 Normal : NORMAL
// 법선벡터
){
VS_OUTPUT Out = (VS_OUTPUT)0;
// 출력데이터
// 좌표변환
Out.Pos = mul(Pos, mWVP);
// 정점색
float amb = -vLightDir.w;
float3
float3
float3
float3
eye
L =
N =
R =
// 환경광의강도
= normalize(vEyePos - Pos.xyz);
-vLightDir; // 로컬좌표계에서의광원벡터
Normal.xyz;
-eye + 2.0f*dot(N,eye)*N; // 반사벡터
Out.Color = vColor * max(amb, dot(Normal, -vLightDir)) + pow(max(0,dot(L, R)), 10);
Out.N = N;
Out.Eye = R;
return Out;
}
float4 PS(VS_OUTPUT In) : COLOR
{
float3 L = -vLightDir.xyz;
float3 R = In.Eye;
float3 N = In.N;
return In.Color * max(.3, dot(N, -vLightDir))
+ pow(max(0,dot(L, R)), 10);;
}
// ------------------------------------------------------------// 장면렌더
// ------------------------------------------------------------VS_OUTPUT VS(
float4 Pos
: POSITION,
// 로컬위치좌표
float4 Normal : NORMAL
// 법선벡터
){
VS_OUTPUT Out = (VS_OUTPUT)0;
// 출력데이터
// 좌표변환
Out.Pos = mul(Pos, mWVP);
// 정점색
float amb = -vLightDir.w;
float3
float3
float3
float3
eye
L =
N =
R =
// 환경광의강도
= normalize(vEyePos - Pos.xyz);
-vLightDir; // 로컬좌표계에서의광원벡터
Normal.xyz;
-eye + 2.0f*dot(N,eye)*N;
// 반사벡터
Out.Color = vColor * max(amb, dot(Normal, -vLightDir)) + pow(max(0,dot(L, R)), 10);
Out.N = N;
Out.Eye = R;
return Out
;
}
// ------------------------------------------------------------float4 PS(VS_OUTPUT In) : COLOR
{
float3 L = -vLightDir.xyz;
float3 R = In.Eye;
float3 N = In.N;
return In.Color * max(.3, dot(N, -vLightDir)) +
pow(max(0,dot(L, R)), 10);;
}
본격적인 렌더링 테크닉을 학습 할 것임
카툰 렌더링을 할 예정
카툰 렌더링에 사용할 모델 (.x 파일)을 구해서모
델을 화면에 띄워 올 것
단, 셰이더를 바로 사용할 수 있게 실습시간에 활
용했던 셰이더를 활용할 것
수행평가
참고 자료 : 실습 예제 + DirectX Tutorial 6