Help with lights

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

Moderators: cheriff, TyRaNiD

Post Reply
RR4
Posts: 4
Joined: Sat Dec 10, 2005 12:37 am

Help with lights

Post by RR4 »

Hi,
I've been playing with PSPSDK for a few weeks, and I tried making my own scene/models loader. I'm using ASE files I'm converting to binaries that I load with my PSP.
But I'm having troubles with lights right now. As it's hard to explain, I took some screenshots to show you.
My scene is a room, with 4 walls, a roof and a floor. On the screens, you'll see 3 green lines, these are the normals of each vertices of the selected face (shown in red). There's also a little cube where the light should be.

Screen 1:
http://www.rr4.net/screenshot1.jpg
On this screen, the light is at the center of the room, everything looks fine.

Screen 2:
http://www.rr4.net/screenshot2.jpg
I moved the light to the left (x--). Notice that the left wall is dark, and the right wall is bright. Also notice that the back wall, the roof and the floor lighting seems correct.

Screen 3:
http://www.rr4.net/screenshot3.jpg
I moved the light to the right (x++). The exact opposite of the screen 2. It seems like left wall and right wall should be inverted...

Screen 4:
http://www.rr4.net/screenshot4.jpg
This one is just to show that it's not only happening with the x axis. This time, I moved up the light (y++). Roof is getting darker, and floor is getting brighter, whereas walls lighting looks good.

Now, here are parts of my source code:

Code: Select all

typedef struct
{
	float u, v;
	float nx, ny, nz;
	float x, y, z;
} Vertex;

typedef struct
{
	Vertex a, b, c;
} Face;

typedef struct
{
	int width, height;
	unsigned char __attribute__((aligned(16))) *image;
} Texture;

typedef struct
{
	char file[125];
	int nbFaces;
	Face *faces;
	Texture texture;
	float xpos, ypos, zpos;
	float xrot, yrot, zrot;
} Model;

typedef struct
{
	float xpos, ypos, zpos;
	float xrot, yrot, zrot;
} Camera;

typedef struct
{
	char type;
	float x, y, z;
	float att1, att2, att3;
} Light;

typedef struct
{
	Camera camera;
	int nbLights, nbModels;
	Light *lights;
	Model *models;
} Scene;

void drawModel(Model model) {

	sceGumMatrixMode(GU_MODEL);
	sceGumLoadIdentity();
	{
		ScePspFVector3 pos = { model.xpos, model.ypos, model.zpos };
		ScePspFVector3 rot = { model.xrot, model.yrot, model.zrot };
		sceGumTranslate(&pos);
		sceGumRotateXYZ(&rot);
	}

	if (model.texture.width!=0 && model.texture.height!=0) {
		sceGuTexMode(GU_PSM_8888, 0, 0, 0);
		sceGuTexImage(0, model.texture.width, model.texture.height, model.texture.width, model.texture.image);
		sceGuTexFunc(GU_TFX_MODULATE, GU_TCC_RGB);
		sceGuTexFilter(GU_LINEAR, GU_LINEAR);
	}
	sceGuAmbientColor(0xff808080);
	sceGuColor(0xffffff);
	sceGumDrawArray(GU_TRIANGLES, GU_NORMAL_32BITF|GU_TEXTURE_32BITF|GU_VERTEX_32BITF|GU_TRANSFORM_3D, model.nbFaces*3, 0, model.faces);
}

void setLight(int index, Light light) {
	ScePspFVector3 lightPosition = {light.x, light.y, light.z};
	sceGuLight(index, light.type, GU_DIFFUSE, &lightPosition);
	sceGuLightColor(index, GU_DIFFUSE, 0xff808080);
	sceGuLightAtt(index, light.att1, light.att2, light.att3); // 0.0f, 0.001f, 0.0f in this case...
}

