DirectX9 - 정점 쉐이더와 픽셀 쉐이더

- 정점 쉐이더

로컬스페이스의 정점을 가저와 (월드, , 투영) 점점을 리턴한다. 

뷰포터 + 레스터라이즈는 장치가 해준다

 

- 픽셀 쉐이더

레스터라이즈가 끝난 픽셀값을 얻어와 최종 출력할 픽셀값으로 만들어 리턴 한다.

인풋 스트럭트는 점점 쉐이더의 아웃풋과 같다.


- 포어드

- 디퍼드 : 자세한 설명


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
// Lambert
float lambert = dot(normal, -lightDirection);
float halfLambert = dot(normal, -lightDirection) * 0.5f + 0.5f; 
 
float3 lambert = max(0, dot(normal.xyz, lightDirection.xyz));
float3 halfLambert = pow(dot(normal.xyz, lightDirection.xyz) * 0.5f + 0.5f, 4);
float3 wrappedDiffuse = float3(1,1,1* saturate((dot(normal.xyz, lightDirection.xyz) + g_offset) / ((1 + g_offset) * (1 + g_offset)));
float3 wrappedDiffuse = saturate((dot(normal.xyz, lightDirection.xyz) + g_offset) / (1 + g_offset));
 
// Specular
float3 look = normalize(g_cameraPosition.xyz - position.xyz);
float3 reflection = normalize(reflect(g_lightDirection.xyz, normal.xyz));
 
pow(max(dot(-look, reflection), 0.f), g_power)
 
// RimLight
// 림라이팅 결과 값을 기존의 Texture Color, Diffuse Color, Specular Color 값들과 합쳐 주어 최종 값을 도출해 낸다.
// 즉 캐릭터의 외곽쪽은 내적의 값이 0이 되고, 중앙으로 올 수록 1이 되는 것을 이용하여 1에서 값을 빼주면, 결과적으로 외곽쪽이 가장 큰 값을 가지게 되고, 중앙쪽이 가장 낮은 값을 가지게 되는 Rim Color가 입혀지게 되는 원리이다. 
float rim = smoothstep(1.- g_rimWidth, 1.f, 1.- saturate((dot(normal.xyz, viewDir.xyz) + g_offset) / (1 + g_offset))ep(1.- g_rimWidth, 1.f, 1.- saturate((dot(normal.xyz, viewDir.xyz) + g_offset) / (1 + g_offset))
 
// NormalMap
// 노멀 맵 텍스처 XYZ를 가지고 해당 픽셀의 RGB값으로 넣게 되는데 각 색상은 해당 픽셀에 있게 될 법선의 각도를 표현한다.
// 탄젠트 공간은 normal이 항상 z축이 되는 공간입니다.
// 탄젠트와 바이노멀은 폴리곤 평면과 평행한데 tangent는 x축을 binormal은 y축 방향으로 표현됩니다.
// 이 두 법선은 노멀맵 텍스쳐의 UV좌표계와 바로 대응되는데,  U좌표가 Tangent, V좌표가 binormal이 됩니다.
 
BumpNormal = Nomal + BumpMap.x * Tangent + BumpMap.y & Binormal;
 
행기준 행렬( Row major matrix ) - d3d
| Tx Ty Tz | 
| Bx By Bz | 
| Nx Ny Nz |
열기준 행렬 ( Column major matrix ) - open gl
| Tx Bx Nx | 
| Ty By Ny | 
| Tz Bz Nz |
 
알파 값 변경법
반투명, 투명방법은 4가지가 있습니다.
 
1. 칼라키로 뺀다
2. 픽셀에 투명값이 있다.
3. SetTextureStage에서 FACTOR로 투명도를 조절한다.
4. 정점의 알파값을 사용한다.
 
 
1. 칼라키로 뺀다
특정색을 지정해서 빼는 방법입니다.
텍스쳐를 생성할때, 칼라키를 지정하면됩니다.
D3DCOLOR ColorKey = D3DCOLOR_XRGB(255,0,255);
D3DXCreateTextureFromFileEx(DXD9, 이름,  크기, 크기, 1, NULL,
                            텍스쳐포맷, 메모리풀, 필터, 필터, ColorKey, NULL, NULL, 텍스쳐포인터);
 
 
2. 픽셀에 투명값이 있다.
포토샵에서 편집하고, png로 저장하면 알파값은 그대로있습니다.
TGA를 사용할때 처럼 채널을 추가 할필요없고요.
DDS에도 알파값을 저장하는 픽셀포맷이 있고요.
SetRenderState에 알파를 사용한다는 옵션만 주면됩니다.
m_pD3dD9->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
m_pD3dD9->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );
m_pD3dD9->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
 
 
3. SetTextureStage에서 FACTOR로 투명도를 조절한다.
이미지가 가지고 있는 알파값에 다시 알파값을 조정할수있습니다.   
픽셀칼러(RGB) * 픽셀알파값(100%로계산) * 원하는 알파값(100%로계산)
m_pD3dD9->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE); 
m_pD3dD9->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); 
m_pD3dD9->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_TFACTOR);
m_pD3dD9->SetRenderState(D3DRS_TEXTUREFACTOR, D3DCOLOR_ARGB(255255255255));
 
 
4. 정점의 알파값을 사용한다.
정점의 칼라가 ARGB를 사용할경우 0xffffffff인데
맨앞의 ff값을 수정해주면, 채워지는 face의알파도 영향을 받습니다.
  
픽셀칼러(RGB) * 픽셀알파값(100%로계산) * 정점알파값(100%로계산)
m_pD3dD9->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE); 
m_pD3dD9->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); 
m_pD3dD9->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);
cs


반응형

'Programming > Shader' 카테고리의 다른 글

[HLSL] Deferred Shading  (0) 2016.12.14
[HLSL] Normal Mapping  (0) 2016.11.27
[HLSL] Texture Splatting  (0) 2016.10.19
[HLSL] Rim Lighting  (0) 2016.10.10
HLSL 사용하기  (1) 2016.10.05
[HLSL] Outline  (0) 2016.09.06
HLSL 함수  (0) 2016.09.05
PR - NPR 렌더링  (0) 2016.04.09