VoxelAO
This commit is contained in:
parent
81b171925c
commit
4209b61d2c
|
@ -14,6 +14,9 @@ precision mediump float;
|
|||
#ifdef _VoxelGI
|
||||
#include "../std/conetrace.glsl"
|
||||
#endif
|
||||
#ifdef _VoxelAO
|
||||
#include "../std/conetrace.glsl"
|
||||
#endif
|
||||
#ifdef _DFAO
|
||||
#include "../std/sdf.glsl"
|
||||
#endif
|
||||
|
@ -25,6 +28,9 @@ uniform sampler2D gbuffer1;
|
|||
#ifdef _VoxelGI
|
||||
//!uniform sampler3D voxels;
|
||||
#endif
|
||||
#ifdef _VoxelAO
|
||||
//!uniform sampler3D voxels;
|
||||
#endif
|
||||
|
||||
uniform float envmapStrength;
|
||||
#ifdef _Irr
|
||||
|
@ -153,6 +159,11 @@ void main() {
|
|||
envl.rgb *= dfao(p, n);
|
||||
#endif
|
||||
|
||||
#ifdef _VoxelAO
|
||||
vec3 wpos = p / voxelgiDimensions;
|
||||
envl.rgb *= 1.0 - traceAO(wpos, n);
|
||||
#endif
|
||||
|
||||
#ifdef _VoxelGI
|
||||
fragColor.rgb += envl * voxelgiEnv;
|
||||
#else
|
||||
|
|
|
@ -112,3 +112,44 @@ vec3 traceRefraction(const vec3 pos, const vec3 normal, const vec3 viewDir, cons
|
|||
const float offset = 3 * VOXEL_SIZE;
|
||||
return transmittance * traceCone(pos, refraction, specularAperture, MAX_DISTANCE, offset).xyz;
|
||||
}
|
||||
|
||||
float traceConeAO(const vec3 origin, vec3 dir, 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;
|
||||
while (sampleCol < 1.0 && dist < maxDist) {
|
||||
float mip = max(log2(diam * voxelgiResolution), 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) {
|
||||
const float TAN_22_5 = 0.55785173935;
|
||||
const float angleMix = 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 float offset = 3 * VOXEL_SIZE;
|
||||
// Normal direction
|
||||
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, 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, c2, angleMix), aperture, MAX_DISTANCE, offset);
|
||||
col += traceConeAO(origin, mix(normal, -c2, angleMix), aperture, MAX_DISTANCE, offset);
|
||||
return col / 9.0;
|
||||
}
|
||||
|
|
|
@ -409,6 +409,19 @@ def make_deferred(rpdat):
|
|||
if rpdat.arm_voxelgi_shadows or rpdat.arm_voxelgi_refraction:
|
||||
links.new(nodes['Image 3D Voxels'].outputs[0], nodes['Deferred Light'].inputs[4])
|
||||
links.new(nodes['Image 3D Voxels'].outputs[0], nodes['Deferred Light.001'].inputs[4])
|
||||
elif rpdat.rp_voxelao:
|
||||
n = nodes['Image 3D Voxels']
|
||||
# n.inputs[4].default_value = 'R8'
|
||||
links.new(nodes['Begin'].outputs[0], nodes['Branch Function Voxelize'].inputs[0])
|
||||
links.new(nodes['Merge Stages Voxelize'].outputs[0], nodes['Set Target Mesh'].inputs[0])
|
||||
res = int(rpdat.rp_voxelgi_resolution)
|
||||
n.inputs[1].default_value = res
|
||||
n.inputs[2].default_value = res
|
||||
n.inputs[3].default_value = res
|
||||
n = nodes['Set Viewport Voxels']
|
||||
n.inputs[1].default_value = res
|
||||
n.inputs[2].default_value = res
|
||||
links.new(nodes['Image 3D Voxels'].outputs[0], nodes['Deferred Indirect'].inputs[4])
|
||||
|
||||
if rpdat.rp_shadowmap != 'None':
|
||||
n = nodes['Shadow Map']
|
||||
|
|
|
@ -93,11 +93,14 @@ def build_node_tree(world):
|
|||
assets.add_embedded_data('iestexture.png')
|
||||
|
||||
voxelgi = False
|
||||
voxelao = False
|
||||
if rpdat.rp_shadowmap == 'None':
|
||||
wrd.world_defs += '_NoShadows'
|
||||
assets.add_khafile_def('arm_no_shadows')
|
||||
if rpdat.rp_voxelgi:
|
||||
voxelgi = True
|
||||
elif rpdat.rp_voxelao:
|
||||
voxelao = True
|
||||
if rpdat.rp_dfrs:
|
||||
wrd.world_defs += '_DFRS'
|
||||
assets.add_khafile_def('arm_sdf')
|
||||
|
@ -125,6 +128,13 @@ def build_node_tree(world):
|
|||
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'
|
||||
|
|
|
@ -5,6 +5,13 @@ import arm.material.mat_state as mat_state
|
|||
import arm.material.mat_utils as mat_utils
|
||||
|
||||
def make(context_id):
|
||||
rpdat = arm.utils.get_rp()
|
||||
if rpdat.rp_voxelgi:
|
||||
return make_gi(context_id)
|
||||
else:
|
||||
return make_ao(context_id)
|
||||
|
||||
def make_gi(context_id):
|
||||
con_voxel = mat_state.data.add_context({ 'name': context_id, 'depth_write': False, 'compare_mode': 'always', 'cull_mode': 'none', 'color_write_red': False, 'color_write_green': False, 'color_write_blue': False, 'color_write_alpha': False, 'conservative_raster': True })
|
||||
wrd = bpy.data.worlds['Arm']
|
||||
|
||||
|
@ -191,3 +198,60 @@ def make(context_id):
|
|||
# frag.write('}')
|
||||
|
||||
return con_voxel
|
||||
|
||||
def make_ao(context_id):
|
||||
con_voxel = mat_state.data.add_context({ 'name': context_id, 'depth_write': False, 'compare_mode': 'always', 'cull_mode': 'none', 'color_write_red': False, 'color_write_green': False, 'color_write_blue': False, 'color_write_alpha': False, 'conservative_raster': True })
|
||||
wrd = bpy.data.worlds['Arm']
|
||||
|
||||
vert = con_voxel.make_vert()
|
||||
frag = con_voxel.make_frag()
|
||||
geom = con_voxel.make_geom()
|
||||
tesc = None
|
||||
tese = None
|
||||
|
||||
geom.ins = vert.outs
|
||||
frag.ins = geom.outs
|
||||
|
||||
frag.add_include('../../Shaders/compiled.glsl')
|
||||
frag.add_include('../../Shaders/std/math.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.write('if (!isInsideCube(wposition)) return;')
|
||||
|
||||
if rpdat.arm_voxelgi_camera:
|
||||
vert.add_uniform('vec3 eye', '_cameraPosition')
|
||||
vert.add_uniform('mat4 W', '_worldMatrix')
|
||||
|
||||
vert.add_out('vec3 wpositionGeom')
|
||||
|
||||
vert.add_include('../../Shaders/compiled.glsl')
|
||||
vert.write('wpositionGeom = vec3(W * vec4(pos, 1.0)) / voxelgiDimensions;')
|
||||
vert.write('gl_Position = vec4(0.0, 0.0, 0.0, 1.0);')
|
||||
|
||||
geom.add_out('vec3 wposition')
|
||||
geom.write('const vec3 p1 = wpositionGeom[1] - wpositionGeom[0];')
|
||||
geom.write('const vec3 p2 = wpositionGeom[2] - wpositionGeom[0];')
|
||||
geom.write('const vec3 p = abs(cross(p1, p2));')
|
||||
geom.write('for (uint i = 0; i < 3; ++i) {')
|
||||
geom.write(' wposition = wpositionGeom[i];')
|
||||
geom.write(' if (p.z > p.x && p.z > p.y) {')
|
||||
geom.write(' gl_Position = vec4(wposition.x, wposition.y, 0.0, 1.0);')
|
||||
geom.write(' }')
|
||||
geom.write(' else if (p.x > p.y && p.x > p.z) {')
|
||||
geom.write(' gl_Position = vec4(wposition.y, wposition.z, 0.0, 1.0);')
|
||||
geom.write(' }')
|
||||
geom.write(' else {')
|
||||
geom.write(' gl_Position = vec4(wposition.x, wposition.z, 0.0, 1.0);')
|
||||
geom.write(' }')
|
||||
geom.write(' EmitVertex();')
|
||||
geom.write('}')
|
||||
geom.write('EndPrimitive();')
|
||||
|
||||
frag.write('vec3 voxel = wposition * 0.5 + vec3(0.5);')
|
||||
frag.write('imageStore(voxels, ivec3(voxelgiResolution * voxel), vec4(1.0));')
|
||||
|
||||
return con_voxel
|
||||
|
|
|
@ -39,7 +39,7 @@ def get_rpasses(material):
|
|||
ar.append('mesh')
|
||||
for con in add_mesh_contexts:
|
||||
ar.append(con)
|
||||
if rpdat.rp_voxelgi:
|
||||
if rpdat.rp_voxelgi or rpdat.rp_voxelao:
|
||||
ar.append('voxel')
|
||||
if rpdat.rp_renderer == 'Deferred Plus':
|
||||
ar.append('rect')
|
||||
|
|
|
@ -134,6 +134,7 @@ class ArmRPListItem(bpy.types.PropertyGroup):
|
|||
rp_greasepencil = bpy.props.BoolProperty(name="Grease Pencil", description="Render Grease Pencil data", default=False, update=update_renderpath)
|
||||
rp_ocean = bpy.props.BoolProperty(name="Ocean", description="Ocean pass", default=False, update=update_renderpath)
|
||||
rp_voxelgi = bpy.props.BoolProperty(name="Voxel GI", description="Voxel-based Global Illumination", default=False, update=update_renderpath)
|
||||
rp_voxelao = bpy.props.BoolProperty(name="Voxel AO", description="Voxel-based Ambient Occlussion", default=False, update=update_renderpath)
|
||||
rp_voxelgi_resolution = bpy.props.EnumProperty(
|
||||
items=[('32', '32', '32'),
|
||||
('64', '64', '64'),
|
||||
|
|
|
@ -883,6 +883,8 @@ class ArmRenderPathPanel(bpy.types.Panel):
|
|||
layout.prop(rpdat, "rp_stereo")
|
||||
layout.prop(rpdat, "rp_greasepencil")
|
||||
layout.prop(rpdat, 'rp_voxelgi')
|
||||
if not rpdat.rp_voxelgi:
|
||||
layout.prop(rpdat, 'rp_voxelao')
|
||||
layout.prop(rpdat, 'rp_voxelgi_resolution')
|
||||
layout.prop(rpdat, 'arm_voxelgi_dimensions')
|
||||
layout.prop(rpdat, 'arm_voxelgi_revoxelize')
|
||||
|
|
|
@ -385,7 +385,7 @@ const float compoDOFFstop = """ + str(round(bpy.data.cameras[0].gpu_dof.fstop *
|
|||
const float compoDOFLength = 160.0;
|
||||
""") # str(round(bpy.data.cameras[0].lens * 100) / 100)
|
||||
|
||||
if rpdat.rp_voxelgi:
|
||||
if rpdat.rp_voxelgi or rpdat.rp_voxelao:
|
||||
f.write(
|
||||
"""const float voxelgiResolution = """ + str(rpdat.rp_voxelgi_resolution) + """;
|
||||
const float voxelgiDimensions = """ + str(round(rpdat.arm_voxelgi_dimensions)) + """;
|
||||
|
|
Loading…
Reference in a new issue