Temporal filter for stable voxels

This commit is contained in:
Lubos Lenco 2017-12-19 18:05:38 +01:00
parent 66d1ead229
commit 409a398730
10 changed files with 191 additions and 89 deletions

View file

@ -23,11 +23,14 @@ uniform sampler2D gbuffer1;
#ifdef _VoxelGI
//!uniform sampler3D voxels;
#endif
#ifdef _VoxelAO
//!uniform sampler3D voxels;
#endif
#ifdef _VoxelGITemporal
//!uniform sampler3D voxelsLast;
uniform float voxelBlend;
#endif
#ifdef _VoxelGICam
uniform vec3 eyeSnap;
#endif
@ -98,7 +101,11 @@ void main() {
vec3 voxpos = p / voxelgiHalfExtents;
#endif
vec4 indirectDiffuse = traceDiffuse(voxpos, n);
#ifdef _VoxelGITemporal
vec4 indirectDiffuse = traceDiffuse(voxpos, n, voxels) * voxelBlend + traceDiffuse(voxpos, n, voxelsLast) * (1.0 - voxelBlend);
#else
vec4 indirectDiffuse = traceDiffuse(voxpos, n, voxels);
#endif
vec3 indirectSpecular = traceSpecular(voxpos, n, v, metrough.y);
indirectSpecular *= f0 * envBRDF.x + envBRDF.y;
@ -165,7 +172,12 @@ void main() {
vec3 voxpos = p / voxelgiHalfExtents;
#endif
envl.rgb *= 1.0 - traceAO(voxpos, n);
#ifdef _VoxelGITemporal
envl.rgb *= 1.0 - (traceAO(voxpos, n, voxels) * voxelBlend + traceAO(voxpos, n, voxelsLast) * (1.0 - voxelBlend));
#else
envl.rgb *= 1.0 - traceAO(voxpos, n, voxels);
#endif
#endif
#ifdef _VoxelGI

View file

@ -17,6 +17,11 @@
"link": "_cameraPositionSnap",
"ifdef": ["_VoxelGICam"]
},
{
"name": "voxelBlend",
"link": "_voxelBlend",
"ifdef": ["_VoxelGITemporal"]
},
{
"name": "eyeLook",
"link": "_cameraLook",

View file

@ -12,6 +12,7 @@ const float VOXEL_SIZE = (2.0 / voxelgiResolution.x) * voxelgiStep;
const float blendFac = (1.0 / max(voxelgiOcc, 0.1));
uniform sampler3D voxels;
uniform sampler3D voxelsLast;
vec3 orthogonal(const vec3 u) {
// Pass normalized u
@ -41,15 +42,16 @@ vec3 tangent(const vec3 n) {
// dir.z * textureLod(voxels[indices.z], pos, lod);
// }
vec4 traceCone(const vec3 origin, vec3 dir, const float aperture, const float maxDist, const float offset) {
vec4 traceCone(sampler3D voxels, const vec3 origin, vec3 dir, const float aperture, const float maxDist, const float offset) {
dir = normalize(dir);
// uvec3 indices = faceIndices(dir);
vec4 sampleCol = vec4(0.0);
float dist = offset;
float diam = dist * aperture;
vec3 samplePos = dir * dist + origin;
vec3 samplePos;
// Step until alpha > 1 or out of bounds
while (sampleCol.a < 1.0 && dist < maxDist) {
samplePos = dir * dist + origin;
// Choose mip level based on the diameter of the cone
float mip = max(log2(diam * voxelgiResolution.x), 0);
// vec4 mipSample = sampleVoxel(samplePos, dir, indices, mip);
@ -61,12 +63,11 @@ vec4 traceCone(const vec3 origin, vec3 dir, const float aperture, const float ma
sampleCol += (1 - sampleCol.a) * mipSample;
dist += max(diam / 2, VOXEL_SIZE); // Step size
diam = dist * aperture;
samplePos = dir * dist + origin;
}
return sampleCol;
}
vec4 traceDiffuse(const vec3 origin, const vec3 normal) {
vec4 traceDiffuse(const vec3 origin, const vec3 normal, sampler3D voxels) {
const float TAN_22_5 = 0.55785173935;
const float angleMix = 0.5f;
const float aperture = TAN_22_5;
@ -75,32 +76,49 @@ vec4 traceDiffuse(const vec3 origin, const vec3 normal) {
const vec3 c1 = 0.5f * (o1 + o2);
const vec3 c2 = 0.5f * (o1 - o2);
const float offset = 1.5 * VOXEL_SIZE * voxelgiOffsetDiff;
// 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);
#ifdef _VoxelCones1
return traceCone(voxels, origin, normal, aperture, MAX_DISTANCE, offset);
#endif
#ifdef _VoxelCones3
vec4 col = traceCone(voxels, origin, normal, aperture, MAX_DISTANCE, offset);
col += traceCone(voxels, origin, mix(normal, -o1, angleMix), aperture, MAX_DISTANCE, offset);
col += traceCone(voxels, origin, mix(normal, c2, angleMix), aperture, MAX_DISTANCE, offset);
return col / (3.0 * blendFac);
#endif
#ifdef _VoxelCones5
vec4 col = traceCone(voxels, origin, normal, aperture, MAX_DISTANCE, offset);
col += traceCone(voxels, origin, mix(normal, -o1, angleMix), aperture, MAX_DISTANCE, offset);
col += traceCone(voxels, origin, mix(normal, -o2, angleMix), aperture, MAX_DISTANCE, offset);
col += traceCone(voxels, origin, mix(normal, c1, angleMix), aperture, MAX_DISTANCE, offset);
col += traceCone(voxels, origin, mix(normal, c2, angleMix), aperture, MAX_DISTANCE, offset);
return col / (5.0 * blendFac);
#else
#endif
#ifdef _VoxelCones9
// Normal direction
vec4 col = traceCone(voxels, origin, normal, aperture, MAX_DISTANCE, offset);
// 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);
col += traceCone(origin, mix(normal, o2, angleMix), aperture, MAX_DISTANCE, offset);
col += traceCone(origin, mix(normal, -o2, angleMix), aperture, MAX_DISTANCE, offset);
col += traceCone(voxels, origin, mix(normal, o1, angleMix), aperture, MAX_DISTANCE, offset);
col += traceCone(voxels, origin, mix(normal, -o1, angleMix), aperture, MAX_DISTANCE, offset);
col += traceCone(voxels, origin, mix(normal, o2, angleMix), aperture, MAX_DISTANCE, offset);
col += traceCone(voxels, origin, mix(normal, -o2, angleMix), aperture, MAX_DISTANCE, offset);
// 4 corners
col += traceCone(origin, mix(normal, c1, 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);
col += traceCone(origin, mix(normal, -c2, angleMix), aperture, MAX_DISTANCE, offset);
col += traceCone(voxels, origin, mix(normal, c1, angleMix), aperture, MAX_DISTANCE, offset);
col += traceCone(voxels, origin, mix(normal, -c1, angleMix), aperture, MAX_DISTANCE, offset);
col += traceCone(voxels, origin, mix(normal, c2, angleMix), aperture, MAX_DISTANCE, offset);
col += traceCone(voxels, origin, mix(normal, -c2, angleMix), aperture, MAX_DISTANCE, offset);
return col / (9.0 * blendFac);
#endif
return vec4(0.0);
}
float traceShadow(const vec3 origin, const vec3 dir, const float aperture, const float targetDistance) {
const float offset = 2 * VOXEL_SIZE * voxelgiOffsetShadow;
return traceCone(origin, dir, aperture, targetDistance, offset).a;
return traceCone(voxels, origin, dir, aperture, targetDistance, offset).a;
}
vec3 traceSpecular(const vec3 pos, const vec3 normal, const vec3 viewDir, const float roughness) {
@ -109,7 +127,7 @@ vec3 traceSpecular(const vec3 pos, const vec3 normal, const vec3 viewDir, const
vec3 specularDir = normalize(reflect(-viewDir, normal));
// Clamp to 1 grad and pi, exponent is angle of cone in radians
const float offset = 3 * VOXEL_SIZE * voxelgiOffsetSpec;
return traceCone(pos, specularDir, specularAperture, MAX_DISTANCE, offset).xyz;
return traceCone(voxels, pos, specularDir, specularAperture, MAX_DISTANCE, offset).xyz;
}
vec3 traceRefraction(const vec3 pos, const vec3 normal, const vec3 viewDir, const float roughness) {
@ -119,27 +137,27 @@ vec3 traceRefraction(const vec3 pos, const vec3 normal, const vec3 viewDir, cons
float rough = max(roughness, 0.03);
float specularAperture = clamp(tan((3.14159265 / 2) * rough), 0.0174533, 3.14159265);
const float offset = 1.5 * VOXEL_SIZE * voxelgiOffsetRefract;
return transmittance * traceCone(pos, refraction, specularAperture, MAX_DISTANCE, offset).xyz;
return transmittance * traceCone(voxels, pos, refraction, specularAperture, MAX_DISTANCE, offset).xyz;
}
float traceConeAO(const vec3 origin, vec3 dir, float aperture, const float maxDist, const float offset) {
float traceConeAO(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 = offset;
float diam = dist * aperture;
vec3 samplePos = dir * dist + origin;
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;
samplePos = dir * dist + origin;
}
return sampleCol;
}
float traceAO(const vec3 origin, const vec3 normal) {
float traceAO(const vec3 origin, const vec3 normal, sampler3D voxels) {
const float TAN_22_5 = 0.55785173935;
const float angleMix = 0.5f;
const float aperture = TAN_22_5;
@ -148,21 +166,40 @@ float traceAO(const vec3 origin, const vec3 normal) {
const vec3 c1 = 0.5f * (o1 + o2);
const vec3 c2 = 0.5f * (o1 - o2);
const float offset = 1.5 * VOXEL_SIZE * voxelgiOffsetDiff;
// Normal direction
float col = traceConeAO(origin, normal, aperture, MAX_DISTANCE, offset);
// Side cones
col += traceConeAO(origin, mix(normal, o1, angleMix), aperture, MAX_DISTANCE, offset);
col += traceConeAO(origin, mix(normal, o2, angleMix), aperture, MAX_DISTANCE, offset);
// Corners
col += traceConeAO(origin, mix(normal, -c1, angleMix), aperture, MAX_DISTANCE, offset);
col += traceConeAO(origin, mix(normal, -c2, angleMix), aperture, MAX_DISTANCE, offset);
#ifdef _VoxelAOCone9
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, c1, angleMix), aperture, MAX_DISTANCE, offset);
col += traceConeAO(origin, mix(normal, c2, angleMix), aperture, MAX_DISTANCE, offset);
return col / (9.0 * blendFac);
#else
#ifdef _VoxelCones1
return traceConeAO(voxels, origin, normal, aperture, MAX_DISTANCE, offset);
#endif
#ifdef _VoxelCones3
float col = traceConeAO(voxels, origin, normal, aperture, MAX_DISTANCE, offset);
col += traceConeAO(voxels, origin, mix(normal, o1, angleMix), aperture, MAX_DISTANCE, offset);
col += traceConeAO(voxels, origin, mix(normal, -c2, angleMix), aperture, MAX_DISTANCE, offset);
return col / (3.0 * blendFac);
#endif
#ifdef _VoxelCones5
float col = traceConeAO(voxels, origin, normal, aperture, MAX_DISTANCE, offset);
col += traceConeAO(voxels, origin, mix(normal, o1, angleMix), aperture, MAX_DISTANCE, offset);
col += traceConeAO(voxels, origin, mix(normal, o2, angleMix), aperture, MAX_DISTANCE, offset);
col += traceConeAO(voxels, origin, mix(normal, -c1, angleMix), aperture, MAX_DISTANCE, offset);
col += traceConeAO(voxels, origin, mix(normal, -c2, angleMix), aperture, MAX_DISTANCE, offset);
return col / (5.0 * blendFac);
#endif
#ifdef _VoxelCones9
float col = traceConeAO(voxels, origin, normal, aperture, MAX_DISTANCE, offset);
col += traceConeAO(voxels, origin, mix(normal, o1, angleMix), aperture, MAX_DISTANCE, offset);
col += traceConeAO(voxels, origin, mix(normal, o2, angleMix), aperture, MAX_DISTANCE, offset);
col += traceConeAO(voxels, origin, mix(normal, -c1, angleMix), aperture, MAX_DISTANCE, offset);
col += traceConeAO(voxels, origin, mix(normal, -c2, angleMix), aperture, MAX_DISTANCE, offset);
col += traceConeAO(voxels, origin, mix(normal, -o1, angleMix), aperture, MAX_DISTANCE, offset);
col += traceConeAO(voxels, origin, mix(normal, -o2, angleMix), aperture, MAX_DISTANCE, offset);
col += traceConeAO(voxels, origin, mix(normal, c1, angleMix), aperture, MAX_DISTANCE, offset);
col += traceConeAO(voxels, origin, mix(normal, c2, angleMix), aperture, MAX_DISTANCE, offset);
return col / (9.0 * blendFac);
#endif
return 0.0;
}

View file

@ -14,6 +14,13 @@ class RenderPathCreator {
return path;
}
#if (rp_gi != "Off")
static var voxels = "voxels";
static var voxelsLast = "voxels";
public static var voxelFrame = 0;
public static var voxelFreq = 6; // Revoxelizing frequency
#end
#if (rp_renderer == "Forward")
static function init() {
// #if rp_shadowmap // Auto-created
@ -70,6 +77,11 @@ class RenderPathCreator {
#if (rp_gi != "Off")
{
initGI();
#if arm_voxelgi_temporal
{
initGI("voxelsB");
}
#end
}
#end
}
@ -91,19 +103,30 @@ class RenderPathCreator {
#if (rp_gi != "Off")
{
if (path.voxelize()) {
path.clearImage("voxels", 0x00000000);
var voxelize = path.voxelize();
#if arm_voxelgi_temporal
voxelize = ++voxelFrame % voxelFreq == 0;
if (voxelize) {
voxels = voxels == "voxels" ? "voxelsB" : "voxels";
voxelsLast = voxels == "voxels" ? "voxelsB" : "voxels";
}
#end
if (voxelize) {
path.clearImage(voxels, 0x00000000);
path.setTarget("");
var res = getVoxelRes();
path.setViewport(res, res);
path.bindTarget("voxels", "voxels");
path.bindTarget(voxels, "voxels");
#if rp_shadowmap
{
path.bindTarget("shadowMap", "shadowMap");
}
#end
path.drawMeshes("voxel");
path.generateMipmaps("voxels");
path.generateMipmaps(voxels);
}
}
#end
@ -142,7 +165,12 @@ class RenderPathCreator {
#if (rp_gi != "Off")
{
path.bindTarget("voxels", "voxels");
path.bindTarget(voxels, "voxels");
#if arm_voxelgi_temporal
{
path.bindTarget(voxelsLast, "voxelsLast");
}
#end
}
#end
@ -218,6 +246,11 @@ class RenderPathCreator {
#if (rp_gi != "Off")
{
initGI();
#if arm_voxelgi_temporal
{
initGI("voxelsB");
}
#end
}
#end
@ -652,19 +685,30 @@ class RenderPathCreator {
}
#end
if (path.voxelize()) {
path.clearImage("voxels", 0x00000000);
var voxelize = path.voxelize();
#if arm_voxelgi_temporal
voxelize = ++voxelFrame % voxelFreq == 0;
if (voxelize) {
voxels = voxels == "voxels" ? "voxelsB" : "voxels";
voxelsLast = voxels == "voxels" ? "voxelsB" : "voxels";
}
#end
if (voxelize) {
path.clearImage(voxels, 0x00000000);
path.setTarget("");
var res = getVoxelRes();
path.setViewport(res, res);
path.bindTarget("voxels", "voxels");
path.bindTarget(voxels, "voxels");
#if ((rp_shadowmap) && (rp_gi == "Voxel GI"))
{
path.bindTarget("shadowMap", "shadowMap");
}
#end
path.drawMeshes("voxel");
path.generateMipmaps("voxels");
path.generateMipmaps(voxels);
}
}
#end
@ -681,7 +725,12 @@ class RenderPathCreator {
#end
#if (rp_gi != "Off")
{
path.bindTarget("voxels", "voxels");
path.bindTarget(voxels, "voxels");
#if arm_voxelgi_temporal
{
path.bindTarget(voxelsLast, "voxelsLast");
}
#end
}
#end
path.drawShader("shader_datas/deferred_indirect/deferred_indirect");
@ -720,7 +769,7 @@ class RenderPathCreator {
#if ((rp_voxelgi_shadows) || (rp_voxelgi_refraction))
{
path.bindTarget("voxels", "voxels");
path.bindTarget(voxels, "voxels");
}
#end
@ -1075,9 +1124,9 @@ class RenderPathCreator {
#end
#if (rp_gi != "Off")
static function initGI() {
static function initGI(tname = "voxels") {
var t = new RenderTargetRaw();
t.name = "voxels";
t.name = tname;
#if (rp_gi == "Voxel AO")
{
t.format = "R8";
@ -1097,6 +1146,7 @@ class RenderPathCreator {
t.height = res;
t.depth = Std.int(res * resZ);
t.is_image = true;
t.mipmaps = true;
path.createRenderTarget(t);
}
#end

View file

@ -383,8 +383,8 @@ def watch_compile(mode):
if result == 0:
bpy.data.worlds['Arm'].arm_recompile = False
state.compileproc_success = True
print('Finished in ' + str(time.time() - profile_time))
on_compiled(mode)
print('Project built in ' + str(time.time() - profile_time))
else:
state.compileproc_success = False
log.print_info('Build failed, check console')

View file

@ -122,29 +122,29 @@ def build_node_tree(world):
if voxelgi or voxelao:
assets.add_khafile_def('arm_voxelgi')
wrd.world_defs += '_VoxelCones' + wrd.arm_voxelgi_cones
if rpdat.arm_voxelgi_revoxelize:
assets.add_khafile_def('arm_voxelgi_revox')
if rpdat.arm_voxelgi_camera:
wrd.world_defs += '_VoxelGICam'
if rpdat.arm_voxelgi_temporal:
assets.add_khafile_def('arm_voxelgi_temporal')
wrd.world_defs += '_VoxelGITemporal'
wrd.world_defs += '_Rad' # Always do radiance for voxels
wrd.world_defs += '_Irr'
if voxelgi:
wrd.world_defs += '_VoxelGI'
if wrd.arm_voxelgi_diff_cones == '5':
wrd.world_defs += '_VoxelGICone5'
if rpdat.arm_voxelgi_shadows:
wrd.world_defs += '_VoxelGIDirect'
wrd.world_defs += '_VoxelGIShadow'
if rpdat.arm_voxelgi_refraction:
wrd.world_defs += '_VoxelGIDirect'
wrd.world_defs += '_VoxelGIRefract'
if rpdat.arm_voxelgi_emission:
wrd.world_defs += '_VoxelGIEmission'
elif voxelao:
wrd.world_defs += '_VoxelAO'
if wrd.arm_voxelgi_ao_cones == '9':
wrd.world_defs += '_VoxelAOCone9'
if voxelgi:
wrd.world_defs += '_VoxelGI'
if rpdat.arm_voxelgi_shadows:
wrd.world_defs += '_VoxelGIDirect'
wrd.world_defs += '_VoxelGIShadow'
if rpdat.arm_voxelgi_refraction:
wrd.world_defs += '_VoxelGIDirect'
wrd.world_defs += '_VoxelGIRefract'
if rpdat.arm_voxelgi_emission:
wrd.world_defs += '_VoxelGIEmission'
elif voxelao:
wrd.world_defs += '_VoxelAO'
if arm.utils.get_gapi().startswith('direct3d'): # Flip Y axis in drawQuad command
wrd.world_defs += '_InvY'

View file

@ -700,10 +700,10 @@ def make_forward_base(con_mesh, parse_opacity=False):
else:
frag.write('vec3 voxpos = wposition / voxelgiHalfExtents;')
if '_VoxelAO' in wrd.world_defs:
frag.write('indirect *= vec3(1.0 - traceAO(voxpos, n));')
# frag.write('indirect = vec3(1.0 - traceAO(voxpos, n));') # AO view
frag.write('indirect *= vec3(1.0 - traceAO(voxpos, n, voxels));')
# frag.write('indirect = vec3(1.0 - traceAO(voxpos, n, voxels));') # AO view
else:
frag.write('vec4 indirectDiffuse = traceDiffuse(voxpos, n);')
frag.write('vec4 indirectDiffuse = traceDiffuse(voxpos, n, voxels);')
frag.write('vec3 indirectSpecular = traceSpecular(voxpos, n, vVec, roughness);')
frag.write('indirectSpecular *= f0 * envBRDF.x + envBRDF.y;')
frag.write('indirect = indirect * voxelgiEnv + vec3(indirectDiffuse.rgb * voxelgiDiff * basecol + indirectSpecular * voxelgiSpec);')

View file

@ -226,16 +226,13 @@ def init_properties():
],
name="Preset", description="Render path preset", default='Deferred', update=props_renderpath.update_preset)
bpy.types.World.arm_voxelgi_diff = bpy.props.FloatProperty(name="Diffuse", description="", default=3.0, update=assets.invalidate_shader_cache)
bpy.types.World.arm_voxelgi_diff_cones = EnumProperty(
bpy.types.World.arm_voxelgi_cones = EnumProperty(
items=[('9', '9', '9'),
('5', '5', '5'),
('3', '3', '3'),
('1', '1', '1'),
],
name="Diffuse Cones", description="Number of cones to trace for VXGI", default='9', update=assets.invalidate_shader_cache)
bpy.types.World.arm_voxelgi_ao_cones = EnumProperty(
items=[('9', '9', '9'),
('5', '5', '5'),
],
name="AO Cones", description="Number of cones to trace for VXAO", default='5', update=assets.invalidate_shader_cache)
name="Cones", description="Number of cones to trace", default='5', 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="Occlusion", 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)

View file

@ -454,6 +454,7 @@ class ArmRPListItem(bpy.types.PropertyGroup):
rp_voxelgi_hdr = bpy.props.BoolProperty(name="HDR Voxels", description="Store voxels in RGBA64 instead of RGBA32", default=False, update=update_renderpath)
arm_voxelgi_dimensions = bpy.props.FloatProperty(name="Dimensions", description="Voxelization bounds",default=16, update=assets.invalidate_shader_cache)
arm_voxelgi_revoxelize = bpy.props.BoolProperty(name="Revoxelize", description="Revoxelize scene each frame", default=False, update=assets.invalidate_shader_cache)
arm_voxelgi_temporal = bpy.props.BoolProperty(name="Temporal Filter", description="Use temporal filtering to stabilize voxels", default=True, update=assets.invalidate_shader_cache)
# arm_voxelgi_multibounce = bpy.props.BoolProperty(name="Multi-bounce", description="Accumulate multiple light bounces", default=False, update=assets.invalidate_shader_cache)
arm_voxelgi_camera = bpy.props.BoolProperty(name="Dynamic Camera", description="Use camera as voxelization origin", default=False, update=assets.invalidate_shader_cache)
# arm_voxelgi_anisotropic = bpy.props.BoolProperty(name="Anisotropic", description="Use anisotropic voxels", default=False, update=update_renderpath)

View file

@ -515,7 +515,7 @@ class ArmoryGenerateNavmeshButton(bpy.types.Operator):
# TODO: build tilecache here
# Navmesh trait
# Navmesh trait
obj.arm_traitlist.add()
obj.arm_traitlist[-1].type_prop = 'Bundled Script'
obj.arm_traitlist[-1].class_name_prop = 'NavMesh'
@ -972,8 +972,9 @@ class ArmRenderPathPanel(bpy.types.Panel):
layout.prop(rpdat, 'arm_voxelgi_revoxelize')
if rpdat.arm_voxelgi_revoxelize:
layout.prop(rpdat, 'arm_voxelgi_camera')
layout.prop(rpdat, 'arm_voxelgi_temporal')
# layout.prop(rpdat, 'arm_voxelgi_anisotropic')
layout.prop(rpdat, 'arm_voxelgi_shadows')
# layout.prop(rpdat, 'arm_voxelgi_shadows')
if rpdat.rp_gi == 'Voxel GI':
layout.prop(rpdat, 'arm_voxelgi_refraction')
layout.prop(rpdat, 'arm_voxelgi_emission')
@ -1073,8 +1074,7 @@ class ArmRenderPropsPanel(bpy.types.Panel):
row = layout.row()
row.prop(wrd, 'arm_voxelgi_offset_shadow')
row.prop(wrd, 'arm_voxelgi_offset_refract')
layout.prop(wrd, 'arm_voxelgi_diff_cones')
layout.prop(wrd, 'arm_voxelgi_ao_cones')
layout.prop(wrd, 'arm_voxelgi_cones')
layout.label('SSAO')
row = layout.row()