Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
- Improved cone tracing direction selection.
- Removed cone tracing bias.
- Removed redundant matrix multiplication in voxelization step.
- Improved voxel visibility function.

### Fixed

Expand Down
2 changes: 1 addition & 1 deletion ShaderLibrary/Radiances/Pixel.cginc
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
if (notInRange || (spotFalloff <= 0.0) || (data.NdotL <= 0.0)) continue;

radiance +=
VoxelVisibility(data.voxelPosition + data.vecN, lightSource.voxelPosition)
VXGI_VoxelVisibility((data.voxelPosition + data.vecN) / Resolution, lightSource.voxelPosition / Resolution)
* GeneralBRDF(data)
* data.NdotL
* spotFalloff
Expand Down
154 changes: 64 additions & 90 deletions ShaderLibrary/Radiances/Sampler.cginc
Original file line number Diff line number Diff line change
@@ -1,100 +1,74 @@
#ifndef VXGI_RADIANCES_SAMPLER
#define VXGI_RADIANCES_SAMPLER
#ifndef VXGI_SHADERLIBRARY_RADIANCES_SAMPLER
#define VXGI_SHADERLIBRARY_RADIANCES_SAMPLER

#ifdef RADIANCE_POINT_SAMPLER
#define RADIANCE_SAMPLER point_clamp_sampler
#else
#define RADIANCE_SAMPLER linear_clamp_sampler
#endif

#define LERP_OCCLUSION(level, position, fraction) lerp(SAMPLE_OCCLUSION(level - 1, position), SAMPLE_OCCLUSION(level, position), fraction)
#define LERP_RADIANCE(level, position, fraction) lerp(SAMPLE_RADIANCE(level - 1, position), SAMPLE_RADIANCE(level, position), fraction)
#define SAMPLE_OCCLUSION(level, position) SAMPLE_RADIANCE(level, position).a
#define SAMPLE_RADIANCE(level, position) Radiances[level].SampleLevel(RADIANCE_SAMPLER, position, 0.0)
#ifdef RADIANCE_POINT_SAMPLER
#define RADIANCE_SAMPLER point_clamp_sampler
#else
#define RADIANCE_SAMPLER linear_clamp_sampler
#endif

#include "Packages/com.looooong.srp.vxgi/ShaderLibrary/Variables.cginc"
#define LERP_RADIANCE(level, position, fraction) lerp(SAMPLE_RADIANCE(level - 1, position), SAMPLE_RADIANCE(level, position), fraction)
#define SAMPLE_RADIANCE(level, position) Radiances[level].SampleLevel(RADIANCE_SAMPLER, position, 0.0)

Texture3D Radiance0;
Texture3D Radiance1;
Texture3D Radiance2;
Texture3D Radiance3;
Texture3D Radiance4;
Texture3D Radiance5;
Texture3D Radiance6;
Texture3D Radiance7;
Texture3D Radiance8;
static Texture3D Radiances[9] = {
Radiance0,
Radiance1,
Radiance2,
Radiance3,
Radiance4,
Radiance5,
Radiance6,
Radiance7,
Radiance8,
};
#include "Packages/com.looooong.srp.vxgi/ShaderLibrary/Variables.cginc"

float SampleLevel(float size)
{
return size <= 1.0 ? size : log2(size) + 1;
}
Texture3D Radiance0;
Texture3D Radiance1;
Texture3D Radiance2;
Texture3D Radiance3;
Texture3D Radiance4;
Texture3D Radiance5;
Texture3D Radiance6;
Texture3D Radiance7;
Texture3D Radiance8;
static Texture3D Radiances[9] = {
Radiance0,
Radiance1,
Radiance2,
Radiance3,
Radiance4,
Radiance5,
Radiance6,
Radiance7,
Radiance8,
};

float SampleOcclusion(float3 position, float size)
{
float level = clamp(SampleLevel(size), 0.0, 8.999999);
uint levelFloor = level;
float SampleLevel(float size)
{
return size <= 1.0 ? size : log2(size) + 1;
}

if (level <= 1.0) {
return lerp(0.0, SAMPLE_OCCLUSION(0, position), level);
} else {
switch (levelFloor) {
case 1:
return LERP_OCCLUSION(1, position, frac(level));
case 2:
return LERP_OCCLUSION(2, position, frac(level));
case 3:
return LERP_OCCLUSION(3, position, frac(level));
case 4:
return LERP_OCCLUSION(4, position, frac(level));
case 5:
return LERP_OCCLUSION(5, position, frac(level));
case 6:
return LERP_OCCLUSION(6, position, frac(level));
case 7:
return LERP_OCCLUSION(7, position, frac(level));
default:
return LERP_OCCLUSION(8, position, frac(level));
}
}
}
float VXGI_VoxelOpacity(float3 position)
{
return Radiance0.SampleLevel(RADIANCE_SAMPLER, position, 0.0).a;
}

