www.jpct.net

jPCT - a 3d engine for Java => Support => Topic started by: AGP on February 08, 2012, 03:18:36 am

Title: Normal Map Shader Lights
Post by: AGP on February 08, 2012, 03:18:36 am
I used the wiki's normal map shader almost entirely. I placed it on a squad of Storm Troopers. And it works, except for the fact that its built-in light doesn't have an effect on the squad. If I fly near it, my ship has a light over it and, at given, but limited, angles I can see the models lit and all the detail of the normal map applied. What's also odd is that the light they have (I've kept their distinctive blue so I can tell it from my ship's light) bounces off my ship just fine if I fly near the squad. Only exact angles seem to be triggering the normal map shader (and object lighting).
Title: Re: Normal Map Shader Lights
Post by: EgonOlsen on February 08, 2012, 08:35:09 am
No, of course not. If you are using shaders, you are completely on your own. You still get the lighting information though (there are some predefined uniforms for this, just look at the GLSL specs), but to actually apply them, you have to code your own lighting formula in the shader. The Robombs sources should contain a phong shader variant for one light. You might also have a look at the default shaders from jPCT-AE (inside the jar), which support up to eight gouraud shaded lights. But you can't use them directly, because GLSL for mobile devices differs from the one for standard OpenGL. The biggest difference is, that the predefined uniforms are not present on mobile.
Title: Re: Normal Map Shader Lights
Post by: AGP on February 08, 2012, 04:46:27 pm
Of course not what? That wasn't a question: only exact angles seem to be triggering the normal map shader (and object lighting). I've moved them around a thousand times to the same results.
Title: Re: Normal Map Shader Lights
Post by: AGP on February 08, 2012, 09:53:01 pm
I'm thinking it may be relative to their size (they're really small). Would that make any sense? If so, is there a setting in Config for that (I have looked but found nothing)?
Title: Re: Normal Map Shader Lights
Post by: EgonOlsen on February 08, 2012, 09:58:33 pm
I was somehow thinking that you expected the normal gl lighting to show up on the model. My bad, i was in a hurry. Have you enabled specular lighting for the squad? It makes this shader usually look better. Also play around with the invRadius setting. You might also want to try this vertex shader instead:

Code: [Select]
attribute vec4 tangent;

varying vec3 lightVec;
varying vec3 eyeVec;
varying vec2 texCoord;

void main(void)
{
gl_Position = ftransform();
texCoord = gl_MultiTexCoord0.xy;

vec3 n = normalize(gl_NormalMatrix * gl_Normal);
vec3 t = normalize(gl_NormalMatrix * vec3(tangent));
vec3 b = cross(n, t);

vec3 vVertex = vec3(gl_ModelViewMatrix * gl_Vertex);
vec3 tmpVec = gl_LightSource[0].position.xyz - vVertex;

lightVec.x = dot(tmpVec, t);
lightVec.y = dot(tmpVec, b);
lightVec.z = dot(tmpVec, n);

tmpVec = -vVertex;
eyeVec.x = dot(tmpVec, t);
eyeVec.y = dot(tmpVec, b);
eyeVec.z = dot(tmpVec, n);
}


It makes use of jPCT capability to automatically calculate the tangent vectors (the other shader in the wiki is actually faking them to a degree). Just make sure that you've assigned the shader before calling build()/compile() or call calcTangentVectors() yourself.
Title: Re: Normal Map Shader Lights
Post by: EgonOlsen on February 08, 2012, 09:59:43 pm
I'm thinking it may be relative to their size (they're really small). Would that make any sense? If so, is there a setting in Config for that (I have looked but found nothing)?
No. It's just about the angle to the light. Just look at the shader...that's all there is. Whatever goes wrong has its source in this small piece of code. The rest of the pipeline doesn't do anything when using a shader.
Title: Re: Normal Map Shader Lights
Post by: AGP on February 08, 2012, 10:25:54 pm
Thanks a lot, I'll give it a try and report back.
Title: Re: Normal Map Shader Lights
Post by: AGP on February 09, 2012, 05:15:18 pm
Thank you very much, it worked. But it should be noted that it only worked when I replaced the little framework from the wiki with the GLSLShader class. Should I change the wiki (this would make for a much better example)? Then again, maybe we should just add it, rather than replace the older one.
Title: Re: Normal Map Shader Lights
Post by: AGP on February 09, 2012, 05:30:56 pm
The normals are being shown, I can see them very clearly on the model. Still, I'm getting the following messages, which eventually conclude with "shader compiled."


