Expose voxel shadow

This commit is contained in:
luboslenco 2019-01-27 19:12:00 +01:00
parent 58ceac834b
commit e17d06225c
8 changed files with 118 additions and 84 deletions

View file

@ -322,14 +322,11 @@ void main() {
// }
#endif
// #ifdef _VoxelGIShadow // #else
// #ifdef _VoxelGICam
// vec3 voxpos = (p - eyeSnap) / voxelgiHalfExtents;
// #else
// vec3 voxpos = p / voxelgiHalfExtents;
// #endif
// if (dotNL > 0.0) svisibility = max(0, 1.0 - traceShadow(voxels, voxpos, l, 0.1, 10.0, n));
// #endif
#ifdef _VoxelAOvar
#ifdef _VoxelShadow
svisibility *= 1.0 - traceShadow(voxels, voxpos, sunDir, 0.14, 5.0);
#endif
#endif
#ifdef _SSRS
float tvis = traceShadowSS(-sunDir, p, gbufferD, invVP, eye);
@ -369,6 +366,7 @@ void main() {
#endif // _Sun
#ifdef _SinglePoint
fragColor.rgb += sampleLight(
p, n, v, dotNV, pointPos, pointCol, albedo, metrough.y, occspec.y, f0
#ifdef _ShadowMap
@ -377,12 +375,19 @@ void main() {
#ifdef _Spot
, true, spotData.x, spotData.y, spotDir
#endif
#ifdef _VoxelAOvar
#ifdef _VoxelShadow
, voxels, voxpos
#endif
#endif
);
#ifdef _Spot
#ifdef _SSS
if (g0.a == 2.0) fragColor.rgb += fragColor.rgb * SSSSTransmittance(LWVPSpot0, p, n, normalize(pointPos - p), lightPlane.y, shadowMapSpot[0]);
#endif
#endif
#endif
#endif
#ifdef _Clusters

View file

@ -1,3 +1,7 @@
#ifndef _CONETRACE_GLSL_
#define _CONETRACE_GLSL_
// References
// https://github.com/Friduric/voxel-cone-tracing
// https://github.com/Cigg/Voxel-Cone-Tracing
@ -111,10 +115,6 @@ vec4 traceDiffuse(const vec3 origin, const vec3 normal, sampler3D voxels) {
return vec4(0.0);
}
float traceShadow(sampler3D voxels, const vec3 origin, const vec3 dir, const float aperture, const float targetDistance, const vec3 normal) {
return traceCone(voxels, origin + normal * 0.04 * voxelgiOffset, dir, aperture, targetDistance, normal).a;
}
vec3 traceSpecular(sampler3D voxels, const vec3 pos, const vec3 normal, const vec3 viewDir, const float roughness) {
float specularAperture = clamp(tan((3.14159265 / 2) * roughness * 0.75), 0.0174533 * 3.0, 3.14159265);
vec3 specularDir = normalize(reflect(-viewDir, normal));
@ -146,6 +146,10 @@ float traceConeAO(sampler3D voxels, const vec3 origin, vec3 dir, const float ape
return sampleCol;
}
float traceShadow(sampler3D voxels, const vec3 origin, const vec3 dir, const float aperture, const float targetDistance) {
return traceConeAO(voxels, origin, dir, aperture, targetDistance);
}
float traceAO(const vec3 origin, const vec3 normal, sampler3D voxels) {
const float angleMix = 0.5f;
const float aperture = 0.55785173935;
@ -196,3 +200,5 @@ float traceAO(const vec3 origin, const vec3 normal, sampler3D voxels) {
return 0.0;
}
#endif

View file

@ -7,6 +7,9 @@
#ifdef _ShadowMap
#include "std/shadows.glsl"
#endif
#ifdef _VoxelAOvar
#include "std/conetrace.glsl"
#endif
#ifdef _ShadowMap
#ifdef _SinglePoint
@ -39,6 +42,11 @@ vec3 sampleLight(const vec3 p, const vec3 n, const vec3 v, const float dotNV, co
#ifdef _Spot
, bool isSpot, float spotA, float spotB, vec3 spotDir
#endif
#ifdef _VoxelAOvar
#ifdef _VoxelShadow
#endif
, sampler3D voxels, vec3 voxpos
#endif
) {
vec3 ld = lp - p;
vec3 l = normalize(ld);
@ -53,6 +61,12 @@ vec3 sampleLight(const vec3 p, const vec3 n, const vec3 v, const float dotNV, co
direct *= lightCol;
direct *= attenuate(distance(p, lp));
#ifdef _VoxelAOvar
#ifdef _VoxelShadow
direct *= 1.0 - traceShadow(voxels, voxpos, l, 0.14, 5.0);
#endif
#endif
#ifdef _Spot
if (isSpot) {
float spotEffect = dot(spotDir, l); // lightDir

View file

@ -78,12 +78,12 @@ def add_world_defs():
# if rpdat.arm_voxelgi_bounces != "1":
# assets.add_khafile_def('rp_gi_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 += '_VoxelGIShadow'
if rpdat.rp_voxelgi_relight:
assets.add_khafile_def('rp_voxelgi_relight')
elif voxelao:
wrd.world_defs += '_VoxelAOvar' # Write a shader variant
if rpdat.arm_voxelgi_shadows:
wrd.world_defs += '_VoxelShadow'
if arm.utils.get_legacy_shaders() and not state.is_viewport:
wrd.world_defs += '_Legacy'
@ -94,6 +94,7 @@ def add_world_defs():
if bo.type == 'LIGHT':
light = bo.data
if light.type == 'AREA' and '_LTC' not in wrd.world_defs:
point_lights += 1
wrd.world_defs += '_LTC'
assets.add_khafile_def('arm_ltc')
if light.type == 'SUN' and '_Sun' not in wrd.world_defs:

View file

@ -55,6 +55,8 @@ def write(vert, frag):
frag.write(' , lightsArray[li * 2 + 1].w') # cutoff
frag.write(' , lightsArraySpot[li].w') # cutoff - exponent
frag.write(' , lightsArraySpot[li].xyz') # spotDir
if '_VoxelShadow' and '_VoxelAOvar':
frag.write(' , voxels, voxpos')
frag.write(');')
frag.write('}') # for numLights

View file

@ -568,73 +568,6 @@ def make_forward_base(con_mesh, parse_opacity=False, transluc_pass=False):
frag.write('vec3 albedo = surfaceAlbedo(basecol, metallic);')
frag.write('vec3 f0 = surfaceF0(basecol, metallic);')
frag.write('vec3 direct = vec3(0.0);')
frag.add_uniform('bool receiveShadow')
if '_Sun' in wrd.world_defs:
frag.add_uniform('vec3 sunCol', '_sunColor')
frag.add_uniform('vec3 sunDir', '_sunDirection')
frag.write('float svisibility = 1.0;')
frag.write('vec3 sh = normalize(vVec + sunDir);')
frag.write('float sdotNL = dot(n, sunDir);')
frag.write('float sdotNH = dot(n, sh);')
frag.write('float sdotVH = dot(vVec, sh);')
if is_shadows:
frag.add_uniform('sampler2DShadow shadowMap')
frag.add_uniform('float shadowsBias', '_sunShadowsBias')
frag.write('if (receiveShadow) {')
if '_CSM' in wrd.world_defs:
frag.add_include('std/shadows.glsl')
frag.add_uniform('vec4 casData[shadowmapCascades * 4 + 4]', '_cascadeData', included=True)
frag.add_uniform('vec3 eye', '_cameraPosition')
frag.write('svisibility = shadowTestCascade(shadowMap, eye, wposition + n * shadowsBias * 10, shadowsBias);')
else:
if tese != None:
tese.add_out('vec4 lightPosition')
tese.add_uniform('mat4 LVP', '_biasLightViewProjectionMatrix')
tese.write('lightPosition = LVP * vec4(wposition, 1.0);')
else:
if is_displacement:
vert.add_out('vec4 lightPosition')
vert.add_uniform('mat4 LVP', '_biasLightViewProjectionMatrix')
vert.write('lightPosition = LVP * vec4(wposition, 1.0);')
else:
vert.add_out('vec4 lightPosition')
vert.add_uniform('mat4 LWVP', '_biasLightWorldViewProjectionMatrix')
vert.write('lightPosition = LWVP * spos;')
frag.write('vec3 lPos = lightPosition.xyz / lightPosition.w;')
frag.write('const vec2 smSize = shadowmapSize;')
frag.write('svisibility = PCF(shadowMap, lPos.xy, lPos.z - shadowsBias, smSize);')
frag.write('}') # receiveShadow
# is_shadows
frag.write('direct += (lambertDiffuseBRDF(albedo, sdotNL) + specularBRDF(f0, roughness, sdotNL, sdotNH, dotNV, sdotVH) * specular) * sunCol * svisibility;')
# sun
if '_SinglePoint' in wrd.world_defs:
frag.add_uniform('vec3 pointPos', link='_pointPosition')
frag.add_uniform('vec3 pointCol', link='_pointColor')
if '_Spot' in wrd.world_defs:
frag.add_uniform('vec3 spotDir', link='_spotDirection')
frag.add_uniform('vec2 spotData', link='_spotData')
if is_shadows:
frag.add_uniform('float pointBias', link='_pointShadowsBias')
if '_Spot' in wrd.world_defs:
# Skip world matrix, already in world-space
frag.add_uniform('mat4 LWVPSpot0', link='_biasLightViewProjectionMatrixSpot0', included=True)
frag.add_uniform('sampler2DShadow shadowMapSpot[1]', included=True)
else:
frag.add_uniform('vec2 lightProj', link='_lightPlaneProj', included=True)
frag.add_uniform('samplerCubeShadow shadowMapPoint[1]', included=True)
frag.write('direct += sampleLight(')
frag.write(' wposition, n, vVec, dotNV, pointPos, pointCol, albedo, roughness, specular, f0')
if is_shadows:
frag.write(' , 0, pointBias')
if '_Spot' in wrd.world_defs:
frag.write(' , true, spotData.x, spotData.y, spotDir')
frag.write(');')
if '_Clusters' in wrd.world_defs:
make_cluster.write(vert, frag)
if '_Brdf' in wrd.world_defs:
frag.add_uniform('sampler2D senvmapBrdf', link='_envmapBrdf')
@ -685,6 +618,77 @@ def make_forward_base(con_mesh, parse_opacity=False, transluc_pass=False):
frag.write('indirect += indirectSpecular * voxelgiSpec * specular;')
frag.write('}')
frag.write('vec3 direct = vec3(0.0);')
frag.add_uniform('bool receiveShadow')
if '_Sun' in wrd.world_defs:
frag.add_uniform('vec3 sunCol', '_sunColor')
frag.add_uniform('vec3 sunDir', '_sunDirection')
frag.write('float svisibility = 1.0;')
frag.write('vec3 sh = normalize(vVec + sunDir);')
frag.write('float sdotNL = dot(n, sunDir);')
frag.write('float sdotNH = dot(n, sh);')
frag.write('float sdotVH = dot(vVec, sh);')
if is_shadows:
frag.add_uniform('sampler2DShadow shadowMap')
frag.add_uniform('float shadowsBias', '_sunShadowsBias')
frag.write('if (receiveShadow) {')
if '_CSM' in wrd.world_defs:
frag.add_include('std/shadows.glsl')
frag.add_uniform('vec4 casData[shadowmapCascades * 4 + 4]', '_cascadeData', included=True)
frag.add_uniform('vec3 eye', '_cameraPosition')
frag.write('svisibility = shadowTestCascade(shadowMap, eye, wposition + n * shadowsBias * 10, shadowsBias);')
else:
if tese != None:
tese.add_out('vec4 lightPosition')
tese.add_uniform('mat4 LVP', '_biasLightViewProjectionMatrix')
tese.write('lightPosition = LVP * vec4(wposition, 1.0);')
else:
if is_displacement:
vert.add_out('vec4 lightPosition')
vert.add_uniform('mat4 LVP', '_biasLightViewProjectionMatrix')
vert.write('lightPosition = LVP * vec4(wposition, 1.0);')
else:
vert.add_out('vec4 lightPosition')
vert.add_uniform('mat4 LWVP', '_biasLightWorldViewProjectionMatrix')
vert.write('lightPosition = LWVP * spos;')
frag.write('vec3 lPos = lightPosition.xyz / lightPosition.w;')
frag.write('const vec2 smSize = shadowmapSize;')
frag.write('svisibility = PCF(shadowMap, lPos.xy, lPos.z - shadowsBias, smSize);')
frag.write('}') # receiveShadow
if '_VoxelShadow' and '_VoxelAOvar':
frag.write('svisibility *= 1.0 - traceShadow(voxels, voxpos, sunDir, 0.14, 5.0);')
frag.write('direct += (lambertDiffuseBRDF(albedo, sdotNL) + specularBRDF(f0, roughness, sdotNL, sdotNH, dotNV, sdotVH) * specular) * sunCol * svisibility;')
# sun
if '_SinglePoint' in wrd.world_defs:
frag.add_uniform('vec3 pointPos', link='_pointPosition')
frag.add_uniform('vec3 pointCol', link='_pointColor')
if '_Spot' in wrd.world_defs:
frag.add_uniform('vec3 spotDir', link='_spotDirection')
frag.add_uniform('vec2 spotData', link='_spotData')
if is_shadows:
frag.add_uniform('float pointBias', link='_pointShadowsBias')
if '_Spot' in wrd.world_defs:
# Skip world matrix, already in world-space
frag.add_uniform('mat4 LWVPSpot0', link='_biasLightViewProjectionMatrixSpot0', included=True)
frag.add_uniform('sampler2DShadow shadowMapSpot[1]', included=True)
else:
frag.add_uniform('vec2 lightProj', link='_lightPlaneProj', included=True)
frag.add_uniform('samplerCubeShadow shadowMapPoint[1]', included=True)
frag.write('direct += sampleLight(')
frag.write(' wposition, n, vVec, dotNV, pointPos, pointCol, albedo, roughness, specular, f0')
if is_shadows:
frag.write(' , 0, pointBias')
if '_Spot' in wrd.world_defs:
frag.write(' , true, spotData.x, spotData.y, spotDir')
if '_VoxelShadow' and '_VoxelAOvar':
frag.write(' , voxels, voxpos')
frag.write(');')
if '_Clusters' in wrd.world_defs:
make_cluster.write(vert, frag)
if '_Emission' in wrd.world_defs:
frag.write('if (emission > 0.0) {')
frag.write(' direct = vec3(0.0);')

View file

@ -395,7 +395,7 @@ class ArmRPListItem(bpy.types.PropertyGroup):
# name="Bounces", description="Trace multiple light bounces", default='1', update=update_renderpath)
arm_voxelgi_camera: BoolProperty(name="Dynamic Camera", description="Use camera as voxelization origin", default=False, update=assets.invalidate_shader_cache)
# arm_voxelgi_anisotropic: BoolProperty(name="Anisotropic", description="Use anisotropic voxels", default=False, update=update_renderpath)
# arm_voxelgi_shadows: BoolProperty(name="Trace Shadows", description="Use voxels to render shadows", default=False, update=update_renderpath)
arm_voxelgi_shadows: BoolProperty(name="Shadows", description="Use voxels to render shadows", default=False, update=update_renderpath)
arm_samples_per_pixel: EnumProperty(
items=[('1', '1', '1'),
('2', '2', '2'),

View file

@ -817,7 +817,9 @@ class ArmRenderPathVoxelsPanel(bpy.types.Panel):
col2.enabled = rpdat.rp_gi == 'Voxel GI'
# col2.prop(rpdat, 'arm_voxelgi_bounces')
col2.prop(rpdat, 'rp_voxelgi_relight')
# col2.prop(rpdat, 'arm_voxelgi_shadows', text='Shadows')
col3 = col.column()
col3.enabled = rpdat.rp_gi == 'Voxel AO'
col3.prop(rpdat, 'arm_voxelgi_shadows')
col.prop(rpdat, 'arm_voxelgi_cones')
col.prop(rpdat, 'rp_voxelgi_resolution')
col.prop(rpdat, 'rp_voxelgi_resolution_z')