forked from LeenkxTeam/LNXSDK
		
	
		
			
	
	
		
			136 lines
		
	
	
		
			4.1 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
		
		
			
		
	
	
			136 lines
		
	
	
		
			4.1 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
| 
								 | 
							
								#version 450
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								layout (local_size_x = 8, local_size_y = 8, local_size_z = 8) in;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#include "compiled.inc"
							 | 
						||
| 
								 | 
							
								#include "std/math.glsl"
							 | 
						||
| 
								 | 
							
								#include "std/gbuffer.glsl"
							 | 
						||
| 
								 | 
							
								#include "std/imageatomic.glsl"
							 | 
						||
| 
								 | 
							
								#ifdef _VoxelShadow
							 | 
						||
| 
								 | 
							
								#include "std/conetrace.glsl"
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								uniform vec3 lightPos;
							 | 
						||
| 
								 | 
							
								uniform vec3 lightColor;
							 | 
						||
| 
								 | 
							
								uniform int lightType;
							 | 
						||
| 
								 | 
							
								uniform vec3 lightDir;
							 | 
						||
| 
								 | 
							
								uniform vec2 spotData;
							 | 
						||
| 
								 | 
							
								#ifdef _ShadowMap
							 | 
						||
| 
								 | 
							
								uniform int lightShadow;
							 | 
						||
| 
								 | 
							
								uniform vec2 lightProj;
							 | 
						||
| 
								 | 
							
								uniform float shadowsBias;
							 | 
						||
| 
								 | 
							
								uniform mat4 LVP;
							 | 
						||
| 
								 | 
							
								#ifdef _ShadowMapAtlas
							 | 
						||
| 
								 | 
							
								uniform int index;
							 | 
						||
| 
								 | 
							
								uniform vec4 pointLightDataArray[maxLightsCluster * 6];
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								uniform float clipmaps[voxelgiClipmapCount * 10];
							 | 
						||
| 
								 | 
							
								uniform int clipmapLevel;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								uniform layout(r32ui) uimage3D voxelsLight;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#ifdef _ShadowMap
							 | 
						||
| 
								 | 
							
								uniform sampler2DShadow shadowMap;
							 | 
						||
| 
								 | 
							
								uniform sampler2D shadowMapTransparent;
							 | 
						||
| 
								 | 
							
								uniform sampler2DShadow shadowMapSpot;
							 | 
						||
| 
								 | 
							
								#ifdef _ShadowMapAtlas
							 | 
						||
| 
								 | 
							
								uniform sampler2DShadow shadowMapPoint;
							 | 
						||
| 
								 | 
							
								#else
							 | 
						||
| 
								 | 
							
								uniform samplerCubeShadow shadowMapPoint;
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#ifdef _ShadowMapAtlas
							 | 
						||
| 
								 | 
							
								// https://www.khronos.org/registry/OpenGL/specs/gl/glspec20.pdf // p:168
							 | 
						||
| 
								 | 
							
								// https://www.gamedev.net/forums/topic/687535-implementing-a-cube-map-lookup-function/5337472/
							 | 
						||
