Shadowmap arrays

This commit is contained in:
luboslenco 2018-12-11 23:05:18 +01:00
parent d8f78638bd
commit 914030e7f4
12 changed files with 178 additions and 123 deletions

View file

@ -106,16 +106,10 @@ uniform vec2 cameraPlane;
#ifdef _ShadowMap
//!uniform vec2 lightProj;
// uniform samplerCubeShadow shadowMap0; //arm_dev
//!uniform samplerCube shadowMap0;
//!uniform samplerCube shadowMap1;
//!uniform samplerCube shadowMap2;
//!uniform samplerCube shadowMap3;
// uniform samplerCubeShadow shadowMapPoint[4]; //arm_dev
//!uniform samplerCube shadowMapPoint[4];
#ifdef _Spot
//!uniform sampler2D shadowMapSpot0;
//!uniform sampler2D shadowMapSpot1;
//!uniform sampler2D shadowMapSpot2;
//!uniform sampler2D shadowMapSpot3;
//!uniform sampler2D shadowMapSpot[4];
//!uniform mat4 LWVPSpot0;
//!uniform mat4 LWVPSpot1;
//!uniform mat4 LWVPSpot2;

View file

@ -197,6 +197,26 @@
"name": "spotData",
"link": "_spotData",
"ifdef": ["_SinglePoint", "_Spot"]
},
{
"name": "LWVPSpot0",
"link": "_biasLightWorldViewProjectionMatrixSpot0",
"ifdef": ["_Spot", "_ShadowMap"]
},
{
"name": "LWVPSpot1",
"link": "_biasLightWorldViewProjectionMatrixSpot1",
"ifdef": ["_Spot", "_ShadowMap"]
},
{
"name": "LWVPSpot2",
"link": "_biasLightWorldViewProjectionMatrixSpot2",
"ifdef": ["_Spot", "_ShadowMap"]
},
{
"name": "LWVPSpot3",
"link": "_biasLightWorldViewProjectionMatrixSpot3",
"ifdef": ["_Spot", "_ShadowMap"]
}
],
"vertex_shader": "../include/pass_viewray.vert.glsl",

View file

@ -45,16 +45,10 @@ uniform vec2 cameraPlane;
#ifdef _ShadowMap
//!uniform vec2 lightProj;
// uniform samplerCubeShadow shadowMap0; //arm_dev
//!uniform samplerCube shadowMap0;
//!uniform samplerCube shadowMap1;
//!uniform samplerCube shadowMap2;
//!uniform samplerCube shadowMap3;
// uniform samplerCubeShadow shadowMapPoint[4]; //arm_dev
//!uniform samplerCube shadowMapPoint[4];
#ifdef _Spot
//!uniform sampler2D shadowMapSpot0;
//!uniform sampler2D shadowMapSpot1;
//!uniform sampler2D shadowMapSpot2;
//!uniform sampler2D shadowMapSpot3;
//!uniform sampler2D shadowMapSpot[4];
//!uniform mat4 LWVPSpot0;
//!uniform mat4 LWVPSpot1;
//!uniform mat4 LWVPSpot2;

View file

@ -136,6 +136,26 @@
"name": "spotData",
"link": "_spotData",
"ifdef": ["_SinglePoint", "_Spot"]
},
{
"name": "LWVPSpot0",
"link": "_biasLightWorldViewProjectionMatrixSpot0",
"ifdef": ["_Spot", "_ShadowMap"]
},
{
"name": "LWVPSpot1",
"link": "_biasLightWorldViewProjectionMatrixSpot1",
"ifdef": ["_Spot", "_ShadowMap"]
},
{
"name": "LWVPSpot2",
"link": "_biasLightWorldViewProjectionMatrixSpot2",
"ifdef": ["_Spot", "_ShadowMap"]
},
{
"name": "LWVPSpot3",
"link": "_biasLightWorldViewProjectionMatrixSpot3",
"ifdef": ["_Spot", "_ShadowMap"]
}
],
"vertex_shader": "../include/pass_viewray.vert.glsl",

View file

@ -1,6 +1,6 @@
const int maxLights = 16;
const int maxLightsCluster = 8;
const int maxLightsCluster = 4; // Ensure fast loop unroll before going higher
const float clusterNear = 3.0;
const vec3 clusterSlices = vec3(16, 16, 16);

View file

