-
Notifications
You must be signed in to change notification settings - Fork 13
/
PixelShader.hlsl
97 lines (75 loc) · 2.52 KB
/
PixelShader.hlsl
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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
#include "Lighting.hlsli"
// How many lights could we handle?
#define MAX_LIGHTS 128
// Data that can change per material
cbuffer perMaterial : register(b0)
{
// Surface color
float3 colorTint;
// UV adjustments
float2 uvScale;
float2 uvOffset;
};
// Data that only changes once per frame
cbuffer perFrame : register(b1)
{
// An array of light data
Light lights[MAX_LIGHTS];
// The amount of lights THIS FRAME
int lightCount;
// Needed for specular (reflection) calculation
float3 cameraPosition;
};
// Defines the input to this pixel shader
// - Should match the output of our corresponding vertex shader
struct VertexToPixel
{
float4 screenPosition : SV_POSITION;
float2 uv : TEXCOORD;
float3 normal : NORMAL;
float3 tangent : TANGENT;
float3 worldPos : POSITION; // The world position of this PIXEL
};
// Texture-related variables
Texture2D Albedo : register(t0);
Texture2D NormalMap : register(t1);
Texture2D RoughnessMap : register(t2);
SamplerState BasicSampler : register(s0);
// Entry point for this pixel shader
float4 main(VertexToPixel input) : SV_TARGET
{
// Always re-normalize interpolated direction vectors
input.normal = normalize(input.normal);
input.tangent = normalize(input.tangent);
// Apply the uv adjustments
input.uv = input.uv * uvScale + uvOffset;
// Normal mapping
input.normal = NormalMapping(NormalMap, BasicSampler, input.uv, input.normal, input.tangent);
// Treating roughness as a pseduo-spec map here
float roughness = RoughnessMap.Sample(BasicSampler, input.uv).r;
float specPower = max(256.0f * (1.0f - roughness), 0.01f); // Ensure we never hit 0
// Gamma correct the texture back to linear space and apply the color tint
float4 surfaceColor = Albedo.Sample(BasicSampler, input.uv);
surfaceColor.rgb = pow(surfaceColor.rgb, 2.2) * colorTint;
// Total color for this pixel
float3 totalColor = float3(0,0,0);
// Loop through all lights this frame
for(int i = 0; i < lightCount; i++)
{
// Which kind of light?
switch (lights[i].Type)
{
case LIGHT_TYPE_DIRECTIONAL:
totalColor += DirLight(lights[i], input.normal, input.worldPos, cameraPosition, specPower, surfaceColor.rgb);
break;
case LIGHT_TYPE_POINT:
totalColor += PointLight(lights[i], input.normal, input.worldPos, cameraPosition, specPower, surfaceColor.rgb);
break;
case LIGHT_TYPE_SPOT:
totalColor += SpotLight(lights[i], input.normal, input.worldPos, cameraPosition, specPower, surfaceColor.rgb);
break;
}
}
// Gamma correction
return float4(pow(totalColor, 1.0f / 2.2f), 1);
}