| 
								 | 
							
								vec2 sampleCube(vec3 dir, out int faceIndex) {
							 | 
						||
| 
								 | 
							
									vec3 dirAbs = abs(dir);
							 | 
						||
| 
								 | 
							
									float ma;
							 | 
						||
| 
								 | 
							
									vec2 uv;
							 | 
						||
| 
								 | 
							
									if(dirAbs.z >= dirAbs.x && dirAbs.z >= dirAbs.y) {
							 | 
						||
| 
								 | 
							
										faceIndex = dir.z < 0.0 ? 5 : 4;
							 | 
						||
| 
								 | 
							
										ma = 0.5 / dirAbs.z;
							 | 
						||
| 
								 | 
							
										uv = vec2(dir.z < 0.0 ? -dir.x : dir.x, -dir.y);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									else if(dirAbs.y >= dirAbs.x) {
							 | 
						||
| 
								 | 
							
										faceIndex = dir.y < 0.0 ? 3 : 2;
							 | 
						||
| 
								 | 
							
										ma = 0.5 / dirAbs.y;
							 | 
						||
| 
								 | 
							
										uv = vec2(dir.x, dir.y < 0.0 ? -dir.z : dir.z);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									else {
							 | 
						||
| 
								 | 
							
										faceIndex = dir.x < 0.0 ? 1 : 0;
							 | 
						||
| 
								 | 
							
										ma = 0.5 / dirAbs.x;
							 | 
						||
| 
								 | 
							
										uv = vec2(dir.x < 0.0 ? dir.z : -dir.z, -dir.y);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									// downscale uv a little to hide seams
							 | 
						||
| 
								 | 
							
									// transform coordinates from clip space to texture space
							 | 
						||
| 
								 | 
							
									#ifndef _FlipY
							 | 
						||
| 
								 | 
							
										return uv * 0.9976 * ma + 0.5;
							 | 
						||
| 
								 | 
							
									#else
							 | 
						||
| 
								 | 
							
										#ifdef HLSL
							 | 
						||
| 
								 | 
							
											return uv * 0.9976 * ma + 0.5;
							 | 
						||
| 
								 | 
							
										#else
							 | 
						||
| 
								 | 
							
											return vec2(uv.x * ma, uv.y * -ma) * 0.9976 + 0.5;
							 | 
						||
| 
								 | 
							
										#endif
							 | 
						||
| 
								 | 
							
									#endif
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								float lpToDepth(vec3 lp, const vec2 lightProj) {
							 | 
						||
| 
								 | 
							
									lp = abs(lp);
							 | 
						||
| 
								 | 
							
									float zcomp = max(lp.x, max(lp.y, lp.z));
							 | 
						||
| 
								 | 
							
									zcomp = lightProj.x - lightProj.y / zcomp;
							 | 
						||
| 
								 | 
							
									return zcomp * 0.5 + 0.5;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void main() {
							 | 
						||
| 
								 | 
							
									int res = voxelgiResolution.x;
							 | 
						||
| 
								 | 
							
									ivec3 dst = ivec3(gl_GlobalInvocationID.xyz);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									vec3 wposition = (gl_GlobalInvocationID.xyz + 0.5) / voxelgiResolution.x;
							 | 
						||
| 
								 | 
							
									wposition = wposition * 2.0 - 1.0;
							 | 
						||
| 
								 | 
							
									wposition *= float(clipmaps[int(clipmapLevel * 10)]);
							 | 
						||
| 
								 | 
							
									wposition *= voxelgiResolution.x;
							 | 
						||
| 
								 | 
							
									wposition += vec3(clipmaps[clipmapLevel * 10 + 4], clipmaps[clipmapLevel * 10 + 5], clipmaps[clipmapLevel * 10 + 6]);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									float visibility;
							 | 
						||
| 
								 | 
							
									vec3 lp = lightPos -wposition;
							 | 
						||
| 
								 | 
							
									vec3 l;
							 | 
						||
| 
								 | 
							
									if (lightType == 0) { l = lightDir; visibility = 1.0; }
							 | 
						||
| 
								 | 
							
									else { l = normalize(lp); visibility = attenuate(distance(wposition, lightPos)); }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#ifdef _ShadowMap
							 | 
						||
| 
								 | 
							
									if (lightShadow == 1) {
							 | 
						||
| 
								 | 
							
										vec4 lightPosition = LVP * vec4(wposition, 1.0);
							 | 
						||
| 
								 | 
							
										vec3 lPos = lightPosition.xyz / lightPosition.w;
							 | 
						||
| 
								 | 
							
										visibility = texture(shadowMap, vec3(lPos.xy, lPos.z - shadowsBias)).r;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									else if (lightShadow == 2) {
							 | 
						||
| 
								 | 
							
										vec4 lightPosition = LVP * vec4(wposition, 1.0);
							 | 
						||
| 
								 | 
							
										vec3 lPos = lightPosition.xyz / lightPosition.w;
							 | 
						||
| 
								 | 
							
										visibility *= texture(shadowMapSpot, vec3(lPos.xy, lPos.z - shadowsBias)).r;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									else if (lightShadow == 3) {
							 | 
						||
| 
								 | 
							
										#ifdef _ShadowMapAtlas
							 | 
						||
| 
								 | 
							
										int faceIndex = 0;
							 | 
						||
| 
								 | 
							
										const int lightIndex = index * 6;
							 | 
						||
| 
								 | 
							
										const vec2 uv = sampleCube(-l, 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
							 | 
						||
| 
								 | 
							
										visibility *= texture(shadowMapPoint, vec3(uvtiled, lpToDepth(lp, lightProj) - shadowsBias)).r;
							 | 
						||
| 
								 | 
							
										#else
							 | 
						||
| 
								 | 
							
										visibility *= texture(shadowMapPoint, vec4(-l, lpToDepth(lp, lightProj) - shadowsBias)).r;
							 | 
						||
| 
								 | 
							
										#endif
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									imageAtomicAdd(voxelsLight, dst, uint(visibility * lightColor.r * 255));
							 | 
						||
| 
								 | 
							
									imageAtomicAdd(voxelsLight, dst + ivec3(0, 0, voxelgiResolution.x), uint(visibility * lightColor.g * 255));
							 | 
						||
| 
								 | 
							
									imageAtomicAdd(voxelsLight, dst + ivec3(0, 0, voxelgiResolution.x * 2), uint(visibility * lightColor.b * 255));
							 | 
						||
| 
								 | 
							
								}
							 |