From e58ba5a3a83c31c9b0de23d6f1c01e27aa16afe2 Mon Sep 17 00:00:00 2001 From: Lubos Lenco Date: Thu, 12 Oct 2017 22:40:30 +0200 Subject: [PATCH] Voxel AO fixes --- .../deferred_indirect/deferred_indirect.json | 2 +- Shaders/std/conetrace.glsl | 19 ++++++++++---- blender/arm/make_world.py | 16 ++++++------ blender/arm/material/make_voxel.py | 25 +++++++++++-------- blender/arm/props.py | 5 ++++ blender/arm/props_ui.py | 1 + 6 files changed, 43 insertions(+), 25 deletions(-) diff --git a/Shaders/deferred_indirect/deferred_indirect.json b/Shaders/deferred_indirect/deferred_indirect.json index aff4feec..4806a116 100755 --- a/Shaders/deferred_indirect/deferred_indirect.json +++ b/Shaders/deferred_indirect/deferred_indirect.json @@ -14,7 +14,7 @@ { "name": "eyeSnap", "link": "_cameraPositionSnap", - "ifdef": ["_VoxelGI"] + "ifdef": ["_VoxelGICam"] }, { "name": "eyeLook", diff --git a/Shaders/std/conetrace.glsl b/Shaders/std/conetrace.glsl index 23d40bc3..6ad41d7f 100755 --- a/Shaders/std/conetrace.glsl +++ b/Shaders/std/conetrace.glsl @@ -76,6 +76,13 @@ vec4 traceDiffuse(const vec3 origin, const vec3 normal) { const float offset = 1.5 * VOXEL_SIZE; // Normal direction vec4 col = traceCone(origin, normal, aperture, MAX_DISTANCE, offset); + #ifdef _VoxelGICone5 + col += traceCone(origin, mix(normal, -o1, angleMix), aperture, MAX_DISTANCE, offset); + col += traceCone(origin, mix(normal, -o2, angleMix), aperture, MAX_DISTANCE, offset); + col += traceCone(origin, mix(normal, c1, angleMix), aperture, MAX_DISTANCE, offset); + col += traceCone(origin, mix(normal, c2, angleMix), aperture, MAX_DISTANCE, offset); + return col / 5.0; + #else // 4 side cones col += traceCone(origin, mix(normal, o1, angleMix), aperture, MAX_DISTANCE, offset); col += traceCone(origin, mix(normal, -o1, angleMix), aperture, MAX_DISTANCE, offset); @@ -87,6 +94,7 @@ vec4 traceDiffuse(const vec3 origin, const vec3 normal) { col += traceCone(origin, mix(normal, c2, angleMix), aperture, MAX_DISTANCE, offset); col += traceCone(origin, mix(normal, -c2, angleMix), aperture, MAX_DISTANCE, offset); return col / 9.0; + #endif } float traceShadow(const vec3 origin, const vec3 dir, const float aperture, const float targetDistance) { @@ -143,13 +151,14 @@ float traceAO(const vec3 origin, const vec3 normal) { float col = traceConeAO(origin, normal, aperture, MAX_DISTANCE, offset); // 4 side cones col += traceConeAO(origin, mix(normal, o1, angleMix), aperture, MAX_DISTANCE, offset); - col += traceConeAO(origin, mix(normal, -o1, angleMix), aperture, MAX_DISTANCE, offset); + // col += traceConeAO(origin, mix(normal, -o1, angleMix), aperture, MAX_DISTANCE, offset); col += traceConeAO(origin, mix(normal, o2, angleMix), aperture, MAX_DISTANCE, offset); - col += traceConeAO(origin, mix(normal, -o2, angleMix), aperture, MAX_DISTANCE, offset); + // col += traceConeAO(origin, mix(normal, -o2, angleMix), aperture, MAX_DISTANCE, offset); // 4 corners - col += traceConeAO(origin, mix(normal, c1, angleMix), aperture, MAX_DISTANCE, offset); + // col += traceConeAO(origin, mix(normal, c1, angleMix), aperture, MAX_DISTANCE, offset); col += traceConeAO(origin, mix(normal, -c1, angleMix), aperture, MAX_DISTANCE, offset); - col += traceConeAO(origin, mix(normal, c2, angleMix), aperture, MAX_DISTANCE, offset); + // col += traceConeAO(origin, mix(normal, c2, angleMix), aperture, MAX_DISTANCE, offset); col += traceConeAO(origin, mix(normal, -c2, angleMix), aperture, MAX_DISTANCE, offset); - return col / 9.0; + // return col / 9.0; + return col / 5.0; } diff --git a/blender/arm/make_world.py b/blender/arm/make_world.py index e0e01eb7..2059a521 100755 --- a/blender/arm/make_world.py +++ b/blender/arm/make_world.py @@ -126,12 +126,18 @@ def build_node_tree(world): wrd.world_defs += '_Rad' # Always do radiance for gi wrd.world_defs += '_Irr' - if voxelgi: + if voxelgi or voxelao: assets.add_khafile_def('arm_voxelgi') if rpdat.arm_voxelgi_revoxelize: assets.add_khafile_def('arm_voxelgi_revox') if rpdat.arm_voxelgi_camera: wrd.world_defs += '_VoxelGICam' + if wrd.arm_voxelgi_diff_cones == '5': + wrd.world_defs += '_VoxelGICone5' + wrd.world_defs += '_Rad' # Always do radiance for voxels + wrd.world_defs += '_Irr' + if voxelgi: + assets.add_khafile_def('arm_voxelgi') if rpdat.arm_voxelgi_shadows: wrd.world_defs += '_VoxelGIDirect' wrd.world_defs += '_VoxelGIShadow' @@ -139,15 +145,9 @@ def build_node_tree(world): wrd.world_defs += '_VoxelGIDirect' wrd.world_defs += '_VoxelGIRefract' wrd.world_defs += '_VoxelGI' - wrd.world_defs += '_Rad' # Always do radiance for voxels - wrd.world_defs += '_Irr' + elif voxelao: - assets.add_khafile_def('arm_voxelgi') - if rpdat.arm_voxelgi_revoxelize: - assets.add_khafile_def('arm_voxelgi_revox') wrd.world_defs += '_VoxelAO' - wrd.world_defs += '_Rad' - wrd.world_defs += '_Irr' if arm.utils.get_gapi().startswith('direct3d'): # Flip Y axis in drawQuad command wrd.world_defs += '_InvY' diff --git a/blender/arm/material/make_voxel.py b/blender/arm/material/make_voxel.py index ab2c6a5f..ed8abb3e 100644 --- a/blender/arm/material/make_voxel.py +++ b/blender/arm/material/make_voxel.py @@ -264,23 +264,24 @@ def make_ao(context_id): frag.add_include('../../Shaders/compiled.glsl') frag.add_include('../../Shaders/std/math.glsl') + frag.add_include('../../Shaders/std/imageatomic.glsl') frag.write_header('#extension GL_ARB_shader_image_load_store : enable') rpdat = arm.utils.get_rp() - frag.add_uniform('layout(RGBA8) image3D voxels') - # frag.add_uniform('layout(R8) image3D voxels') + frag.add_uniform('layout(r32ui) uimage3D voxels') frag.write('if (!isInsideCube(voxposition)) return;') - frag.write('vec3 wposition = voxposition * voxelgiHalfExtents;') - - # if rpdat.arm_voxelgi_camera: - # vert.add_uniform('vec3 eye', '_cameraPosition') - vert.add_uniform('mat4 W', '_worldMatrix') - - vert.add_out('vec3 voxpositionGeom') vert.add_include('../../Shaders/compiled.glsl') - vert.write('voxpositionGeom = vec3(W * vec4(pos, 1.0)) / voxelgiHalfExtents;') + vert.add_uniform('mat4 W', '_worldMatrix') + vert.add_out('vec3 voxpositionGeom') + + if rpdat.arm_voxelgi_camera: + vert.add_uniform('vec3 eyeSnap', '_cameraPositionSnap') + vert.write('voxpositionGeom = (vec3(W * vec4(pos, 1.0)) - eyeSnap) / voxelgiHalfExtents;') + else: + vert.write('voxpositionGeom = vec3(W * vec4(pos, 1.0)) / voxelgiHalfExtents;') + # vert.write('gl_Position = vec4(0.0, 0.0, 0.0, 1.0);') geom.add_out('vec3 voxposition') @@ -303,6 +304,8 @@ def make_ao(context_id): geom.write('EndPrimitive();') frag.write('vec3 voxel = voxposition * 0.5 + vec3(0.5);') - frag.write('imageStore(voxels, ivec3(voxelgiResolution * voxel), vec4(1.0));') + # frag.write('imageStore(voxels, ivec3(voxelgiResolution * voxel), vec4(1.0));') + frag.write('uint val = convVec4ToRGBA8(vec4(1.0) * 255);') + frag.write('imageAtomicMax(voxels, ivec3(voxelgiResolution * voxel), val);') return con_voxel diff --git a/blender/arm/props.py b/blender/arm/props.py index 5df04702..3b316c76 100755 --- a/blender/arm/props.py +++ b/blender/arm/props.py @@ -174,6 +174,11 @@ def init_properties(): ], name="Preset", description="Render path preset", default='Deferred', update=update_preset) bpy.types.World.arm_voxelgi_diff = bpy.props.FloatProperty(name="Diffuse", description="", default=1.0, update=assets.invalidate_shader_cache) + bpy.types.World.arm_voxelgi_diff_cones = EnumProperty( + items=[('9', '9', '9'), + ('5', '5', '5'), + ], + name="Diffuse Cones", description="", default='9', update=assets.invalidate_shader_cache) bpy.types.World.arm_voxelgi_spec = bpy.props.FloatProperty(name="Specular", description="", default=1.0, update=assets.invalidate_shader_cache) bpy.types.World.arm_voxelgi_occ = bpy.props.FloatProperty(name="Occlussion", description="", default=1.0, update=assets.invalidate_shader_cache) bpy.types.World.arm_voxelgi_env = bpy.props.FloatProperty(name="Env Map", description="Contribute light from environment map", default=0.0, update=assets.invalidate_shader_cache) diff --git a/blender/arm/props_ui.py b/blender/arm/props_ui.py index 50bdbd97..25c11924 100644 --- a/blender/arm/props_ui.py +++ b/blender/arm/props_ui.py @@ -1016,6 +1016,7 @@ class ArmRenderPropsPanel(bpy.types.Panel): row = layout.row() row.prop(wrd, 'arm_voxelgi_step') row.prop(wrd, 'arm_voxelgi_range') + layout.prop(wrd, 'arm_voxelgi_diff_cones') layout.label('SSAO') layout.prop(wrd, 'arm_ssao_size')