This commit is contained in:
Lubos Lenco 2017-08-22 10:04:13 +02:00
parent 81b171925c
commit 4209b61d2c
9 changed files with 144 additions and 2 deletions

View file

@ -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

View file

@ -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;
}

View file

@ -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']

View file

@ -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'

View file

@ -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

View file

@ -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')

View file

@ -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'),

View file

@ -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')

View file

@ -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)) + """;