void drawScene(Scene scene) {
	int i;

	for &#40;i=0;i<scene.nbLights;i++&#41;
		setLight&#40;i, scene.lights&#91;i&#93;&#41;;

	for &#40;i=0;i<scene.nbModels;i++&#41;
		drawModel&#40;scene.models&#91;i&#93;&#41;;
&#125;

int main&#40;&#41; &#123;
	Scene room;

	pspDebugScreenInit&#40;&#41;;
	SetupCallbacks&#40;&#41;;

	// loading scene
	// ...
	sceKernelDcacheWritebackAll&#40;&#41;;

	sceGuInit&#40;&#41;;
	sceGuStart&#40;GU_DIRECT,list&#41;;
	sceGuDrawBuffer&#40;GU_PSM_8888,&#40;void*&#41;0,BUF_WIDTH&#41;;
	sceGuDispBuffer&#40;SCR_WIDTH,SCR_HEIGHT,&#40;void*&#41;0x88000,BUF_WIDTH&#41;;
	sceGuDepthBuffer&#40;&#40;void*&#41;0x110000,BUF_WIDTH&#41;;
	sceGuOffset&#40;2048 - &#40;SCR_WIDTH/2&#41;,2048 - &#40;SCR_HEIGHT/2&#41;&#41;;
	sceGuViewport&#40;2048,2048,SCR_WIDTH,SCR_HEIGHT&#41;;
	sceGuDepthRange&#40;0xc350,0x2710&#41;;
	sceGuScissor&#40;0,0,SCR_WIDTH,SCR_HEIGHT&#41;;
	sceGuEnable&#40;GU_SCISSOR_TEST&#41;;
	sceGuDepthFunc&#40;GU_GEQUAL&#41;;
	sceGuEnable&#40;GU_DEPTH_TEST&#41;;
	sceGuFrontFace&#40;GU_CW&#41;;
	sceGuShadeModel&#40;GU_SMOOTH&#41;;
	sceGuEnable&#40;GU_CULL_FACE&#41;;
	sceGuEnable&#40;GU_CLIP_PLANES&#41;;
	sceGuEnable&#40;GU_TEXTURE_2D&#41;;
	if &#40;room.nbLights>0&#41; &#123;
		sceGuEnable&#40;GU_LIGHTING&#41;;
		sceGuEnable&#40;GU_LIGHT0&#41;;
	&#125;
	if &#40;room.nbLights>1&#41;
		sceGuEnable&#40;GU_LIGHT1&#41;;
	if &#40;room.nbLights>2&#41;
		sceGuEnable&#40;GU_LIGHT2&#41;;
	if &#40;room.nbLights>3&#41;
		sceGuEnable&#40;GU_LIGHT3&#41;;
	sceGuFinish&#40;&#41;;
	sceGuSync&#40;0,0&#41;;

	sceDisplayWaitVblankStart&#40;&#41;;
	sceGuDisplay&#40;GU_TRUE&#41;;

	for&#40;;;&#41; &#123;
		// Keypad stuff
		// ...
 		sceGuStart&#40;GU_DIRECT,list&#41;;

		sceGuClearColor&#40;0xff554433&#41;;
		sceGuClearDepth&#40;0&#41;;
		sceGuClear&#40;GU_COLOR_BUFFER_BIT|GU_DEPTH_BUFFER_BIT&#41;;
		sceGuAmbient&#40;0x00222222&#41;;

		sceGumMatrixMode&#40;GU_PROJECTION&#41;;
		sceGumLoadIdentity&#40;&#41;;
		sceGumPerspective&#40;75.0f,16.0f/9.0f,0.5f,1000.0f&#41;;

		sceGumMatrixMode&#40;GU_VIEW&#41;;
		sceGumLoadIdentity&#40;&#41;;
		&#123;
			ScePspFVector3 pos = &#123; room.camera.xpos, room.camera.ypos, room.camera.zpos &#125;;
			ScePspFVector3 rot = &#123; room.camera.xrot, room.camera.yrot, room.camera.zrot &#125;;
			sceGumTranslate&#40;&pos&#41;;
			sceGumRotateXYZ&#40;&rot&#41;;
		&#125;

		drawScene&#40;room&#41;;

		sceGuFinish&#40;&#41;;
		sceGuSync&#40;0,0&#41;;
	&#125;

	freeScene&#40;room&#41;;
	quit&#40;&#41;;
	return 0;
&#125;
Can anybody tell me what I'm doing wrong? This is kind of weird to me, and I just don't get it...
ector
Posts: 195
Joined: Thu May 12, 2005 10:22 pm

Post by ector »

Your light attenuation values are kind of weird. Try changing them..
http://www.dtek.chalmers.se/~tronic/PSPTexTool.zip Free texture converter for PSP with source. More to come.
RR4
Posts: 4
Joined: Sat Dec 10, 2005 12:37 am

Post by RR4 »

Yeah, that's what I thought first, so I tried removing the line with sceGuLightAtt, and use the default attenuation. Without success... Same weird lightning...
I'm not familiar with this attenuation thing, do you have any values I could try?
User avatar
dot_blank
Posts: 498
Joined: Wed Sep 28, 2005 8:47 am
Location: Brasil

Post by dot_blank »

from your post i cannot tell what light type you are using in this code

Code: Select all

void setLight&#40;int index, Light light&#41; &#123;
   ScePspFVector3 lightPosition = &#123;light.x, light.y, light.z&#125;;
   sceGuLight&#40;index, light.type, GU_DIFFUSE, &lightPosition&#41;;//what kind of    light is index
   sceGuLightColor&#40;index, GU_DIFFUSE, 0xff808080&#41;;
   sceGuLightAtt&#40;index, light.att1, light.att2, light.att3&#41;; // 0.0f, 0.001f, 0.0f in this case...
&#125;
but from those pics it seems you are using
a point light and have you tried to properly set
up your light?

something simple like this

Code: Select all

int light;
light = sceGuLight&#40;index, GU_POINTLIGHT, GU_DIFFUSE_AND_SPECULAR, &lightPosition&#41;;
also your struct of Light is setup right but
when you get to this

Code: Select all

void drawScene&#40;Scene scene&#41; &#123;
   int i;

   for &#40;i=0;i<scene.nbLights;i++&#41;
      setLight&#40;i, scene.lights&#91;i&#93;&#41;;

   for &#40;i=0;i<scene.nbModels;i++&#41;
      drawModel&#40;scene.models&#91;i&#93;&#41;;
&#125; 
light type gets incremented and thus would change
the type every pass of this for loop

Code: Select all

for &#40;i=0;i<scene.nbLights;i++&#41;
      setLight&#40;i, scene.lights&#91;i&#93;&#41;;
hope this shows you your problem and helps
you see what is needed to change ;P
Last edited by dot_blank on Sun Dec 11, 2005 1:23 pm, edited 1 time in total.
10011011 00101010 11010111 10001001 10111010
RR4
Posts: 4
Joined: Sat Dec 10, 2005 12:37 am

Post by RR4 »

dot_blank wrote:from your post i cannot tell what light type you are using in this code
but from those pics it seems you are using
a directional light and have you tried to properly set
up your light?
Oops, sorry for the confusion, I realize it's not quite clear...
In fact, I'm using a GU_POINTLIGHT. The type of light is read from files and stored in my light structure as 'light.type'.

Now, concerning the for loop in drawScene, the first parameter of my setLight function is the number of the light. This way I can tell which light I'm setting. Furthermore, there's only one light actually in my scene, so the for loop is equivalent to:

Code: Select all

setLight&#40;0, scene.lights&#91;0&#93;&#41;;
And my setLight is equivalent to:

Code: Select all

ScePspFVector3 lightPosition = &#123;light.x, light.y, light.z&#125;; 
sceGuLight&#40;0, light.type, GU_DIFFUSE, &lightPosition&#41;; //index=0, light type=light.type=GU_POINTLIGHT and doesn't change 
sceGuLightColor&#40;0, GU_DIFFUSE, 0xff808080&#41;; 
sceGuLightAtt&#40;0, light.att1, light.att2, light.att3&#41;; // 0.0f, 0.001f, 0.0f in this case... 
Hope it's clearer now :)
Anyway thanks for your help, but I don't think my troubles come from here...
memon
Posts: 63
Joined: Mon Oct 03, 2005 10:51 pm

Post by memon »

Your pictures decribe correct behavior of point lights. See this image taken from a well known 3D software:

http://www.moppiproductions.net/memon/stash/light.jpg

If you draw the normals and the direction to lthe light source you ge the idea :) The direction from a vertex to the light source at the wall near the light source is almost perpendicular, in which case the cosine approaches to zero, which you can see well in the picture too. The opposite happens to the oppositing wall... it receives more light as the light source gets further away (assumin no distance attenuation).

