Hey guys, here is an video of the problem: https://youtu.be/4nXbgaZw3x8

I'm designing a lighting system in my game, and originally was using the shader from this tutorial: https://github.com/mattdesl/lwjgl-ba.../ShaderLesson6

I was able to implement that, and it looked great (its the first one you see in the video of the problem).

Now I'm adapting that version to a "deferred lighting" system so that I can use a lot of lights, and although it seems to be working, the shadows near the center of the light look harsh/bad. It also looks like the original shader can actually 'brighten' the scene, whereas the new-shader can only darken (add shadows) since the blending is set to multiply (see the "rundown" section below).EDIT: After taking another look at the video, it seems like this might be the main issue (not being able to 'brighten' the scene). Not sure what to do though.

This is the shader from "ShaderLesson6" that I was previously using, and looked good:

Code :

//GL ES specific stuff #ifdef GL_ES #define LOWP lowp precision mediump float; #else #define LOWP #endif //attributes from vertex shader varying LOWP vec4 vColor; varying vec2 vTexCoord; //our texture samplers uniform sampler2D u_texture; //diffuse map uniform sampler2D u_normals; //normal map //values used for shading algorithm... uniform vec2 Resolution; //resolution of screen uniform vec3 LightPos; //light position, normalized uniform LOWP vec4 LightColor; //light RGBA -- alpha is intensity uniform LOWP vec4 AmbientColor; //ambient RGBA -- alpha is intensity uniform vec3 Falloff; //attenuation coefficients void main() { //RGBA of our diffuse color vec4 DiffuseColor = texture2D(u_texture, vTexCoord); //RGB of our normal map vec3 NormalMap = texture2D(u_normals, vTexCoord).rgb; //The delta position of light vec3 LightDir = vec3(LightPos.xy - (gl_FragCoord.xy / Resolution.xy), LightPos.z); //Correct for aspect ratio LightDir.x *= Resolution.x / Resolution.y; //Determine distance (used for attenuation) BEFORE we normalize our LightDir float D = length(LightDir); //normalize our vectors vec3 N = normalize(NormalMap * 2.0 - 1.0); vec3 L = normalize(LightDir); //Pre-multiply light color with intensity //Then perform \"N dot L\" to determine our diffuse term vec3 Diffuse = (LightColor.rgb * LightColor.a) * max(dot(N, L), 0.0); //pre-multiply ambient color with intensity vec3 Ambient = AmbientColor.rgb * AmbientColor.a; //calculate attenuation float Attenuation = 1.0 / ( Falloff.x + (Falloff.y*D) + (Falloff.z*D*D) ); //the calculation which brings it all together vec3 Intensity = Ambient + Diffuse * Attenuation; vec3 FinalColor = DiffuseColor.rgb * Intensity; gl_FragColor = vColor * vec4(FinalColor, DiffuseColor.a); }";

This is the "deferred lighting" shader that I'm using now, which is basically the same thing except this new one is used for *each* light, and only calculates the light's intensity:

Code :

#ifdef GL_ES #define LOWP lowp precision mediump float; #else #define LOWP #endif //attributes from vertex shader varying LOWP vec4 vColor; varying vec2 vTexCoord; //texture samplers uniform sampler2D u_texture; //values for shading algorithm uniform vec2 resolution; //Resolution of Screen uniform vec3 lightPosition; //Position of Light, normalized uniform LOWP vec4 lightColor; //Light RGBA -- alpha is intensity uniform vec3 falloff; //attenuation coefficients uniform float zoomModifier; //Inverse of camera zoom (1f/camera.zoom) void main() { //RGBA of our normal map vec4 normalMapColor = texture2D(u_texture, vTexCoord); //The Delta position of light vec3 lightDir = vec3(lightPosition.xy - (gl_FragCoord.xy / resolution.xy), lightPosition.z); //Correct for aspect ratio lightDir.x *= resolution.x / resolution.y; //Correct for camera zoom lightDir.xy *= zoomModifier; //Determine distance (used for attenuation) BEFORE we normalize our LightDir float D = length(lightDir); //Normalized-normalMapColor vec3 N = normalize(normalMapColor * 2.0 - 1.0); //Normalized-lightDirection vec3 L = normalize(lightDir); //Pre-multiply light color with intensity, then perform "N dot L" to determine diffuse term vec3 diffuse = (lightColor.rgb * lightColor.a) * max(dot(N,L), 0.0); //Calculate attenuation float attenuation = 1.0 / (falloff.x + (falloff.y * D) + (falloff.z * D * D)); //Calculate intensity vec3 finalIntensity = diffuse * attenuation; gl_FragColor = vColor * vec4(finalIntensity.rgb, normalMapColor.a); }

This is the rundown of what I'm doing with the new shader:

1) Render the scene normally to the screen (default shader, regular textures)

2) Draw all of my normal-maps to a FrameBuffer ("normalMapBuffer")

3) On another FrameBuffer ("intensityFrameBuffer"), clear with the ambient light color

4) Set blending to additive (GL_ONE, GL_ONE)

5) For each of my lights, draw light to the intensityFrameBuffer using the normalMapBuffer texture and the newly-written shader

6) Set blending to multiply (GL_DST_COLOR, GL_ZERO)

7) Draw the intensityFrameBuffer to the screen

I'm pretty new to lighting/shaders, so I'm *hoping* its something simple I'm doing wrong, like using the wrong blending settings.

OriginalShader with light intensity = 1:

https://i.imgur.com/rTjZn5f.png

OriginalShader with light intensity = 2:

https://i.imgur.com/ZcRjgwF.png

NewShader with light intensity = 1:

https://i.imgur.com/YWMtese.png

Shader with light intensity = 2:

New

https://i.imgur.com/4SeV3nF.png