2020-08-27 18:14:17 +00:00
|
|
|
#include "Macros.fxh"
|
|
|
|
|
|
|
|
DECLARE_TEXTURE(AlbedoTexture, 0);
|
|
|
|
DECLARE_TEXTURE(NormalTexture, 1);
|
|
|
|
DECLARE_TEXTURE(MetallicRoughnessTexture, 2);
|
|
|
|
|
2020-12-11 00:02:13 +00:00
|
|
|
float3 AlbedoValue;
|
|
|
|
float MetallicValue;
|
|
|
|
float RoughnessValue;
|
2020-08-27 18:14:17 +00:00
|
|
|
|
2020-12-11 00:02:13 +00:00
|
|
|
float4 UVOffsetAndDimensions;
|
2020-08-27 18:14:17 +00:00
|
|
|
|
2020-12-11 00:02:13 +00:00
|
|
|
float4x4 World;
|
|
|
|
float4x4 ViewProjection;
|
2020-08-27 18:14:17 +00:00
|
|
|
|
|
|
|
struct VertexInput
|
|
|
|
{
|
2020-12-11 00:02:13 +00:00
|
|
|
float3 Position : POSITION;
|
2020-08-27 18:14:17 +00:00
|
|
|
float3 Normal : NORMAL;
|
2020-12-07 21:50:32 +00:00
|
|
|
float2 TexCoord : TEXCOORD;
|
2020-08-27 18:14:17 +00:00
|
|
|
};
|
|
|
|
|
2020-12-11 00:02:13 +00:00
|
|
|
struct VertexInstancedInput
|
|
|
|
{
|
|
|
|
float3 Position : POSITION;
|
|
|
|
float3 Normal : NORMAL;
|
|
|
|
float2 TexCoord : TEXCOORD0;
|
|
|
|
float3 Translation : TEXCOORD2;
|
|
|
|
float2 UVData : TANGENT;
|
|
|
|
};
|
|
|
|
|
2020-08-27 18:14:17 +00:00
|
|
|
struct PixelInput
|
|
|
|
{
|
|
|
|
float4 Position : SV_POSITION;
|
|
|
|
float3 PositionWorld : TEXCOORD0;
|
|
|
|
float3 NormalWorld : TEXCOORD1;
|
|
|
|
float2 TexCoord : TEXCOORD2;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct PixelOutput
|
|
|
|
{
|
|
|
|
float4 gPosition : COLOR0;
|
|
|
|
float4 gNormal : COLOR1;
|
|
|
|
float4 gAlbedo : COLOR2;
|
|
|
|
float4 gMetallicRoughness : COLOR3;
|
|
|
|
};
|
|
|
|
|
|
|
|
// Vertex Shader
|
|
|
|
|
|
|
|
PixelInput main_vs(VertexInput input)
|
|
|
|
{
|
|
|
|
PixelInput output;
|
|
|
|
|
|
|
|
output.PositionWorld = mul(input.Position, World).xyz;
|
2020-12-07 21:50:32 +00:00
|
|
|
output.NormalWorld = normalize(mul(input.Normal, World));
|
2020-12-11 00:02:13 +00:00
|
|
|
|
|
|
|
float2 texCoord;
|
|
|
|
texCoord.x = (input.TexCoord.x / UVOffsetAndDimensions.z) + UVOffsetAndDimensions.x;
|
|
|
|
texCoord.y = (input.TexCoord.y / UVOffsetAndDimensions.w) + UVOffsetAndDimensions.y;
|
|
|
|
output.TexCoord = texCoord;
|
2020-12-07 21:50:32 +00:00
|
|
|
|
|
|
|
float4x4 worldViewProjection = mul(World, ViewProjection);
|
|
|
|
output.Position = mul(input.Position, worldViewProjection);
|
2020-08-27 18:14:17 +00:00
|
|
|
|
|
|
|
return output;
|
|
|
|
}
|
|
|
|
|
2020-12-09 06:20:54 +00:00
|
|
|
PixelInput instanced_vs(
|
2020-12-11 00:02:13 +00:00
|
|
|
VertexInstancedInput input
|
2020-12-09 06:20:54 +00:00
|
|
|
) {
|
2020-12-07 09:30:09 +00:00
|
|
|
PixelInput output;
|
|
|
|
|
2020-12-08 10:49:18 +00:00
|
|
|
float4x4 world = float4x4(
|
|
|
|
float4(1, 0, 0, 0),
|
|
|
|
float4(0, 1, 0, 0),
|
|
|
|
float4(0, 0, 1, 0),
|
2020-12-11 00:02:13 +00:00
|
|
|
float4(input.Translation.x, input.Translation.y, input.Translation.z, 1)
|
2020-12-09 06:20:54 +00:00
|
|
|
);
|
2020-12-08 10:49:18 +00:00
|
|
|
|
|
|
|
float4x4 worldViewProjection = mul(world, ViewProjection);
|
|
|
|
|
|
|
|
output.PositionWorld = mul(input.Position, world);
|
|
|
|
output.NormalWorld = mul(input.Normal, world);
|
2020-12-09 06:20:54 +00:00
|
|
|
|
|
|
|
float2 texCoord;
|
2020-12-11 00:02:13 +00:00
|
|
|
texCoord.x = (input.TexCoord.x / 8) + input.UVData.x;
|
|
|
|
texCoord.y = (input.TexCoord.y / 1) + input.UVData.y;
|
|
|
|
output.TexCoord = input.TexCoord;
|
2020-12-07 21:50:32 +00:00
|
|
|
|
|
|
|
output.Position = mul(input.Position, worldViewProjection);
|
2020-12-07 09:30:09 +00:00
|
|
|
|
|
|
|
return output;
|
|
|
|
}
|
|
|
|
|
2020-08-27 18:14:17 +00:00
|
|
|
// Pixel Shaders
|
|
|
|
|
|
|
|
// Easy trick to get tangent-normals to world-space to keep PBR code simplified.
|
|
|
|
float3 GetNormalFromMap(float3 worldPos, float2 texCoords, float3 normal)
|
|
|
|
{
|
|
|
|
float3 tangentNormal = SAMPLE_TEXTURE(NormalTexture, texCoords).xyz * 2.0 - 1.0;
|
|
|
|
|
|
|
|
float3 Q1 = ddx(worldPos);
|
|
|
|
float3 Q2 = ddy(worldPos);
|
|
|
|
float2 st1 = ddx(texCoords);
|
|
|
|
float2 st2 = ddy(texCoords);
|
|
|
|
|
|
|
|
float3 N = normalize(normal);
|
|
|
|
float3 T = normalize(Q1*st2.y - Q2*st1.y);
|
|
|
|
float3 B = -normalize(cross(N, T));
|
|
|
|
float3x3 TBN = float3x3(T, B, N);
|
|
|
|
|
|
|
|
return normalize(mul(tangentNormal, TBN));
|
|
|
|
}
|
|
|
|
|
|
|
|
PixelOutput NonePS(PixelInput input)
|
|
|
|
{
|
|
|
|
PixelOutput output;
|
|
|
|
|
2020-10-01 19:46:25 +00:00
|
|
|
output.gPosition = float4(input.PositionWorld, 1.0);
|
|
|
|
output.gNormal = float4(normalize(input.NormalWorld), 1.0);
|
2020-08-27 18:14:17 +00:00
|
|
|
output.gAlbedo = float4(AlbedoValue, 1.0);
|
2020-10-01 19:46:25 +00:00
|
|
|
output.gMetallicRoughness = float4(MetallicValue, RoughnessValue, 0.0, 1.0);
|
2020-08-27 18:14:17 +00:00
|
|
|
|
|
|
|
return output;
|
|
|
|
}
|
|
|
|
|
|
|
|
PixelOutput AlbedoPS(PixelInput input)
|
|
|
|
{
|
|
|
|
PixelOutput output;
|
|
|
|
|
2020-10-01 19:46:25 +00:00
|
|
|
output.gPosition = float4(input.PositionWorld, 1.0);
|
|
|
|
output.gNormal = float4(normalize(input.NormalWorld), 1.0);
|
2020-08-27 18:14:17 +00:00
|
|
|
output.gAlbedo = SAMPLE_TEXTURE(AlbedoTexture, input.TexCoord);
|
2020-10-01 19:46:25 +00:00
|
|
|
output.gMetallicRoughness = float4(MetallicValue, RoughnessValue, 0.0, 1.0);
|
2020-08-27 18:14:17 +00:00
|
|
|
|
|
|
|
return output;
|
|
|
|
}
|
|
|
|
|
|
|
|
PixelOutput MetallicRoughnessPS(PixelInput input)
|
|
|
|
{
|
|
|
|
PixelOutput output;
|
|
|
|
|
2020-10-01 19:46:25 +00:00
|
|
|
output.gPosition = float4(input.PositionWorld, 1.0);
|
|
|
|
output.gNormal = float4(normalize(input.NormalWorld), 1.0);
|
2020-08-27 18:14:17 +00:00
|
|
|
output.gAlbedo = float4(AlbedoValue, 1.0);
|
|
|
|
output.gMetallicRoughness = SAMPLE_TEXTURE(MetallicRoughnessTexture, input.TexCoord);
|
|
|
|
|
|
|
|
return output;
|
|
|
|
}
|
|
|
|
|
|
|
|
PixelOutput NormalPS(PixelInput input)
|
|
|
|
{
|
|
|
|
PixelOutput output;
|
|
|
|
|
2020-10-01 19:46:25 +00:00
|
|
|
output.gPosition = float4(input.PositionWorld, 1.0);
|
|
|
|
output.gNormal = float4(GetNormalFromMap(input.PositionWorld, input.TexCoord, input.NormalWorld), 1.0);
|
2020-08-27 18:14:17 +00:00
|
|
|
output.gAlbedo = float4(AlbedoValue, 1.0);
|
2020-10-01 19:46:25 +00:00
|
|
|
output.gMetallicRoughness = float4(MetallicValue, RoughnessValue, 0.0, 1.0);
|
2020-08-27 18:14:17 +00:00
|
|
|
|
|
|
|
return output;
|
|
|
|
}
|
|
|
|
|
|
|
|
PixelOutput AlbedoMetallicRoughnessPS(PixelInput input)
|
|
|
|
{
|
|
|
|
PixelOutput output;
|
|
|
|
|
2020-10-01 19:46:25 +00:00
|
|
|
output.gPosition = float4(input.PositionWorld, 1.0);
|
|
|
|
output.gNormal = float4(normalize(input.NormalWorld), 1.0);
|
2020-08-27 18:14:17 +00:00
|
|
|
output.gAlbedo = SAMPLE_TEXTURE(AlbedoTexture, input.TexCoord);
|
|
|
|
output.gMetallicRoughness = SAMPLE_TEXTURE(MetallicRoughnessTexture, input.TexCoord);
|
|
|
|
|
|
|
|
return output;
|
|
|
|
}
|
|
|
|
|
|
|
|
PixelOutput AlbedoNormalPS(PixelInput input)
|
|
|
|
{
|
|
|
|
PixelOutput output;
|
|
|
|
|
2020-10-01 19:46:25 +00:00
|
|
|
output.gPosition = float4(input.PositionWorld, 1.0);
|
|
|
|
output.gNormal = float4(GetNormalFromMap(input.PositionWorld, input.TexCoord, input.NormalWorld), 1.0);
|
2020-08-27 18:14:17 +00:00
|
|
|
output.gAlbedo = SAMPLE_TEXTURE(AlbedoTexture, input.TexCoord);
|
2020-10-01 19:46:25 +00:00
|
|
|
output.gMetallicRoughness = float4(MetallicValue, RoughnessValue, 0.0, 1.0);
|
2020-08-27 18:14:17 +00:00
|
|
|
|
|
|
|
return output;
|
|
|
|
}
|
|
|
|
|
|
|
|
PixelOutput MetallicRoughnessNormalPS(PixelInput input)
|
|
|
|
{
|
|
|
|
PixelOutput output;
|
|
|
|
|
2020-10-01 19:46:25 +00:00
|
|
|
output.gPosition = float4(input.PositionWorld, 1.0);
|
|
|
|
output.gNormal = float4(GetNormalFromMap(input.PositionWorld, input.TexCoord, input.NormalWorld), 1.0);
|
2020-08-27 18:14:17 +00:00
|
|
|
output.gAlbedo = float4(AlbedoValue, 1.0);
|
|
|
|
output.gMetallicRoughness = SAMPLE_TEXTURE(MetallicRoughnessTexture, input.TexCoord);
|
|
|
|
|
|
|
|
return output;
|
|
|
|
}
|
|
|
|
|
|
|
|
PixelOutput AlbedoMetallicRoughnessNormalMapPS(PixelInput input)
|
|
|
|
{
|
|
|
|
PixelOutput output;
|
|
|
|
|
2020-10-01 19:46:25 +00:00
|
|
|
output.gPosition = float4(input.PositionWorld, 1.0);
|
|
|
|
output.gNormal = float4(GetNormalFromMap(input.PositionWorld, input.TexCoord, input.NormalWorld), 1.0);
|
2020-08-27 18:14:17 +00:00
|
|
|
output.gAlbedo = SAMPLE_TEXTURE(AlbedoTexture, input.TexCoord);
|
|
|
|
output.gMetallicRoughness = SAMPLE_TEXTURE(MetallicRoughnessTexture, input.TexCoord);
|
|
|
|
|
|
|
|
return output;
|
|
|
|
}
|
|
|
|
|
|
|
|
PixelShader PSArray[8] =
|
|
|
|
{
|
|
|
|
compile ps_3_0 NonePS(),
|
|
|
|
|
|
|
|
compile ps_3_0 AlbedoPS(),
|
|
|
|
compile ps_3_0 MetallicRoughnessPS(),
|
|
|
|
compile ps_3_0 NormalPS(),
|
|
|
|
|
|
|
|
compile ps_3_0 AlbedoMetallicRoughnessPS(),
|
|
|
|
compile ps_3_0 AlbedoNormalPS(),
|
|
|
|
compile ps_3_0 MetallicRoughnessNormalPS(),
|
|
|
|
|
|
|
|
compile ps_3_0 AlbedoMetallicRoughnessNormalMapPS()
|
|
|
|
};
|
|
|
|
|
|
|
|
int PSIndices[8] =
|
|
|
|
{
|
|
|
|
0, 1, 2, 3, 4, 5, 6, 7
|
|
|
|
};
|
|
|
|
|
2020-12-07 09:30:09 +00:00
|
|
|
int PixelShaderIndex = 0;
|
2020-08-27 18:14:17 +00:00
|
|
|
|
|
|
|
Technique GBuffer
|
|
|
|
{
|
|
|
|
Pass
|
|
|
|
{
|
2020-12-11 00:02:13 +00:00
|
|
|
VertexShader = compile vs_3_0 instanced_vs();
|
2020-12-07 09:30:09 +00:00
|
|
|
PixelShader = (PSArray[PSIndices[PixelShaderIndex]]);
|
2020-08-27 18:14:17 +00:00
|
|
|
}
|
|
|
|
}
|