Skip to content

Commit 4504e5f

Browse files
committed
[DDGI] Compute visualization probe directions
1 parent dd90529 commit 4504e5f

File tree

4 files changed

+62
-43
lines changed

4 files changed

+62
-43
lines changed

src/graphics/shaders/gbuffer_ps.hlsl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ PS_OUTPUT PS_Main(PS_INPUT IN)
8686

8787
PS_OUTPUT o;
8888
o.Output0 = float4(baseColor.x, baseColor.y, baseColor.z, (InstanceParams.m_MaterialIdx / 255.0f));
89-
o.Output1 = float4(EncodeNormals(normal), velocity.x, velocity.y);
89+
o.Output1 = float4(OctahedralEncode(normal), velocity.x, velocity.y);
9090
o.Output2 = float4(emissive.x, emissive.y, emissive.z, EncodeFP16(roughness, metalness));
9191

9292
#if ETH_TOOLMODE

src/graphics/shaders/lighting/globalillumination/irradiancefieldvisualize_vsps.hlsl

Lines changed: 58 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222

2323
#include "common/globalconstants.h"
2424
#include "common/irradiancefieldparams.h"
25+
#include "utils/encoding.hlsl"
2526
#include "utils/constants.hlsl"
2627
#include "utils/helpers.hlsl"
2728

@@ -33,7 +34,7 @@ Texture2D<float2> IrradianceFieldProbeDepth : register(t1);
3334
struct VS_OUTPUT
3435
{
3536
float4 Position : SV_Position;
36-
float2 TexCoord : TEXCOORD0;
37+
float3 WorldPos : TEXCOORD0;
3738
nointerpolation uint ProbeIndex : TEXCOORD1;
3839
};
3940

@@ -51,70 +52,88 @@ float3 GetProbeWorldPosition(uint probeIndex)
5152

