Main Menu

GLSL Help

Started by Andrew_3ds, April 07, 2015, 03:52:59

Previous topic - Next topic

Andrew_3ds

I'm trying to implement multiple lights in my game, and it's working for the most part but a few things aren't quite working like they're supposed to. Each time I add another light the ambient lighting gets lighter for some reason, and after putting about 3-4 lights in the room everything is extremely bright and almost just a white color.

Here is the fragment shader code: http://pastebin.com/Vu9K6dzf

Here are some images of what it is looking like:
1 light: http://i.imgur.com/3aw3gw3.png
2 lights: http://i.imgur.com/hBAqYAA.png
3 lights: http://i.imgur.com/DZPN4vT.png
4 lights: http://i.imgur.com/GheDamZ.png

Kai

The odd thing about your shader is that you are using the 'pass_worldPos' (which presumably contains the world-space position of your vertices) as the normal in lighting calculations, since you are passing it as the second argument to 'applyLight()'.
Also, the second parameter 'surfaceNormal' unfortunately hides the 'surfaceNormal' varying/in variable.
So, you probably want to just remove the second parameter of 'applyLight', since you already have all information as varying/in.

The next thing, because you were saying something about ambient light getting brigther: you do not have ambient lighting in your shader. You currently only have point lights. And those of course add up.
Related to this is the next perculiar thing: Whenever your lights do not contribute any energy to a shaded surface point, you simply assume (1, 1, 1) as the light's contribution. Therefore, unlit surfaces will be completely lit by itself. Maybe this is what you considered "ambient" lighting.

Another thing is: You do not attenuate your point lights based on the distance between the light position and the surface point.
Physically correct light would attenuate based on the inverse square of the distance between light center and surface point. See http://en.wikipedia.org/wiki/Inverse-square_law.
You currently only consider the surface normal when attenuating. So, a point 10,000 units away from the light source receives the same amount of energy as one that is just 2 units away.

Andrew_3ds

I didn't notice that I was passing it, thank you for noticing that, I fixed it. the surfaceNormal variable is just the normal times the modelmatrix, so it is in it's respective position to the model's transformation. I added ambient lighting by making a constant variable of 0.2, and if the linear color of the pixel divided by the number of lights equals the ambient, I know that it is supposed to be lit as ambient (because each time applyLight() is called it adds the current color of the pixel - even if it's ambient, so checking if the sum of the lights is equal to ambient divided by the number of times applyLight() is being called, I know that it's supposed to be ambient lighting). I think it's working now, but now I have another problem. No matter where the light is, for some reason the light is still reflecting in the center of the plane and not where it's supposed to be. Example: http://i.imgur.com/ag9T5NI.png. You can see that the light is to the right of the monkey(by the brightness of his right side compared to left) but the light is still only being shown in the center of the plane for some reason.

Vert shader:http://pastebin.com/rWMMim7J
Frag shader:http://pastebin.com/0c9ND4Sc

I also added distance checking so it get's decreasingly dimmer as it furthers away.

Kai

The issue is with your vertex shader.
To transform the model-space normal into view-space (or rather world-space like you do it) you need to multiply the normal vector with the transpose of the inverse of the model matrix.
This is because the normal is not a position but a direction. For example: if you translate your model, lets say, on the x-axis, you do not want your normal to also "translate" and denormalize, but it should remain constant.
Have a look at: http://www.lighthouse3d.com/tutorials/glsl-tutorial/the-normal-matrix/.
They are using the modelview matrix there, but that's because they do their lighting computations in view-space.

Andrew_3ds

Hm. I changed the code to this:
mat4 normalMatrix = transpose(inverse(modelMatrix));
surfaceNormal = (normalMatrix * vec4(normals,0)).xyz;


But it still doesn't do anything.

abcdef

mat4 modelView = view * model;
    mat4 normalMatrix = view * transpose(inverse(modelView));