| @ -58,15 +58,7 @@ vec2 sampleCube(vec3 dir, out int faceIndex) { | ||||
| } | ||||
| #endif | ||||
|  | ||||
| vec3 PCF(sampler2DShadow shadowMap, | ||||
| 		#ifdef _ShadowMapTransparent | ||||
| 		sampler2D shadowMapTransparent, | ||||
| 		#endif | ||||
| 		const vec2 uv, const float compare, const vec2 smSize | ||||
| 		#ifdef _ShadowMapTransparent | ||||
| 		, const bool transparent | ||||
| 		#endif | ||||
| 		) { | ||||
| vec3 PCF(sampler2DShadow shadowMap, sampler2D shadowMapTransparent, const vec2 uv, const float compare, const vec2 smSize, const bool transparent) { | ||||
| 	vec3 result = vec3(0.0); | ||||
| 	result.x = texture(shadowMap, vec3(uv + (vec2(-1.0, -1.0) / smSize), compare)); | ||||
| 	result.x += texture(shadowMap, vec3(uv + (vec2(-1.0, 0.0) / smSize), compare)); | ||||
| @ -79,13 +71,11 @@ vec3 PCF(sampler2DShadow shadowMap, | ||||
| 	result.x += texture(shadowMap, vec3(uv + (vec2(1.0, 1.0) / smSize), compare)); | ||||
| 	result = result.xxx / 9.0; | ||||
|  | ||||
| 	#ifdef _ShadowMapTransparent | ||||
| 	if (transparent == false) { | ||||
| 		vec4 shadowmap_transparent = texture(shadowMapTransparent, uv); | ||||
| 		if (shadowmap_transparent.a < compare) | ||||
| 			result *= shadowmap_transparent.rgb; | ||||
| 	} | ||||
| 	#endif | ||||
|  | ||||
| 	return result; | ||||
| } | ||||
| @ -97,15 +87,41 @@ float lpToDepth(vec3 lp, const vec2 lightProj) { | ||||
| 	return zcomp * 0.5 + 0.5; | ||||
| } | ||||
|  | ||||
| vec3 PCFCube(samplerCubeShadow shadowMapCube, | ||||
| 			#ifdef _ShadowMapTransparent | ||||
| 			samplerCube shadowMapCubeTransparent, | ||||
| 			#endif | ||||
| 			const vec3 lp, vec3 ml, const float bias, const vec2 lightProj, const vec3 n | ||||
| 			#ifdef _ShadowMapTransparent | ||||
| 			, const bool transparent | ||||
| 			#endif | ||||
| 			) { | ||||
| #ifndef _ShadowMapAtlas | ||||
| vec3 PCFCube(samplerCubeShadow shadowMapCube, samplerCube shadowMapCubeTransparent, vec3 lp, vec3 ml, float bias, vec2 lightProj, vec3 n, const bool transparent) { | ||||
|     const float s = shadowmapCubePcfSize; | ||||
|     float compare = lpToDepth(lp, lightProj) - bias * 1.5; | ||||
|     ml = ml + n * bias * 20; | ||||
|     #ifdef _InvY | ||||
|     ml.y = -ml.y; | ||||
|     #endif | ||||
|      | ||||
|     float shadowFactor = 0.0; | ||||
|     shadowFactor = texture(shadowMapCube, vec4(ml, compare)); | ||||
|     shadowFactor += texture(shadowMapCube, vec4(ml + vec3(s, s, s), compare)); | ||||
|     shadowFactor += texture(shadowMapCube, vec4(ml + vec3(-s, s, s), compare)); | ||||
|     shadowFactor += texture(shadowMapCube, vec4(ml + vec3(s, -s, s), compare)); | ||||
|     shadowFactor += texture(shadowMapCube, vec4(ml + vec3(s, s, -s), compare)); | ||||
|     shadowFactor += texture(shadowMapCube, vec4(ml + vec3(-s, -s, s), compare)); | ||||
|     shadowFactor += texture(shadowMapCube, vec4(ml + vec3(s, -s, -s), compare)); | ||||
|     shadowFactor += texture(shadowMapCube, vec4(ml + vec3(-s, s, -s), compare)); | ||||
|     shadowFactor += texture(shadowMapCube, vec4(ml + vec3(-s, -s, -s), compare)); | ||||
|     shadowFactor /= 9.0; | ||||
|      | ||||
|     vec3 result = vec3(shadowFactor); | ||||
|      | ||||
|     if (transparent == false) { | ||||
|         vec4 shadowmap_transparent = texture(shadowMapCubeTransparent, ml); | ||||
|         if (shadowmap_transparent.a < compare) | ||||
|             result *= shadowmap_transparent.rgb; | ||||
|     } | ||||
|  | ||||
|     return result; | ||||
| } | ||||
| #endif | ||||
|  | ||||
| #ifdef _ShadowMapAtlas | ||||
| vec3 PCFCube(samplerCubeShadow shadowMapCube, samplerCube shadowMapCubeTransparent, const vec3 lp, vec3 ml, const float bias, const vec2 lightProj, const vec3 n, const bool transparent) { | ||||
| 	const float s = shadowmapCubePcfSize; // TODO: incorrect... | ||||
| 	float compare = lpToDepth(lp, lightProj) - bias * 1.5; | ||||
| 	ml = ml + n * bias * 20; | ||||
| @ -124,18 +140,16 @@ vec3 PCFCube(samplerCubeShadow shadowMapCube, | ||||
| 	result.x += texture(shadowMapCube, vec4(ml + vec3(-s, -s, -s), compare)); | ||||
| 	result = result.xxx / 9.0; | ||||
|  | ||||
| 	#ifdef _ShadowMapTransparent | ||||
| 	if (transparent == false) { | ||||
| 		vec4 shadowmap_transparent = texture(shadowMapCubeTransparent, ml); | ||||
| 		if (shadowmap_transparent.a < compare) | ||||
| 			result *= shadowmap_transparent.rgb; | ||||
| 	} | ||||
| 	#endif | ||||
|  | ||||
| 	return result; | ||||
| } | ||||
|  | ||||
| #ifdef _ShadowMapAtlas | ||||
|  | ||||
| // transform "out-of-bounds" coordinates to the correct face/coordinate system | ||||
| // https://www.khronos.org/opengl/wiki/File:CubeMapAxes.png | ||||
| vec2 transformOffsetedUV(const int faceIndex, out int newFaceIndex, vec2 uv) { | ||||
| @ -229,31 +243,21 @@ vec2 transformOffsetedUV(const int faceIndex, out int newFaceIndex, vec2 uv) { | ||||
| 	return uv; | ||||
| } | ||||
|  | ||||
| vec3 PCFFakeCube(sampler2DShadow shadowMap, | ||||
| 				#ifdef _ShadowMapTransparent | ||||
| 				sampler2D shadowMapTransparent, | ||||
| 				#endif | ||||
| 				const vec3 lp, vec3 ml, const float bias, const vec2 lightProj, const vec3 n, const int index | ||||
| 				#ifdef _ShadowMapTransparent | ||||
| 				, const bool transparent | ||||
| 				#endif | ||||
| 				) { | ||||
| vec3 PCFFakeCube(sampler2DShadow shadowMap, sampler2D shadowMapTransparent, const vec3 lp, vec3 ml, const float bias, const vec2 lightProj, const vec3 n, const int index, const bool transparent) { | ||||
| 	const vec2 smSize = smSizeUniform; // TODO: incorrect... | ||||
| 	const float compare = lpToDepth(lp, lightProj) - bias * 1.5; | ||||
| 	ml = ml + n * bias * 20; | ||||
|  | ||||
| 	int faceIndex = 0; | ||||
| 	const int lightIndex = index * 6; | ||||
| 	const vec2 uv = sampleCube(ml, faceIndex); | ||||
|  | ||||
| 	vec4 pointLightTile = pointLightDataArray[lightIndex + faceIndex]; // x: tile X offset, y: tile Y offset, z: tile size relative to atlas | ||||
| 	vec2 uvtiled = pointLightTile.z * uv + pointLightTile.xy; | ||||
| 	#ifdef _FlipY | ||||
| 	uvtiled.y = 1.0 - uvtiled.y; // invert Y coordinates for direct3d coordinate system | ||||
| 	#endif | ||||
|  | ||||
| 	if (any(lessThan(uvtiled, vec2(0.0))) || any(greaterThan(uvtiled, vec2(1.0)))) { | ||||
| 		return vec3(1.0); // Handle edge cases by returning full light | ||||
| 	} | ||||
|  | ||||
| 	vec3 result = vec3(0.0); | ||||
| 	result.x += texture(shadowMap, vec3(uvtiled, compare)); | ||||
| 	// soft shadowing | ||||
| @ -266,6 +270,14 @@ vec3 PCFFakeCube(sampler2DShadow shadowMap, | ||||
| 	#endif | ||||
| 	result.x += texture(shadowMap, vec3(uvtiled, compare)); | ||||
|  | ||||
| 	uvtiled = transformOffsetedUV(faceIndex, newFaceIndex, vec2(uv + (vec2(-1.0, 1.0) / smSize))); | ||||
| 	pointLightTile = pointLightDataArray[lightIndex + newFaceIndex]; | ||||
| 	uvtiled = pointLightTile.z * uvtiled + pointLightTile.xy; | ||||
| 	#ifdef _FlipY | ||||
| 	uvtiled.y = 1.0 - uvtiled.y; // invert Y coordinates for direct3d coordinate system | ||||
| 	#endif | ||||
| 	result.x += texture(shadowMap, vec3(uvtiled, compare)); | ||||
|  | ||||
| 	uvtiled = transformOffsetedUV(faceIndex, newFaceIndex, vec2(uv + (vec2(0.0, -1.0) / smSize))); | ||||
| 	pointLightTile = pointLightDataArray[lightIndex + newFaceIndex]; | ||||
| 	uvtiled = pointLightTile.z * uvtiled + pointLightTile.xy; | ||||
| @ -322,47 +334,30 @@ vec3 PCFFakeCube(sampler2DShadow shadowMap, | ||||
| 	uvtiled.y = 1.0 - uvtiled.y; // invert Y coordinates for direct3d coordinate system | ||||
| 	#endif | ||||
|  | ||||
| 	#ifdef _ShadowMapTransparent | ||||
| 	if (transparent == false) { | ||||
| 		vec4 shadowmap_transparent = texture(shadowMapTransparent, uvtiled); | ||||
| 		if (shadowmap_transparent.a < compare) | ||||
| 			result *= shadowmap_transparent.rgb; | ||||
| 	} | ||||
| 	#endif | ||||
|  | ||||
| 	return result; | ||||
| } | ||||
| #endif | ||||
|  | ||||
| vec3 shadowTest(sampler2DShadow shadowMap, | ||||
| 				#ifdef _ShadowMapTransparent | ||||
| 				sampler2D shadowMapTransparent, | ||||
| 				#endif | ||||
| 				const vec3 lPos, const float shadowsBias | ||||
| 				#ifdef _ShadowMapTransparent | ||||
| 				, const bool transparent | ||||
| 				#endif | ||||
| 				) { | ||||
| vec3 shadowTest(sampler2DShadow shadowMap, sampler2D shadowMapTransparent, const vec3 lPos, const float shadowsBias, const bool transparent) { | ||||
| 	#ifdef _SMSizeUniform | ||||
| 	vec2 smSize = smSizeUniform; | ||||
| 	#else | ||||
| 	const vec2 smSize = shadowmapSize; | ||||
| 	#endif | ||||
| 	if (lPos.x < 0.0 || lPos.y < 0.0 || lPos.x > 1.0 || lPos.y > 1.0) return vec3(1.0); | ||||
| 	return PCF(shadowMap, | ||||
| 				#ifdef _ShadowMapTransparent | ||||
| 				shadowMapTransparent, | ||||
| 				#endif | ||||
| 				lPos.xy, lPos.z - shadowsBias, smSize | ||||
| 				#ifdef _ShadowMapTransparent | ||||
| 				, transparent | ||||
| 				#endif | ||||
| 				); | ||||
| 	return PCF(shadowMap, shadowMapTransparent, lPos.xy, lPos.z - shadowsBias, smSize, transparent); | ||||
| } | ||||
|  | ||||
| #ifdef _CSM | ||||
| mat4 getCascadeMat(const float d, out int casi, out int casIndex) { | ||||
| 	const int c = shadowmapCascades; | ||||
|  | ||||
| 	// Get cascade index | ||||
| 	// TODO: use bounding box slice selection instead of sphere | ||||
| 	const vec4 ci = vec4(float(c > 0), float(c > 1), float(c > 2), float(c > 3)); | ||||
| @ -378,26 +373,21 @@ mat4 getCascadeMat(const float d, out int casi, out int casIndex) { | ||||
| 		float(d > casData[c * 4].z), | ||||
| 		float(d > casData[c * 4].w)); | ||||
| 	casi = int(min(dot(ci, comp), c)); | ||||
|  | ||||
| 	// Get cascade mat | ||||
| 	casIndex = casi * 4; | ||||
|  | ||||
| 	return mat4( | ||||
| 		casData[casIndex    ], | ||||
| 		casData[casIndex + 1], | ||||
| 		casData[casIndex + 2], | ||||
| 		casData[casIndex + 3]); | ||||
|  | ||||
| 	// if (casIndex == 0) return mat4(casData[0], casData[1], casData[2], casData[3]); | ||||
| 	// .. | ||||
| } | ||||
|  | ||||
| vec3 shadowTestCascade(sampler2DShadow shadowMap, | ||||
| 					   #ifdef _ShadowMapTransparent | ||||
| 					   sampler2D shadowMapTransparent, | ||||
| 					   #endif | ||||
| 					   const vec3 eye, const vec3 p, const float shadowsBias | ||||
| 					   #ifdef _ShadowMapTransparent | ||||
| 					   , const bool transparent | ||||
| 					   #endif | ||||
| 					   ) { | ||||
| vec3 shadowTestCascade(sampler2DShadow shadowMap, sampler2D shadowMapTransparent, const vec3 eye, const vec3 p, const float shadowsBias, const bool transparent) { | ||||
| 	#ifdef _SMSizeUniform | ||||
| 	vec2 smSize = smSizeUniform; | ||||
| 	#else | ||||
| @ -405,22 +395,16 @@ vec3 shadowTestCascade(sampler2DShadow shadowMap, | ||||
| 	#endif | ||||
| 	const int c = shadowmapCascades; | ||||
| 	float d = distance(eye, p); | ||||
|  | ||||
| 	int casi; | ||||
| 	int casIndex; | ||||
| 	mat4 LWVP = getCascadeMat(d, casi, casIndex); | ||||
|  | ||||
| 	vec4 lPos = LWVP * vec4(p, 1.0); | ||||
| 	lPos.xyz /= lPos.w; | ||||
|  | ||||
| 	vec3 visibility = vec3(1.0); | ||||
| 	if (lPos.w > 0.0) visibility = PCF(shadowMap, | ||||
| 									#ifdef _ShadowMapTransparent | ||||
| 									shadowMapTransparent, | ||||
| 									#endif | ||||
| 									lPos.xy, lPos.z - shadowsBias, smSize | ||||
| 									#ifdef _ShadowMapTransparent | ||||
| 									, transparent | ||||
| 									#endif | ||||
| 									); | ||||
| 	if (lPos.w > 0.0) visibility = PCF(shadowMap, shadowMapTransparent, lPos.xy, lPos.z - shadowsBias, smSize, transparent); | ||||
|  | ||||
| 	// Blend cascade | ||||
| 	// https://github.com/TheRealMJP/Shadows | ||||
| @ -439,20 +423,13 @@ vec3 shadowTestCascade(sampler2DShadow shadowMap, | ||||
| 		vec4 lPos2 = LWVP2 * vec4(p, 1.0); | ||||
| 		lPos2.xyz /= lPos2.w; | ||||
| 		vec3 visibility2 = vec3(1.0); | ||||
| 		if (lPos2.w > 0.0) visibility2 = PCF(shadowMap, | ||||
| 											#ifdef _ShadowMapTransparent | ||||
| 											shadowMapTransparent, | ||||
| 											#endif | ||||
| 											lPos.xy, lPos.z - shadowsBias, smSize | ||||
| 											#ifdef _ShadowMapTransparent | ||||
| 											, transparent | ||||
| 											#endif | ||||
| 											); | ||||
| 		if (lPos2.w > 0.0) visibility2 = PCF(shadowMap, shadowMapTransparent, lPos2.xy, lPos2.z - shadowsBias, smSize, transparent); | ||||
|  | ||||
| 		float lerpAmt = smoothstep(0.0, blendThres, splitDist); | ||||
| 		return mix(visibility2, visibility, lerpAmt); | ||||
| 	} | ||||
| 	return visibility; | ||||
|  | ||||
| 	// Visualize cascades | ||||
| 	// if (ci == 0) albedo.rgb = vec3(1.0, 0.0, 0.0); | ||||
| 	// if (ci == 4) albedo.rgb = vec3(0.0, 1.0, 0.0); | ||||
| @ -460,4 +437,4 @@ vec3 shadowTestCascade(sampler2DShadow shadowMap, | ||||
| 	// if (ci == 12) albedo.rgb = vec3(1.0, 1.0, 0.0); | ||||
| } | ||||
| #endif | ||||
| #endif | ||||
| #endif | ||||
|  | ||||
		Reference in New Issue
	
	Block a user