Fragment shader failed to compile with the following errors:
ERROR: 0:1: error(#132) Syntax error: 'fragmentshader' parse error
ERROR: error(#273) 1 compilation errors.  No code generated


Vertex shader failed to compile with the following errors:
ERROR: 0:1: error(#132) Syntax error: 'vertexshader' parse error
ERROR: error(#273) 1 compilation errors.  No code generated


[ Thu Feb 09 14:29:12 EST 2012 ] - ERROR: Vertex and Fragment shader(s) were not
 successfully compiled before glLinkProgram() was called.  Link failed.

Tangent handle not found (tangents needed: false)!
Shader compiled!
Title: Re: Normal Map Shader Lights
Post by: EgonOlsen on February 09, 2012, 06:02:29 pm
You seem to pass the file names where you are actually supposed to pass the source code. You can load it via the loadText-methods in Loader or in any other way you prefer.
Title: Re: Normal Map Shader Lights
Post by: AGP on February 09, 2012, 06:09:12 pm
But does it have logic to address that? Because I am seeing the normals.
Title: Re: Normal Map Shader Lights
Post by: EgonOlsen on February 09, 2012, 06:12:11 pm
But does it have logic to address that? Because I am seeing the normals.
If the shader doesn't compile, you'll simply get basic multi-texturing.
Title: Re: Normal Map Shader Lights
Post by: AGP on February 09, 2012, 06:16:30 pm
Code: [Select]
trooperSquad.setRenderHook(new GLSLShader(Loader.loadTextFile("vertexshader.glsl"), Loader.loadTextFile("fragmentshader.glsl")));

DOESN'T show the normals (but does claim to compile the shaders). Now I'm really confused.
Title: Re: Normal Map Shader Lights
Post by: AGP on February 09, 2012, 08:17:41 pm
From what I gathered, the normal map was serving as an additional texture, which is why I was seeing the normals drawn on the model). And since the light I was using (as is the wiki's--bad choice of color, by the way) was blue, I didn't think anything when the troopers appeared blue. But now that the shader compiles, it simply doesn't work.
Title: Re: Normal Map Shader Lights
Post by: EgonOlsen on February 09, 2012, 09:32:40 pm
I don't get it....what do you expect and what do you get? You should be happy that it doesn't show the normals. It's not supposed to do that. The normal map is an additional texture layer that shouldn't be seen but taken by the shader to calculate per pixel lighting. Have to tried to lower the invRadius significantly?
Title: Re: Normal Map Shader Lights
Post by: AGP on February 09, 2012, 09:46:45 pm
About the lighting: since both a normal map and the wiki's light are blue, one can mistake one for the other. Choosing any other color for the light would be more appropriate.

And I mean that it doesn't curve the normals in the way that it's supposed to. I'll try messing with invRadius and report back, thanks.
Title: Re: Normal Map Shader Lights
Post by: EgonOlsen on February 09, 2012, 09:51:44 pm
...curve the normals...
I'm not sure what you mean by this...???
Title: Re: Normal Map Shader Lights
Post by: AGP on February 09, 2012, 10:09:35 pm
Distort them, then. It doesn't do what it's supposed to.

Funny thing, now, is that when I used the little framework from the wiki with the new shader you gave me I'm back to the original issue of seeing the appropriate distortion but having the light one work at certain angles. Is there anything we could add to the framework to address this?
Title: Re: Normal Map Shader Lights
Post by: EgonOlsen on February 09, 2012, 10:20:25 pm
It has nothing to do with using GLSLShader or the code from the wiki. They are very similar except that GLSLShader does better error handling (EDIT: And that it doesn't support injection of tangent vectors, which the shader code that i had posted needs). I rather guess that this is a case of false expectations of what it is supposed to do. The whole magic is in the shader. It has nothing to do with how you apply it as long as it gets applied (which obviously happens). It does what it's supposed to do...you have the code, you can change it to anything you like. What you get from the wiki is a basic normal mapping shader. If that's not what you want or the results are not what you expect them to be, you always have the option to tweak the shader in any way you like.

Maybe you can illustrate your issue with a screen shot...?
Title: Re: Normal Map Shader Lights
Post by: AGP on February 09, 2012, 10:30:57 pm
Fine, but I'm telling you: it's working now (with the wiki's little framework and the new shader you gave me), but with the same lighting angle issue as originally. Odd, sure, but untrue it isn't. PrintScreen doesn't work with fullscreen OpenGL, but I guess I can still grab a screenshot from the FrameBuffer, right? If so, I'll post one.
Title: Re: Normal Map Shader Lights
Post by: EgonOlsen on February 09, 2012, 10:34:24 pm
As i've edited in my post above: That shader framework can't work correctly with that shader code because it doesn't know what to do with the shaders tangent-uniform...all tangent vectors will be (0,0,0) in that case. Scrap that wiki-framework and use GLSLShader instead. Just don't bother with it...it was meant as an example of how to do it on your own if you absolutely have too...but actually, you don't.
Title: Re: Normal Map Shader Lights
Post by: AGP on February 10, 2012, 12:28:54 am
OK, you do realize that your edit contradicts the rest of your post, right? Might as well edit more.

But here's a follow-up: how am I using GLSLShader wrong if the other one is working (even if only at exact angles)?
Title: Re: Normal Map Shader Lights
Post by: EgonOlsen on February 10, 2012, 07:08:39 am
It contradicts nothing. It says that they are similar except for error logging and tangent vectors. It doesn't say that they are equal. And no, the wiki-code combined with the posted shader code DOESN'T work. It can't, because it doesn't inject the tangent vectors. You might see something, but that's all bogus...not what the shader is supposed to do. Please use the GLSLShader-class instead! If it "doesn't work" (which is still too vague to be of any value), then it's better to find out what the problem is instead of using some code that will definitely never create correct results.
As said, it's all in the shader. The shader does what it's told to do. And this particular shader is actually pretty simple. Just make sure that invRadius is small if your light source is farer away than it was in the examples and make sure that the tangents have been calculated (do it yourself by calling the method to be sure).
Title: Re: Normal Map Shader Lights
Post by: AGP on February 10, 2012, 07:13:59 am
I suggested the wiki framework was incomplete and asked about what to add to it for the lights. You countered with "it's a case of false expectations." Anyway, I see no way to change invRadius with GLSLShader (I had simply divided the result of locRadius by some integer on the wiki framework but I don't get to do this with GLSLShader.
Title: Re: Normal Map Shader Lights
Post by: EgonOlsen on February 10, 2012, 07:48:51 am
Just do

Code: [Select]
shader.setStaticUniform("invRadius", 0.00000001f); // or whatever value...for light sources far away, it should be small.
Title: Re: Normal Map Shader Lights
Post by: AGP on February 10, 2012, 07:54:53 am
Thanks a lot, I'll report back.