[GLSL] Question about normal mapping

Started by
7 comments, last by JohnnyCode 10 years ago

I took a look at some tutorials on the internet about how to do normal mapping and they all convert the light direction with into tangent space.

In my shader setup every shader has a "#define NUM_LIGHTS" and a respective array of structs for each light.

Every tutorial I looked at only calculated the lightDir for one light and passing it on with the "out" modifier to the fragment shader.

How would I go about passing, for example, 4 lightDirs to the fragmentShader, without creating a vec3 lightDir0; vec3 lightDir1; etc for each light?

I looked up arrays with out modifier but it seems those dont work on every card?

Hopefully someone can clarify this for me.

Have a nice day!

Advertisement

inputs to fragment shader are varying variables issued from vertex function , and those are rather very limited, not considering GPU you use. The standard bypass of "multilights" in a shader is to establish the vertex object space position as a varying variable input to pixel shader, and subtract this position in pixel shader from light uniform you pick (being in object space). In case of a lightdirection, directional light, you just keep it as an uniform variable of pixel shader in apropriate space, and vary(interpolate) only vertex normal from vertex shader to pixel shader (along with vertex tangent/binormal, depending on wheather you do normal mapping or perpixel lightning only).

Isn't it very unefficient making the BTN-Matrix(tangent space) in the fragment shader?

I used a vec3 vLightDirs[NUM_LIGHTS] to pass the light dirs in tangent space. Is this gonna cause problem on certain gpus?

http://stackoverflow.com/questions/7954927/glsl-passing-a-list-of-values-to-fragment-shader

I am just making a theory so bare with me.

This can help, for your case I would assume that you would want to make it a uniform 1-D array. Have it so that lets say in your scene your had four lights. The first element would say how many lights are in your current scene. You can use flow control *looks up keywords* for/while and use that number to process each light in the array. So it will pull a 4 in the first array then after that pull 3 numbers from the array to use as light vectors. Also you can store more data like light color and stuff for more effects. Only problem with this is that if the lights move/create/destroy/change in any way then you will have to update the array with a new one, which really isn't much of a problem.

The method you mentioned here is to pass data from cpu to the fragment shader.

What I want is passing multiple vec3's from vertex to fragment shader.

i used


out vec3 vLightDirs[4];

to pass 4 light dirs to fragment shader. I just hope that this works on every gpu

The method you mentioned here is to pass data from cpu to the fragment shader.

What I want is passing multiple vec3's from vertex to fragment shader.

i used


out vec3 vLightDirs[4];

to pass 4 light dirs to fragment shader. I just hope that this works on every gpu

Depends on what OpenGL version you use. If you use 3.0 version I believe most GPUs made after August, 2008 will work. But I hope someone will correct me if I am wrong.

4 varying vec4 vectors are lowend gpus likely limit. But in any case, you have those 2 methods available . Which one is more effective depends on amount of lights you are to shade, 4 lights are likely limit of the first method to compute less, since method 2 demands only normal+tangent+postion interpolation and moving texture normal to object space. The second method is also more effective if amount of vertices of model is bigger than its fillrate.

Thanks Johnny Code for the clarification. I want to shade 4 lights.

4 varying vec4 vectors are lowend gpus likely limit. But in any case, you have those 2 methods available . Which one is more effective depends on amount of lights you are to shade, 4 lights are likely limit of the first method to compute less, since method 2 demands only normal+tangent+postion interpolation and moving texture normal to object space. The second method is also more effective if amount of vertices of model is bigger than its fillrate.

Well it's highly unlikely that there is less fillrate than vertices, at least with the game I am making(mid-poly count with cartoony art style).

you should than pay a special attention to divisions and square roots amount in pixel function then. Remember, that compared to those, multiplications and additions you can waste as you please. Also, second method has certain precision advances toward first, since, transforming light vector to texture space will alter its length inapropriate (tangent matrix is very unlikely orthonormal, so if you compute radius based point lights, go for the second method)

This topic is closed to new replies.

Advertisement