float4 SampleRadiance(float3 position, float size)
{
float level = clamp(SampleLevel(size), 0.0, 8.999999);
uint levelFloor = level;
float4 SampleRadiance(float3 position, float size)
{
float level = clamp(SampleLevel(size), 0.0, 8.999999);
uint levelFloor = level;

if (level <= 1.0) {
return lerp(0.0, SAMPLE_RADIANCE(0, position), level);
} else {
switch (levelFloor) {
case 1:
return LERP_RADIANCE(1, position, frac(level));
case 2:
return LERP_RADIANCE(2, position, frac(level));
case 3:
return LERP_RADIANCE(3, position, frac(level));
case 4:
return LERP_RADIANCE(4, position, frac(level));
case 5:
return LERP_RADIANCE(5, position, frac(level));
case 6:
return LERP_RADIANCE(6, position, frac(level));
case 7:
return LERP_RADIANCE(7, position, frac(level));
default:
return LERP_RADIANCE(8, position, frac(level));
}
if (level <= 1.0) {
return lerp(0.0, SAMPLE_RADIANCE(0, position), level);
} else {
switch (levelFloor) {
case 1:
return LERP_RADIANCE(1, position, frac(level));
case 2:
return LERP_RADIANCE(2, position, frac(level));
case 3:
return LERP_RADIANCE(3, position, frac(level));
case 4:
return LERP_RADIANCE(4, position, frac(level));
case 5:
return LERP_RADIANCE(5, position, frac(level));
case 6:
return LERP_RADIANCE(6, position, frac(level));
case 7:
return LERP_RADIANCE(7, position, frac(level));
default:
return LERP_RADIANCE(8, position, frac(level));
}
}
#endif
}
#endif // VXGI_SHADERLIBRARY_RADIANCES_SAMPLER
2 changes: 1 addition & 1 deletion ShaderLibrary/Radiances/Voxel.cginc
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
if (notInRange || (spotFalloff <= 0.0) || (data.NdotL <= 0.0)) continue;

radiance +=
VoxelVisibility(data.voxelPosition + data.vecL / data.NdotL, lightSource.voxelPosition)
VXGI_VoxelVisibility((data.voxelPosition + data.vecL / data.NdotL) / Resolution, lightSource.voxelPosition / Resolution)
* data.NdotL
* spotFalloff
* lightSource.Attenuation(localPosition);
Expand Down
106 changes: 59 additions & 47 deletions ShaderLibrary/Variables.cginc
Original file line number Diff line number Diff line change
@@ -1,51 +1,63 @@
#ifndef VXGI_VARIABLES
#define VXGI_VARIABLES
#ifndef VXGI_SHADERLIBRARY_VARIABLES
#define VXGI_SHADERLIBRARY_VARIABLES

#include "Packages/com.looooong.srp.vxgi/ShaderLibrary/Structs/LightSource.hlsl"
#include "Packages/com.looooong.srp.vxgi/ShaderLibrary/Structs/LightSource.hlsl"

uint Resolution;
uint LightCount;
float4x4 VoxelToWorld;
float4x4 WorldToVoxel;
SamplerState point_clamp_sampler;
SamplerState linear_clamp_sampler;
StructuredBuffer<LightSource> LightSources;
uint Resolution;
uint LightCount;
float4x4 VoxelToWorld;
float4x4 WorldToVoxel;
SamplerState point_clamp_sampler;
SamplerState linear_clamp_sampler;
StructuredBuffer<LightSource> LightSources;

static float ConeDirectionThreshold = sin(atan(1.0/3.0));
static float ConeDirectionThreshold = sin(atan(1.0/3.0));

// Cone tracing direction for indirect diffuse calculations
static float3 Directions[32] = {
float3(+0.000000, +1.000000, +0.000000),
float3(+0.000000, -1.000000, +0.000000),
float3(+0.000000, +0.187595, -0.982245),
float3(+0.000000, -0.187595, +0.982245),
float3(+0.000000, +0.745356, -0.666656),
float3(+0.000000, -0.745356, +0.666656),
float3(+0.000000, +0.794654, +0.607060),
float3(+0.000000, -0.794654, -0.607060),
float3(+0.356818, +0.333334, +0.872681),
float3(+0.356818, -0.333334, -0.872681),
float3(-0.356818, +0.333334, +0.872681),
float3(-0.356818, -0.333334, -0.872681),
float3(+0.525736, +0.794654, -0.303524),
float3(+0.525736, -0.794654, +0.303524),
float3(-0.525736, +0.794654, -0.303524),
float3(-0.525736, -0.794654, +0.303524),
float3(+0.577350, +0.333334, -0.745356),
float3(+0.577350, -0.333334, +0.745356),
float3(-0.577350, +0.333334, -0.745356),
float3(-0.577350, -0.333334, +0.745356),
float3(+0.577350, +0.745356, +0.333334),
float3(+0.577350, -0.745356, -0.333334),
float3(-0.577350, +0.745356, +0.333334),
float3(-0.577350, -0.745356, -0.333334),
float3(+0.850648, +0.187595, +0.491129),
float3(+0.850648, -0.187595, -0.491129),
float3(-0.850648, +0.187595, +0.491129),
float3(-0.850648, -0.187595, -0.491129),
float3(+0.934174, +0.333334, -0.127319),
float3(+0.934174, -0.333334, +0.127319),
float3(-0.934174, +0.333334, -0.127319),
float3(-0.934174, -0.333334, +0.127319),
};
#endif
// Cone tracing direction for indirect diffuse calculations
static float3 Directions[32] = {
float3(+0.000000, +1.000000, +0.000000),
float3(+0.000000, -1.000000, +0.000000),
float3(+0.000000, +0.187595, -0.982245),
float3(+0.000000, -0.187595, +0.982245),
float3(+0.000000, +0.745356, -0.666656),
float3(+0.000000, -0.745356, +0.666656),
float3(+0.000000, +0.794654, +0.607060),
float3(+0.000000, -0.794654, -0.607060),
float3(+0.356818, +0.333334, +0.872681),
float3(+0.356818, -0.333334, -0.872681),
float3(-0.356818, +0.333334, +0.872681),
float3(-0.356818, -0.333334, -0.872681),
float3(+0.525736, +0.794654, -0.303524),
float3(+0.525736, -0.794654, +0.303524),
float3(-0.525736, +0.794654, -0.303524),
float3(-0.525736, -0.794654, +0.303524),
float3(+0.577350, +0.333334, -0.745356),
float3(+0.577350, -0.333334, +0.745356),
float3(-0.577350, +0.333334, -0.745356),
float3(-0.577350, -0.333334, +0.745356),
float3(+0.577350, +0.745356, +0.333334),
float3(+0.577350, -0.745356, -0.333334),
float3(-0.577350, +0.745356, +0.333334),
float3(-0.577350, -0.745356, -0.333334),
float3(+0.850648, +0.187595, +0.491129),
float3(+0.850648, -0.187595, -0.491129),
float3(-0.850648, +0.187595, +0.491129),
float3(-0.850648, -0.187595, -0.491129),
float3(+0.934174, +0.333334, -0.127319),
float3(+0.934174, -0.333334, +0.127319),
float3(-0.934174, +0.333334, -0.127319),
float3(-0.934174, -0.333334, +0.127319),
};

static float3 VXGI_VoxelSizes[] = {
1.0 / Resolution,
2.0 / Resolution,
4.0 / Resolution,
8.0 / Resolution,
16.0 / Resolution,
32.0 / Resolution,
64.0 / Resolution,
128.0 / Resolution,
256.0 / Resolution
};
#endif // VXGI_SHADERLIBRARY_VARIABLES
45 changes: 24 additions & 21 deletions ShaderLibrary/Visibility.cginc
Original file line number Diff line number Diff line change
@@ -1,25 +1,28 @@
#ifndef VXGI_VISIBILITY
#define VXGI_VISIBILITY
#ifndef VXGI_SHADERLIBRARY_VISIBILITY
#define VXGI_SHADERLIBRARY_VISIBILITY

#include "Packages/com.looooong.srp.vxgi/ShaderLibrary/Variables.cginc"
#include "Packages/com.looooong.srp.vxgi/ShaderLibrary/Utilities.cginc"
#include "Packages/com.looooong.srp.vxgi/ShaderLibrary/Radiances/Sampler.cginc"
#include "Packages/com.looooong.srp.vxgi/ShaderLibrary/Variables.cginc"
#include "Packages/com.looooong.srp.vxgi/ShaderLibrary/Utilities.cginc"
#include "Packages/com.looooong.srp.vxgi/ShaderLibrary/Radiances/Sampler.cginc"

// Calculate visibility between 2 points in voxel space
float VoxelVisibility(float3 p1, float3 p2)
{
float occlusion = 0.0;
float3 direction = normalize(p2 - p1);
float3 step = direction / Resolution;
// Calculate visibility between 2 points in voxel space
float VXGI_VoxelVisibility(float3 p1, float3 p2)
{
uint level = 0;
float opacity = 0.0;
float stepDistance = distance(p1, p2);
float stepSize = 0.5 * VXGI_VoxelSizes[level];
float3 stepDirection = normalize(p2 - p1);
float3 step = stepSize * stepDirection;

for (
float3 coordinate = p1 / Resolution + step;
occlusion < 1.0 && TextureSDF(coordinate) > 0.0 && dot(mad(-coordinate, Resolution, p2), direction) > 0.5;
coordinate += 0.5 * step
) {
occlusion += (1.0 - occlusion) * SampleOcclusion(coordinate, 1.0);
}

return 1.0 - occlusion;
for (
p1 += step, stepDistance -= stepSize;
opacity < 1.0 && stepDistance > 0.0;
p1 += step, stepDistance -= stepSize
) {
if (TextureSDF(p1) > 0.0) opacity += (1.0 - opacity) * VXGI_VoxelOpacity(p1);
}
#endif

return 1.0 - opacity;
}
#endif // VXGI_SHADERLIBRARY_VISIBILITY