Dynamic camera for voxels
This commit is contained in:
parent
68b7380785
commit
2985ea60d0
|
@ -27,9 +27,11 @@ uniform sampler2D gbuffer1;
|
|||
|
||||
#ifdef _VoxelGI
|
||||
//!uniform sampler3D voxels;
|
||||
uniform vec3 eyeSnap;
|
||||
#endif
|
||||
#ifdef _VoxelAO
|
||||
//!uniform sampler3D voxels;
|
||||
uniform vec3 eyeSnap;
|
||||
#endif
|
||||
|
||||
uniform float envmapStrength;
|
||||
|
@ -90,24 +92,27 @@ void main() {
|
|||
|
||||
#ifdef _VoxelGI
|
||||
#ifdef _VoxelGICam
|
||||
const float step = voxelgiDimensions / voxelgiResolution;
|
||||
vec3 eyeSnap = ivec3(eye / step) * step;
|
||||
vec3 wpos = (p - eyeSnap) / voxelgiDimensions;
|
||||
vec3 voxpos = (p - eyeSnap) / voxelgiHalfExtents;
|
||||
#else
|
||||
vec3 wpos = p / voxelgiDimensions;
|
||||
vec3 voxpos = p / voxelgiHalfExtents;
|
||||
#endif
|
||||
vec4 indirectDiffuse = traceDiffuse(wpos, n);
|
||||
vec3 indirectSpecular = traceSpecular(wpos, n, v, metrough.y);
|
||||
|
||||
vec4 indirectDiffuse = traceDiffuse(voxpos, n);
|
||||
|
||||
vec3 indirectSpecular = traceSpecular(voxpos, n, v, metrough.y);
|
||||
indirectSpecular *= f0 * envBRDF.x + envBRDF.y;
|
||||
indirectSpecular = vec3(0.0);
|
||||
|
||||
fragColor.rgb = indirectDiffuse.rgb * voxelgiDiff * g1.rgb + indirectSpecular * voxelgiSpec;
|
||||
|
||||
// if (!isInsideCube(voxpos)) fragColor = vec4(1.0); // Show bounds
|
||||
|
||||
#ifdef _SSAO
|
||||
fragColor.rgb *= texture(ssaotex, texCoord).r * 0.5 + 0.5;
|
||||
#endif
|
||||
|
||||
// float opacity = g1.a;
|
||||
// if (opacity < 1.0) fragColor.rgb = mix(indirectRefractiveLight(-v, n, vec3(1.0), opacity, wpos), fragColor.rgb, opacity);
|
||||
// if (opacity < 1.0) fragColor.rgb = mix(indirectRefractiveLight(-v, n, vec3(1.0), opacity, voxpos), fragColor.rgb, opacity);
|
||||
|
||||
// return;
|
||||
#endif
|
||||
|
@ -162,8 +167,14 @@ void main() {
|
|||
#endif
|
||||
|
||||
#ifdef _VoxelAO
|
||||
vec3 wpos = p / voxelgiDimensions;
|
||||
envl.rgb *= 1.0 - traceAO(wpos, n);
|
||||
|
||||
#ifdef _VoxelGICam
|
||||
vec3 voxpos = (p - eyeSnap) / voxelgiHalfExtents;
|
||||
#else
|
||||
vec3 voxpos = p / voxelgiHalfExtents;
|
||||
#endif
|
||||
|
||||
envl.rgb *= 1.0 - traceAO(voxpos, n);
|
||||
#endif
|
||||
|
||||
#ifdef _VoxelGI
|
||||
|
@ -171,4 +182,14 @@ void main() {
|
|||
#else
|
||||
fragColor.rgb = envl;
|
||||
#endif
|
||||
|
||||
// Show voxels
|
||||
// vec3 origin = vec3(texCoord * 2.0 - 1.0, 0.99);
|
||||
// vec3 direction = vec3(0.0, 0.0, -1.0);
|
||||
// vec4 color = vec4(0.0f);
|
||||
// for(uint step = 0; step < 400 && color.a < 0.99f; ++step) {
|
||||
// vec3 point = origin + 0.005 * step * direction;
|
||||
// color += (1.0f - color.a) * textureLod(voxels, point * 0.5 + 0.5, 0);
|
||||
// }
|
||||
// fragColor.rgb += color.rgb;
|
||||
}
|
||||
|
|
|
@ -7,11 +7,15 @@
|
|||
"compare_mode": "always",
|
||||
"cull_mode": "none",
|
||||
"links": [
|
||||
|
||||
{
|
||||
"name": "eye",
|
||||
"link": "_cameraPosition"
|
||||
},
|
||||
{
|
||||
"name": "eyeSnap",
|
||||
"link": "_cameraPositionSnap",
|
||||
"ifdef": ["_VoxelGI"]
|
||||
},
|
||||
{
|
||||
"name": "eyeLook",
|
||||
"link": "_cameraLook",
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
// https://research.nvidia.com/sites/default/files/publications/GIVoxels-pg2011-authors.pdf
|
||||
|
||||
const float MAX_DISTANCE = 1.73205080757;
|
||||
const float VOXEL_SIZE = 1.0 / voxelgiResolution;
|
||||
const float VOXEL_SIZE = 2.0 / voxelgiResolution;
|
||||
|
||||
uniform sampler3D voxels;
|
||||
|
||||
|
@ -73,7 +73,7 @@ vec4 traceDiffuse(const vec3 origin, const vec3 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;
|
||||
const float offset = 1.5 * VOXEL_SIZE;
|
||||
// Normal direction
|
||||
vec4 col = traceCone(origin, normal, aperture, MAX_DISTANCE, offset);
|
||||
// 4 side cones
|
||||
|
@ -90,7 +90,7 @@ vec4 traceDiffuse(const vec3 origin, const vec3 normal) {
|
|||
}
|
||||
|
||||
float traceShadow(const vec3 origin, const vec3 dir, const float aperture, const float targetDistance) {
|
||||
const float offset = 4 * VOXEL_SIZE;
|
||||
const float offset = 2 * VOXEL_SIZE;
|
||||
return traceCone(origin, dir, aperture, targetDistance, offset).a;
|
||||
}
|
||||
|
||||
|
@ -99,7 +99,7 @@ vec3 traceSpecular(const vec3 pos, const vec3 normal, const vec3 viewDir, const
|
|||
float specularAperture = clamp(tan((3.14159265 / 2) * rough * 0.75), 0.0174533, 3.14159265);
|
||||
vec3 specularDir = normalize(reflect(-viewDir, normal));
|
||||
// Clamp to 1 grad and pi, exponent is angle of cone in radians
|
||||
const float offset = 6 * VOXEL_SIZE;
|
||||
const float offset = 3 * VOXEL_SIZE;
|
||||
return traceCone(pos, specularDir, specularAperture, MAX_DISTANCE, offset).xyz;
|
||||
}
|
||||
|
||||
|
@ -109,7 +109,7 @@ vec3 traceRefraction(const vec3 pos, const vec3 normal, const vec3 viewDir, cons
|
|||
vec3 refraction = refract(viewDir, normal, 1.0 / ior);
|
||||
float rough = max(roughness, 0.03);
|
||||
float specularAperture = clamp(tan((3.14159265 / 2) * rough), 0.0174533, 3.14159265);
|
||||
const float offset = 3 * VOXEL_SIZE;
|
||||
const float offset = 1.5 * VOXEL_SIZE;
|
||||
return transmittance * traceCone(pos, refraction, specularAperture, MAX_DISTANCE, offset).xyz;
|
||||
}
|
||||
|
||||
|
@ -138,7 +138,7 @@ float traceAO(const vec3 origin, const vec3 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;
|
||||
const float offset = 1.5 * VOXEL_SIZE;
|
||||
// Normal direction
|
||||
float col = traceConeAO(origin, normal, aperture, MAX_DISTANCE, offset);
|
||||
// 4 side cones
|
||||
|
|
|
@ -39,7 +39,7 @@ def set_preset(self, context, preset):
|
|||
rpdat.rp_background = 'World'
|
||||
rpdat.rp_stereo = False
|
||||
rpdat.rp_greasepencil = False
|
||||
rpdat.rp_voxelgi = False
|
||||
rpdat.rp_gi = 'Off'
|
||||
rpdat.rp_render_to_texture = False
|
||||
rpdat.rp_supersampling = '1'
|
||||
rpdat.rp_antialiasing = 'None'
|
||||
|
@ -70,7 +70,7 @@ def set_preset(self, context, preset):
|
|||
rpdat.rp_background = 'World'
|
||||
rpdat.rp_stereo = False
|
||||
rpdat.rp_greasepencil = False
|
||||
rpdat.rp_voxelgi = False
|
||||
rpdat.rp_gi = 'Off'
|
||||
rpdat.rp_render_to_texture = True
|
||||
rpdat.rp_supersampling = '1'
|
||||
rpdat.rp_antialiasing = 'SMAA'
|
||||
|
@ -101,7 +101,7 @@ def set_preset(self, context, preset):
|
|||
rpdat.rp_background = 'World'
|
||||
rpdat.rp_stereo = False
|
||||
rpdat.rp_greasepencil = False
|
||||
rpdat.rp_voxelgi = False
|
||||
rpdat.rp_gi = 'Off'
|
||||
rpdat.rp_render_to_texture = True
|
||||
rpdat.rp_supersampling = '1'
|
||||
rpdat.rp_antialiasing = 'FXAA'
|
||||
|
@ -131,7 +131,7 @@ def set_preset(self, context, preset):
|
|||
rpdat.rp_background = 'World'
|
||||
rpdat.rp_stereo = False
|
||||
rpdat.rp_greasepencil = False
|
||||
rpdat.rp_voxelgi = True
|
||||
rpdat.rp_gi = 'Voxel GI'
|
||||
rpdat.rp_voxelgi_resolution = '256'
|
||||
rpdat.rp_render_to_texture = True
|
||||
rpdat.rp_supersampling = '2'
|
||||
|
@ -165,7 +165,7 @@ def set_preset(self, context, preset):
|
|||
rpdat.rp_background = 'World'
|
||||
rpdat.rp_stereo = False
|
||||
rpdat.rp_greasepencil = False
|
||||
rpdat.rp_voxelgi = False
|
||||
rpdat.rp_gi = 'Off'
|
||||
rpdat.rp_render_to_texture = True
|
||||
rpdat.rp_supersampling = '1'
|
||||
rpdat.rp_antialiasing = 'TAA'
|
||||
|
@ -196,7 +196,7 @@ def set_preset(self, context, preset):
|
|||
rpdat.rp_background = 'World'
|
||||
rpdat.rp_stereo = True
|
||||
rpdat.rp_greasepencil = False
|
||||
rpdat.rp_voxelgi = False
|
||||
rpdat.rp_gi = 'Off'
|
||||
rpdat.rp_render_to_texture = False
|
||||
rpdat.rp_supersampling = '1'
|
||||
rpdat.rp_antialiasing = 'None'
|
||||
|
@ -227,7 +227,7 @@ def set_preset(self, context, preset):
|
|||
rpdat.rp_background = 'Clear'
|
||||
rpdat.rp_stereo = False
|
||||
rpdat.rp_greasepencil = False
|
||||
rpdat.rp_voxelgi = False
|
||||
rpdat.rp_gi = 'Off'
|
||||
rpdat.rp_render_to_texture = False
|
||||
rpdat.rp_supersampling = '1'
|
||||
rpdat.rp_antialiasing = 'None'
|
||||
|
@ -393,11 +393,17 @@ def make_deferred(rpdat):
|
|||
nodes['Begin'].inputs[1].default_value = rpdat.rp_hdr
|
||||
nodes['Screen'].inputs[0].default_value = int(rpdat.rp_supersampling)
|
||||
|
||||
if rpdat.rp_voxelgi:
|
||||
if rpdat.rp_gi == 'Voxel GI':
|
||||
n = nodes['Image 3D Voxels']
|
||||
# if rpdat.rp_voxelgi_hdr:
|
||||
# n.inputs[4].default_value = 'RGBA64'
|
||||
links.new(nodes['Begin'].outputs[0], nodes['Branch Function Voxelize'].inputs[0])
|
||||
|
||||
# One lamp only for now - draw shadow map in advance
|
||||
links.new(nodes['Begin'].outputs[0], nodes['Set Target SM'].inputs[0])
|
||||
links.new(nodes['Draw Meshes SM'].outputs[0], nodes['Branch Function Voxelize'].inputs[0])
|
||||
l = nodes['Loop Lamps'].outputs[1].links[0]
|
||||
links.remove(l)
|
||||
links.new(nodes['Loop Lamps'].outputs[1], nodes['Deferred Light'].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
|
||||
|
@ -410,7 +416,7 @@ 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:
|
||||
elif rpdat.rp_gi == 'Voxel AO':
|
||||
n = nodes['Image 3D Voxels']
|
||||
# n.inputs[4].default_value = 'R8'
|
||||
links.new(nodes['Begin'].outputs[0], nodes['Branch Function Voxelize'].inputs[0])
|
||||
|
|
|
@ -107,9 +107,12 @@ def build_node_tree(world):
|
|||
if rpdat.rp_shadowmap == 'None':
|
||||
wrd.world_defs += '_NoShadows'
|
||||
assets.add_khafile_def('arm_no_shadows')
|
||||
if rpdat.rp_voxelgi:
|
||||
if rpdat.rp_shadowmap_cascades != '1':
|
||||
wrd.world_defs += '_CSM'
|
||||
assets.add_khafile_def('arm_csm')
|
||||
if rpdat.rp_gi == 'Voxel GI':
|
||||
voxelgi = True
|
||||
elif rpdat.rp_voxelao:
|
||||
elif rpdat.rp_gi == 'Voxel AO':
|
||||
voxelao = True
|
||||
if rpdat.rp_dfrs:
|
||||
wrd.world_defs += '_DFRS'
|
||||
|
|
|
@ -411,10 +411,7 @@ def make_forward_mobile(con_mesh):
|
|||
frag.add_uniform('vec3 lightPos', '_lampPosition')
|
||||
frag.add_uniform('float envmapStrength', link='_envmapStrength')
|
||||
|
||||
if '_NoShadows' in wrd.world_defs:
|
||||
is_shadows = False
|
||||
else:
|
||||
is_shadows = True
|
||||
is_shadows = not '_NoShadows' in wrd.world_defs
|
||||
|
||||
frag.write('float visibility = 1.0;')
|
||||
frag.write('float dotNL = max(dot(n, lightDir), 0.0);')
|
||||
|
@ -553,14 +550,8 @@ def make_forward_base(con_mesh, parse_opacity=False):
|
|||
frag.add_uniform('sampler2D senvmapBrdf', link='_envmapBrdf')
|
||||
frag.add_uniform('int envmapNumMipmaps', link='_envmapNumMipmaps')
|
||||
|
||||
if '_NoShadows' in wrd.world_defs:
|
||||
is_shadows = False
|
||||
else:
|
||||
is_shadows = True
|
||||
if '_PCSS' in wrd.world_defs:
|
||||
is_pcss = True
|
||||
else:
|
||||
is_pcss = False
|
||||
is_shadows = not '_NoShadows' in wrd.world_defs
|
||||
is_pcss = '_PCSS' in wrd.world_defs
|
||||
|
||||
frag.write('float visibility = 1.0;')
|
||||
frag.write('vec3 lp = lightPos - wposition;')
|
||||
|
|
|
@ -6,7 +6,7 @@ import arm.material.mat_utils as mat_utils
|
|||
|
||||
def make(context_id):
|
||||
rpdat = arm.utils.get_rp()
|
||||
if rpdat.rp_voxelgi:
|
||||
if rpdat.rp_gi == 'Voxel GI':
|
||||
return make_gi(context_id)
|
||||
else:
|
||||
return make_ao(context_id)
|
||||
|
@ -15,10 +15,7 @@ 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']
|
||||
|
||||
if '_NoShadows' in wrd.world_defs:
|
||||
is_shadows = False
|
||||
else:
|
||||
is_shadows = True
|
||||
is_shadows = not '_NoShadows' in wrd.world_defs
|
||||
|
||||
vert = con_voxel.make_vert()
|
||||
frag = con_voxel.make_frag()
|
||||
|
@ -46,13 +43,17 @@ def make_gi(context_id):
|
|||
frag.add_uniform('int lightType', '_lampType')
|
||||
frag.add_uniform('vec3 lightDir', '_lampDirection')
|
||||
|
||||
frag.write('if (!isInsideCube(wposition)) return;')
|
||||
frag.write('if (!isInsideCube(voxposition)) return;')
|
||||
frag.write('vec3 wposition = voxposition * voxelgiHalfExtents;')
|
||||
|
||||
frag.write('float visibility = 1.0;')
|
||||
frag.write('vec3 lp = lightPos - wposition * voxelgiDimensions;')
|
||||
frag.write('vec3 lp = lightPos - wposition;')
|
||||
frag.write('vec3 l;')
|
||||
frag.write('if (lightType == 0) l = lightDir;')
|
||||
frag.write('else { l = normalize(lp); visibility *= attenuate(distance(wposition * voxelgiDimensions, lightPos)); }')
|
||||
frag.write('else { l = normalize(lp); visibility *= attenuate(distance(wposition, lightPos)); }')
|
||||
|
||||
frag.write('float dotNL = max(dot(wnormal, l), 0.0);')
|
||||
frag.write('if (dotNL == 0.0) return;')
|
||||
|
||||
if is_shadows:
|
||||
frag.add_include('../../Shaders/std/shadows.glsl')
|
||||
|
@ -63,11 +64,12 @@ def make_gi(context_id):
|
|||
frag.add_uniform('float shadowsBias', '_lampShadowsBias')
|
||||
frag.write('if (lightShadow == 1 && lampPos.w > 0.0) {')
|
||||
frag.write(' vec3 lpos = lampPos.xyz / lampPos.w;')
|
||||
# frag.write(' if (lpos.x < 0.0 || lpos.y < 0.0 || lpos.x > 1.0 || lpos.y > 1.0) return;')
|
||||
# Note: shadowmap bound for sun lamp is tight behind the camera - can cause darkening no close surfaces
|
||||
frag.write(' if (texture(shadowMap, lpos.xy).r < lpos.z - shadowsBias) visibility = 0.0;')
|
||||
# frag.write(' visibility = PCF(lpos.xy, lpos.z - shadowsBias);')
|
||||
frag.write('}')
|
||||
frag.write('else if (lightShadow == 2) visibility *= float(texture(shadowMapCube, -l).r + shadowsBias > lpToDepth(lp, lightPlane));')
|
||||
else:
|
||||
frag.write('int lightShadow = 0;')
|
||||
|
||||
# frag.write('if (lightType == 2) {')
|
||||
# frag.write(' float spotEffect = dot(lightDir, l);')
|
||||
|
@ -106,7 +108,6 @@ def make_gi(context_id):
|
|||
if parse_opacity:
|
||||
frag.write('float opacity;')
|
||||
frag.write('float dotNV = 0.0;')
|
||||
frag.write('float dotNL = max(dot(wnormal, l), 0.0);')
|
||||
cycles.parse(mat_state.nodes, con_voxel, vert, frag, geom, tesc, tese, parse_opacity=parse_opacity, parse_displacement=False, basecol_only=True)
|
||||
|
||||
if not frag.contains('vec3 n ='):
|
||||
|
@ -121,12 +122,10 @@ def make_gi(context_id):
|
|||
vert.write('mpositionGeom = pos;')
|
||||
vert.write_pre = False
|
||||
|
||||
if rpdat.arm_voxelgi_camera:
|
||||
vert.add_uniform('vec3 eye', '_cameraPosition')
|
||||
vert.add_uniform('mat4 W', '_worldMatrix')
|
||||
vert.add_uniform('mat3 N', '_normalMatrix')
|
||||
|
||||
vert.add_out('vec3 wpositionGeom')
|
||||
vert.add_out('vec3 voxpositionGeom')
|
||||
vert.add_out('vec3 wnormalGeom')
|
||||
|
||||
vert.add_include('../../Shaders/compiled.glsl')
|
||||
|
@ -140,20 +139,19 @@ def make_gi(context_id):
|
|||
vert.write('texCoordGeom = tex;')
|
||||
|
||||
if rpdat.arm_voxelgi_camera:
|
||||
vert.write('const float step = voxelgiDimensions / voxelgiResolution;') # TODO: Pass as uniform
|
||||
vert.write('vec3 eyeSnap = ivec3(eye / step) * step;') # TODO: Pass as uniform
|
||||
vert.write('wpositionGeom = (vec3(W * vec4(pos, 1.0)) - eyeSnap) / voxelgiDimensions;')
|
||||
vert.add_uniform('vec3 eyeSnap', '_cameraPositionSnap')
|
||||
vert.write('voxpositionGeom = (vec3(W * vec4(pos, 1.0)) - eyeSnap) / voxelgiHalfExtents;')
|
||||
else:
|
||||
vert.write('wpositionGeom = vec3(W * vec4(pos, 1.0)) / voxelgiDimensions;')
|
||||
vert.write('voxpositionGeom = vec3(W * vec4(pos, 1.0)) / voxelgiHalfExtents;')
|
||||
vert.write('wnormalGeom = normalize(N * nor);')
|
||||
vert.write('gl_Position = vec4(0.0, 0.0, 0.0, 1.0);')
|
||||
# vert.write('gl_Position = vec4(0.0, 0.0, 0.0, 1.0);')
|
||||
|
||||
if is_shadows:
|
||||
vert.add_out('vec4 lampPosGeom')
|
||||
vert.add_uniform('mat4 LWVP', '_biasLampWorldViewProjectionMatrix')
|
||||
vert.write('lampPosGeom = LWVP * vec4(pos, 1.0);')
|
||||
|
||||
geom.add_out('vec3 wposition')
|
||||
geom.add_out('vec3 voxposition')
|
||||
geom.add_out('vec3 wnormal')
|
||||
if is_shadows:
|
||||
geom.add_out('vec4 lampPos')
|
||||
|
@ -164,11 +162,11 @@ def make_gi(context_id):
|
|||
if export_mpos:
|
||||
geom.add_out('vec3 mposition')
|
||||
|
||||
geom.write('const vec3 p1 = wpositionGeom[1] - wpositionGeom[0];')
|
||||
geom.write('const vec3 p2 = wpositionGeom[2] - wpositionGeom[0];')
|
||||
geom.write('const vec3 p1 = voxpositionGeom[1] - voxpositionGeom[0];')
|
||||
geom.write('const vec3 p2 = voxpositionGeom[2] - voxpositionGeom[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(' voxposition = voxpositionGeom[i];')
|
||||
geom.write(' wnormal = wnormalGeom[i];')
|
||||
if is_shadows:
|
||||
geom.write(' lampPos = lampPosGeom[i];')
|
||||
|
@ -179,13 +177,13 @@ def make_gi(context_id):
|
|||
if export_mpos:
|
||||
geom.write(' mposition = mpositionGeom[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(' gl_Position = vec4(voxposition.x, voxposition.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(' gl_Position = vec4(voxposition.y, voxposition.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(' gl_Position = vec4(voxposition.x, voxposition.z, 0.0, 1.0);')
|
||||
geom.write(' }')
|
||||
geom.write(' EmitVertex();')
|
||||
geom.write('}')
|
||||
|
@ -195,7 +193,7 @@ def make_gi(context_id):
|
|||
frag.write('vec3 color = basecol;')
|
||||
else:
|
||||
frag.write('vec3 color = basecol * visibility * lightColor * dotNL;')
|
||||
frag.write('vec3 voxel = wposition * 0.5 + vec3(0.5);')
|
||||
frag.write('vec3 voxel = voxposition * 0.5 + 0.5;')
|
||||
|
||||
# if rpdat.arm_material_model == 'Cycles':
|
||||
# frag.write('color = min(color * 0.9, vec3(0.9)) + min(color / 200.0, 0.1);') # Higher range to allow emission
|
||||
|
@ -205,33 +203,33 @@ def make_gi(context_id):
|
|||
# else:
|
||||
frag.write('color = clamp(color, vec3(0.0), vec3(1.0));')
|
||||
|
||||
# frag.write('uint val = convVec4ToRGBA8(vec4(color, 1.0) * 255);')
|
||||
# frag.write('imageAtomicMax(voxels, ivec3(voxelgiResolution * voxel), val);')
|
||||
frag.write('uint val = convVec4ToRGBA8(vec4(color, 1.0) * 255);')
|
||||
frag.write('imageAtomicMax(voxels, ivec3(voxelgiResolution * voxel), val);')
|
||||
|
||||
# frag.write('imageStore(voxels, ivec3(voxelgiResolution * voxel), vec4(color, 1.0));')
|
||||
# frag.write('imageAtomicRGBA8Avg(voxels, ivec3(voxelgiResolution * voxel), vec4(color, 1.0));')
|
||||
|
||||
frag.write('ivec3 coords = ivec3(voxelgiResolution * voxel);')
|
||||
if parse_opacity:
|
||||
frag.write('vec4 val = vec4(color, opacity);')
|
||||
else:
|
||||
frag.write('vec4 val = vec4(color, 1.0);')
|
||||
frag.write('val *= 255.0;')
|
||||
frag.write('uint newVal = encUnsignedNibble(convVec4ToRGBA8(val), 1);')
|
||||
frag.write('uint prevStoredVal = 0;')
|
||||
frag.write('uint currStoredVal;')
|
||||
# frag.write('int counter = 0;')
|
||||
# frag.write('while ((currStoredVal = imageAtomicCompSwap(voxels, coords, prevStoredVal, newVal)) != prevStoredVal && counter < 16) {')
|
||||
frag.write('while ((currStoredVal = imageAtomicCompSwap(voxels, coords, prevStoredVal, newVal)) != prevStoredVal) {')
|
||||
frag.write(' vec4 rval = convRGBA8ToVec4(currStoredVal & 0xFEFEFEFE);')
|
||||
frag.write(' uint n = decUnsignedNibble(currStoredVal);')
|
||||
frag.write(' rval = rval * n + val;')
|
||||
frag.write(' rval /= ++n;')
|
||||
frag.write(' rval = round(rval / 2) * 2;')
|
||||
frag.write(' newVal = encUnsignedNibble(convVec4ToRGBA8(rval), n);')
|
||||
frag.write(' prevStoredVal = currStoredVal;')
|
||||
# frag.write(' counter++;')
|
||||
frag.write('}')
|
||||
# frag.write('ivec3 coords = ivec3(voxelgiResolution * voxel);')
|
||||
# if parse_opacity:
|
||||
# frag.write('vec4 val = vec4(color, opacity);')
|
||||
# else:
|
||||
# frag.write('vec4 val = vec4(color, 1.0);')
|
||||
# frag.write('val *= 255.0;')
|
||||
# frag.write('uint newVal = encUnsignedNibble(convVec4ToRGBA8(val), 1);')
|
||||
# frag.write('uint prevStoredVal = 0;')
|
||||
# frag.write('uint currStoredVal;')
|
||||
# # frag.write('int counter = 0;')
|
||||
# # frag.write('while ((currStoredVal = imageAtomicCompSwap(voxels, coords, prevStoredVal, newVal)) != prevStoredVal && counter < 16) {')
|
||||
# frag.write('while ((currStoredVal = imageAtomicCompSwap(voxels, coords, prevStoredVal, newVal)) != prevStoredVal) {')
|
||||
# frag.write(' vec4 rval = convRGBA8ToVec4(currStoredVal & 0xFEFEFEFE);')
|
||||
# frag.write(' uint n = decUnsignedNibble(currStoredVal);')
|
||||
# frag.write(' rval = rval * n + val;')
|
||||
# frag.write(' rval /= ++n;')
|
||||
# frag.write(' rval = round(rval / 2) * 2;')
|
||||
# frag.write(' newVal = encUnsignedNibble(convVec4ToRGBA8(rval), n);')
|
||||
# frag.write(' prevStoredVal = currStoredVal;')
|
||||
# # frag.write(' counter++;')
|
||||
# frag.write('}')
|
||||
|
||||
# frag.write('val.rgb *= 255.0f;')
|
||||
# frag.write('uint newVal = convVec4ToRGBA8(val);')
|
||||
|
@ -269,38 +267,39 @@ def make_ao(context_id):
|
|||
frag.add_uniform('layout(RGBA8) image3D voxels')
|
||||
# frag.add_uniform('layout(R8) image3D voxels')
|
||||
|
||||
frag.write('if (!isInsideCube(wposition)) return;')
|
||||
frag.write('if (!isInsideCube(voxposition)) return;')
|
||||
frag.write('vec3 wposition = voxposition * voxelgiHalfExtents;')
|
||||
|
||||
if rpdat.arm_voxelgi_camera:
|
||||
vert.add_uniform('vec3 eye', '_cameraPosition')
|
||||
# if rpdat.arm_voxelgi_camera:
|
||||
# vert.add_uniform('vec3 eye', '_cameraPosition')
|
||||
vert.add_uniform('mat4 W', '_worldMatrix')
|
||||
|
||||
vert.add_out('vec3 wpositionGeom')
|
||||
vert.add_out('vec3 voxpositionGeom')
|
||||
|
||||
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);')
|
||||
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 wposition')
|
||||
geom.write('const vec3 p1 = wpositionGeom[1] - wpositionGeom[0];')
|
||||
geom.write('const vec3 p2 = wpositionGeom[2] - wpositionGeom[0];')
|
||||
geom.add_out('vec3 voxposition')
|
||||
geom.write('const vec3 p1 = voxpositionGeom[1] - voxpositionGeom[0];')
|
||||
geom.write('const vec3 p2 = voxpositionGeom[2] - voxpositionGeom[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(' voxposition = voxpositionGeom[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(' gl_Position = vec4(voxposition.x, voxposition.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(' gl_Position = vec4(voxposition.y, voxposition.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(' gl_Position = vec4(voxposition.x, voxposition.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('vec3 voxel = voxposition * 0.5 + vec3(0.5);')
|
||||
frag.write('imageStore(voxels, ivec3(voxelgiResolution * voxel), vec4(1.0));')
|
||||
|
||||
return con_voxel
|
||||
|
|
|
@ -27,7 +27,7 @@ def get_rpasses(material):
|
|||
# ar.append('depth')
|
||||
|
||||
rpdat = arm.utils.get_rp()
|
||||
vgirefract = rpdat.rp_voxelgi and rpdat.arm_voxelgi_refraction
|
||||
vgirefract = rpdat.rp_gi == 'Voxel GI' and rpdat.arm_voxelgi_refraction
|
||||
|
||||
if material.arm_decal:
|
||||
ar.append('decal')
|
||||
|
@ -39,7 +39,7 @@ def get_rpasses(material):
|
|||
ar.append('mesh')
|
||||
for con in add_mesh_contexts:
|
||||
ar.append(con)
|
||||
if rpdat.rp_voxelgi or rpdat.rp_voxelao:
|
||||
if rpdat.rp_gi == 'Voxel GI' or rpdat.rp_gi == 'Voxel AO':
|
||||
ar.append('voxel')
|
||||
if rpdat.rp_renderer == 'Deferred Plus':
|
||||
ar.append('rect')
|
||||
|
|
|
@ -80,8 +80,15 @@ class ArmRPListItem(bpy.types.PropertyGroup):
|
|||
('1024', '1024', '1024'),
|
||||
('2048', '2048', '2048'),
|
||||
('4096', '4096', '4096'),
|
||||
('8192', '8192', '8192')],
|
||||
('8192', '8192', '8192'),
|
||||
('16384', '16384', '16384'),],
|
||||
name="Shadow Map", description="Shadow map resolution", default='2048', update=update_renderpath)
|
||||
rp_shadowmap_cascades = EnumProperty(
|
||||
items=[('1', '1', '1'),
|
||||
('2', '2', '2'),
|
||||
('3', '3', '3'),
|
||||
('4', '4', '4')],
|
||||
name="Cascades", description="Shadow map cascades", default='3', update=update_renderpath)
|
||||
rp_supersampling = EnumProperty(
|
||||
items=[('1', '1X', '1X'),
|
||||
('2', '2X', '2X'),
|
||||
|
@ -138,8 +145,13 @@ class ArmRPListItem(bpy.types.PropertyGroup):
|
|||
rp_stereo = bpy.props.BoolProperty(name="Stereo", description="Stereo rendering", default=False, update=update_renderpath)
|
||||
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_gi = bpy.props.EnumProperty(
|
||||
items=[('Off', 'Off', 'Off'),
|
||||
('Voxel GI', 'Voxel GI', 'Voxel GI'),
|
||||
('Voxel AO', 'Voxel AO', 'Voxel AO')
|
||||
],
|
||||
name="Global Illumination", description="Dynamic global illumination", default='Off', update=update_renderpath)
|
||||
rp_voxelgi_resolution = bpy.props.EnumProperty(
|
||||
items=[('32', '32', '32'),
|
||||
('64', '64', '64'),
|
||||
|
@ -186,10 +198,10 @@ class ArmRPListItem(bpy.types.PropertyGroup):
|
|||
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_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="Camera", description="Use camera as voxelization origin", 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)
|
||||
arm_voxelgi_shadows = bpy.props.BoolProperty(name="Shadows", description="Use voxels to render shadows", default=False, update=update_renderpath)
|
||||
arm_voxelgi_refraction = bpy.props.BoolProperty(name="Refraction", description="Use voxels to render refraction", default=False, update=update_renderpath)
|
||||
arm_voxelgi_shadows = bpy.props.BoolProperty(name="Trace Shadows", description="Use voxels to render shadows", default=False, update=update_renderpath)
|
||||
arm_voxelgi_refraction = bpy.props.BoolProperty(name="Trace Refraction", description="Use voxels to render refraction", default=False, update=update_renderpath)
|
||||
arm_samples_per_pixel = EnumProperty(
|
||||
items=[('1', '1X', '1X'),
|
||||
('2', '2X', '2X'),
|
||||
|
|
|
@ -918,6 +918,8 @@ class ArmRenderPathPanel(bpy.types.Panel):
|
|||
layout.prop(rpdat, "rp_renderer")
|
||||
layout.prop(rpdat, "arm_material_model")
|
||||
layout.prop(rpdat, "rp_shadowmap")
|
||||
if rpdat.rp_shadowmap != 'None':
|
||||
layout.prop(rpdat, "rp_shadowmap_cascades")
|
||||
layout.prop(rpdat, "rp_translucency_state")
|
||||
layout.prop(rpdat, "rp_overlays_state")
|
||||
layout.prop(rpdat, "rp_decals_state")
|
||||
|
@ -927,19 +929,18 @@ class ArmRenderPathPanel(bpy.types.Panel):
|
|||
layout.prop(rpdat, "rp_hdr")
|
||||
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')
|
||||
else:
|
||||
layout.prop(rpdat, 'rp_voxelgi_resolution')
|
||||
layout.prop(rpdat, 'arm_voxelgi_dimensions')
|
||||
layout.prop(rpdat, 'arm_voxelgi_revoxelize')
|
||||
# layout.prop(rpdat, 'arm_voxelgi_camera')
|
||||
# layout.prop(rpdat, 'arm_voxelgi_multibounce')
|
||||
# layout.prop(rpdat, 'arm_voxelgi_anisotropic')
|
||||
layout.prop(rpdat, 'arm_voxelgi_shadows')
|
||||
layout.prop(rpdat, 'arm_voxelgi_refraction')
|
||||
# layout.prop(rpdat, 'rp_voxelgi_hdr')
|
||||
layout.prop(rpdat, 'rp_gi')
|
||||
if rpdat.rp_gi != 'Off':
|
||||
layout.prop(rpdat, 'rp_voxelgi_resolution')
|
||||
layout.prop(rpdat, 'arm_voxelgi_dimensions')
|
||||
layout.prop(rpdat, 'arm_voxelgi_revoxelize')
|
||||
if rpdat.arm_voxelgi_revoxelize:
|
||||
layout.prop(rpdat, 'arm_voxelgi_camera')
|
||||
# layout.prop(rpdat, 'arm_voxelgi_multibounce')
|
||||
# layout.prop(rpdat, 'arm_voxelgi_anisotropic')
|
||||
layout.prop(rpdat, 'arm_voxelgi_shadows')
|
||||
layout.prop(rpdat, 'arm_voxelgi_refraction')
|
||||
# layout.prop(rpdat, 'rp_voxelgi_hdr')
|
||||
|
||||
layout.separator()
|
||||
layout.prop(rpdat, "rp_render_to_texture")
|
||||
|
@ -951,7 +952,7 @@ class ArmRenderPathPanel(bpy.types.Panel):
|
|||
layout.prop(rpdat, "rp_ssao")
|
||||
layout.prop(rpdat, "rp_ssr")
|
||||
if rpdat.rp_ssr:
|
||||
layout.prop(rpdat, 'arm_ssr_half_res')
|
||||
layout.prop(rpdat, 'arm_ssr_half_res')
|
||||
# layout.prop(wrd, 'arm_ssao_half_res')
|
||||
# layout.prop(rpdat, "rp_dfao")
|
||||
# layout.prop(rpdat, "rp_dfrs")
|
||||
|
|
|
@ -246,6 +246,12 @@ class Main {
|
|||
}
|
||||
#end""")
|
||||
|
||||
if rpdat.rp_gi == 'Voxel GI' or rpdat.rp_gi == 'Voxel AO':
|
||||
f.write("""
|
||||
public static inline var voxelgiVoxelSize = """ + str(rpdat.arm_voxelgi_dimensions) + " / " + str(rpdat.rp_voxelgi_resolution) + """;
|
||||
public static inline var voxelgiHalfExtents = """ + str(round(rpdat.arm_voxelgi_dimensions / 2.0)) + """;
|
||||
""")
|
||||
|
||||
f.write("""
|
||||
public static function main() {
|
||||
iron.object.BoneAnimation.skinMaxBones = """ + str(wrd.arm_skin_max_bones) + """;
|
||||
|
@ -332,6 +338,7 @@ const float PI2 = PI * 2.0;
|
|||
const vec2 cameraPlane = vec2(""" + str(round(clip_start * 100) / 100) + """, """ + str(round(clip_end * 100) / 100) + """);
|
||||
const vec2 shadowmapSize = vec2(""" + str(shadowmap_size) + """, """ + str(shadowmap_size) + """);
|
||||
const float shadowmapCubePcfSize = """ + str(round(wrd.arm_pcfsize * 10000) / 10000) + """;
|
||||
const int shadowmapCascades = """ + str(rpdat.rp_shadowmap_cascades) + """;
|
||||
""")
|
||||
if rpdat.arm_clouds:
|
||||
f.write(
|
||||
|
@ -423,10 +430,10 @@ 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 or rpdat.rp_voxelao:
|
||||
if rpdat.rp_gi == 'Voxel GI' or rpdat.rp_gi == 'Voxel AO':
|
||||
f.write(
|
||||
"""const float voxelgiResolution = """ + str(rpdat.rp_voxelgi_resolution) + """;
|
||||
const float voxelgiDimensions = """ + str(round(rpdat.arm_voxelgi_dimensions)) + """;
|
||||
"""const int voxelgiResolution = """ + str(rpdat.rp_voxelgi_resolution) + """;
|
||||
const float voxelgiHalfExtents = """ + str(round(rpdat.arm_voxelgi_dimensions / 2.0)) + """;
|
||||
const float voxelgiDiff = """ + str(round(wrd.arm_voxelgi_diff * 100) / 100) + """;
|
||||
const float voxelgiSpec = """ + str(round(wrd.arm_voxelgi_spec * 100) / 100) + """;
|
||||
const float voxelgiOcc = """ + str(round(wrd.arm_voxelgi_occ * 100) / 100) + """;
|
||||
|
|
Loading…
Reference in a new issue