After successfully loading textures, meshes, and setting up the transformation pipeline, the next step was obviously lights. I set a GU_DIFFUSE_AND_SPECULAR Point Light right next to my typical tessellated cube.
Global ambient seems to be used always.
Diffuse seems to work fine. The contribution from diffuse gets added to the ambient light based on distance.
Specular, however, is all over the place. I get streaks of specular light across my cube's faces, and the worst part: rotating the camera CHANGES the specular highlights, but moving the camera doesn't. That should never happen, since specular light is based on vertex normal, vector from vertex to light, and vector from camera position to vertex. Position should affect but orientation shouldn't, but I'm seeing the opposite.
The interesting bit is that specular highlights only seem to show when I'm roughly looking towards -Z. This made me think of D3D's obscure D3DRS_LOCALVIEWER flag, which does away with any Camera position and uses a (0,0,1) Halfway vector, but I never really played with that one.
I played around with the scaling of the world matrix (and the model's size) but no changes - that's a good sign, but I have ran out of ideas. In any case, specular does not get added on top of the texture, rather added to the diffuse and later modulated with the texture (i.e. the rasterizer doesn't get a separate specular interpolant), so it may be wiser to forget about it altogether, but I don't like unfinished business.
Any guru that can shed some (heh) light on this topic?
A somewhat unrelated curiosity: where do vertex normals come from if they aren't included in the vertex format? They seem to be (1, 0, 0) but I'm not 100% sure (tried with normal-less sprites).
Lights. Where's my specular gone?
Re: Lights. Where's my specular gone?
Scratch that, sceGuLightMode(1) does the trick. Tried other values, nothing seemed to affect. It seems setting bit 0 of the mode means "add specular AFTER texture blending", whereas when the bit is clear, it means "add specular before texture blending".Paco wrote:specular does not get added on top of the texture, rather added to the diffuse and later modulated with the texture
Hehehe I see this was just added to svn, even if tersely explained. :P
Code: Select all
94 5E LMODE Light Model
0: Lighting model
0: Single color
1: Separate specular color
Code: Select all
10: Unknown (diffuse color, affected by specular power)
Paco
Re: Lights. Where's my specular gone?
The PSP transforms the lights by the view matrix, and vertices with view*model (or world, I guess). If you're transforming vertices with the view matrix then lights will move too.Paco wrote:Global ambient seems to be used always.
Diffuse seems to work fine. The contribution from diffuse gets added to the ambient light based on distance.
Specular, however, is all over the place. I get streaks of specular light across my cube's faces, and the worst part: rotating the camera CHANGES the specular highlights, but moving the camera doesn't. That should never happen, since specular light is based on vertex normal, vector from vertex to light, and vector from camera position to vertex. Position should affect but orientation shouldn't, but I'm seeing the opposite.
I see you worked this out. I had just gone through understanding as much as I could about the lighting for PSPGL, and added the comment to commands.txt. In general, OpenGL is a good start for understanding the PSP's hardware; it seems to have been a strong influence. In GL, glLightModel can set either GL_SEPARATE_SPECULAR or GL_SINGLE_COLOR mode for specular highlights; SINGLE_COLOR is the default.The interesting bit is that specular highlights only seem to show when I'm roughly looking towards -Z. This made me think of D3D's obscure D3DRS_LOCALVIEWER flag, which does away with any Camera position and uses a (0,0,1) Halfway vector, but I never really played with that one.
I played around with the scaling of the world matrix (and the model's size) but no changes - that's a good sign, but I have ran out of ideas. In any case, specular does not get added on top of the texture, rather added to the diffuse and later modulated with the texture (i.e. the rasterizer doesn't get a separate specular interpolant), so it may be wiser to forget about it altogether, but I don't like unfinished business.
glLightModel can also set a GL_LIGHT_MODEL_LOCAL_VIEWER setting, I assume is the same as the D3D thing you're talking about (since D3D was also strongly influenced by OpenGL). I haven't found any register for this setting (but I haven't looked very hard). Given how much of a performance hit 4 lights seems to have, I don't think the PSP needs more things to calculate.
Dunno. They could just be the last normal in the last vertex used which had a normal.A somewhat unrelated curiosity: where do vertex normals come from if they aren't included in the vertex format? They seem to be (1, 0, 0) but I'm not 100% sure (tried with normal-less sprites).
I can confirm that the specular is "LOCAL_VIEWER". I ran the lights sample on the real psp and the specular reflections in the ground really looks like local_viewer. I then implemented lighting in my experimental PSP emulator, using the local viewer approach, and arrived at an essentially identical image.
http://www.dtek.chalmers.se/~tronic/PSPTexTool.zip Free texture converter for PSP with source. More to come.
Ok so the LOCAL VIEWER thing seems confirmed. My highlights currently seem to appear at the sides of the object, but never at the front, exactly the typical issue people comment on before they discover the switch and turn it on (it defaults to off in OpenGL, I think).
Now the remaining question is... Is localviewer compatible with a coordinate system in which the Z goes positive into the scene (your typical left-handed csys)? I am afraid it isn't, since the specular model uses a fixed vector for view-space vertex-to-eye (essentially -vertex, with vertex.z being positive in a left-handed system), and this fixed vector seems to be (0,0,1).
http://www.ibiblio.org/pub/packages/dev ... rc/light.c
shows how the source for Mesa doesn't even try to guess what kind of coordinate system is being used, and puts a (0,0,1) straight there. This is also suggested in the actual documentation for OpenGL (which is typically right-handed) and, interestingly, for Direct3D, which promotes left-handedness.
Time to go back and change all the maths for the system before it's too late. :(
Edit: yup, changed my projection matrix, vertex culling order and Z-buffer setup and the specular highlights come out correct now.
Now the remaining question is... Is localviewer compatible with a coordinate system in which the Z goes positive into the scene (your typical left-handed csys)? I am afraid it isn't, since the specular model uses a fixed vector for view-space vertex-to-eye (essentially -vertex, with vertex.z being positive in a left-handed system), and this fixed vector seems to be (0,0,1).
http://www.ibiblio.org/pub/packages/dev ... rc/light.c
shows how the source for Mesa doesn't even try to guess what kind of coordinate system is being used, and puts a (0,0,1) straight there. This is also suggested in the actual documentation for OpenGL (which is typically right-handed) and, interestingly, for Direct3D, which promotes left-handedness.
Time to go back and change all the maths for the system before it's too late. :(
Edit: yup, changed my projection matrix, vertex culling order and Z-buffer setup and the specular highlights come out correct now.
Paco
Scratch that: changed my view matrix (negate 3rd column) and my projection matrix (negate 3rd row) and all worked fine without any further adjustments. Lighting takes place in view space, before applying the projection.Paco wrote:Edit: yup, changed my projection matrix, vertex culling order and Z-buffer setup and the specular highlights come out correct now.
Well, one further adjustment needed: had to negate the fog values. That would indicate that fog calculations are done during lighting.
Enough spam! :)
Paco