플랫 셰이딩
면의 법선벡터와 조명벡터로 면의 밝기를 계산한다
공간 변환 후 넘겨주기만 하면 된다. 월드공간 좌표는 따로 빼고
ddx / ddy 함수는 변화량을 구하는 함수, hlsl ddx 검색
고로 셰이딩
정점의 법선벡터와 조명벡터로 정점의 밝기를 계산한다.
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
|
float4x4 matViewProjection;
float4 gWorldLightPosition;
float4 gWorldCameraPosition;
struct VS_INPUT
{
float4 mPosition : POSITION0;
float3 mNormal : NORMAL;
};
struct VS_OUTPUT
{
float4 mPosition : POSITION0;
float3 mColor : COLOR1;
};
VS_OUTPUT vs_main( VS_INPUT Input )
{
VS_OUTPUT Output;
Output.mPosition = mul( Input.mPosition, matViewProjection );
float4 projectionLightPosition = mul(gWorldLightPosition, matViewProjection);
float4 projectionCameraPosition = mul(gWorldCameraPosition, matViewProjection);
float3 projectionNormal = mul(Input.mNormal, (float3x3)matViewProjection);
float3 lightDir = Output.mPosition.xyz - projectionLightPosition.xyz;
lightDir = normalize(lightDir);
float3 viewDir = Output.mPosition.xyz - projectionCameraPosition.xyz;
viewDir = normalize(viewDir);
float3 reflection = reflect(lightDir, projectionNormal);
reflection = normalize(reflection);
float3 diffuse = dot(-lightDir, projectionNormal);
diffuse = saturate(diffuse);
float3 specular = 0;
if(diffuse.x > 0)
{
specular = saturate(dot(reflection, -viewDir));
specular = pow(specular, 20.0f);
}
float3 ambient = float3(0.1f, 0.1f, 0.1f);
Output.mColor = float4(ambient + diffuse + specular, 1);
return( Output );
}
|
cs |
투영 공간에서 연산을 수행했다
1
2
3
4
5
6
7
8
9
10
|
struct PS_INPUT
{
float3 mColor : COLOR1;
};
float4 ps_main(PS_INPUT Input) : COLOR0
{
return float4(Input.mColor, 1);
}
|
cs |
ambient가 이렇게 간단하게 계산이 될 것 같지는 않지만,
고로 셰이딩은 간단히 말해 밝기 계산을 정점 셰이더에서 처리하는 것을 의미한다.
보간의 힘을 빌리기 때문에 굳이 어떻게든 퀄리티를 떨어트린다면 이정도로 떨어트릴 수 있다.
예전 게임들에서 자주 보인 빛의 형태가 보인다.
퐁 셰이딩
픽셀의 법선벡터와 조명벡터로 픽셀의 밝기를 계산
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
|
float4x4 matViewProjection;
float4 gWorldLightPosition;
float4 gWorldCameraPosition;
struct VS_INPUT
{
float4 mPosition : POSITION0;
float3 mNormal : NORMAL;
};
struct VS_OUTPUT
{
float4 mPosition : POSITION0;
float3 mLightDir : TEXCOORD0;
float3 mViewDir : TEXCOORD1;
float3 mNormal : TEXCOORD2;
};
VS_OUTPUT vs_main( VS_INPUT Input )
{
VS_OUTPUT Output;
Output.mPosition = mul( Input.mPosition, matViewProjection );
float4 projectionLightPosition = mul(gWorldLightPosition, matViewProjection);
float4 projectionCameraPosition = mul(gWorldCameraPosition, matViewProjection);
float3 projectionNormal = mul(Input.mNormal, (float3x3)matViewProjection);
Output.mNormal = projectionNormal;
float3 lightDir = Output.mPosition.xyz - projectionLightPosition.xyz;
lightDir = normalize(lightDir);
Output.mLightDir = lightDir;
float3 viewDir = Output.mPosition.xyz - projectionCameraPosition.xyz;
viewDir = normalize(viewDir);
Output.mViewDir = viewDir;
return Output;
}
|
cs |
마찬가지로, 투영 공간에서 광원벡터, 카메라벡터를 계산했다.
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
|
struct PS_INPUT
{
float3 mLightDir : TEXCOORD0;
float3 mViewDir : TEXCOORD1;
float3 mNormal : TEXCOORD2;
};
float4 ps_main(PS_INPUT Input) : COLOR0
{
Input.mLightDir = normalize(Input.mLightDir);
Input.mViewDir = normalize(Input.mViewDir);
Input.mNormal = normalize(Input.mNormal);
float3 diffuse = dot(-Input.mLightDir, Input.mNormal);
diffuse = saturate(diffuse);
float3 reflection = reflect(Input.mLightDir, Input.mNormal);
reflection = normalize(reflection);
float3 specular = 0;
if(diffuse.x > 0)
{
specular = saturate(dot(reflection, -Input.mViewDir));
specular = pow(specular, 20.0f);
}
float3 ambient = float3(0.1f, 0.1f, 0.1f);
return float4(diffuse + ambient + specular, 1);
}
|
cs |
실제 밝기의 계산은 픽셀 셰이더에서 해줘야 한다.
아니 근데 이게 맞나...?
결과물만 보자면 맞긴 한데... 이 방식이 맞나
보다시피, 둘이 대놓고 비교하면 큰 차이가 나긴 한다.
아무튼, 고로 셰이딩과 퐁 셰이딩은 위와 같다.
androgameprgm.tistory.com/entry/RenderMonkey-Tutorial-03?category=217339
'그래픽스' 카테고리의 다른 글
유니티 셰이더, 셰이더 (0) | 2020.09.08 |
---|---|
Volumetric Light (0) | 2020.09.08 |
상수 버퍼, constant buffer (0) | 2020.09.08 |
Assimp (0) | 2020.09.08 |
God Ray (0) | 2020.09.07 |