Skip to content

Commit

Permalink
Fixed voxelization volume
Browse files Browse the repository at this point in the history
  • Loading branch information
AEspinosaDev committed Jan 14, 2025
1 parent 4a056a1 commit 419c762
Show file tree
Hide file tree
Showing 6 changed files with 166 additions and 54 deletions.
33 changes: 18 additions & 15 deletions resources/shaders/VXGI/voxelization.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -185,21 +185,24 @@ void main() {
scene.lights[i].type != DIRECTIONAL_LIGHT ? normalize(scene.lights[i].worldPosition.xyz - _pos) : normalize(scene.lights[i].worldPosition.xyz), //wi //wo
scene.lights[i].color * computeAttenuation(scene.lights[i].worldPosition.xyz, _pos,scene.lights[i].areaEffect,int(scene.lights[i].type)) * scene.lights[i].intensity
);
if(scene.lights[i].shadowCast == 1) {
if(scene.lights[i].shadowType == 0) //Classic
lighting *= computeShadow(shadowMap, scene.lights[i], i, _pos);
if(scene.lights[i].shadowType == 1) //VSM
lighting *= computeVarianceShadow(shadowMap, scene.lights[i], i, _pos);
if(scene.lights[i].shadowType == 2) //Raytraced
lighting *= computeRaytracedShadow(
TLAS,
blueNoiseMap,
_pos,
scene.lights[i].type != DIRECTIONAL_LIGHT ? scene.lights[i].worldPosition.xyz - _pos : scene.lights[i].shadowData.xyz,
1,
0.0,
0);
}


//Visibility__________________________
// if(scene.lights[i].shadowCast == 1) {
// if(scene.lights[i].shadowType == 0) //Classic
// lighting *= computeShadow(shadowMap, scene.lights[i], i, _pos);
// if(scene.lights[i].shadowType == 1) //VSM
// lighting *= computeVarianceShadow(shadowMap, scene.lights[i], i, _pos);
// if(scene.lights[i].shadowType == 2) //Raytraced
// lighting *= computeRaytracedShadow(
// TLAS,
// blueNoiseMap,
// _pos,
// scene.lights[i].type != DIRECTIONAL_LIGHT ? scene.lights[i].worldPosition.xyz - _pos : scene.lights[i].shadowData.xyz,
// 1,
// 0.0,
// 0);
// }

color += lighting;
}
Expand Down
67 changes: 54 additions & 13 deletions resources/shaders/deferred/composition.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ int g_isReflective;
vec4 g_temp;



