====== a ====== ===== 이펙트파일 구성 요소 ===== * *.fx 파일 : hlsl 스크립트 파일 * D3DXCreateEffectFromFile() : (*.fx) 스크립트 파일을 읽어들임 * D3DXCreateEffect() : fxc.exe로 컴파일한 바이너리 읽음 ==== 전역변수 선언 ==== * 애플리케이션에서 설정하는 변수는 전역변수로 선언되어야 한다. * 텍스쳐도 전역 파일로 정의한다. float4x4 mWVP; // 4x4 행렬 texture Tex; // 텍스쳐 ==== 샘플러스테이트 ==== * 텍스쳐를 읽어들이는 샘플러 스테이트를 설정 * 읽어들일 텍스쳐도 정의 sampler Samp = sampler_state { Texture = ; MinFilter = LINEAR; MagFilter = LINEAR; MipFilter = NONE; AddressU = Clamp; AddressV = Clamp; } ==== 정점셰이더 출력 구조체 ==== struct VS_OUTPUT { float4 Pos : POSITION; float2 Tex : TEXCOORD0; } * 변수타입, 변수이름, **시멘틱스**(의미강조) ==== 정점셰이더 ==== * 셰이더 코드가 들어가는 코드 //example VS_OUTPUT VS ( float4 Pos : POSITION float2 Tex : TEXCOORD0 ) { VS_OUTPUT out = (VS_OUTPUT)0; out.Pos = mul(Pos, mWMP); out.Tex = Tex; return out; } ==== 픽셀셰이더 ==== float4 PS( VS_OUTPUT in ) : COLOR { return tex2D(Samp, in.Tex); } ==== 테크닉 ==== * 렌더링 방법을 모아두는 곳 * 셰이더 버젼과 사용할 함수 정의 * 멀티 패스 렌더링도 설정 technique TShader { pass P0 { VertexShader = compile vs_1_1 VS(); PixelShader = compile ps_1_1 PS(); } } ===== 명령 ===== * %%if () then {} else {} ...%% * %%do {} while ();%% * %%while () {}; %% * %%for( ; ; ) {};%% 다수의 산술 함수들 지원 ====== 셰이더프로그래밍(책) 메모 ====== ====== 간단한 3D 파이프라인 ====== - Vertex Shader -> Rasterizer : 정점위치 - Rasterize -> Pixel Shader : 픽셀위치 - Pixel Shader -> Screen : 색상 정점쉐이더 (Vertex Shader) * 정점수만큼 실행 된다. * 정점셰이더가 출력하는 점을 모아서 픽셀을 찍을 위치를 정한다음 * 픽셀 셰이더로 넘어간다. ====== BAsic (HLSL) ====== ====== 기본 코드 ====== ===== VertexShader ===== VS_OUTPUT vs_main( VS_INPUT input ) * VS_INPUT : 입력용 구조체 * VS_OUTPUT : 출력용 구조체 * 입,출력에 대한 구조체는 형식을 스스로 정의한다. ==== 변수 정의를 위한 타입 ==== * float4 : (x,y,z,w)의 성분을 갖는 벡터 변수 타입 * float4x4 : float4 타입의 4x4 행렬 변수 ==== 입출력 부분 구조체 선언 ==== // POSITION은 시맨틱으로 좌표정보임을 알리는 역할을 한다. struct VS_INPUT { float4 mPosition : POSITION; } struct VS_OUTPUT { float4 mPosition : POSITION; } ====화면 변환을 위한 행렬 변수 정의==== * 모델의 정점 정보를 읽어와서 - 월드좌표계로 변환 (행렬곱) 후 저장 - 위의 값에서 뷰좌표계로 변환 (행렬곱) 후 저장 - 원근/평면 투시를 위한 투시 변환 (행렬곱) 후 저장 이 과정이 끝나야 화면에 표시할 수 있는 좌표계로 변환된다. // 좌표계변환을 위한 각 행렬들. 셰이더 작성 프로그램에는 사전에 정의된 값이 있음. float4x4 gWorldMatrix; float4x4 gViewMatrix; float4x4 gProjectionMatrix; ====정점의 좌표 변환==== VS_OUTPUT vs_main(VS_INPUT Input) { VS_OUTPUT Output; Output.mPosition = mul( Input.mPosition, gWorldMatrix ); Output.mPosition = mul( Output.mPosition, gViewMatrix ); Output.mPosition = mul( Output.mPosition, gProjectionMatrix ); return Output; } ===== 픽셀셰이더 ===== * 리턴값이 float4 형식이지만 COLOR (rgba) 임을 명시 * 이해하기 좋게 쓰는 듯한.. float4 ps_main() : COLOR { return float4( 1.0f, 0.9f, 0.0f, 1.0f ); } ====== 난반사 (Diffuse) ====== * 여러 방향으로 고르게 퍼지는 직접광원의 하나 * 람베르트 모델을 사용해서 난반사광의 빛의 강도를 계산한다. 람베르트 모델 * 표면법선과 입사광의 각의 코사인을 구하면 난반사광의 양이 된다. * Cos는 0도일때 '1', 180일때 0이 되는 볼록한 모양의 그래프 * 표면법선 바로 위에 광원이 있을때, 최대치 * 표면법선과 90도 또는 그 이상이면 최소치가 된다. 난반사광 구하기 * cos을 사용하는 대신, * 내적dot product연산을 활용해서 구한다. 이런 순서로 * dot(A,B) = cos{theta} delim{|}{A}{|}delim{|}{B}{|} * theta : Vector_A, Vector_B의 각도 * delim{|}{A}{|} : Vector_A의 길이 * delim{|}{B}{|} : Vector_B의 길이 * costheta를 구하기 위해서 자리 이동 : \\ costheta = {dot(A,B)} / {delim{|}{A}{|}delim{|}{B}{|}} * 벡터길이를 1(단위벡터)로 설정 : \\ costheta = dot(A,B) ====== 정반사 (Specular) ====== 정반사Supercular Light는 입사각과 출사각이 같은 빛. * 난반사는 전체에 골고루 퍼지는 것 대비. 정반사를 구하는 것은 퐁모델을 사용. * 카메라벡터가 이루는 각도의 코사인을 구해서 여러번 거듭제곱하면 구한다고.. 구할때 사용할 벡터 * 출사각 벡터 * 카메라의 벡터 * 이 둘의 Cos 값 * 거듭제곱 : \\ 거듭제곱을 하면 cos 값이 점점 작아져서 빛이 동그라게 모이게 된다. ====== HLSL function ====== | reflect() | 벡터의 반사벡터를 (빛의 입사각의 반사각을 구하는) 구하는 함수 | | ::: | param1 : 입사각 방향벡터, param2 : 입사각이 닿는, 반사면의 법선벡터 | | mul() | 벡터 곱하기 | | normalize() | 노말벡터 구하기 | | dot() | 벡터 내적을 구한다. 두 벡터의 cos{theta}를 구하는데도 사용 | | | |