Files
FlaxEngine/Source/Shaders/GBuffer.hlsl

160 lines
4.2 KiB
HLSL

// Copyright (c) Wojciech Figat. All rights reserved.
#ifndef __GBUFFER__
#define __GBUFFER__
#include "./Flax/GBufferCommon.hlsl"
#if !defined(NO_GBUFFER_SAMPLING)
// GBuffer
Texture2D GBuffer0 : register(t0);
Texture2D GBuffer1 : register(t1);
Texture2D GBuffer2 : register(t2);
Texture2D Depth : register(t3);
#if defined(USE_GBUFFER_CUSTOM_DATA)
Texture2D GBuffer3 : register(t4);
#endif
// GBuffer Layout:
// GBuffer0 = [RGB] Color, [A] AO
// GBuffer1 = [RGB] Normal, [A] ShadingModel
// GBuffer2 = [R] Roughness, [G] Metalness, [B] Specular, [A] UNUSED
// GBuffer3 = [RGBA] Custom Data (per shading mode)
#endif
// Linearize raw device depth
float LinearizeZ(GBufferData gBuffer, float depth)
{
return gBuffer.ViewInfo.w / (depth - gBuffer.ViewInfo.z);
}
// Convert linear depth to device depth
float LinearZ2DeviceDepth(GBufferData gBuffer, float linearDepth)
{
return (gBuffer.ViewInfo.w / linearDepth) + gBuffer.ViewInfo.z;
}
// Get view space position at given pixel coordinate with given device depth
float3 GetViewPos(GBufferData gBuffer, float2 uv, float deviceDepth)
{
float4 clipPos = float4(uv * float2(2.0, -2.0) + float2(-1.0, 1.0), deviceDepth, 1.0);
float4 viewPos = mul(clipPos, gBuffer.InvProjectionMatrix);
return viewPos.xyz / viewPos.w;
}
// Get world space position at given pixel coordinate with given device depth
float3 GetWorldPos(GBufferData gBuffer, float2 uv, float deviceDepth)
{
float3 viewPos = GetViewPos(gBuffer, uv, deviceDepth);
return mul(float4(viewPos, 1), gBuffer.InvViewMatrix).xyz;
}
#if !defined(NO_GBUFFER_SAMPLING)
// Sample raw device depth buffer
float SampleZ(float2 uv)
{
return SAMPLE_RT(Depth, uv).r;
}
// Sample linear depth
float SampleDepth(GBufferData gBuffer, float2 uv)
{
float deviceDepth = SampleZ(uv);
return LinearizeZ(gBuffer, deviceDepth);
}
// Get view space position at given pixel coordinate
float3 GetViewPos(GBufferData gBuffer, float2 uv)
{
float deviceDepth = SampleZ(uv);
return GetViewPos(gBuffer, uv, deviceDepth);
}
// Get world space position at given pixel coordinate
float3 GetWorldPos(GBufferData gBuffer, float2 uv)
{
float deviceDepth = SampleZ(uv);
return GetWorldPos(gBuffer, uv, deviceDepth);
}
// Sample normal vector with pixel shading model
float3 SampleNormal(float2 uv, out int shadingModel)
{
// Sample GBuffer
float4 gBuffer1 = SAMPLE_RT(GBuffer1, uv);
// Decode normal and shading model
shadingModel = (int)(gBuffer1.a * 3.999);
return DecodeNormal(gBuffer1.rgb);
}
// Sample GBuffer
GBufferSample SampleGBuffer(GBufferData gBuffer, float2 uv)
{
GBufferSample result;
// Sample GBuffer
float4 gBuffer0 = SAMPLE_RT(GBuffer0, uv);
float4 gBuffer1 = SAMPLE_RT(GBuffer1, uv);
float4 gBuffer2 = SAMPLE_RT(GBuffer2, uv);
#if defined(USE_GBUFFER_CUSTOM_DATA)
float4 gBuffer3 = SAMPLE_RT(GBuffer3, uv);
#endif
// Decode normal and shading model
result.Normal = DecodeNormal(gBuffer1.rgb);
result.ShadingModel = (int)(gBuffer1.a * 3.999);
// Calculate view space and world space positions
result.ViewPos = GetViewPos(gBuffer, uv);
result.WorldPos = mul(float4(result.ViewPos, 1), gBuffer.InvViewMatrix).xyz;
// Decode GBuffer data
result.Color = gBuffer0.rgb;
result.AO = gBuffer0.a;
result.Roughness = gBuffer2.r;
result.Metalness = gBuffer2.g;
result.Specular = gBuffer2.b;
#if defined(USE_GBUFFER_CUSTOM_DATA)
result.CustomData = gBuffer3;
#endif
return result;
}
// Sample GBuffer (fast - only few parameters are being sampled)
GBufferSample SampleGBufferFast(GBufferData gBuffer, float2 uv)
{
GBufferSample result;
// Sample GBuffer
float4 gBuffer1 = SAMPLE_RT(GBuffer1, uv);
// Decode normal and shading model
result.Normal = DecodeNormal(gBuffer1.rgb);
result.ShadingModel = (int)(gBuffer1.a * 3.999);
// Calculate view space position
result.ViewPos = GetViewPos(gBuffer, uv);
result.WorldPos = mul(float4(result.ViewPos, 1), gBuffer.InvViewMatrix).xyz;
return result;
}
#if defined(USE_GBUFFER_CUSTOM_DATA)
// Sample GBuffer custom data only
float4 SampleGBufferCustomData(float2 uv)
{
return SAMPLE_RT(GBuffer3, uv);
}
#endif
#endif
#endif