사용자 도구

사이트 도구


language:shader:basic

차이

문서의 선택한 두 판 사이의 차이를 보여줍니다.

차이 보기로 링크

양쪽 이전 판이전 판
다음 판
이전 판
language:shader:basic [2014/04/23 17:17] – [정반사 (Specular)] kieunslanguage:shader:basic [2024/04/23 22:44] (현재) – 바깥 편집 127.0.0.1
줄 1: 줄 1:
 +====== 간단한 3D 파이프라인 ======
  
 +  - Vertex Shader -> Rasterizer : 정점위치
 +  - Rasterize -> Pixel Shader : 픽셀위치
 +  - Pixel Shader -> Screen : 색상
 +
 +정점쉐이더 (Vertex Shader)
 +
 +  * 정점수만큼 실행 된다.
 +  * 정점셰이더가 출력하는 점을 모아서 픽셀을 찍을 위치를 정한다음
 +  * 픽셀 셰이더로 넘어간다.
 +
 +====== BAsic (HLSL) ======
 +
 +====== 기본 코드 ======
 +
 +===== VertexShader =====
 +
 +<code>
 +VS_OUTPUT vs_main( VS_INPUT input )
 +</code>
 +
 +  * VS_INPUT : 입력용 구조체
 +  * VS_OUTPUT : 출력용 구조체
 +  * 입,출력에 대한 구조체는 형식을 스스로 정의한다.
 +
 +==== 변수 정의를 위한 타입 ====
 +
 +  * float4 : (x,y,z,w)의 성분을 갖는 벡터 변수 타입
 +  * float4x4 : float4 타입의 4x4 행렬 변수
 +
 +==== 입출력 부분 구조체 선언 ====
 +
 +<code>
 +// POSITION은 시맨틱으로 좌표정보임을 알리는 역할을 한다.
 +struct VS_INPUT { float4 mPosition : POSITION; }
 +struct VS_OUTPUT { float4 mPosition : POSITION; }
 +</code>
 +
 +====화면 변환을 위한 행렬 변수 정의====
 +
 +  * 모델의 정점 정보를 읽어와서
 +    - 월드좌표계로 변환 (행렬곱) 후 저장 
 +    - 위의 값에서 뷰좌표계로 변환 (행렬곱) 후 저장 
 +    - 원근/평면 투시를 위한 투시 변환 (행렬곱) 후 저장 
 +
 +이 과정이 끝나야 화면에 표시할 수 있는 좌표계로 변환된다.
 +
 +<code>
 +// 좌표계변환을 위한 각 행렬들. 셰이더 작성 프로그램에는 사전에 정의된 값이 있음.
 +float4x4 gWorldMatrix;
 +float4x4 gViewMatrix;
 +float4x4 gProjectionMatrix;
 +</code>
 +
 +====정점의 좌표 변환====
 +
 +<code>
 +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;
 +}
 +</code>
 +
 +
 +===== 픽셀셰이더 =====
 +
 +  * 리턴값이 float4 형식이지만 COLOR (rgba) 임을 명시
 +  * 이해하기 좋게 쓰는 듯한..
 +
 +<code>
 +float4 ps_main() : COLOR
 +{
 +  return float4( 1.0f, 0.9f, 0.0f, 1.0f );
 +}
 +</code>
 +
 +====== 난반사 (Diffuse) ======
 +
 +  * 여러 방향으로 고르게 퍼지는 직접광원의 하나
 +  * 람베르트 모델을 사용해서 난반사광의 빛의 강도를 계산한다.
 +
 +람베르트 모델
 +
 +  * 표면법선과 입사광의 각의 코사인을 구하면 난반사광의 양이 된다.
 +  * Cos는 0도일때 '1', 180일때 0이 되는 볼록한 모양의 그래프
 +  * 표면법선 바로 위에 광원이 있을때, 최대치
 +  * 표면법선과 90도 또는 그 이상이면 최소치가 된다.
 +
 +난반사광 구하기
 +
 +  * cos을 사용하는 대신,
 +  * 내적<sup>dot product</sup>연산을 활용해서 구한다.
 +  
 +이런 순서로
 +
 +  * dot(A,B) = <m>cos{theta} delim{|}{A}{|}delim{|}{B}{|}</m>
 +    * <m>theta</m> : Vector_A, Vector_B의 각도
 +    * <m>delim{|}{A}{|}</m> : Vector_A의 길이
 +    * <m>delim{|}{B}{|}</m> : Vector_B의 길이
 +
 +  * cos<m>theta</m>를 구하기 위해서 자리 이동 : \\ cos<m>theta</m> = <m>{dot(A,B)} / {delim{|}{A}{|}delim{|}{B}{|}}</m>
 +  
 +  * 벡터길이를 1(단위벡터)로 설정 : \\ cos<m>theta</m> = dot(A,B)
 +
 +====== 정반사 (Specular) ======
 +
 +정반사<sup>Supercular Light</sup>는 입사각과 출사각이 같은 빛.
 +  * 난반사는 전체에 골고루 퍼지는 것 대비.
 +
 +정반사를 구하는 것은 퐁모델을 사용.
 +  * 카메라벡터가 이루는 각도의 코사인을 구해서 여러번 거듭제곱하면 구한다고..
 +
 +구할때 사용할 벡터
 +  * 출사각 벡터
 +  * 카메라의 벡터
 +  * 이 둘의 Cos 값
 +  * 거듭제곱 : \\ 거듭제곱을 하면 cos 값이 점점 작아져서 빛이 동그라게 모이게 된다.
 +
 +====== HLSL function ======
 +
 +| reflect()   | 벡터의 반사벡터를 (빛의 입사각의 반사각을 구하는) 구하는 함수       |
 +| :::         | param1 : 입사각 방향벡터, param2 : 입사각이 닿는, 반사면의 법선벡터 |
 +| mul()       | 벡터 곱하기                                                         |
 +| normalize() | 노말벡터 구하기                                                     |
 +| dot()       | 벡터 내적을 구한다. 두 벡터의 <m>cos{theta}</m>를 구하는데도 사용   |
 +|                                                                                 |