In my picture I have a little bit more tesselation so the lighting is captured better. But you light is working just perfectly.
RR4
Posts: 4
Joined: Sat Dec 10, 2005 12:37 am

Post by RR4 »

Allright, I think I got it now, thanks to your help :)
I didn't realised the angle between the normal and the vertex to light direction was so important. I guess I'll just have to play with the attenuation to get the lighting I want.
Thank you very much :)
User avatar
dot_blank
Posts: 498
Joined: Wed Sep 28, 2005 8:47 am
Location: Brasil

Post by dot_blank »

RR4 wrote:
dot_blank wrote:from your post i cannot tell what light type you are using in this code
but from those pics it seems you are using
a directional light and have you tried to properly set
up your light?
Oops, sorry for the confusion, I realize it's not quite clear...
In fact, I'm using a GU_POINTLIGHT.

oops!/, sorry for this typo but hey i see
that you were doing everything properly ;)
10011011 00101010 11010111 10001001 10111010
Dr. Vegetable
Posts: 171
Joined: Mon Nov 14, 2005 1:32 am
Location: Boston, Massachusetts
Contact:

Post by Dr. Vegetable »

You might look into whether there is a way to set an ambient light level as another possible solution. An ambient light level sets a basic illumination value at all points in space, regardless of the location of any directional or point light sources. If your scenes are too dark, sometimes adding a small ambient lighting value can be easier (and even more realistic) than trying to ensure that your specific light sources adequately illuminate all surfaces under all conditions.

Sorry, I am new to GL, but once worked on a project coding a 3D rendering package. But this is such a basic feature that it's got to be available.
Post Reply