5253
// TODO: This calculation is probably accounting for the border wrong!!
5354
// Also, it is not interpolating
54-
float3 SampleProbeIrradiance(uint probeIndex, float2 uv)
55+
float3 SampleProbeIrradiance(uint probeIndex, float3 worldDir)
5556
{
56-
const uint x = probeIndex % IrradianceFieldParams.m_GridResolution.x;
57-
const uint temp = probeIndex / IrradianceFieldParams.m_GridResolution.x;
58-
const uint y = temp % IrradianceFieldParams.m_GridResolution.y;
59-
const uint z = temp / IrradianceFieldParams.m_GridResolution.y;
60-
61-
const uint probeAtlasX = x + y * IrradianceFieldParams.m_GridResolution.x;
62-
const uint probeAtlasY = z;
63-
64-
const float2 probeUV = uv * (IrradianceFieldParams.m_NumProbeIrradianceInteriorTexels + 1.0);
65-
66-
const uint2 atlasCoord = uint2(
67-
probeAtlasX * IrradianceFieldParams.m_NumProbeIrradianceInteriorTexels + probeUV.x,
68-
probeAtlasY * IrradianceFieldParams.m_NumProbeIrradianceInteriorTexels + probeUV.y
57+
uint x = probeIndex % IrradianceFieldParams.m_GridResolution.x;
58+
uint temp = probeIndex / IrradianceFieldParams.m_GridResolution.x;
59+
uint y = temp % IrradianceFieldParams.m_GridResolution.y;
60+
uint z = temp / IrradianceFieldParams.m_GridResolution.y;
61+
62+
uint probeAtlasX = x + y * IrradianceFieldParams.m_GridResolution.x;
63+
uint probeAtlasY = z;
64+
65+
float2 octCoord = OctahedralEncode(normalize(worldDir));
66+
float2 probeUV = octCoord * IrradianceFieldParams.m_NumProbeIrradianceInteriorTexels + 1.0;
67+
68+
uint probeSize = IrradianceFieldParams.m_NumProbeIrradianceInteriorTexels + 2;
69+
uint2 atlasCoord = uint2(
70+
probeAtlasX * probeSize + probeUV.x,
71+
probeAtlasY * probeSize + probeUV.y
6972
);
70-
71-
// Debug visualize temp
72-
return float3(uv, 1.0f);
73-
73+
7474
return IrradianceFieldProbeAtlas[atlasCoord];
7575
}
7676

77+
float2 RayIntersectSphere(float3 rayOrigin, float3 rayDir, float4 sphere)
78+
{
79+
float3 oc = rayOrigin - sphere.xyz;
80+
float b = dot(oc, rayDir);
81+
float c = dot(oc, oc) - sphere.w * sphere.w;
82+
float h = b * b - c;
83+
84+
if (h < 0.0)
85+
return float2(-1.0, -1.0);
86+
87+
h = sqrt(h);
88+
return float2(-b - h, -b + h);
89+
}
90+
7791
VS_OUTPUT VS_Main(uint vertexID : SV_VertexID, uint instanceID : SV_InstanceID)
7892
{
7993
VS_OUTPUT output;
8094

81-
const float2 offsets[6] =
95+
const float2 offsets[6] =
8296
{
8397
float2(-1, -1), float2(1, -1), float2(1, 1),
8498
float2(-1, -1), float2(1, 1), float2(-1, 1)
8599
};
86100

87-
const float2 uvs[6] =
88-
{
89-
float2(0, 1), float2(1, 1), float2(1, 0),
90-
float2(0, 1), float2(1, 0), float2(0, 0)
91-
};
92-
93101
const float3 probeWorldPos = GetProbeWorldPosition(instanceID);
94-
const float3 viewDir = normalize(GlobalConstants.m_CameraPosition.xyz - probeWorldPos);
95102

96-
// Create orthonormal basis for billboard
97-
float3 up = float3(0, 1, 0);
98-
float3 right = normalize(cross(up, viewDir));
99-
up = cross(viewDir, right);
103+
const float4 probeClipPos = mul(GlobalConstants.m_ViewProjectionMatrix, float4(probeWorldPos, 1.0));
104+
const float3 probeNDC = probeClipPos.xyz / probeClipPos.w;
105+
const float screenRadius = IrradianceFieldParams.m_VisualizeProbeRadius * 2.0f / probeClipPos.w;
106+
107+
const float aspectRatio = GlobalConstants.m_ProjectionMatrix[1][1] / GlobalConstants.m_ProjectionMatrix[0][0];
108+
float2 ndcOffset = offsets[vertexID] * screenRadius;
109+
ndcOffset.x /= aspectRatio;
100110

101-
float3 worldPos = probeWorldPos + (right * offsets[vertexID].x + up * offsets[vertexID].y) * IrradianceFieldParams.m_VisualizeProbeRadius;
102-
output.Position = mul(GlobalConstants.m_ViewProjectionMatrix, float4(worldPos, 1.0));
103-
output.TexCoord = uvs[vertexID];
111+
const float4 vertexClipPos = float4(probeNDC.xy + ndcOffset, probeNDC.z, 1.0);
112+
const float4 vertexWorldPos = mul(GlobalConstants.m_ViewProjectionMatrixInv, vertexClipPos);
113+
114+
output.Position = vertexClipPos;
115+
output.WorldPos = vertexWorldPos.xyz / vertexWorldPos.w;
104116
output.ProbeIndex = instanceID;
105117

106118
return output;
107119
}
108120

109121
float4 PS_Main(VS_OUTPUT IN) : SV_Target
110122
{
111-
float dist = length(IN.TexCoord * 2.0 - 1.0);
112-
if (dist > 1.0)
113-
discard;
123+
const float3 probeWorldCenter = GetProbeWorldPosition(IN.ProbeIndex);
124+
const float probeRadius = IrradianceFieldParams.m_VisualizeProbeRadius;
125+
const float3 rayOrigin = GlobalConstants.m_CameraPosition.xyz;
126+
const float3 rayDir = normalize(IN.WorldPos - rayOrigin);
127+
128+
const float4 sphere = float4(probeWorldCenter, probeRadius);
129+
const float2 intersections = RayIntersectSphere(rayOrigin, rayDir, sphere);
130+
clip(intersections.x);
114131

115-
float3 probeColor = SampleProbeIrradiance(IN.ProbeIndex, IN.TexCoord);
132+
const float3 intersectionPos = rayOrigin + rayDir * intersections.x;
133+
const float3 worldDir = normalize(intersectionPos - probeWorldCenter);
134+
const float3 probeColor = SampleProbeIrradiance(IN.ProbeIndex, worldDir);
116135

117-
return float4(probeColor, 1.0);
136+
return float4(worldDir, 1.0);
118137
}
119138

120139
#endif // __IRRADIANCE_FIELD_VISUALIZE_VSPS_HLSL__

src/graphics/shaders/lighting/restir/gireservoirmanagement.hlsl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,8 +94,8 @@ struct GIReservoir
9494
static GIPackedReservoir Pack(GIReservoir reservoir)
9595
{
9696
GIPackedReservoir packedReservoir;
97-
packedReservoir.m_PackedNormals.xy = EncodeNormals(reservoir.m_Sample.m_VisibleNormal);
98-
packedReservoir.m_PackedNormals.zw = EncodeNormals(reservoir.m_Sample.m_SampleNormal);
97+
packedReservoir.m_PackedNormals.xy = OctahedralEncode(reservoir.m_Sample.m_VisibleNormal);
98+
packedReservoir.m_PackedNormals.zw = OctahedralEncode(reservoir.m_Sample.m_SampleNormal);
9999
packedReservoir.m_WeightSum = reservoir.m_WeightSum;
100100
packedReservoir.m_TargetPdf = reservoir.m_TargetPdf;
101101

src/graphics/shaders/utils/encoding.hlsl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ float2 OctWrap(float2 v)
3737
return (1.0 - abs(v.yx)) * float2((v.x >= 0) ? 1 : -1, (v.y >= 0) ? 1 : -1);
3838
}
3939

40-
float2 EncodeNormals(float3 n)
40+
float2 OctahedralEncode(float3 n)
4141
{
4242
n /= (abs(n.x) + abs(n.y) + abs(n.z));
4343
n.xy = n.z >= 0.0 ? n.xy : OctWrap(n.xy);

0 commit comments

Comments
 (0)