You're breathtaking!
This commit is contained in:
177
Source/Shaders/GBuffer.hlsl
Normal file
177
Source/Shaders/GBuffer.hlsl
Normal file
@@ -0,0 +1,177 @@
|
||||
// Copyright (c) 2012-2020 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;
|
||||
}
|
||||
|
||||
// Sample GBuffer normal vector, shading model and view space position
|
||||
GBufferSample SampleGBufferNormalVPos(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);
|
||||
|
||||
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
|
||||
Reference in New Issue
Block a user