vec3 GI(vec3 worldPos, vec3 worldNormal){
const float VOXEL_SIZE = 1.0/float(settings.vxgi.resolution);
const float ISQRT2 = 0.707106;
Expand All @@ -112,35 +113,36 @@ vec3 GI(vec3 worldPos, vec3 worldNormal){
// Backward in cone direction improves GI, and forward direction removes
// artifacts.
const float CONE_OFFSET = -0.01;
const float CONE_SPREAD = 0.325;

// Trace front cone
indirect += w[0] * traceDiffuseVoxelCone(voxelMap, C_ORIGIN + CONE_OFFSET * worldNormal, worldNormal, VOXEL_SIZE );
indirect += w[0] * traceVoxelCone(voxelMap, C_ORIGIN + CONE_OFFSET * worldNormal, worldNormal,CONE_SPREAD, VOXEL_SIZE );

// Trace 4 side cones.
const vec3 s1 = mix(worldNormal, ortho, ANGLE_MIX);
indirect += w[1] * traceDiffuseVoxelCone(voxelMap, C_ORIGIN + CONE_OFFSET * ortho, s1, VOXEL_SIZE );
indirect += w[1] * traceVoxelCone(voxelMap, C_ORIGIN + CONE_OFFSET * ortho, s1,CONE_SPREAD, VOXEL_SIZE );

const vec3 s2 = mix(worldNormal, -ortho, ANGLE_MIX);
indirect += w[1] * traceDiffuseVoxelCone(voxelMap, C_ORIGIN - CONE_OFFSET * ortho, s2, VOXEL_SIZE );
indirect += w[1] * traceVoxelCone(voxelMap, C_ORIGIN - CONE_OFFSET * ortho, s2,CONE_SPREAD, VOXEL_SIZE );

const vec3 s3 = mix(worldNormal, ortho2, ANGLE_MIX);
indirect += w[1] * traceDiffuseVoxelCone(voxelMap, C_ORIGIN + CONE_OFFSET * ortho2, s3, VOXEL_SIZE );
indirect += w[1] * traceVoxelCone(voxelMap, C_ORIGIN + CONE_OFFSET * ortho2, s3,CONE_SPREAD, VOXEL_SIZE );

const vec3 s4 = mix(worldNormal, -ortho2, ANGLE_MIX);
indirect += w[1] * traceDiffuseVoxelCone(voxelMap, C_ORIGIN - CONE_OFFSET * ortho2, s4, VOXEL_SIZE );
indirect += w[1] * traceVoxelCone(voxelMap, C_ORIGIN - CONE_OFFSET * ortho2, s4,CONE_SPREAD, VOXEL_SIZE );

// Trace 4 corner cones.
const vec3 c1 = mix(worldNormal, corner, ANGLE_MIX);
indirect += w[2] * traceDiffuseVoxelCone(voxelMap, C_ORIGIN + CONE_OFFSET * corner, c1, VOXEL_SIZE );
indirect += w[2] * traceVoxelCone(voxelMap, C_ORIGIN + CONE_OFFSET * corner, c1,CONE_SPREAD, VOXEL_SIZE );

const vec3 c2 = mix(worldNormal, -corner, ANGLE_MIX);
indirect += w[2] * traceDiffuseVoxelCone(voxelMap, C_ORIGIN - CONE_OFFSET * corner, c2, VOXEL_SIZE );
indirect += w[2] * traceVoxelCone(voxelMap, C_ORIGIN - CONE_OFFSET * corner, c2,CONE_SPREAD, VOXEL_SIZE );

const vec3 c3 = mix(worldNormal, corner2, ANGLE_MIX);
indirect += w[2] * traceDiffuseVoxelCone(voxelMap, C_ORIGIN + CONE_OFFSET * corner2, c3, VOXEL_SIZE );
indirect += w[2] * traceVoxelCone(voxelMap, C_ORIGIN + CONE_OFFSET * corner2, c3,CONE_SPREAD, VOXEL_SIZE );

const vec3 c4 = mix(worldNormal, -corner2, ANGLE_MIX);
indirect += w[2] * traceDiffuseVoxelCone(voxelMap, C_ORIGIN - CONE_OFFSET * corner2, c4, VOXEL_SIZE );
indirect += w[2] * traceVoxelCone(voxelMap, C_ORIGIN - CONE_OFFSET * corner2, c4,CONE_SPREAD, VOXEL_SIZE );

// Return result.
// return DIFFUSE_INDIRECT_FACTOR * material.diffuseReflectivity * acc * (material.diffuseColor + vec3(0.001f));
Expand Down Expand Up @@ -187,6 +189,7 @@ void main()
vec3 direct = vec3(0.0);
vec3 ambient = vec3(0.0);
vec3 indirect = vec3(0.0);
vec3 indirect2 = vec3(0.0);

vec3 modelPos = (camera.invView * vec4(g_pos.xyz, 1.0)).xyz;
vec3 modelNormal = (camera.invView * vec4(g_normal.xyz, 0.0)).xyz;
Expand All @@ -206,12 +209,50 @@ void main()
brdf.F0 = vec3(0.04);
brdf.F0 = mix(brdf.F0, brdf.albedo, brdf.metalness);
brdf.emission = g_emission;

// GI ____________________________
// Indirect Component ____________________________
if(settings.vxgi.enabled == 1){
indirect = GI(modelPos, modelNormal)*settings.vxgi.strength*g_albedo;
vec3 diffuseIndirect = vec3(0.0);

const float VOXEL_SIZE = 1.0/float(settings.vxgi.resolution);


// Offset startPos to avoid self occlusion
vec3 startPos = modelPos + modelNormal * VOXEL_SIZE;

float coneTraceCount = 0.0;
float cosSum = 0.0;
for (int i = 0; i < DIFFUSE_CONE_COUNT; ++i)
{
float cosTheta = dot(modelNormal, DIFFUSE_CONE_DIRECTIONS[i]);

if (cosTheta < 0.0)
continue;

coneTraceCount += 1.0;
diffuseIndirect += traceVoxelCone(voxelMap, startPos, DIFFUSE_CONE_DIRECTIONS[i],DIFFUSE_CONE_APERTURE , VOXEL_SIZE );
}

diffuseIndirect /= coneTraceCount;
// indirectContribution.a *= u_ambientOcclusionFactor;

diffuseIndirect.rgb *= g_albedo * settings.vxgi.strength;


indirect = diffuseIndirect.rgb;


// indirect = GI(modelPos, modelNormal)*settings.vxgi.strength*g_albedo;
indirect*= settings.enableAO == 1 ? (brdf.ao * SSAO) : brdf.ao;

// vec3 specularConeDirection = reflect(normalize(camera.position.xyz-modelPos), modelNormal);
// vec3 specularIndirect = vec3(0.0);


// specularIndirect = traceVoxelCone(voxelMap, startPos, specularConeDirection, max(brdf.roughness, 0.05) , VOXEL_SIZE );
// // specularIndirect = castCone(startPos, specularConeDirection, max(roughness, MIN_SPECULAR_APERTURE), MAX_TRACE_DISTANCE, minLevel).rgb * specColor.rgb * u_indirectSpecularIntensity;
// indirect2+=specularIndirect;
}


//Direct Component ________________________
for(int i = 0; i < scene.numLights; i++) {
Expand All @@ -232,7 +273,6 @@ void main()
if(scene.lights[i].shadowType == 1) //VSM
lighting *= computeVarianceShadow(shadowMap, scene.lights[i], i, modelPos);
if(scene.lights[i].shadowType == 2) //Raytraced
// lighting *= traceShadowCone(voxelMap, modelPos, scene.lights[i].type != DIRECTIONAL_LIGHT ? scene.lights[i].worldPosition.xyz - modelPos : scene.lights[i].shadowData.xyz, modelNormal, 1.0/float(settings.vxgi.resolution), length(scene.lights[i].worldPosition.xyz - modelPos) );
lighting *= computeRaytracedShadow(
TLAS,
blueNoiseMap,
Expand Down Expand Up @@ -263,6 +303,7 @@ void main()
ambient = (scene.ambientIntensity * scene.ambientColor) * brdf.albedo;
}
ambient *= settings.enableAO == 1 ? (brdf.ao * SSAO) : brdf.ao;

//SSR ________________________________
vec3 fresnel = fresnelSchlick(max(dot(g_normal, normalize(g_pos)), 0.0), brdf.F0);
if(settings.ssr.enabled == 1 && g_isReflective == 1){
Expand Down
103 changes: 79 additions & 24 deletions resources/shaders/include/VXGI.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,62 @@ struct VXGI {
uint enabled;
};

vec3 traceDiffuseVoxelCone(sampler3D voxelization ,const vec3 O, vec3 dir, const float VOXEL_SIZE){
const int DIFFUSE_CONE_COUNT = 16;
const float DIFFUSE_CONE_APERTURE = 0.872665;

const vec3 DIFFUSE_CONE_DIRECTIONS[16] = {
vec3(0.57735, 0.57735, 0.57735),
vec3(0.57735, -0.57735, -0.57735),
vec3(-0.57735, 0.57735, -0.57735),
vec3(-0.57735, -0.57735, 0.57735),
vec3(-0.903007, -0.182696, -0.388844),
vec3(-0.903007, 0.182696, 0.388844),
vec3(0.903007, -0.182696, 0.388844),
vec3(0.903007, 0.182696, -0.388844),
vec3(-0.388844, -0.903007, -0.182696),
vec3(0.388844, -0.903007, 0.182696),
vec3(0.388844, 0.903007, -0.182696),
vec3(-0.388844, 0.903007, 0.182696),
vec3(-0.182696, -0.388844, -0.903007),
vec3(0.182696, 0.388844, -0.903007),
vec3(-0.182696, 0.388844, 0.903007),
vec3(0.182696, -0.388844, 0.903007)
};

// vec4 traceVoxelCone(sampler3D voxelization, vec3 origin, vec3 direction, float tanHalfAngle)
// {
// float lod = 0.0f;
// vec3 color = vec3(0.0f);
// float alpha = 0.0f;
// float occlusion = 0.0f;

// //Voxel Cube Size
// float voxelWorldSize = VoxelGridWorldSize / VoxelDimensions;
// float dist = voxelWorldSize;
// vec3 startPos = Position_world + Normal_world * voxelWorldSize;

// while(dist < MAX_DISTANCE && alpha < MAX_ALPHA)
// {
// float diameter = max(voxelWorldSize, 2.0f * tanHalfAngle * dist);
// float lodLevel = log2(diameter / voxelWorldSize);
// vec4 voxelColor = SampleVoxels(startPos + dist * direction, lodLevel);

// color += (1.0f - alpha) * voxelColor.rgb;
// occlusion += ((1.0f - alpha) * voxelColor.a) / (1.0f + 0.03f * diameter);
// alpha += (1.0f - alpha) * voxelColor.a;
// dist += diameter;
// }

// return vec4(color, occlusion);
// }

/*
FIRST TRY
*/
vec3 traceVoxelCone(sampler3D voxelization ,const vec3 O, vec3 dir, const float CONE_SPREAD, const float VOXEL_SIZE){
dir = normalize(dir);

const float CONE_SPREAD = 0.325;
// const float CONE_SPREAD = 0.325;

vec4 color = vec4(0.0);

Expand Down Expand Up @@ -49,25 +101,28 @@ vec3 traceDiffuseVoxelCone(sampler3D voxelization ,const vec3 O, vec3 dir, const

}

// Returns a soft shadow blend by using shadow cone tracing.
// Uses 2 samples per step, so it's pretty expensive.
float traceShadowCone(sampler3D voxelization , vec3 O, vec3 dir, vec3 normal, const float VOXEL_SIZE, float targetDistance){
O += normal * 0.05; // Removes artifacts but makes self shadowing for dense meshes meh.

float color = 0;

float dist = 3 * VOXEL_SIZE;
// I'm using a pretty big margin here since I use an emissive light ball with a pretty big radius in my demo scenes.
const float STOP = targetDistance - 16 * VOXEL_SIZE;

while(dist < STOP && color < 1){
vec3 c = mapToZeroOne(O + dist * dir, scene.minCoord.xyz, scene.maxCoord.xyz);
float l = pow(dist, 2); // Experimenting with inverse square falloff for shadows.
float s1 = 0.062 * textureLod(voxelization, c, 1 + 0.75 * l).a;
float s2 = 0.135 * textureLod(voxelization, c, 4.5 * l).a;
float s = s1 + s2;
color += (1 - color) * s;
dist += 0.9 * VOXEL_SIZE * (1 + 0.05 * l);
}
return 1 - pow(smoothstep(0, 1, color * 1.4), 1.0 / 1.4);
}
vec3 diffuseVoxelGI(sampler3D voxelMap, vec3 worldPos, vec3 worldNormal, int resolution){
// vec3 diffuseIndirect = vec3(0.0);

// const float VOXEL_SIZE = 1.0/float(resolution);


// vec3 startPos = worldPos + worldNormal * VOXEL_SIZE;

// float coneTraceCount = 0.0;
// float cosSum = 0.0;
// for (int i = 0; i < DIFFUSE_CONE_COUNT; ++i)
// {
// float cosTheta = dot(worldNormal, DIFFUSE_CONE_DIRECTIONS[i]);
// if (cosTheta < 0.0)
// continue;
// coneTraceCount += 1.0;
// diffuseIndirect += traceVoxelCone(voxelMap, startPos, DIFFUSE_CONE_DIRECTIONS[i],DIFFUSE_CONE_APERTURE , VOXEL_SIZE ) * cosTheta;
// }

// diffuseIndirect /= DIFFUSE_CONE_COUNT * 0.5;

// // indirectContribution.a *= u_ambientOcclusionFactor;
// return diffuseIndirect;

}
3 changes: 2 additions & 1 deletion resources/shaders/misc/tonemapping.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ layout(location = 0) out vec4 outputImage;
void main()
{
vec3 result = texture(inputImage,v_uv).rgb;
result = vec3(1.0) - exp(-result * 1.0);
float exposure = 1.0;
result = vec3(1.0) - exp(-result * exposure);
// result = result / (result + vec3(1.0));

outputImage = vec4(result,1.0); //WIP
Expand Down
3 changes: 2 additions & 1 deletion src/core/passes/voxelization_pass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ void VoxelizationPass::create_voxelization_image() {
m_resourceImages[0].create_view(config);

SamplerConfig samplerConfig = {};
samplerConfig.samplerAddressMode = ADDRESS_MODE_CLAMP_TO_EDGE;
samplerConfig.samplerAddressMode = ADDRESS_MODE_CLAMP_TO_BORDER;
samplerConfig.border = BorderColor::FLOAT_OPAQUE_BLACK;
m_resourceImages[0].create_sampler(samplerConfig);
}

Expand Down
11 changes: 11 additions & 0 deletions src/core/scene/scene.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,13 @@ VKFW::Graphics::TLAS* VKFW::Core::get_TLAS(Scene* const scene) {
}
void VKFW::Core::Scene::update_AABB() {

m_volume.maxCoords = Vec3(0.0);
m_volume.minCoords = Vec3(INFINITY);

for (Mesh* m : m_meshes)
{
if (!m->is_active())
continue;
BV const* bvolume = m->get_bounding_volume();
if (!bvolume)
continue;
Expand All @@ -34,5 +39,11 @@ void VKFW::Core::Scene::update_AABB() {
m_volume.minCoords.z = minCoords.z;
}

// Make a cube container for voxelization
float maxTerm = std::max(std::max(m_volume.maxCoords.r, m_volume.maxCoords.g), m_volume.maxCoords.b);
float minTerm = std::min(std::min(m_volume.minCoords.r, m_volume.minCoords.g), m_volume.minCoords.b);
m_volume.maxCoords = Vec3(maxTerm);
m_volume.minCoords = Vec3(minTerm);

m_volume.center = (m_volume.maxCoords + m_volume.minCoords) * 0.5f;
}

0 comments on commit 419c762

Please sign in to comment.