armory/Shaders/std/conetrace.glsl

123 lines
4.6 KiB
Plaintext
Raw Permalink Normal View History

2019-01-27 19:12:00 +01:00
#ifndef _CONETRACE_GLSL_
#define _CONETRACE_GLSL_
2017-08-06 17:36:25 +02:00
// References
2017-02-22 15:50:19 +01:00
// https://github.com/Friduric/voxel-cone-tracing
// https://github.com/Cigg/Voxel-Cone-Tracing
2017-08-03 14:01:04 +02:00
// https://github.com/GreatBlambo/voxel_cone_tracing/
2017-02-22 15:50:19 +01:00
// 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
2017-10-23 16:24:57 +02:00
const float MAX_DISTANCE = 1.73205080757 * voxelgiRange;
const float VOXEL_SIZE = (2.0 / voxelgiResolution.x) * voxelgiStep;
2017-08-06 17:36:25 +02:00
2018-01-29 23:52:42 +01:00
// uniform sampler3D voxels;
// uniform sampler3D voxelsLast;
2017-08-06 17:36:25 +02:00
// vec3 orthogonal(const vec3 u) {
// // Pass normalized u
// const vec3 v = vec3(0.99146, 0.11664, 0.05832); // Pick any normalized vector
// return abs(dot(u, v)) > 0.99999 ? cross(u, vec3(0.0, 1.0, 0.0)) : cross(u, v);
// }
2017-08-03 14:01:04 +02:00
2017-08-03 17:25:13 +02:00
vec3 tangent(const vec3 n) {
vec3 t1 = cross(n, vec3(0, 0, 1));
vec3 t2 = cross(n, vec3(0, 1, 0));
if (length(t1) > length(t2)) return normalize(t1);
else return normalize(t2);
}
2017-08-03 14:01:04 +02:00
2018-03-26 00:30:24 +02:00
float traceConeAO(sampler3D voxels, const vec3 origin, vec3 dir, const float aperture, const float maxDist) {
2017-08-22 10:04:13 +02:00
dir = normalize(dir);
float sampleCol = 0.0;
2018-03-26 00:30:24 +02:00
float dist = 1.5 * VOXEL_SIZE * voxelgiOffset;
2017-08-22 10:04:13 +02:00
float diam = dist * aperture;
2017-12-19 18:05:38 +01:00
vec3 samplePos;
2017-08-22 10:04:13 +02:00
while (sampleCol < 1.0 && dist < maxDist) {
2017-12-19 18:05:38 +01:00
samplePos = dir * dist + origin;
2017-10-23 01:55:47 +02:00
float mip = max(log2(diam * voxelgiResolution.x), 0);
2017-08-22 10:04:13 +02:00
float mipSample = textureLod(voxels, samplePos * 0.5 + vec3(0.5), mip).r;
sampleCol += (1 - sampleCol) * mipSample;
dist += max(diam / 2, VOXEL_SIZE);
diam = dist * aperture;
}
return sampleCol;
}
2019-02-09 15:34:16 +01:00
float traceConeAOShadow(sampler3D voxels, const vec3 origin, vec3 dir, const float aperture, const float maxDist, const float offset) {
dir = normalize(dir);
float sampleCol = 0.0;
float dist = 1.5 * VOXEL_SIZE * voxelgiOffset * 2.5; //
float diam = dist * aperture;
vec3 samplePos;
while (sampleCol < 1.0 && dist < maxDist) {
samplePos = dir * dist + origin;
float mip = max(log2(diam * voxelgiResolution.x), 0);
float mipSample = textureLod(voxels, samplePos * 0.5 + vec3(0.5), mip).r;
sampleCol += (1 - sampleCol) * mipSample;
dist += max(diam / 2, VOXEL_SIZE);
diam = dist * aperture;
}
return sampleCol;
}
float traceShadow(sampler3D voxels, const vec3 origin, const vec3 dir) {
return traceConeAO(voxels, origin, dir, 0.14 * voxelgiAperture, 2.5 * voxelgiRange);
2019-01-27 19:12:00 +01:00
}
2017-12-19 18:05:38 +01:00
float traceAO(const vec3 origin, const vec3 normal, sampler3D voxels) {
2017-08-22 10:04:13 +02:00
const float angleMix = 0.5f;
2018-03-26 00:30:24 +02:00
const float aperture = 0.55785173935;
2018-02-27 20:27:27 +01:00
vec3 o1 = normalize(tangent(normal));
vec3 o2 = normalize(cross(o1, normal));
vec3 c1 = 0.5f * (o1 + o2);
vec3 c2 = 0.5f * (o1 - o2);
2018-12-07 13:48:40 +01:00
#ifdef HLSL
2019-01-04 15:02:53 +01:00
const float factor = voxelgiOcc * 0.93;
2018-12-07 13:48:40 +01:00
#else
2019-01-04 15:02:53 +01:00
const float factor = voxelgiOcc * 0.90;
2018-12-07 13:48:40 +01:00
#endif
2017-12-19 18:05:38 +01:00
#ifdef _VoxelCones1
2018-12-07 13:48:40 +01:00
return traceConeAO(voxels, origin, normal, aperture, MAX_DISTANCE) * factor;
2017-12-19 18:05:38 +01:00
#endif
#ifdef _VoxelCones3
2018-03-26 00:30:24 +02:00
float col = traceConeAO(voxels, origin, normal, aperture, MAX_DISTANCE);
col += traceConeAO(voxels, origin, mix(normal, o1, angleMix), aperture, MAX_DISTANCE);
col += traceConeAO(voxels, origin, mix(normal, -c2, angleMix), aperture, MAX_DISTANCE);
2018-12-07 13:48:40 +01:00
return (col / 3.0) * factor;
2017-12-19 18:05:38 +01:00
#endif
#ifdef _VoxelCones5
2018-03-26 00:30:24 +02:00
float col = traceConeAO(voxels, origin, normal, aperture, MAX_DISTANCE);
col += traceConeAO(voxels, origin, mix(normal, o1, angleMix), aperture, MAX_DISTANCE);
col += traceConeAO(voxels, origin, mix(normal, o2, angleMix), aperture, MAX_DISTANCE);
col += traceConeAO(voxels, origin, mix(normal, -c1, angleMix), aperture, MAX_DISTANCE);
col += traceConeAO(voxels, origin, mix(normal, -c2, angleMix), aperture, MAX_DISTANCE);
2018-12-07 13:48:40 +01:00
return (col / 5.0) * factor;
2017-11-04 16:16:07 +01:00
#endif
2017-12-19 18:05:38 +01:00
#ifdef _VoxelCones9
2018-03-26 00:30:24 +02:00
float col = traceConeAO(voxels, origin, normal, aperture, MAX_DISTANCE);
col += traceConeAO(voxels, origin, mix(normal, o1, angleMix), aperture, MAX_DISTANCE);
col += traceConeAO(voxels, origin, mix(normal, o2, angleMix), aperture, MAX_DISTANCE);
col += traceConeAO(voxels, origin, mix(normal, -c1, angleMix), aperture, MAX_DISTANCE);
col += traceConeAO(voxels, origin, mix(normal, -c2, angleMix), aperture, MAX_DISTANCE);
col += traceConeAO(voxels, origin, mix(normal, -o1, angleMix), aperture, MAX_DISTANCE);
col += traceConeAO(voxels, origin, mix(normal, -o2, angleMix), aperture, MAX_DISTANCE);
col += traceConeAO(voxels, origin, mix(normal, c1, angleMix), aperture, MAX_DISTANCE);
col += traceConeAO(voxels, origin, mix(normal, c2, angleMix), aperture, MAX_DISTANCE);
2018-12-07 13:48:40 +01:00
return (col / 9.0) * factor;
2017-12-19 18:05:38 +01:00
#endif
return 0.0;
2017-08-22 10:04:13 +02:00
}
2019-01-27 19:12:00 +01:00
#endif