@ -10,16 +10,10 @@
#ifdef _ShadowMap
uniform vec2 lightProj;
// uniform samplerCubeShadow shadowMap0; //arm_dev
uniform samplerCube shadowMap0;
uniform samplerCube shadowMap1;
uniform samplerCube shadowMap2;
uniform samplerCube shadowMap3;
// uniform samplerCubeShadow shadowMapPoint[4]; //arm_dev
uniform samplerCube shadowMapPoint[4];
#ifdef _Spot
uniform sampler2D shadowMapSpot0;
uniform sampler2D shadowMapSpot1;
uniform sampler2D shadowMapSpot2;
uniform sampler2D shadowMapSpot3;
uniform sampler2D shadowMapSpot[4];
uniform mat4 LWVPSpot0;
uniform mat4 LWVPSpot1;
uniform mat4 LWVPSpot2;
@ -57,8 +51,22 @@ vec3 sampleLight(const vec3 p, const vec3 n, const vec3 v, const float dotNV, co
direct *= smoothstep(spotB, spotA, spotEffect);
}
#ifdef _ShadowMap
vec4 lPos = LWVPSpot0 * vec4(p + n * bias * 10, 1.0);
if (lPos.w > 0.0) direct *= shadowTest(shadowMapSpot0, lPos.xyz / lPos.w, bias, shadowmapSize);
if (index == 0) {
vec4 lPos = LWVPSpot0 * vec4(p + n * bias * 10, 1.0);
direct *= shadowTest(shadowMapSpot[0], lPos.xyz / lPos.w, bias, shadowmapSize);
}
else if (index == 1) {
vec4 lPos = LWVPSpot1 * vec4(p + n * bias * 10, 1.0);
direct *= shadowTest(shadowMapSpot[1], lPos.xyz / lPos.w, bias, shadowmapSize);
}
else if (index == 2) {
vec4 lPos = LWVPSpot2 * vec4(p + n * bias * 10, 1.0);
direct *= shadowTest(shadowMapSpot[2], lPos.xyz / lPos.w, bias, shadowmapSize);
}
else if (index == 3) {
vec4 lPos = LWVPSpot3 * vec4(p + n * bias * 10, 1.0);
direct *= shadowTest(shadowMapSpot[3], lPos.xyz / lPos.w, bias, shadowmapSize);
}
#endif
return direct;
}
@ -88,10 +96,10 @@ vec3 sampleLight(const vec3 p, const vec3 n, const vec3 v, const float dotNV, co
#ifdef _ShadowMap
// Oh well..
if (index == 0) direct *= PCFCube(shadowMap0, ld, -l, bias, lightProj, n);
else if (index == 1) direct *= PCFCube(shadowMap1, ld, -l, bias, lightProj, n);
else if (index == 2) direct *= PCFCube(shadowMap2, ld, -l, bias, lightProj, n);
else if (index == 3) direct *= PCFCube(shadowMap3, ld, -l, bias, lightProj, n);
if (index == 0) direct *= PCFCube(shadowMapPoint[0], ld, -l, bias, lightProj, n);
else if (index == 1) direct *= PCFCube(shadowMapPoint[1], ld, -l, bias, lightProj, n);
else if (index == 2) direct *= PCFCube(shadowMapPoint[2], ld, -l, bias, lightProj, n);
else if (index == 3) direct *= PCFCube(shadowMapPoint[3], ld, -l, bias, lightProj, n);
#endif
return direct;

View file

@ -9,16 +9,10 @@
#ifdef _ShadowMap
uniform vec2 lightProj;
// uniform samplerCubeShadow shadowMap0; //arm_dev
uniform samplerCube shadowMap0;
uniform samplerCube shadowMap1;
uniform samplerCube shadowMap2;
uniform samplerCube shadowMap3;
// uniform samplerCubeShadow shadowMapPoint[4]; //arm_dev
uniform samplerCube shadowMapPoint[4];
#ifdef _Spot
uniform sampler2D shadowMapSpot0;
uniform sampler2D shadowMapSpot1;
uniform sampler2D shadowMapSpot2;
uniform sampler2D shadowMapSpot3;
uniform sampler2D shadowMapSpot[4];
uniform mat4 LWVPSpot0;
uniform mat4 LWVPSpot1;
uniform mat4 LWVPSpot2;
@ -56,9 +50,21 @@ vec3 sampleLight(const vec3 p, const vec3 n, const vec3 v, const float dotNV, co
direct *= smoothstep(spotB, spotA, spotEffect);
}
#ifdef _ShadowMap
vec4 lPos = LWVPSpot0 * vec4(p + n * bias * 10, 1.0);
if (lPos.w > 0.0) {
direct *= shadowTest(shadowMapSpot0, lPos.xyz / lPos.w, bias, shadowmapSize);
if (index == 0) {
vec4 lPos = LWVPSpot0 * vec4(p + n * bias * 10, 1.0);
direct *= shadowTest(shadowMapSpot[0], lPos.xyz / lPos.w, bias, shadowmapSize);
}
else if (index == 1) {
vec4 lPos = LWVPSpot1 * vec4(p + n * bias * 10, 1.0);
direct *= shadowTest(shadowMapSpot[1], lPos.xyz / lPos.w, bias, shadowmapSize);
}
else if (index == 2) {
vec4 lPos = LWVPSpot2 * vec4(p + n * bias * 10, 1.0);
direct *= shadowTest(shadowMapSpot[2], lPos.xyz / lPos.w, bias, shadowmapSize);
}
else if (index == 3) {
vec4 lPos = LWVPSpot3 * vec4(p + n * bias * 10, 1.0);
direct *= shadowTest(shadowMapSpot[3], lPos.xyz / lPos.w, bias, shadowmapSize);
}
#endif
return direct;
@ -66,10 +72,10 @@ vec3 sampleLight(const vec3 p, const vec3 n, const vec3 v, const float dotNV, co
#endif
#ifdef _ShadowMap
if (index == 0) direct *= PCFCube(shadowMap0, ld, -l, bias, lightProj, n);
else if (index == 1) direct *= PCFCube(shadowMap1, ld, -l, bias, lightProj, n);
else if (index == 2) direct *= PCFCube(shadowMap2, ld, -l, bias, lightProj, n);
else if (index == 3) direct *= PCFCube(shadowMap3, ld, -l, bias, lightProj, n);
if (index == 0) direct *= PCFCube(shadowMapPoint[0], ld, -l, bias, lightProj, n);
else if (index == 1) direct *= PCFCube(shadowMapPoint[1], ld, -l, bias, lightProj, n);
else if (index == 2) direct *= PCFCube(shadowMapPoint[2], ld, -l, bias, lightProj, n);
else if (index == 3) direct *= PCFCube(shadowMapPoint[3], ld, -l, bias, lightProj, n);
#endif
return direct;

View file

@ -57,35 +57,19 @@ class Inc {
break;
}
for (i in 0...pointIndex) {
var n = "shadowMap" + i;
var n = "shadowMapPoint[" + i + "]";
path.bindTarget(n, n);
}
for (i in 0...spotIndex) {
var n = "shadowMapSpot" + i;
var n = "shadowMapSpot[" + i + "]";
path.bindTarget(n, n);
}
// var target = shadowMapName(l);
// if (target == "shadowMapCube") {
// #if kha_webgl
// // Bind empty map to non-cubemap sampler
// path.bindTarget("arm_empty", "shadowMap");
// #end
// path.bindTarget("shadowMapCube", "shadowMapCube");
// }
// else {
// #if kha_webgl
// // Bind empty map to cubemap sampler
// path.bindTarget("arm_empty_cube", "shadowMapCube");
// #end
// path.bindTarget("shadowMap", "shadowMap");
// }
}
static function shadowMapName(l:iron.object.LightObject):String {
if (l.data.raw.type == "sun") return "shadowMap";
if (l.data.raw.type == "point") return "shadowMap" + pointIndex;
else return "shadowMapSpot" + spotIndex;
if (l.data.raw.type == "point") return "shadowMapPoint[" + pointIndex + "]";
else return "shadowMapSpot[" + spotIndex + "]";
}
static function getShadowMap(l:iron.object.LightObject):String {
@ -108,7 +92,9 @@ class Inc {
var sizew = path.light.data.raw.shadowmap_size;
var sizeh = sizew;
#if arm_csm // Cascades - atlas on x axis
sizew = sizew * iron.object.LightObject.cascadeCount;
if (l.data.raw.type == "sun") {
sizew = sizew * iron.object.LightObject.cascadeCount;
}
#end
var t = new RenderTargetRaw();
t.name = target;
@ -129,7 +115,6 @@ class Inc {
for (l in iron.Scene.active.lights) {
if (!l.visible || !l.data.raw.cast_shadow) continue;
path.light = l;
var shadowmap = Inc.getShadowMap(l);
var faces = l.data.raw.shadowmap_cube ? 6 : 1;
for (i in 0...faces) {

View file

@ -148,44 +148,50 @@ def parse_shader(sres, c, con, defs, lines, parse_attributes):
found = True
break
if found == False:
tu = {}
tu['name'] = cid
# sampler2D / image2D
if ctype.startswith('image') or ctype.startswith('uimage'):
tu['is_image'] = True
# Check for link
for l in c['links']:
if l['name'] == cid:
valid_link = True
if cid[-1] == ']': # Array of samplers - sampler2D mySamplers[2]
# Add individual units - mySamplers[0], mySamplers[1]
for i in range(int(cid[-2])):
tu = {}
con['texture_units'].append(tu)
tu['name'] = cid[:-2] + str(i) + ']'
else:
tu = {}
con['texture_units'].append(tu)
tu['name'] = cid
if ctype.startswith('image') or ctype.startswith('uimage'):
tu['is_image'] = True
# Check for link
for l in c['links']:
if l['name'] == cid:
valid_link = True
if 'ifdef' in l:
def_found = False
for d in defs:
for link_def in l['ifdef']:
if d == link_def:
def_found = True
if 'ifdef' in l:
def_found = False
for d in defs:
for link_def in l['ifdef']:
if d == link_def:
def_found = True
break
if def_found:
break
if not def_found:
valid_link = False
if 'ifndef' in l:
def_found = False
for d in defs:
for link_def in l['ifndef']:
if d == link_def:
def_found = True
break
if def_found:
break
if def_found:
break
if not def_found:
valid_link = False
valid_link = False
if 'ifndef' in l:
def_found = False
for d in defs:
for link_def in l['ifndef']:
if d == link_def:
def_found = True
break
if def_found:
break
if def_found:
valid_link = False
if valid_link:
tu['link'] = l['link']
break
con['texture_units'].append(tu)
if valid_link:
tu['link'] = l['link']
break
else: # Constant
if cid.find('[') != -1: # Float arrays
cid = cid.split('[')[0]
@ -196,6 +202,7 @@ def parse_shader(sres, c, con, defs, lines, parse_attributes):
break
if found == False:
const = {}
con['constants'].append(const)
const['type'] = ctype
const['name'] = cid
# Check for link
@ -230,7 +237,6 @@ def parse_shader(sres, c, con, defs, lines, parse_attributes):
if valid_link:
const['link'] = l['link']
break
con['constants'].append(const)
def make(res, base_name, json_data, fp, defs):
sres = {}

View file

@ -11,10 +11,7 @@ def write(vert, frag):
frag.add_uniform('sampler2D clustersData', link='_clustersData')
if is_shadows:
frag.add_uniform('vec2 lightProj', link='_lightPlaneProj', included=True)
frag.add_uniform('samplerCube shadowMap0', included=True)
frag.add_uniform('samplerCube shadowMap1', included=True)
frag.add_uniform('samplerCube shadowMap2', included=True)
frag.add_uniform('samplerCube shadowMap3', included=True)
frag.add_uniform('samplerCube shadowMapPoint[4]', included=True)
vert.add_out('vec4 wvpposition')
vert.write('wvpposition = gl_Position;')
# wvpposition.z / wvpposition.w
@ -27,8 +24,15 @@ def write(vert, frag):
frag.write('#endif')
if '_Spot' in wrd.world_defs:
frag.add_uniform('vec4 lightsArraySpot[maxLights]', link='_lightsArraySpot')
frag.write('int numSpots = int(texelFetch(clustersData, ivec2(clusterI, 1 + maxLightsCluster), 0).r * 255);')
frag.write('int numPoints = numLights - numSpots;')
if is_shadows:
frag.add_uniform('mat4 LWVPSpot0', link='_biasLightWorldViewProjectionMatrixSpot0', included=True)
frag.add_uniform('mat4 LWVPSpot1', link='_biasLightWorldViewProjectionMatrixSpot1', included=True)
frag.add_uniform('mat4 LWVPSpot2', link='_biasLightWorldViewProjectionMatrixSpot2', included=True)
frag.add_uniform('mat4 LWVPSpot3', link='_biasLightWorldViewProjectionMatrixSpot3', included=True)
frag.add_uniform('sampler2D shadowMapSpot[4]', included=True)
frag.write('for (int i = 0; i < min(numLights, maxLightsCluster); i++) {')
frag.write('int li = int(texelFetch(clustersData, ivec2(clusterI, i + 1), 0).r * 255);')

View file

@ -512,19 +512,28 @@ def make_forward_mobile(con_mesh):
frag.write('vec3 ld = pointPos - wposition;')
frag.write('vec3 l = normalize(ld);')
frag.write('float dotNL = max(dot(n, l), 0.0);')
# 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('sampler2D shadowMapSpot0', included=True)
if is_shadows:
if '_Spot' in wrd.world_defs:
frag.add_uniform('vec3 spotDir', link='_spotDirection')
frag.add_uniform('vec2 spotData', link='_spotData')
if is_shadows:
vert.add_out('vec4 spotPosition')
vert.add_uniform('mat4 LWVPSpot0', '_biasLightWorldViewProjectionMatrixSpot0')
vert.write('spotPosition = LWVPSpot0 * spos;')
frag.add_uniform('float pointBias', link='_pointShadowsBias')
frag.add_uniform('sampler2D shadowMapSpot[1]')
frag.write('if (spotPosition.w > 0.0) {')
frag.write(' vec3 lPos = spotPosition.xyz / spotPosition.w;')
frag.write(' const float texelSize = 1.0 / shadowmapSize.x;')
frag.write(' visibility = float(texture(shadowMap, lPos.xy).r + pointBias > lPos.z);')
frag.write('}')
elif is_shadows:
frag.add_include('std/shadows.glsl')
frag.add_uniform('vec2 lightProj', link='_lightPlaneProj')
frag.add_uniform('samplerCube shadowMap0')
frag.add_uniform('samplerCube shadowMapPoint[1]')
frag.add_uniform('float pointBias', link='_pointShadowsBias')
frag.write('const float s = shadowmapCubePcfSize;') # TODO: incorrect...
frag.write('float compare = lpToDepth(ld - n * pointBias * 80, lightProj);')
frag.write('visibility = step(compare, texture(shadowMap0, -l + n * pointBias * 80).r);')
frag.write('visibility = step(compare, texture(shadowMapPoint[0], -l + n * pointBias * 80).r);')
frag.write('direct += basecol * dotNL * pointCol * attenuate(distance(wposition, pointPos)) * visibility;')
@ -724,13 +733,17 @@ def make_forward_base(con_mesh, parse_opacity=False):
frag.add_uniform('vec3 pointCol', link='_pointColor')
if is_shadows:
frag.add_uniform('vec2 lightProj', link='_lightPlaneProj', included=True)
frag.add_uniform('samplerCube shadowMap0', included=True)
frag.add_uniform('samplerCube shadowMapPoint[1]', included=True)
frag.add_uniform('float pointBias', link='_pointShadowsBias')
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('sampler2D shadowMapSpot0', included=True)
frag.add_uniform('mat4 LWVPSpot0', '_biasLightWorldViewProjectionMatrixSpot0', included=True)
frag.add_uniform('mat4 LWVPSpot1', '_biasLightWorldViewProjectionMatrixSpot1', included=True)
frag.add_uniform('mat4 LWVPSpot2', '_biasLightWorldViewProjectionMatrixSpot2', included=True)
frag.add_uniform('mat4 LWVPSpot3', '_biasLightWorldViewProjectionMatrixSpot3', included=True)
frag.add_uniform('sampler2D shadowMapSpot[4]', included=True)
frag.write('direct += sampleLight(')
frag.write(' wposition, n, vVec, dotNV, pointPos, pointCol, albedo, roughness, specular, f0')
if is_shadows:
@ -782,7 +795,6 @@ def make_forward_base(con_mesh, parse_opacity=False):
frag.write('vec3 voxpos = wposition / voxelgiHalfExtents;')
if '_VoxelAO' in wrd.world_defs:
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, voxels);')
frag.write('indirect = indirect * voxelgiEnv + vec3(indirectDiffuse.rgb * voxelgiDiff * basecol);')

View file

@ -199,7 +199,13 @@ class Shader:
uname = ar[-1]
if utype.startswith('sampler') or utype.startswith('image') or utype.startswith('uimage'):
is_image = True if (utype.startswith('image') or utype.startswith('uimage')) else None
self.context.add_texture_unit(utype, uname, link=link, is_image=is_image)
if uname[-1] == ']': # Array of samplers - sampler2D mySamplers[2]
# Add individual units - mySamplers[0], mySamplers[1]
for i in range(int(uname[-2])):
uname_array = uname[:-2] + str(i) + ']'
self.context.add_texture_unit(utype, uname_array, link=link, is_image=is_image)
else:
self.context.add_texture_unit(utype, uname, link=link, is_image=is_image)
else:
# Prefer vec4[] for d3d to avoid padding
if ar[0] == 'float' and '[' in ar[1]: