Lights. Where's my specular gone?

Discuss the development of new homebrew software, tools and libraries.

Moderators: cheriff, TyRaNiD

Post Reply
Paco
Posts: 54
Joined: Sun Oct 09, 2005 6:53 pm

Lights. Where's my specular gone?

Post by Paco »

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).
Paco
Paco
Posts: 54
Joined: Sun Oct 09, 2005 6:53 pm

Re: Lights. Where's my specular gone?

Post by Paco »

Paco wrote:specular does not get added on top of the texture, rather added to the diffuse and later modulated with the texture
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".

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
I wonder if there's a flag hidden somewhere, similar to the D3DRS_LOCALVIEWER one I mentioned, which makes specular calculations work correctly. Maybe

Code: Select all

10: Unknown (diffuse color, affected by specular power)
this one? Gonna have to figure out how to send this command, given that the gu code has it hardcoded to either 0 or 1. :)
Paco
holger
Posts: 204
Joined: Thu Aug 18, 2005 10:57 am

Post by holger »

try reg 0x5f, bits [9..8], light type.
jsgf
Posts: 254
Joined: Tue Jul 12, 2005 11:02 am
Contact:

Re: Lights. Where's my specular gone?

Post by jsgf »

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.
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.
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.
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.

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.
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).
Dunno. They could just be the last normal in the last vertex used which had a normal.
jsgf
Posts: 254
Joined: Tue Jul 12, 2005 11:02 am
Contact:

Post by jsgf »

holger wrote:try reg 0x5f, bits [9..8], light type.
In OpenGL, local viewer is a global property, rather than per-light, though I guess it could make sense to have it per-light. I played with various bits in lightmodel (0x5e), but didn't see effect other than separate specular.

J
ector
Posts: 195
Joined: Thu May 12, 2005 10:22 pm

Post by ector »

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.
Paco
Posts: 54
Joined: Sun Oct 09, 2005 6:53 pm

Post by Paco »

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.
Paco
Paco
Posts: 54
Joined: Sun Oct 09, 2005 6:53 pm

Post by Paco »

Paco wrote:Edit: yup, changed my projection matrix, vertex culling order and Z-buffer setup and the specular highlights come out correct now.
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.

Well, one further adjustment needed: had to negate the fog values. That would indicate that fog calculations are done during lighting.

Enough spam! :)
Paco
Post Reply