| 
									
										
										
										
											2025-01-22 16:18:30 +01:00
										 |  |  | /* | 
					
						
							|  |  |  | Copyright (c) 2024 Turánszki János | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Permission is hereby granted, free of charge, to any person obtaining a copy | 
					
						
							|  |  |  | of this software and associated documentation files (the "Software"), to deal | 
					
						
							|  |  |  | in the Software without restriction, including without limitation the rights | 
					
						
							|  |  |  | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | 
					
						
							|  |  |  | copies of the Software, and to permit persons to whom the Software is | 
					
						
							|  |  |  | furnished to do so, subject to the following conditions: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The above copyright notice and this permission notice shall be included in | 
					
						
							|  |  |  | all copies or substantial portions of the Software. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | 
					
						
							|  |  |  | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | 
					
						
							|  |  |  | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE | 
					
						
							|  |  |  | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | 
					
						
							|  |  |  | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | 
					
						
							|  |  |  | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | 
					
						
							|  |  |  | THE SOFTWARE. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | #ifndef _CONETRACE_GLSL_ | 
					
						
							|  |  |  | #define _CONETRACE_GLSL_ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-05-21 01:01:47 +00:00
										 |  |  | #include "std/constants.glsl" | 
					
						
							| 
									
										
										
										
											2025-01-22 16:18:30 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | // References | 
					
						
							|  |  |  | // https://github.com/Friduric/voxel-cone-tracing | 
					
						
							|  |  |  | // https://github.com/Cigg/Voxel-Cone-Tracing | 
					
						
							|  |  |  | // https://github.com/GreatBlambo/voxel_cone_tracing/ | 
					
						
							|  |  |  | // http://simonstechblog.blogspot.com/2013/01/implementing-voxel-cone-tracing.html | 
					
						
							|  |  |  | // http://leifnode.com/2015/05/voxel-cone-traced-global-illumination/ | 
					
						
							|  |  |  | // http://www.seas.upenn.edu/%7Epcozzi/OpenGLInsights/OpenGLInsights-SparseVoxelization.pdf | 
					
						
							|  |  |  | // https://research.nvidia.com/sites/default/files/publications/GIVoxels-pg2011-authors.pdf | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const float MAX_DISTANCE = voxelgiRange; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef _VoxelGI | 
					
						
							|  |  |  | uniform sampler3D dummy; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | vec4 sampleVoxel(sampler3D voxels, vec3 P, const float clipmaps[voxelgiClipmapCount * 10], const float clipmap_index, const float step_dist, const int precomputed_direction, const vec3 face_offset, const vec3 direction_weight) { | 
					
						
							|  |  |  |  	vec4 col = vec4(0.0); | 
					
						
							|  |  |  | 	vec3 tc = (P - vec3(clipmaps[int(clipmap_index * 10 + 4)], clipmaps[int(clipmap_index * 10 + 5)], clipmaps[int(clipmap_index * 10 + 6)])) / (float(clipmaps[int(clipmap_index * 10)]) * voxelgiResolution); | 
					
						
							|  |  |  | 	vec3 half_texel = vec3(0.5) / voxelgiResolution; | 
					
						
							|  |  |  | 	tc = tc * 0.5 + 0.5; | 
					
						
							|  |  |  | 	tc = clamp(tc, half_texel, 1.0 - half_texel); | 
					
						
							|  |  |  | 	tc.x = (tc.x + precomputed_direction) / (6 + DIFFUSE_CONE_COUNT); | 
					
						
							|  |  |  | 	tc.y = (tc.y + clipmap_index) / voxelgiClipmapCount; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (precomputed_direction == 0) { | 
					
						
							|  |  |  | 		col = direction_weight.x * textureLod(voxels, vec3(tc.x + face_offset.x, tc.y, tc.z), 0) | 
					
						
							|  |  |  | 			+ direction_weight.y * textureLod(voxels, vec3(tc.x + face_offset.y, tc.y, tc.z), 0) | 
					
						
							|  |  |  | 			+ direction_weight.z * textureLod(voxels, vec3(tc.x + face_offset.z, tc.y, tc.z), 0); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else | 
					
						
							|  |  |  | 		col = textureLod(voxels, tc, 0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	col *= step_dist / float(clipmaps[int(clipmap_index * 10)]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return col; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #endif | 
					
						
							|  |  |  | #ifdef _VoxelAOvar | 
					
						
							|  |  |  | float sampleVoxel(sampler3D voxels, vec3 P, const float clipmaps[voxelgiClipmapCount * 10], const float clipmap_index, const float step_dist, const int precomputed_direction, const vec3 face_offset, const vec3 direction_weight) { | 
					
						
							|  |  |  |  	float opac = 0.0; | 
					
						
							|  |  |  | 	vec3 tc = (P - vec3(clipmaps[int(clipmap_index * 10 + 4)], clipmaps[int(clipmap_index * 10 + 5)], clipmaps[int(clipmap_index * 10 + 6)])) / (float(clipmaps[int(clipmap_index * 10)]) * voxelgiResolution); | 
					
						
							|  |  |  | 	vec3 half_texel = vec3(0.5) / voxelgiResolution; | 
					
						
							|  |  |  | 	tc = tc * 0.5 + 0.5; | 
					
						
							|  |  |  | 	tc = clamp(tc, half_texel, 1.0 - half_texel); | 
					
						
							|  |  |  | 	tc.x = (tc.x + precomputed_direction) / (6 + DIFFUSE_CONE_COUNT); | 
					
						
							|  |  |  | 	tc.y = (tc.y + clipmap_index) / voxelgiClipmapCount; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (precomputed_direction == 0) { | 
					
						
							|  |  |  | 		opac = direction_weight.x * textureLod(voxels, vec3(tc.x + face_offset.x, tc.y, tc.z), 0).r | 
					
						
							|  |  |  | 			+ direction_weight.y * textureLod(voxels, vec3(tc.x + face_offset.y, tc.y, tc.z), 0).r | 
					
						
							|  |  |  | 			+ direction_weight.z * textureLod(voxels, vec3(tc.x + face_offset.z, tc.y, tc.z), 0).r; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else | 
					
						
							|  |  |  | 		opac = textureLod(voxels, tc, 0).r; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	opac *= step_dist / float(clipmaps[int(clipmap_index * 10)]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return opac; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | #endif | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef _VoxelGI | 
					
						
							|  |  |  | vec4 traceCone(const sampler3D voxels, const sampler3D voxelsSDF, const vec3 origin, const vec3 n, const vec3 dir, const int precomputed_direction, const bool use_sdf, const float aperture, const float step_size, const float clipmaps[voxelgiClipmapCount * 10]) { | 
					
						
							|  |  |  |     vec4 sampleCol = vec4(0.0); | 
					
						
							|  |  |  | 	float voxelSize0 = float(clipmaps[0]) * 2.0; | 
					
						
							|  |  |  | 	float dist = voxelSize0; | 
					
						
							|  |  |  | 	float step_dist = dist; | 
					
						
							|  |  |  | 	vec3 samplePos; | 
					
						
							| 
									
										
										
										
											2025-05-22 02:16:35 +00:00
										 |  |  | 	vec3 start_pos = origin + n * voxelSize0; | 
					
						
							| 
									
										
										
										
											2025-01-22 16:18:30 +01:00
										 |  |  | 	int clipmap_index0 = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	vec3 aniso_direction = -dir; | 
					
						
							|  |  |  | 	vec3 face_offset = vec3( | 
					
						
							| 
									
										
										
										
											2025-08-14 22:58:57 +00:00
										 |  |  | 		aniso_direction.x > 0.0 ? 0.0 : 1.0, | 
					
						
							|  |  |  | 		aniso_direction.y > 0.0 ? 2.0 : 3.0, | 
					
						
							|  |  |  | 		aniso_direction.z > 0.0 ? 4.0 : 5.0 | 
					
						
							| 
									
										
										
										
											2025-01-22 16:18:30 +01:00
										 |  |  | 	) / (6 + DIFFUSE_CONE_COUNT); | 
					
						
							|  |  |  | 	vec3 direction_weight = abs(dir); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	float coneCoefficient = 2.0 * tan(aperture * 0.5); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     while (sampleCol.a < 1.0 && dist < MAX_DISTANCE && clipmap_index0 < voxelgiClipmapCount) { | 
					
						
							|  |  |  | 		vec4 mipSample = vec4(0.0); | 
					
						
							|  |  |  | 		float diam = max(voxelSize0, dist * coneCoefficient); | 
					
						
							|  |  |  |         float lod = clamp(log2(diam / voxelSize0), clipmap_index0, voxelgiClipmapCount - 1); | 
					
						
							|  |  |  |         float clipmap_index = floor(lod); | 
					
						
							|  |  |  | 		float clipmap_blend = fract(lod); | 
					
						
							|  |  |  | 		vec3 p0 = start_pos + dir * dist; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         samplePos = (p0 - vec3(clipmaps[int(clipmap_index * 10 + 4)], clipmaps[int(clipmap_index * 10 + 5)], clipmaps[int(clipmap_index * 10 + 6)])) / (float(clipmaps[int(clipmap_index * 10)]) * voxelgiResolution); | 
					
						
							|  |  |  | 		samplePos = samplePos * 0.5 + 0.5; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (any(notEqual(samplePos, clamp(samplePos, 0.0, 1.0)))) { | 
					
						
							|  |  |  | 			clipmap_index0++; | 
					
						
							|  |  |  | 			continue; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		mipSample = sampleVoxel(voxels, p0, clipmaps, clipmap_index, step_dist, precomputed_direction, face_offset, direction_weight); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if(clipmap_blend > 0.0 && clipmap_index < voxelgiClipmapCount - 1) { | 
					
						
							|  |  |  | 			vec4 mipSampleNext = sampleVoxel(voxels, p0, clipmaps, clipmap_index + 1.0, step_dist, precomputed_direction, face_offset, direction_weight); | 
					
						
							| 
									
										
										
										
											2025-05-30 19:16:59 +00:00
										 |  |  | 			mipSample = mix(mipSample, mipSampleNext, clipmap_blend); | 
					
						
							| 
									
										
										
										
											2025-01-22 16:18:30 +01:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		sampleCol += (1.0 - sampleCol.a) * mipSample; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		float stepSizeCurrent = step_size; | 
					
						
							|  |  |  | 		if (use_sdf) { | 
					
						
							|  |  |  | 			// half texel correction is applied to avoid sampling over current clipmap: | 
					
						
							|  |  |  | 			const vec3 half_texel = vec3(0.5) / voxelgiResolution; | 
					
						
							|  |  |  | 			vec3 tc0 = clamp(samplePos, half_texel, 1 - half_texel); | 
					
						
							|  |  |  | 			tc0.y = (tc0.y + clipmap_index) / voxelgiClipmapCount; // remap into clipmap | 
					
						
							|  |  |  | 			float sdf = textureLod(voxelsSDF, tc0, 0).r; | 
					
						
							|  |  |  | 			stepSizeCurrent = max(step_size, sdf - diam); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		step_dist = diam * stepSizeCurrent; | 
					
						
							|  |  |  | 		dist += step_dist; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  |     return sampleCol; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | vec4 traceDiffuse(const vec3 origin, const vec3 normal, const sampler3D voxels, const float clipmaps[voxelgiClipmapCount * 10]) { | 
					
						
							|  |  |  | 	float sum = 0.0; | 
					
						
							|  |  |  | 	vec4 amount = vec4(0.0); | 
					
						
							| 
									
										
										
										
											2025-05-30 19:16:59 +00:00
										 |  |  | 	mat3 TBN = makeTangentBasis(normal); | 
					
						
							| 
									
										
										
										
											2025-01-22 16:18:30 +01:00
										 |  |  | 	for (int i = 0; i < DIFFUSE_CONE_COUNT; ++i) { | 
					
						
							| 
									
										
										
										
											2025-05-30 19:16:59 +00:00
										 |  |  | 		vec3 coneDir = TBN * DIFFUSE_CONE_DIRECTIONS[i]; | 
					
						
							| 
									
										
										
										
											2025-01-22 16:18:30 +01:00
										 |  |  | 		const float cosTheta = dot(normal, coneDir); | 
					
						
							|  |  |  | 		if (cosTheta <= 0) | 
					
						
							|  |  |  | 			continue; | 
					
						
							|  |  |  | 		int precomputed_direction = 6 + i; | 
					
						
							|  |  |  | 		amount += traceCone(voxels, dummy, origin, normal, coneDir, precomputed_direction, false, DIFFUSE_CONE_APERTURE, 1.0, clipmaps) * cosTheta; | 
					
						
							|  |  |  | 		sum += cosTheta; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	amount /= sum; | 
					
						
							|  |  |  | 	amount.rgb = max(amount.rgb, vec3(0.0)); | 
					
						
							|  |  |  | 	amount.a = clamp(amount.a, 0.0, 1.0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return amount * voxelgiOcc; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | vec4 traceSpecular(const vec3 origin, const vec3 normal, const sampler3D voxels, const sampler3D voxelsSDF, const vec3 viewDir, const float roughness, const float clipmaps[voxelgiClipmapCount * 10], const vec2 pixel, const vec2 velocity) { | 
					
						
							| 
									
										
										
										
											2025-05-30 19:16:59 +00:00
										 |  |  | 	vec3 specularDir = reflect(normalize(-viewDir), normal); | 
					
						
							| 
									
										
										
										
											2025-01-22 16:18:30 +01:00
										 |  |  | 	vec3 P = origin + specularDir * ((BayerMatrix8[int(pixel.x + velocity.x) % 8][int(pixel.y + velocity.y) % 8] - 0.5)) * voxelgiStep; | 
					
						
							|  |  |  | 	vec4 amount = traceCone(voxels, voxelsSDF, P, normal, specularDir, 0, true, roughness, voxelgiStep, clipmaps); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	amount.rgb = max(vec3(0.0), amount.rgb); | 
					
						
							|  |  |  | 	amount.a = clamp(amount.a, 0.0, 1.0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return amount * voxelgiOcc; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-07 14:38:30 +00:00
										 |  |  | vec4 traceRefraction(const vec3 origin, const vec3 normal, sampler3D voxels, sampler3D voxelsSDF, const vec3 viewDir, const float ior, const float roughness, const float clipmaps[voxelgiClipmapCount * 10], const vec2 pixel, const vec2 velocity, const float opacity) { | 
					
						
							| 
									
										
										
										
											2025-05-30 19:16:59 +00:00
										 |  |  |  	const float transmittance = 1.0 - opacity; | 
					
						
							|  |  |  |  	vec3 refractionDir = refract(normalize(-viewDir), normal, 1.0 / ior); | 
					
						
							| 
									
										
										
										
											2025-01-22 16:18:30 +01:00
										 |  |  |  	vec3 P = origin + refractionDir * (BayerMatrix8[int(pixel.x + velocity.x) % 8][int(pixel.y + velocity.y) % 8] - 0.5) * voxelgiStep; | 
					
						
							|  |  |  | 	vec4 amount =  transmittance * traceCone(voxels, voxelsSDF, P, normal, refractionDir, 0, true, roughness, voxelgiStep, clipmaps); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	amount.rgb = max(vec3(0.0), amount.rgb); | 
					
						
							|  |  |  | 	amount.a = clamp(amount.a, 0.0, 1.0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return amount * voxelgiOcc; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | #endif | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef _VoxelAOvar | 
					
						
							|  |  |  | float traceConeAO(const sampler3D voxels, const vec3 origin, const vec3 n, const vec3 dir, const int precomputed_direction, const float aperture, const float step_size, const float clipmaps[voxelgiClipmapCount * 10]) { | 
					
						
							|  |  |  | 	float sampleCol = 0.0; | 
					
						
							|  |  |  | 	float voxelSize0 = float(clipmaps[0]) * 2.0; | 
					
						
							|  |  |  | 	float dist = voxelSize0; | 
					
						
							|  |  |  | 	float step_dist = dist; | 
					
						
							|  |  |  | 	vec3 samplePos; | 
					
						
							| 
									
										
										
										
											2025-05-22 02:16:35 +00:00
										 |  |  | 	vec3 start_pos = origin + n * voxelSize0; | 
					
						
							| 
									
										
										
										
											2025-01-22 16:18:30 +01:00
										 |  |  | 	int clipmap_index0 = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	vec3 aniso_direction = -dir; | 
					
						
							|  |  |  | 	vec3 face_offset = vec3( | 
					
						
							| 
									
										
										
										
											2025-08-14 22:58:57 +00:00
										 |  |  | 		aniso_direction.x > 0.0 ? 0.0 : 1.0, | 
					
						
							|  |  |  | 		aniso_direction.y > 0.0 ? 2.0 : 3.0, | 
					
						
							|  |  |  | 		aniso_direction.z > 0.0 ? 4.0 : 5.0 | 
					
						
							| 
									
										
										
										
											2025-01-22 16:18:30 +01:00
										 |  |  | 	) / (6 + DIFFUSE_CONE_COUNT); | 
					
						
							|  |  |  | 	vec3 direction_weight = abs(dir); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	float coneCoefficient = 2.0 * tan(aperture * 0.5); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     while (sampleCol < 1.0 && dist < MAX_DISTANCE && clipmap_index0 < voxelgiClipmapCount) { | 
					
						
							|  |  |  | 		float mipSample = 0.0; | 
					
						
							|  |  |  | 		float diam = max(voxelSize0, dist * coneCoefficient); | 
					
						
							|  |  |  |         float lod = clamp(log2(diam / voxelSize0), clipmap_index0, voxelgiClipmapCount - 1); | 
					
						
							|  |  |  | 		float clipmap_index = floor(lod); | 
					
						
							|  |  |  | 		float clipmap_blend = fract(lod); | 
					
						
							|  |  |  | 		vec3 p0 = start_pos + dir * dist; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         samplePos = (p0 - vec3(clipmaps[int(clipmap_index * 10 + 4)], clipmaps[int(clipmap_index * 10 + 5)], clipmaps[int(clipmap_index * 10 + 6)])) / (float(clipmaps[int(clipmap_index * 10)]) * voxelgiResolution.x); | 
					
						
							|  |  |  | 		samplePos = samplePos * 0.5 + 0.5; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if ((any(notEqual(clamp(samplePos, 0.0, 1.0), samplePos)))) { | 
					
						
							|  |  |  | 			clipmap_index0++; | 
					
						
							|  |  |  | 			continue; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		mipSample = sampleVoxel(voxels, p0, clipmaps, clipmap_index, step_dist, precomputed_direction, face_offset, direction_weight); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if(clipmap_blend > 0.0 && clipmap_index < voxelgiClipmapCount - 1) { | 
					
						
							|  |  |  | 			float mipSampleNext = sampleVoxel(voxels, p0, clipmaps, clipmap_index + 1.0, step_dist, precomputed_direction, face_offset, direction_weight); | 
					
						
							|  |  |  | 			mipSample = mix(mipSample, mipSampleNext, clipmap_blend); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		sampleCol += (1.0 - sampleCol) * mipSample; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		step_dist = diam * step_size; | 
					
						
							|  |  |  | 		dist += step_dist; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  |     return sampleCol; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | float traceAO(const vec3 origin, const vec3 normal, const sampler3D voxels, const float clipmaps[voxelgiClipmapCount * 10]) { | 
					
						
							|  |  |  | 	float sum = 0.0; | 
					
						
							|  |  |  | 	float amount = 0.0; | 
					
						
							|  |  |  | 	for (int i = 0; i < DIFFUSE_CONE_COUNT; i++) { | 
					
						
							|  |  |  | 		vec3 coneDir = DIFFUSE_CONE_DIRECTIONS[i]; | 
					
						
							|  |  |  | 		int precomputed_direction = 6 + i; | 
					
						
							|  |  |  | 		const float cosTheta = dot(normal, coneDir); | 
					
						
							|  |  |  | 		if (cosTheta <= 0) | 
					
						
							|  |  |  | 			continue; | 
					
						
							|  |  |  | 		amount += traceConeAO(voxels, origin, normal, coneDir, precomputed_direction, DIFFUSE_CONE_APERTURE, 1.0, clipmaps) * cosTheta; | 
					
						
							|  |  |  | 		sum += cosTheta; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	amount /= sum; | 
					
						
							|  |  |  | 	amount = clamp(amount, 0.0, 1.0); | 
					
						
							|  |  |  | 	return amount * voxelgiOcc; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | #endif | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef _VoxelShadow | 
					
						
							|  |  |  | float traceConeShadow(const sampler3D voxels, const sampler3D voxelsSDF, const vec3 origin, const vec3 n, const vec3 dir, const float aperture, const float step_size, const float clipmaps[voxelgiClipmapCount * 10]) { | 
					
						
							|  |  |  |     float sampleCol = 0.0; | 
					
						
							|  |  |  | 	float voxelSize0 = float(clipmaps[0]) * 2.0; | 
					
						
							|  |  |  | 	float dist = voxelSize0; | 
					
						
							|  |  |  | 	float step_dist = dist; | 
					
						
							|  |  |  | 	vec3 samplePos; | 
					
						
							| 
									
										
										
										
											2025-05-22 02:16:35 +00:00
										 |  |  | 	vec3 start_pos = origin + n * voxelSize0; | 
					
						
							| 
									
										
										
										
											2025-01-22 16:18:30 +01:00
										 |  |  | 	int clipmap_index0 = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	vec3 aniso_direction = -dir; | 
					
						
							|  |  |  | 	vec3 face_offset = vec3( | 
					
						
							| 
									
										
										
										
											2025-08-14 22:58:57 +00:00
										 |  |  | 		aniso_direction.x > 0.0 ? 0.0 : 1.0, | 
					
						
							|  |  |  | 		aniso_direction.y > 0.0 ? 2.0 : 3.0, | 
					
						
							|  |  |  | 		aniso_direction.z > 0.0 ? 4.0 : 5.0 | 
					
						
							| 
									
										
										
										
											2025-01-22 16:18:30 +01:00
										 |  |  | 	) / (6 + DIFFUSE_CONE_COUNT); | 
					
						
							|  |  |  | 	vec3 direction_weight = abs(dir); | 
					
						
							|  |  |  | 	float coneCoefficient = 2.0 * tan(aperture * 0.5); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     while (sampleCol < 1.0 && dist < MAX_DISTANCE && clipmap_index0 < voxelgiClipmapCount) { | 
					
						
							|  |  |  | 		float mipSample = 0.0; | 
					
						
							|  |  |  | 		float diam = max(voxelSize0, dist * coneCoefficient); | 
					
						
							|  |  |  |         float lod = clamp(log2(diam / voxelSize0), clipmap_index0, voxelgiClipmapCount - 1); | 
					
						
							|  |  |  | 		float clipmap_index = floor(lod); | 
					
						
							|  |  |  | 		float clipmap_blend = fract(lod); | 
					
						
							|  |  |  | 		vec3 p0 = start_pos + dir * dist; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-05-30 19:16:59 +00:00
										 |  |  |         samplePos = (p0 - vec3(clipmaps[int(clipmap_index * 10 + 4)], clipmaps[int(clipmap_index * 10 + 5)], clipmaps[int(clipmap_index * 10 + 6)])) / (float(clipmaps[int(clipmap_index * 10)]) * voxelgiResolution); | 
					
						
							| 
									
										
										
										
											2025-01-22 16:18:30 +01:00
										 |  |  | 		samplePos = samplePos * 0.5 + 0.5; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if ((any(notEqual(samplePos, clamp(samplePos, 0.0, 1.0))))) { | 
					
						
							|  |  |  | 			clipmap_index0++; | 
					
						
							|  |  |  | 			continue; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		#ifdef _VoxelAOvar | 
					
						
							|  |  |  | 		mipSample = sampleVoxel(voxels, p0, clipmaps, clipmap_index, step_dist, 0, face_offset, direction_weight); | 
					
						
							|  |  |  | 		#else | 
					
						
							|  |  |  | 		mipSample = sampleVoxel(voxels, p0, clipmaps, clipmap_index, step_dist, 0, face_offset, direction_weight).a; | 
					
						
							|  |  |  | 		#endif | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if(clipmap_blend > 0.0 && clipmap_index < voxelgiClipmapCount - 1) { | 
					
						
							|  |  |  | 			#ifdef _VoxelAOvar | 
					
						
							|  |  |  | 			float mipSampleNext = sampleVoxel(voxels, p0, clipmaps, clipmap_index + 1.0, step_dist, 0, face_offset, direction_weight); | 
					
						
							|  |  |  | 			#else | 
					
						
							|  |  |  | 			float mipSampleNext = sampleVoxel(voxels, p0, clipmaps, clipmap_index + 1.0, step_dist, 0, face_offset, direction_weight).a; | 
					
						
							|  |  |  | 			#endif | 
					
						
							|  |  |  | 			mipSample = mix(mipSample, mipSampleNext, clipmap_blend); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		sampleCol += (1.0 - sampleCol) * mipSample; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		float stepSizeCurrent = step_size; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// half texel correction is applied to avoid sampling over current clipmap: | 
					
						
							|  |  |  | 		const vec3 half_texel = vec3(0.5) / voxelgiResolution; | 
					
						
							|  |  |  | 		vec3 tc0 = clamp(samplePos, half_texel, 1 - half_texel); | 
					
						
							|  |  |  | 		tc0.y = (tc0.y + clipmap_index) / voxelgiClipmapCount; // remap into clipmap | 
					
						
							|  |  |  | 		float sdf = textureLod(voxelsSDF, tc0, 0.0).r; | 
					
						
							|  |  |  | 		stepSizeCurrent = max(step_size, sdf - diam); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		step_dist = diam * stepSizeCurrent; | 
					
						
							|  |  |  | 		dist += step_dist; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return sampleCol; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-07 14:38:30 +00:00
										 |  |  | float traceShadow(const vec3 origin, const vec3 normal, const sampler3D voxels, const sampler3D voxelsSDF, const vec3 dir, const float clipmaps[voxelgiClipmapCount * 10], const vec2 pixel, const vec2 velocity) { | 
					
						
							|  |  |  |  	vec3 P = origin + dir * (BayerMatrix8[int(pixel.x + velocity.x) % 8][int(pixel.y + velocity.y) % 8] - 0.5) * voxelgiStep; | 
					
						
							| 
									
										
										
										
											2025-05-21 01:01:47 +00:00
										 |  |  | 	float amount = traceConeShadow(voxels, voxelsSDF, P, normal, dir, SHADOW_CONE_APERTURE, voxelgiStep, clipmaps); | 
					
						
							| 
									
										
										
										
											2025-01-22 16:18:30 +01:00
										 |  |  | 	amount = clamp(amount, 0.0, 1.0); | 
					
						
							|  |  |  | 	return amount * voxelgiOcc; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | #endif | 
					
						
							|  |  |  | #endif // _CONETRACE_GLSL_ |