Skip to content

Commit

Permalink
reimplenting voxel bounces
Browse files Browse the repository at this point in the history
  • Loading branch information
e2002e committed Feb 16, 2023
1 parent cceed5c commit 32fb1e8
Show file tree
Hide file tree
Showing 9 changed files with 186 additions and 25 deletions.
2 changes: 1 addition & 1 deletion Sources/armory/object/Uniforms.hx
Expand Up @@ -216,7 +216,7 @@ class Uniforms {
#if (rp_voxels != 'Off')
case "_voxelBlend": { // Blend current and last voxels
var freq = armory.renderpath.RenderPathCreator.voxelFreq;
return (armory.renderpath.RenderPathCreator.voxelFrame % freq) / freq;
return (armory.renderpath.RenderPathCreator.voxelFrame % freq + 1) / freq;
}
#end
#if rp_bloom
Expand Down
150 changes: 147 additions & 3 deletions Sources/armory/renderpath/Inc.hx
Expand Up @@ -13,7 +13,14 @@ class Inc {
static var spotIndex = 0;
static var lastFrame = -1;

#if (rp_voxels && arm_config)
#if (rp_voxelgi_bounces)
static var bounce_sh:kha.compute.Shader = null;
static var bounce_ta:kha.compute.TextureUnit;
static var bounce_tb:kha.compute.TextureUnit;
static var bounce_tc:kha.compute.TextureUnit;
#end

#if ((rp_voxels != 'Off') && arm_config)
static var voxelsCreated = false;
#end

Expand Down Expand Up @@ -488,8 +495,6 @@ class Inc {
}
#end



public static inline function getCubeSize(): Int {
#if (rp_shadowmap_cube == 256)
return 256;
Expand Down Expand Up @@ -602,6 +607,30 @@ class Inc {
static function endShadowsRenderProfile() { shadowsRenderTime += kha.Scheduler.realTime() - startShadowsRenderTime; }
public static function endFrame() { shadowsLogicTime = 0; shadowsRenderTime = 0; }
#end

#if (rp_voxels == 'Voxel GI')
public static function computeVoxelsEnd() {
var rts = path.renderTargets;
var res = Inc.getVoxelRes();

#if (rp_voxelgi_bounces)
if (bounce_sh == null) {
bounce_sh = path.getComputeShader("voxel_bounce");
bounce_ta = bounce_sh.getTextureUnit("voxelsNor");
bounce_tb = bounce_sh.getTextureUnit("voxelsFrom");
bounce_tc = bounce_sh.getTextureUnit("voxelsTo");
}
//path.clearImage("voxelsBounce", 0x00000000);
kha.compute.Compute.setShader(bounce_sh);
kha.compute.Compute.setTexture(bounce_ta, rts.get("voxelsNor").image, kha.compute.Access.Read);
kha.compute.Compute.setTexture3DParameters(bounce_tb, kha.graphics4.TextureAddressing.Clamp, kha.graphics4.TextureAddressing.Clamp, kha.graphics4.TextureAddressing.Clamp, kha.graphics4.TextureFilter.LinearFilter, kha.graphics4.TextureFilter.PointFilter, kha.graphics4.MipMapFilter.LinearMipFilter);
kha.compute.Compute.setSampledTexture(bounce_tb, rts.get("voxels").image);
kha.compute.Compute.setTexture(bounce_tc, rts.get("voxelsBounce").image, kha.compute.Access.Write);
kha.compute.Compute.compute(res, res, res);
path.generateMipmaps("voxelsBounce");
#end
}
#end
}

#if arm_shadowmap_atlas
Expand Down Expand Up @@ -1025,6 +1054,121 @@ class ShadowMapTile {
}
i--;
}

#if (rp_voxels == "Voxel GI")
public static function computeVoxelsBegin() {
if (voxel_sh == null) {
voxel_sh = path.getComputeShader("voxel_light");
voxel_ta = voxel_sh.getTextureUnit("voxelsOpac");
voxel_tb = voxel_sh.getTextureUnit("voxelsNor");
voxel_tc = voxel_sh.getTextureUnit("voxels");
voxel_td = voxel_sh.getTextureUnit("shadowMap");
voxel_te = voxel_sh.getTextureUnit("shadowMapSpot");
voxel_tf = voxel_sh.getTextureUnit("shadowMapPoint");

voxel_ca = voxel_sh.getConstantLocation("lightPos");
voxel_cb = voxel_sh.getConstantLocation("lightColor");
voxel_cc = voxel_sh.getConstantLocation("lightType");
voxel_cd = voxel_sh.getConstantLocation("lightDir");
voxel_ci = voxel_sh.getConstantLocation("spotData");
#if (rp_shadowmap)
voxel_ce = voxel_sh.getConstantLocation("lightShadow");
voxel_cf = voxel_sh.getConstantLocation("lightProj");
voxel_cg = voxel_sh.getConstantLocation("LVP");
voxel_ch = voxel_sh.getConstantLocation("shadowsBias");
#end
}
path.clearImage("voxels", 0x00000000);
}
public static function computeVoxels() {
var rts = path.renderTargets;
var res = Inc.getVoxelRes();
var lights = iron.Scene.active.lights;
for (i in 0...lights.length) {
var l = lights[i];
if (!l.visible) continue;
path.light = l;

kha.compute.Compute.setShader(voxel_sh);
kha.compute.Compute.setTexture(voxel_ta, rts.get("voxelsOpac").image, kha.compute.Access.Read);
kha.compute.Compute.setTexture(voxel_tb, rts.get("voxelsNor").image, kha.compute.Access.Read);
kha.compute.Compute.setTexture(voxel_tc, rts.get("voxels").image, kha.compute.Access.Write);

#if (rp_shadowmap)
if (l.data.raw.type == "sun") {
kha.compute.Compute.setSampledTexture(voxel_td, rts.get("shadowMap").image);
kha.compute.Compute.setInt(voxel_ce, 1); // lightShadow
}
else if (l.data.raw.type == "spot") {
kha.compute.Compute.setSampledTexture(voxel_te, rts.get("shadowMapSpot[0]").image);
kha.compute.Compute.setInt(voxel_ce, 2);
}
else {
kha.compute.Compute.setSampledCubeMap(voxel_tf, rts.get("shadowMapPoint[0]").cubeMap);
kha.compute.Compute.setInt(voxel_ce, 3);
}

// // lightProj
var near = l.data.raw.near_plane;
var far = l.data.raw.far_plane;
var a:kha.FastFloat = far + near;
var b:kha.FastFloat = far - near;
var f2:kha.FastFloat = 2.0;
var c:kha.FastFloat = f2 * far * near;
var vx:kha.FastFloat = a / b;
var vy:kha.FastFloat = c / b;
kha.compute.Compute.setFloat2(voxel_cf, vx, vy);
// // LVP
m.setFrom(l.VP);
m.multmat(iron.object.Uniforms.biasMat);
kha.compute.Compute.setMatrix(voxel_cg, m.self);
// // shadowsBias
kha.compute.Compute.setFloat(voxel_ch, l.data.raw.shadows_bias);
#end

// // lightPos
kha.compute.Compute.setFloat3(voxel_ca, l.transform.worldx(), l.transform.worldy(), l.transform.worldz());
// // lightCol
var f = l.data.raw.strength;
kha.compute.Compute.setFloat3(voxel_cb, l.data.raw.color[0] * f, l.data.raw.color[1] * f, l.data.raw.color[2] * f);
// // lightType
kha.compute.Compute.setInt(voxel_cc, iron.data.LightData.typeToInt(l.data.raw.type));
// // lightDir
var v = l.look();
kha.compute.Compute.setFloat3(voxel_cd, v.x, v.y, v.z);
// // spotData
if (l.data.raw.type == "spot") {
var vx = l.data.raw.spot_size;
var vy = vx - l.data.raw.spot_blend;
kha.compute.Compute.setFloat2(voxel_ci, vx, vy);
}

kha.compute.Compute.compute(res, res, res);
}
}
public static function computeVoxelsEnd() {
var rts = path.renderTargets;
var res = Inc.getVoxelRes();
path.generateMipmaps("voxels");

#if (rp_voxelgi_bounces)
if (bounce_sh == null) {
bounce_sh = path.getComputeShader("voxel_bounce");
bounce_ta = bounce_sh.getTextureUnit("voxelsNor");
bounce_tb = bounce_sh.getTextureUnit("voxelsFrom");
bounce_tc = bounce_sh.getTextureUnit("voxelsTo");
}
path.clearImage("voxelsBounce", 0x00000000);
kha.compute.Compute.setShader(bounce_sh);
kha.compute.Compute.setTexture(bounce_ta, rts.get("voxelsNor").image, kha.compute.Access.Read);
kha.compute.Compute.setTexture3DParameters(bounce_tb, kha.graphics4.TextureAddressing.Clamp, kha.graphics4.TextureAddressing.Clamp, kha.graphics4.TextureAddressing.Clamp, kha.graphics4.TextureFilter.LinearFilter, kha.graphics4.TextureFilter.PointFilter, kha.graphics4.MipMapFilter.LinearMipFilter);
kha.compute.Compute.setSampledTexture(bounce_tb, rts.get("voxels").image);
kha.compute.Compute.setTexture(bounce_tc, rts.get("voxelsBounce").image, kha.compute.Access.Write);
kha.compute.Compute.compute(res, res, res);
path.generateMipmaps("voxelsBounce");
#end
}
#end
}

#if arm_shadowmap_atlas_lod
Expand Down
15 changes: 13 additions & 2 deletions Sources/armory/renderpath/RenderPathDeferred.hx
Expand Up @@ -66,6 +66,12 @@ class RenderPathDeferred {

#if (rp_voxels == "Voxel AO")
path.loadShader("shader_datas/deferred_light/deferred_light_VoxelAOvar");
#else
Inc.initGI("voxelsOpac");
Inc.initGI("voxelsNor");
#if (rp_gi_bounces)
Inc.initGI("voxelsBounce");
#end
#end
}
#end
Expand Down Expand Up @@ -577,7 +583,7 @@ class RenderPathDeferred {

if (voxelize) {
var voxtex = voxels;

path.clearImage(voxtex, 0x00000000);
path.setTarget("");

Expand All @@ -590,7 +596,7 @@ class RenderPathDeferred {
}
#end

path.bindTarget(voxels, "voxels");
path.bindTarget(voxtex, "voxels");

#if (rp_shadowmap && (rp_voxels == "Voxel GI"))
{
Expand All @@ -601,8 +607,13 @@ class RenderPathDeferred {
#end
}
#end

path.drawMeshes("voxel");
path.generateMipmaps(voxels);

#if rp_voxelgi_bounces
Inc.computeVoxelsEnd();
#end
}
}
#end
Expand Down
3 changes: 3 additions & 0 deletions blender/arm/make_renderpath.py
Expand Up @@ -106,6 +106,9 @@ def add_world_defs():

if voxelgi:
wrd.world_defs += '_VoxelGI'
if rpdat.arm_voxelgi_bounces != "1":
assets.add_khafile_def('rp_voxelgi_bounces={0}'.format(rpdat.arm_voxelgi_bounces))
assets.add_shader_external(arm.utils.get_sdk_path() + '/armory/Shaders/voxel_bounce/voxel_bounce.comp.glsl')
if rpdat.arm_voxelgi_shadows:
wrd.world_defs += '_VoxelShadow'
if rpdat.rp_voxelgi_relight:
Expand Down
2 changes: 1 addition & 1 deletion blender/arm/material/cycles_nodes/nodes_converter.py
Expand Up @@ -94,7 +94,7 @@ def parse_valtorgb(node: bpy.types.ShaderNodeValToRGB, out_socket: bpy.types.Nod
# The last entry is included twice so that the interpolation
# between indices works (no out of bounds error)
cols_var = c.node_name(node.name).upper() + '_COLS'
cols_entries = ', '.join(f'vec3({elem.color[0]}, {elem.color[1]}, {elem.color[2]})' for elem in elems)
cols_entries = ', '.join(f'vec4({elem.color[0]}, {elem.color[1]}, {elem.color[2]}, {elem.color[3]})' for elem in elems)
cols_entries += f', vec3({elems[len(elems) - 1].color[0]}, {elems[len(elems) - 1].color[1]}, {elems[len(elems) - 1].color[2]})'
state.curshader.add_const("vec3", cols_var, cols_entries, array_size=len(elems) + 1)

Expand Down
19 changes: 9 additions & 10 deletions blender/arm/material/make_mesh.py
Expand Up @@ -269,12 +269,11 @@ def make_deferred(con_mesh, rpasses):
frag.write('fragColor[GBUF_IDX_EMISSION] = vec4(emissionCol, 0.0);') # Alpha channel is unused at the moment
frag.write('#endif')

frag.write('#ifdef _VoxelGIRefract')
if parse_opacity:
frag.write('fragColor[GBUF_IDX_REFRACTION] = vec4(rior, opacity, 0.0, 0.0);')
else:
frag.write('fragColor[GBUF_IDX_REFRACTION] = vec4(1.0, 1.0, 0.0, 0.0);')
frag.write('#endif')
if '_VoxelGIRefract' in wrd.world_defs:
if parse_opacity:
frag.write('fragColor[GBUF_IDX_REFRACTION] = vec4(rior, opacity, 0.0, 0.0);')
else:
frag.write('fragColor[GBUF_IDX_REFRACTION] = vec4(1.0, 1.0, 0.0, 0.0);')

return con_mesh

Expand Down Expand Up @@ -648,6 +647,9 @@ def make_forward_base(con_mesh, parse_opacity=False, transluc_pass=False):

frag.add_uniform('float envmapStrength', link='_envmapStrength')
frag.write('indirect *= envmapStrength * occlusion;')

frag.write('vec3 diffuse = vec3(0.0);')
frag.write('vec3 reflection = vec3(0.0);')

if '_VoxelAOvar' in wrd.world_defs:
frag.add_include('std/conetrace.glsl')
Expand All @@ -664,10 +666,7 @@ def make_forward_base(con_mesh, parse_opacity=False, transluc_pass=False):
else:
frag.write('indirect *= vec3(1.0 - traceAO(voxpos, n, voxels));')

frag.write('vec3 diffuse = vec3(0.0);')
frag.write('vec3 reflection = vec3(0.0);')

if '_VoxelGI' in wrd.world_defs:
elif '_VoxelGI' in wrd.world_defs:
frag.add_include('std/conetrace.glsl')
frag.add_uniform('sampler3D voxels')
if '_VoxelGICam' in wrd.world_defs:
Expand Down
14 changes: 7 additions & 7 deletions blender/arm/material/make_voxel.py
Expand Up @@ -46,11 +46,6 @@ def make_gi(context_id):
frag.write_header('#extension GL_ARB_shader_image_load_store : enable')

rpdat = arm.utils.get_rp()
if arm.utils.get_gapi() == 'direct3d11':
for e in con_voxel.data['vertex_elements']:
if e['name'] == 'nor':
con_voxel.data['vertex_elements'].remove(e)
break
frag.add_uniform('layout(rgba16) writeonly image3D voxels')

frag.write('if (abs(voxposition.z) > ' + rpdat.rp_voxelgi_resolution_z + ' || abs(voxposition.x) > 1 || abs(voxposition.y) > 1) return;')
Expand Down Expand Up @@ -106,6 +101,7 @@ def make_gi(context_id):

vert.add_uniform('mat4 W', '_worldMatrix')
vert.add_out('vec3 voxpositionGeom')
vert.add_out('vec3 wnormalGeom')
vert.add_include('compiled.inc')

if con_voxel.is_elem('col'):
Expand All @@ -125,6 +121,8 @@ def make_gi(context_id):

geom.add_out('vec3 voxposition')
geom.add_out('vec4 lightPosition')
geom.add_out('vec3 wnormal')

if con_voxel.is_elem('col'):
geom.add_out('vec3 vcolor')
if con_voxel.is_elem('tex'):
Expand All @@ -134,7 +132,7 @@ def make_gi(context_id):
if export_bpos:
geom.add_out('vec3 bposition')

if arm.utils.get_gapi() == 'direct3d11':
if arm.utils.get_gapi() == False:#'direct3d11':
voxHalfExt = str(round(rpdat.arm_voxelgi_dimensions / 2.0))
if rpdat.arm_voxelgi_revoxelize and rpdat.arm_voxelgi_camera:
vert.write(' stage_output.svpos.xyz = (mul(float4(stage_input.pos.xyz, 1.0), W).xyz - eyeSnap) / float3(' + voxHalfExt + ', ' + voxHalfExt + ', ' + voxHalfExt + ');')
Expand Down Expand Up @@ -202,6 +200,7 @@ def make_gi(context_id):
geom.write(' }')
geom.write('}')
else:

if rpdat.arm_voxelgi_revoxelize and rpdat.arm_voxelgi_camera:
vert.add_uniform('vec3 eyeSnap', '_cameraPositionSnap')
vert.write('voxpositionGeom = (vec3(W * vec4(pos.xyz, 1.0)) - eyeSnap) / voxelgiHalfExtents;')
Expand Down Expand Up @@ -409,7 +408,8 @@ def make_gi(context_id):

frag.write('basecol += emissionCol;')
frag.write('vec3 voxel = voxposition * 0.5 + 0.5;')
frag.write('imageStore(voxels, ivec3((voxelgiResolution ) * voxel), vec4(min(basecol, vec3(1.0)), opacity));')
frag.write('imageStore(voxels, ivec3(voxelgiResolution * voxel), vec4(basecol, opacity));')
frag.write('imageStore(voxelsNor, ivec3(voxelgiResolution * voxel), wnormal);')

return con_voxel

Expand Down
5 changes: 4 additions & 1 deletion blender/arm/props_renderpath.py
Expand Up @@ -508,7 +508,10 @@ class ArmRPListItem(bpy.types.PropertyGroup):
arm_voxelgi_temporal: BoolProperty(name="Temporal Filter", description="Use temporal filtering to stabilize voxels", default=False, update=assets.invalidate_shader_cache)
arm_voxelgi_camera: BoolProperty(name="Dynamic Camera", description="Use camera as voxelization origin", default=False, update=assets.invalidate_shader_cache)
arm_voxelgi_shadows: BoolProperty(name="Shadows", description="Use voxels to render shadows", default=False, update=update_renderpath)

arm_voxelgi_bounces: EnumProperty(
items=[('1', '1', '1'),
('2', '2', '2')],
name="Bounces", description="Trace multiple light bounces", default='1', update=update_renderpath)
arm_samples_per_pixel: EnumProperty(
items=[('1', '1', '1'),
('2', '2', '2'),
Expand Down
1 change: 1 addition & 0 deletions blender/arm/props_ui.py
Expand Up @@ -1692,6 +1692,7 @@ def draw(self, context):
col.prop(rpdat, 'arm_voxelgi_shadows', text='Shadows')
col2.prop(rpdat, 'rp_voxelgi_relight')
col2.prop(rpdat, 'arm_voxelgi_refraction', text='Refraction')
col2.prop(rpdat, 'arm_voxelgi_bounces')
col.prop(rpdat, 'arm_voxelgi_cones')
col.prop(rpdat, 'rp_voxelgi_resolution')
col.prop(rpdat, 'rp_voxelgi_resolution_z')
Expand Down

0 comments on commit 32fb1e8

Please sign in to comment.