OpenGL Fragments

Hello guys, I’m here searching for a quick help cause I’m not being successful…

I’m trying to make a Fragment that will apply lighting effect on 2D walls, the thing is, I made two separate algorithms for it, one applies the light effect, and one applies the day light effect.

the problem is the light effect its making everything totally black exept the lighting area…

Fragment for light effect



#version 330 compatibility

uniform sampler2D texture;
in vec2 texCoords;

uniform float dayLight;

uniform vec2 lightPosition[50];
uniform vec3 lightColor[50];
uniform float lightIntensity[50];
uniform float lightInUse[50];

void main() {	
	vec4 color = vec4(1.0, 1.0, 1.0, 1.0);
	vec4 tex = texture2D(texture, gl_TexCoord[0].st);
	color = tex;
	
	int num = 0;	
	for (int i = 0; i < 50; i++) {
		if (lightInUse[i] == 1) {
			vec2 pos = lightPosition[i];
			float distance = length(pos - gl_FragCoord.xy);
			if (pos.x == 0 && pos.y == 0) continue;
			num++;
			vec3 col = lightColor[i];
			float ints = lightIntensity[i];
			
			float distance = length(pos - gl_FragCoord.xy);
			float attenuation = 1.0 / distance;
			
			float falloff = 80;
			falloff -= distance / 25.0f / ints ;		
			
			color *= vec4(attenuation, attenuation, attenuation, pow(attenuation, 3)) * vec4((col / distance * 15) * ints, 1.0) + 0.01;
			
			color /= (distance / (ints * falloff));
		}
	}
	color *= 30.0 * pow(166.0, float(num - 1)) + 1;
		
	gl_FragColor = color; 
}

Fragment for day light effect



#version 330 compatibility

uniform sampler2D texture;
in vec2 texCoords;

uniform float dayLight;

void main() {	
	vec4 color = vec4(1.0, 1.0, 1.0, 1.0);
	vec4 tex = texture2D(texture, gl_TexCoord[0].st);
	color = tex;
	
	color = vec4(color * vec4(dayLight, dayLight, dayLight, dayLight));	
	color *= 30.0 * pow(166.0, float(num - 1)) + 1;
		
	gl_FragColor = color; 
}

How can I combine these two together?

Thank you for your time.

I had this problem a while back. Its pretty easy explanation, but implementing it could be a pain because it could change the way you implement your code completely.

Its called forward-rendering, and its when you render your scene once as an “ambient” (Just its texture, and the scenes brightness), then you translate the world a bit towards the screen (So there’s no problem with blending), then you render the scene again (Per-light) with your light shader, and just your light pixels.

For example, in your render loop:


GL11.glEnable(GL11.GL_BLEND);

GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
ambientShader.bind(); //Your day light effect shader
 scene.render();
ambientShader.unbind();

//Render JUST THE LIGHT'S PIXELS, not the textures
GL11.glBlendFunc(GL11.GL_ONE, GL11.GL_ONE);
for(Light light : lights){
     light.shader.bind();
      scene.render();
     light.shader.unbind();
}

ui.render();

I might be getting this whole forward-render thing wrong, but here’s an article on forward-rendering vs differed shading (it explains both):

thank you for your anwser I had actually never thought of that… I’ll try it

Another way to do this is to switch your blending mode to additive blending.

Sorry, if I wasn’t on my phone then I would provide some example code. To aid you in your googling, you change the blending mode to GL_ONE and GL_ONE.

I put in the correct blending code in my reply, I just started an example for forward rendering + additive blending a few days ago and the code I added works :wink:

Thank’s guys, I have a question on the fragments, how can I compare two vec4?

I want to only change the result if the calculated color(its in a vec4) is darker then the existent color(its a vec4 too)

The min function in GLSL works component wise for any type of vector (except booleans). So:


gl_FragColor = min(existing, calculated);

will result in the darkest colour (Manhattan distance style, not absolute magnitude).