forked from RobertBeckebans/RBDOOM-3-BFG
-
Notifications
You must be signed in to change notification settings - Fork 0
/
specular shader
79 lines (71 loc) · 2.68 KB
/
specular shader
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
Specular Light = (R · V)n
Our entire equation is now:
Final Color = (Diffuse Light + Ambient Light + Specular Light) * Diffuse Color
Implementation
// Tweakables:
static const float AmbientIntensity = 1.0f; // The intensity of the ambient light.
static const float DiffuseIntensity = 1.0f; // The intensity of the diffuse light.
static const float SpecularIntensity = 2.0f; // The intensity of the specular light.
static const float SpecularPower = 8.0f; // The specular power, used as 'glossiness' factor.
static const float4 SunColor = {0.9f, 0.9f, 0.5f, 1.0f}; // Color vector of the sunlight.
// Application fed data:
const float4x4 matWorldViewProj; // World*view*projection matrix.
const float4x4 matWorld; // World matrix.
const float4 vecAmbient; // Ambient color.
const float4 vecSunDir; // The sun light direction vector.
const float4 vecViewPos; // View position.
texture entSkin1;
// Color map.
sampler ColorMapSampler = sampler_state // Color map sampler.
{
Texture = <entSkin1>;
MipFilter = Linear; // required for mipmapping
};
// Vertex Shader:
void SpecularVS(
in float4 InPos: POSITION,
in float3 InNormal: NORMAL,
in float2 InTex: TEXCOORD0,
out float4 OutPos: POSITION,
out float2 OutTex: TEXCOORD0,
out float3 OutNormal: TEXCOORD1,
out float3 OutViewDir: TEXCOORD2)
{
// Transform the vertex from object space to clip space:
OutPos = mul(InPos, matWorldViewProj);
// Transform the normal from object space to world space:
OutNormal = normalize(mul(InNormal, matWorld));;
// Pass the texture coordinate to the pixel shader:
OutTex = InTex;
// Calculate a vector from the vertex to the view:
OutViewDir = vecViewPos - mul(InPos, matWorld);
}
// Pixel Shader:
float4 SpecularPS(
in float2 InTex: TEXCOORD0,
in float3 InNormal: TEXCOORD1,
in float4 InViewDir: TEXCOORD2) : COLOR
{
// Calculate the ambient term:
float4 Ambient = AmbientIntensity * vecAmbient;
// Calculate the diffuse term:
InNormal = normalize(InNormal);
float4 Diffuse = DiffuseIntensity * SunColor * saturate(dot(-vecSunDir, InNormal));
// Fetch the pixel color from the color map:
float4 Color = tex2D(ColorMapSampler, InTex);
// Calculate the reflection vector:
float3 R = normalize(2 * dot(InNormal, -vecSunDir) * InNormal + vecSunDir);
// Calculate the speculate component:
float Specular = pow(saturate(dot(R, normalize(InViewDir))), SpecularPower) * SpecularIntensity;
// Calculate final color:
return (Ambient + Diffuse + Specular) * Color;
}
// Technique:
technique SpecularTechnique
{
pass P0
{
VertexShader = compile vs_2_0 SpecularVS();
PixelShader = compile ps_2_0 SpecularPS();
}
}