#version 330 core in vec2 vUV; in vec2 vFragScreenPos; out vec4 FragColor; uniform sampler2D uTex; uniform sampler2D uNormalMap; #define MAX_LIGHTS 512 uniform int uLightCount; uniform vec2 uLightPos[MAX_LIGHTS]; uniform vec3 uLightColor[MAX_LIGHTS]; uniform float uLightIntensity[MAX_LIGHTS]; uniform float uLightRadius[MAX_LIGHTS]; void main() { vec4 texColor = texture(uTex, vUV); if (texColor.a < 0.1) discard; vec3 normal = texture(uNormalMap, vUV).rgb * 2.0 - 1.0; normal = normalize(normal); vec3 finalLight = vec3(0.0); for (int i = 0; i < uLightCount; ++i) { vec2 lightVec = uLightPos[i] - vFragScreenPos; float dist = length(lightVec); if (dist < uLightRadius[i]) { vec2 lightDir2D = normalize(lightVec); vec3 lightDir = normalize(vec3(lightDir2D, 1.0)); // pseudo-3D float attenuation = 1.0 - dist / uLightRadius[i]; float diff = max(dot(normal, lightDir), 0.0); vec3 light = uLightColor[i] * diff * attenuation * uLightIntensity[i]; finalLight += light; } } vec3 result = texColor.rgb * finalLight; FragColor = vec4(result, texColor.a); }