More conetracing

This commit is contained in:
Lubos Lenco 2017-08-03 17:25:13 +02:00
parent 4a992ebd19
commit 2f292b786c
4 changed files with 79 additions and 82 deletions

View file

@ -90,16 +90,17 @@ void main() {
#else
vec3 wpos = p / voxelgiDimensions;
#endif
vec4 indirectDiffuse = indirectDiffuseLight(wpos, n);
// vec4 indirectDiffuse = traceDiffuse(wpos, n);
// vec4 indirectDiffuse = indirectDiffuseLight(wpos, n);
vec4 indirectDiffuse = traceDiffuse(wpos, n);
vec3 reflectWorld = reflect(-v, n);
vec3 indirectSpecular = traceSpecularVoxelCone(wpos, reflectWorld, n, metrough.y * 12.0);
vec3 indirectSpecular = traceSpecularVoxelCone(wpos, reflectWorld, n, metrough.y * 12.0 + 3.0);
indirectSpecular *= f0 * envBRDF.x + envBRDF.y;
fragColor.rgb = indirectDiffuse.rgb * voxelgiDiff * g1.rgb + indirectSpecular * voxelgiSpec;
float occ = 1.0 - indirectDiffuse.a * 0.2 * voxelgiOcc;
fragColor.rgb *= occ;
// fragColor.rgb *= occ;
// float occ = indirectDiffuse.a;
#ifdef _SSAO
fragColor.rgb *= texture(ssaotex, texCoord).r * 0.5 + 0.5;

View file

@ -11,12 +11,12 @@ const float VOXEL_SIZE = 1.0 / voxelgiResolution;
const float MAX_MIPMAP = 5.4;
const float VOXEL_RATIO = 128.0 / voxelgiResolution;
// 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);
// }
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);
}
// uvec3 face_indices(vec3 dir) {
// uvec3 ret;
@ -39,59 +39,56 @@ vec3 orthogonal(const vec3 u) {
return abs(dot(u, v)) > 0.99999 ? cross(u, vec3(0.0, 1.0, 0.0)) : cross(u, v);
}
// vec4 trace_cone(vec3 origin, vec3 dir, float aperture, float max_dist) {
// dir = normalize(dir);
// // uvec3 indices = face_indices(dir);
// vec4 sample_color = vec4(0.0);
// float dist = 3 * VOXEL_SIZE;
// float diam = dist * aperture;
// vec3 sample_position = dir * dist + origin;
// // Step until alpha > 1 or out of bounds
// while (sample_color.a < 1.0 && dist < max_dist) {
// // Choose mip level based on the diameter of the cone
// float mip = max(log2(diam * voxelgiResolution), 0);
// // vec4 mip_sample = sample_voxel(sample_position, dir, indices, mip);
// vec4 mip_sample = textureLod(voxels, sample_position * 0.5 + vec3(0.5), mip);
// // Blend mip sample with current sample color
// sample_color += (1 - sample_color.a) * mip_sample;
// float step_size = max(diam / 2, VOXEL_SIZE);
// dist += step_size;
// diam = dist * aperture;
// sample_position = dir * dist + origin;
// }
// return sample_color;
// }
vec4 trace_cone(vec3 origin, vec3 dir, float aperture, float max_dist) {
dir = normalize(dir);
// uvec3 indices = face_indices(dir);
vec4 sample_color = vec4(0.0);
float dist = 3 * VOXEL_SIZE;
float diam = dist * aperture;
vec3 sample_position = dir * dist + origin;
// Step until alpha > 1 or out of bounds
while (sample_color.a < 1.0 && dist < max_dist) {
// Choose mip level based on the diameter of the cone
float mip = max(log2(diam * voxelgiResolution), 0);
// vec4 mip_sample = sample_voxel(sample_position, dir, indices, mip);
vec4 mip_sample = textureLod(voxels, sample_position * 0.5 + vec3(0.5), mip);
// Blend mip sample with current sample color
sample_color += ((1 - sample_color.a) * mip_sample) * (1.0 / max(voxelgiOcc, 0.1));
float step_size = max(diam / 2, VOXEL_SIZE);
dist += step_size;
diam = dist * aperture;
sample_position = dir * dist + origin;
}
return sample_color;
}
// vec4 traceDiffuse(vec3 origin, vec3 normal) {
// const float TAN_22_5 = 0.55785173935;
// const float MAX_DISTANCE = 1.73205080757;
// const float angle_mix = 0.5f;
// const float aperture = TAN_22_5;
// vec4 result_diffuse = vec4(0.0);
vec4 traceDiffuse(vec3 origin, vec3 normal) {
const float TAN_22_5 = 0.55785173935;
const float MAX_DISTANCE = 1.73205080757;
const float angle_mix = 0.5f;
const float aperture = TAN_22_5;
const vec3 o1 = normalize(tangent(normal));
const vec3 o2 = normalize(cross(o1, normal));
const vec3 c1 = 0.5f * (o1 + o2);
const vec3 c2 = 0.5f * (o1 - o2);
// const vec3 o1 = normalize(tangent(normal));
// const vec3 o2 = normalize(cross(o1, normal));
// Normal direction
vec4 col = trace_cone(origin, normal, aperture, MAX_DISTANCE);
// const vec3 c1 = 0.5f * (o1 + o2);
// const vec3 c2 = 0.5f * (o1 - o2);
// 4 side cones
col += trace_cone(origin, mix(normal, o1, angle_mix), aperture, MAX_DISTANCE);
col += trace_cone(origin, mix(normal, -o1, angle_mix), aperture, MAX_DISTANCE);
col += trace_cone(origin, mix(normal, o2, angle_mix), aperture, MAX_DISTANCE);
col += trace_cone(origin, mix(normal, -o2, angle_mix), aperture, MAX_DISTANCE);
// // Normal direction
// result_diffuse += trace_cone(origin, normal, aperture, MAX_DISTANCE);
// 4 corners
col += trace_cone(origin, mix(normal, c1, angle_mix), aperture, MAX_DISTANCE);
col += trace_cone(origin, mix(normal, -c1, angle_mix), aperture, MAX_DISTANCE);
col += trace_cone(origin, mix(normal, c2, angle_mix), aperture, MAX_DISTANCE);
col += trace_cone(origin, mix(normal, -c2, angle_mix), aperture, MAX_DISTANCE);
// // 4 side cones
// result_diffuse += trace_cone(origin, mix(normal, o1, angle_mix), aperture, MAX_DISTANCE);
// result_diffuse += trace_cone(origin, mix(normal, -o1, angle_mix), aperture, MAX_DISTANCE);
// result_diffuse += trace_cone(origin, mix(normal, o2, angle_mix), aperture, MAX_DISTANCE);
// result_diffuse += trace_cone(origin, mix(normal, -o2, angle_mix), aperture, MAX_DISTANCE);
// // 4 corners
// result_diffuse += trace_cone(origin, mix(normal, c1, angle_mix), aperture, MAX_DISTANCE);
// result_diffuse += trace_cone(origin, mix(normal, -c1, angle_mix), aperture, MAX_DISTANCE);
// result_diffuse += trace_cone(origin, mix(normal, c2, angle_mix), aperture, MAX_DISTANCE);
// result_diffuse += trace_cone(origin, mix(normal, -c2, angle_mix), aperture, MAX_DISTANCE);
// return vec4(result_diffuse.rgb / 9, 1.0);
// }
return col / 9.0;
}
vec4 traceDiffuseVoxelCone(const vec3 from, vec3 direction) {
direction = normalize(direction);

View file

@ -52,7 +52,7 @@ def make(context_id):
frag.add_uniform('layout(r32ui) uimage3D voxels')
frag.add_uniform('vec3 lightPos', '_lampPosition')
frag.add_uniform('vec3 lightColor', '_lampColor')
frag.add_uniform('vec3 lightColor', '_lampColorVoxel')
frag.write('if (!isInsideCube(wposition)) return;')
@ -140,32 +140,31 @@ def make(context_id):
# frag.write('imageStore(voxels, ivec3(voxelgiResolution * voxel), vec4(color, 1.0));')
# else:
frag.write('color = clamp(color, vec3(0.0), vec3(1.0));')
frag.write('uint val = convVec4ToRGBA8(vec4(color, 1.0) * 255);')
frag.write('imageAtomicMax(voxels, ivec3(voxelgiResolution * voxel), val);')
# frag.write('uint val = convVec4ToRGBA8(vec4(color, 1.0) * 255);')
# frag.write('imageAtomicMax(voxels, ivec3(voxelgiResolution * voxel), val);')
# frag.write('imageStore(voxels, ivec3(voxelgiResolution * voxel), vec4(color, 1.0));')
# frag.write('imageAtomicRGBA8Avg(voxels, ivec3(voxelgiResolution * voxel), vec4(color, 1.0));')
# frag.write('ivec3 coords = ivec3(voxelgiResolution * voxel);')
# frag.write('vec4 val = vec4(color, 1.0);')
# frag.write('val *= 255.0;')
# frag.write('uint newVal = encUnsignedNibble(convVec4ToRGBA8(val), 1);')
# frag.write('uint prevStoredVal = 0;')
# frag.write('uint currStoredVal;')
# # frag.write('int counter = 0;')
# frag.write('// Loop as long as destination value gets changed by other threads')
# # frag.write('while ((currStoredVal = imageAtomicCompSwap(voxels, coords, prevStoredVal, newVal)) != prevStoredVal && counter < 16) {')
# frag.write('while ((currStoredVal = imageAtomicCompSwap(voxels, coords, prevStoredVal, newVal)) != prevStoredVal) {')
# frag.write(' vec4 rval = convRGBA8ToVec4(currStoredVal & 0xFEFEFEFE);')
# frag.write(' uint n = decUnsignedNibble(currStoredVal);')
# frag.write(' rval = rval * n + val;')
# frag.write(' rval /= ++n;')
# frag.write(' rval = round(rval / 2) * 2;')
# frag.write(' newVal = encUnsignedNibble(convVec4ToRGBA8(rval), n);')
# frag.write(' prevStoredVal = currStoredVal;')
# # frag.write(' counter++;')
# frag.write('}')
frag.write('ivec3 coords = ivec3(voxelgiResolution * voxel);')
frag.write('vec4 val = vec4(color, 1.0);')
frag.write('val *= 255.0;')
frag.write('uint newVal = encUnsignedNibble(convVec4ToRGBA8(val), 1);')
frag.write('uint prevStoredVal = 0;')
frag.write('uint currStoredVal;')
# frag.write('int counter = 0;')
# frag.write('while ((currStoredVal = imageAtomicCompSwap(voxels, coords, prevStoredVal, newVal)) != prevStoredVal && counter < 16) {')
frag.write('while ((currStoredVal = imageAtomicCompSwap(voxels, coords, prevStoredVal, newVal)) != prevStoredVal) {')
frag.write(' vec4 rval = convRGBA8ToVec4(currStoredVal & 0xFEFEFEFE);')
frag.write(' uint n = decUnsignedNibble(currStoredVal);')
frag.write(' rval = rval * n + val;')
frag.write(' rval /= ++n;')
frag.write(' rval = round(rval / 2) * 2;')
frag.write(' newVal = encUnsignedNibble(convVec4ToRGBA8(rval), n);')
frag.write(' prevStoredVal = currStoredVal;')
# frag.write(' counter++;')
frag.write('}')
# frag.write('val.rgb *= 255.0f;')
# frag.write('uint newVal = convVec4ToRGBA8(val);')

View file

@ -426,7 +426,7 @@ def init_properties():
bpy.types.World.voxelgi_diff = bpy.props.FloatProperty(name="Diffuse", description="", default=1.0, update=assets.invalidate_shader_cache)
bpy.types.World.voxelgi_spec = bpy.props.FloatProperty(name="Specular", description="", default=1.0, update=assets.invalidate_shader_cache)
bpy.types.World.voxelgi_occ = bpy.props.FloatProperty(name="Occlussion", description="", default=1.0, update=assets.invalidate_shader_cache)
bpy.types.World.voxelgi_env = bpy.props.FloatProperty(name="Env Map", description="Contribute light from environment map", default=0.2, update=assets.invalidate_shader_cache)
bpy.types.World.voxelgi_env = bpy.props.FloatProperty(name="Env Map", description="Contribute light from environment map", default=0.0, update=assets.invalidate_shader_cache)
bpy.types.World.voxelgi_step = bpy.props.FloatProperty(name="Step", description="Step size", default=1.0, update=assets.invalidate_shader_cache)
bpy.types.World.voxelgi_range = bpy.props.FloatProperty(name="Range", description="Maximum range", default=1.0, update=assets.invalidate_shader_cache)
bpy.types.World.sss_width = bpy.props.FloatProperty(name="SSS Width", description="SSS blur strength", default=1.0, update=assets.invalidate_shader_cache)