Capture cubemap shadows
This commit is contained in:
parent
d8044cf1df
commit
9afaaabbcb
|
@ -45,6 +45,7 @@ uniform mat4 LWVP;
|
|||
uniform vec3 lightColor;
|
||||
uniform vec3 lightDir;
|
||||
uniform vec3 lightPos;
|
||||
uniform vec2 lightPlane;
|
||||
uniform int lightType;
|
||||
uniform int lightShadow;
|
||||
uniform float shadowsBias;
|
||||
|
@ -111,8 +112,8 @@ float shadowTest(const vec3 lPos) {
|
|||
return PCF(lPos.xy, lPos.z - shadowsBias);
|
||||
#endif
|
||||
}
|
||||
float shadowTestCube(const vec3 lPos, const vec3 l) {
|
||||
return PCFCube(l, lPos.z - shadowsBias);
|
||||
float shadowTestCube(const vec3 lp, const vec3 l) {
|
||||
return PCFCube(lp, -l, shadowsBias, lightPlane);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -174,8 +175,8 @@ void main() {
|
|||
vec3 albedo = surfaceAlbedo(g1.rgb, metrough.x); // g1.rgb - basecolor
|
||||
vec3 f0 = surfaceF0(g1.rgb, metrough.x);
|
||||
|
||||
vec3 l;
|
||||
l = normalize(lightPos - p);
|
||||
vec3 lp = lightPos - p;
|
||||
vec3 l = normalize(lp);
|
||||
|
||||
float visibility = 1.0;
|
||||
#ifndef _NoShadows
|
||||
|
@ -185,8 +186,7 @@ void main() {
|
|||
if (lampPos.w > 0.0) visibility = shadowTest(lampPos.xyz / lampPos.w);
|
||||
}
|
||||
else if (lightShadow == 2) { // Cube
|
||||
vec4 lampPos = LWVP * vec4(p, 1.0);
|
||||
if (lampPos.w > 0.0) visibility = shadowTestCube(lampPos.xyz / lampPos.w, l);
|
||||
visibility = shadowTestCube(lp, l);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -21,6 +21,10 @@
|
|||
"name": "lightPos",
|
||||
"link": "_lampPosition"
|
||||
},
|
||||
{
|
||||
"name": "lightPlane",
|
||||
"link": "_lampPlane"
|
||||
},
|
||||
{
|
||||
"name": "lightDir",
|
||||
"link": "_lampDirection"
|
||||
|
|
|
@ -3,19 +3,19 @@
|
|||
uniform sampler2D shadowMap;
|
||||
uniform samplerCube shadowMapCube;
|
||||
|
||||
float texture2DCompare(const vec2 uv, const float compare){
|
||||
float shadowCompare(const vec2 uv, const float compare){
|
||||
float depth = texture(shadowMap, uv).r;
|
||||
return step(compare, depth);
|
||||
}
|
||||
|
||||
float texture2DShadowLerp(const vec2 uv, const float compare){
|
||||
float shadowLerp(const vec2 uv, const float compare){
|
||||
const vec2 texelSize = vec2(1.0) / shadowmapSize;
|
||||
vec2 f = fract(uv * shadowmapSize + 0.5);
|
||||
vec2 centroidUV = floor(uv * shadowmapSize + 0.5) / shadowmapSize;
|
||||
float lb = texture2DCompare(centroidUV, compare);
|
||||
float lt = texture2DCompare(centroidUV + texelSize * vec2(0.0, 1.0), compare);
|
||||
float rb = texture2DCompare(centroidUV + texelSize * vec2(1.0, 0.0), compare);
|
||||
float rt = texture2DCompare(centroidUV + texelSize, compare);
|
||||
float lb = shadowCompare(centroidUV, compare);
|
||||
float lt = shadowCompare(centroidUV + texelSize * vec2(0.0, 1.0), compare);
|
||||
float rb = shadowCompare(centroidUV + texelSize * vec2(1.0, 0.0), compare);
|
||||
float rt = shadowCompare(centroidUV + texelSize, compare);
|
||||
float a = mix(lb, lt, f.y);
|
||||
float b = mix(rb, rt, f.y);
|
||||
float c = mix(a, b, f.x);
|
||||
|
@ -27,22 +27,43 @@ float PCF(const vec2 uv, const float compare) {
|
|||
// for (int x = -1; x <= 1; x++){
|
||||
// for(int y = -1; y <= 1; y++){
|
||||
// vec2 off = vec2(x, y) / shadowmapSize;
|
||||
// result += texture2DShadowLerp(shadowmapSize, uv + off, compare);
|
||||
float result = texture2DShadowLerp(uv + (vec2(-1.0, -1.0) / shadowmapSize), compare);
|
||||
result += texture2DShadowLerp(uv + (vec2(-1.0, 0.0) / shadowmapSize), compare);
|
||||
result += texture2DShadowLerp(uv + (vec2(-1.0, 1.0) / shadowmapSize), compare);
|
||||
result += texture2DShadowLerp(uv + (vec2(0.0, -1.0) / shadowmapSize), compare);
|
||||
result += texture2DShadowLerp(uv, compare);
|
||||
result += texture2DShadowLerp(uv + (vec2(0.0, 1.0) / shadowmapSize), compare);
|
||||
result += texture2DShadowLerp(uv + (vec2(1.0, -1.0) / shadowmapSize), compare);
|
||||
result += texture2DShadowLerp(uv + (vec2(1.0, 0.0) / shadowmapSize), compare);
|
||||
result += texture2DShadowLerp(uv + (vec2(1.0, 1.0) / shadowmapSize), compare);
|
||||
// result += shadowLerp(shadowmapSize, uv + off, compare);
|
||||
float result = shadowLerp(uv + (vec2(-1.0, -1.0) / shadowmapSize), compare);
|
||||
result += shadowLerp(uv + (vec2(-1.0, 0.0) / shadowmapSize), compare);
|
||||
result += shadowLerp(uv + (vec2(-1.0, 1.0) / shadowmapSize), compare);
|
||||
result += shadowLerp(uv + (vec2(0.0, -1.0) / shadowmapSize), compare);
|
||||
result += shadowLerp(uv, compare);
|
||||
result += shadowLerp(uv + (vec2(0.0, 1.0) / shadowmapSize), compare);
|
||||
result += shadowLerp(uv + (vec2(1.0, -1.0) / shadowmapSize), compare);
|
||||
result += shadowLerp(uv + (vec2(1.0, 0.0) / shadowmapSize), compare);
|
||||
result += shadowLerp(uv + (vec2(1.0, 1.0) / shadowmapSize), compare);
|
||||
// }
|
||||
// }
|
||||
return result / 9.0;
|
||||
}
|
||||
|
||||
float PCFCube(const vec3 l, const float compare) {
|
||||
// No PCF yet..
|
||||
return float(texture(shadowMapCube, -l).r > compare);
|
||||
float lpToDepth(vec3 lp, const vec2 lightPlane) {
|
||||
float d = lightPlane.y - lightPlane.x;
|
||||
lp = abs(lp);
|
||||
float zcomp = max(lp.x, max(lp.y, lp.z));
|
||||
zcomp = (lightPlane.y + lightPlane.x) / (d) - (2.0 * lightPlane.y * lightPlane.x) / (d) / zcomp;
|
||||
return zcomp * 0.5 + 0.5;
|
||||
}
|
||||
|
||||
float PCFCube(const vec3 lp, const vec3 ml, const float bias, const vec2 lightPlane) {
|
||||
// return float(texture(shadowMapCube, ml).r + bias > lpToDepth(lp));
|
||||
|
||||
const float s = 0.001; // TODO: incorrect...
|
||||
float compare = lpToDepth(lp, lightPlane) - bias;
|
||||
float result = step(compare, texture(shadowMapCube, ml).r);
|
||||
result += step(compare, texture(shadowMapCube, ml + vec3(s, s, s)).r);
|
||||
result += step(compare, texture(shadowMapCube, ml + vec3(-s, s, s)).r);
|
||||
result += step(compare, texture(shadowMapCube, ml + vec3(s, -s, s)).r);
|
||||
result += step(compare, texture(shadowMapCube, ml + vec3(s, s, -s)).r);
|
||||
result += step(compare, texture(shadowMapCube, ml + vec3(-s, -s, s)).r);
|
||||
result += step(compare, texture(shadowMapCube, ml + vec3(s, -s, -s)).r);
|
||||
result += step(compare, texture(shadowMapCube, ml + vec3(-s, s, -s)).r);
|
||||
result += step(compare, texture(shadowMapCube, ml + vec3(-s, -s, -s)).r);
|
||||
result /= 9.0;
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -1193,31 +1193,6 @@ class ArmoryExporter:
|
|||
return space.region_3d.perspective_matrix
|
||||
return None
|
||||
|
||||
# def make_fake_omni_lamps(self, o, bobject):
|
||||
# # Look down
|
||||
# o['transform']['values'] = [1.0, 0.0, 0.0, bobject.location.x, 0.0, 1.0, 0.0, bobject.location.y, 0.0, 0.0, 1.0, bobject.location.z, 0.0, 0.0, 0.0, 1.0]
|
||||
# if not hasattr(o, 'children'):
|
||||
# o['children'] = []
|
||||
# # Make child lamps
|
||||
# for i in range(0, 5):
|
||||
# child_lamp = {}
|
||||
# child_lamp['name'] = o['name'] + '__' + str(i)
|
||||
# child_lamp['data_ref'] = o['data_ref']
|
||||
# child_lamp['type'] = 'lamp_object'
|
||||
# if i == 0:
|
||||
# mat = [0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0]
|
||||
# elif i == 1:
|
||||
# mat = [0.0, 0.0, -1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0]
|
||||
# elif i == 2:
|
||||
# mat = [0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0]
|
||||
# elif i == 3:
|
||||
# mat = [0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0]
|
||||
# elif i == 4:
|
||||
# mat = [-1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0]
|
||||
# child_lamp['transform'] = {}
|
||||
# child_lamp['transform']['values'] = mat
|
||||
# o['children'].append(child_lamp)
|
||||
|
||||
def export_object(self, bobject, scene, poseBone = None, parento = None):
|
||||
# This function exports a single object in the scene and includes its name,
|
||||
# object reference, material references (for meshes), and transform.
|
||||
|
@ -1366,10 +1341,6 @@ class ArmoryExporter:
|
|||
# Export the transform. If object is animated, then animation tracks are exported here
|
||||
self.export_object_transform(bobject, scene, o)
|
||||
|
||||
# 6 directional lamps
|
||||
# if type == NodeTypeLamp and objref.type == 'POINT' and objref.lamp_omni_shadows:
|
||||
# self.make_fake_omni_lamps(o, bobject)
|
||||
|
||||
# Viewport Camera - overwrite active camera matrix with viewport matrix
|
||||
if type == NodeTypeCamera and bpy.data.worlds['Arm'].arm_play_viewport_camera and self.scene.camera != None and bobject.name == self.scene.camera.name:
|
||||
viewport_matrix = self.get_viewport_view_matrix()
|
||||
|
@ -2075,6 +2046,9 @@ class ArmoryExporter:
|
|||
if lamp_size > 1:
|
||||
o['shadows_bias'] += 0.00001 * lamp_size
|
||||
o['lamp_size'] = lamp_size * 10 # Match to Cycles
|
||||
if objtype == 'POINT' and objref.lamp_omni_shadows:
|
||||
o['fov'] = 1.5708 # 90 deg
|
||||
o['shadowmap_cube'] = True
|
||||
|
||||
# Parse nodes
|
||||
# Emission only for now
|
||||
|
@ -2098,12 +2072,6 @@ class ArmoryExporter:
|
|||
o['color_texture'] = color_node.image.name
|
||||
break
|
||||
|
||||
# Fake omni shadows
|
||||
if objref.lamp_omni_shadows:
|
||||
o['fov'] = 1.5708 # 90 deg
|
||||
o['shadowmap_cube'] = True
|
||||
# o['strength'] /= 6
|
||||
|
||||
self.output['lamp_datas'].append(o)
|
||||
|
||||
def export_camera(self, objectRef):
|
||||
|
|
|
@ -225,6 +225,7 @@ const float PI = 3.1415926535;
|
|||
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 vec2 shadowmapCubeSize = shadowmapSize / 4.0;
|
||||
""")
|
||||
if wrd.generate_clouds:
|
||||
f.write(
|
||||
|
|
Loading…
Reference in a new issue