Help with Coloring a Texture THEN Applying Lighting in Fragment Shader

Started by Setlock, October 27, 2018, 15:40:30

Previous topic - Next topic

Setlock

Hey everyone, I was just wondering if someone could take a moment and help me with my lighting problem. I use textures that are in grey scale then I color them how I like, whether thats green, blue, purple whatever. I have just finished work on lighting and whenever I try to multiply my color vector with my diffuse vector depending on the color of the light the object needing to be lit wont light up. For example and object that I color green (rgb=(0,1,0))  will not be lit up by a red light(rgb=(1,0,0)) but if I light my scene using only white lights (rgb=(1,1,1)) everything is fine. My main question is how can I get the colored light to combine with the color I change the texture to.

Here is my fragment shader. Distance is simply the distance from the vector to the light, lightColor is obviously the color of the light and attenuation is the attenuation factor of the light, and finally color is just the color of the object whether thats blue or green etc etc.

vec3 totalDiffuse = vec3(0.0);
	
	for(int i = 0; i < 4; i++)
	{
		float attFactor = attenuation[i].x + (attenuation[i].y * distance[i]) + (attenuation[i].z * distance[i] * distance[i]);
		totalDiffuse = totalDiffuse + (lightColor[i])/attFactor;
	}
	totalDiffuse = max(totalDiffuse,0.1);
	
	out_Color = texture(textureSampler, pass_textureCoords)*vec4(color,alpha)*vec4(totalDiffuse,1.0);

KaiHH

Actually, everything is correct: (0,1,0) * (1,0,0) just is (0,0,0). That would be the case in real-world, too.
If you were in a completly dark room and had a surface which absolutely only reflected green light of a single wavelength and then only shine a red light of a single wavelength onto it, you would still see an absolute black surface.
The question now is: What do you expect to see when you shine a red light onto a green surface?

Setlock

Quote from: KaiHH on October 27, 2018, 15:51:30
Actually, everything is correct: (0,1,0) * (1,0,0) just is (0,0,0). That would be the case in real-world, too.
If you were in a completly dark room and had a surface which absolutely only reflected green light of a single wavelength and then only shine a red light of a single wavelength onto it, you would still see an absolute black surface.
The question now is: What do you expect to see when you shine a red light onto a green surface?

Actually you made me think about it and you're right, I should have thought about that. I think now when I make things like terrain or grass I'll give it a bit of a red or blue component so it isn't just a completely "toxic green" thanks XD

What I really expect is simply a strong red light on a green surface but now with the change I said above I think all should be good

Setlock

Quote from: KaiHH on October 27, 2018, 15:51:30
Actually, everything is correct: (0,1,0) * (1,0,0) just is (0,0,0). That would be the case in real-world, too.
If you were in a completly dark room and had a surface which absolutely only reflected green light of a single wavelength and then only shine a red light of a single wavelength onto it, you would still see an absolute black surface.
The question now is: What do you expect to see when you shine a red light onto a green surface?

Actually the more I think about it the more I can find issues with how it will end up working. What I really want is for any surface (other than red of course) to show that there is a red light and the same with green blue or any color. Regardless of the light color I would like the player to be able to tell that the light on that surface is that color. So really show the light as if it was shining on a white surface instead of a green one or blue one.

KaiHH

At this point, if I were you, I would grab an image editing program of your choice and paint images for a few surface/light (color, intensity) configurations to see how the end result should look like. You can then probably derive a computation to achieve this effect in the shader. Probably additive blending might be what you want. So: resultColor = surfaceDiffuseColor + lightColor. Or, like you said, for a red surface just add a small amount of green and blue which will then be scaled up by the light's color. This will likely require also some normalization (essentially tone mapping) so that you will not end up with a complete saturated yellow lit surface where the surface color was red (with a little bit of green and blue) and the light color was green (which might still be physically correct but not what you actually wanted).

Setlock

Quote from: KaiHH on October 27, 2018, 19:02:40
At this point, if I were you, I would grab an image editing program of your choice and paint images for a few surface/light (color, intensity) configurations to see how the end result should look like. You can then probably derive a computation to achieve this effect in the shader. Probably additive blending might be what you want. So: resultColor = surfaceDiffuseColor + lightColor. Or, like you said, for a red surface just add a small amount of green and blue which will then be scaled up by the light's color. This will likely require also some normalization (essentially tone mapping) so that you will not end up with a complete saturated yellow lit surface where the surface color was red (with a little bit of green and blue) and the light color was green (which might still be physically correct but not what you actually wanted).

Yah the issue I keep running in to is that I would ideally just like the surface to show that it has a red light on it regardless of its own color(except if its red of course). But then I run into the second issue of white light, if I shine a white light on an object I would still like it to have a green hue not an overbearing white light. So im not sure if additive blending is the best solution And then like you said if I make a green surface a little bit red the red light shows but its not very bright. So not sure what I should do

Setlock

So I was able to get what I want, all light colors will appear exactly as they are on the terrain. The issue now is when I want to light the scene the white light is an overbearing white, so it doesnt light the scene properly because the light it is casting is this pure white. Any ideas on a solution for making the white light normal again but keeping the rest of the color the same?