Lighting double sided surface

Blitz3D Forums/Blitz3D Beginners Area/Lighting double sided surface

puki(Posted 2004) [#1]
Hi peeps - "puki" here.

I've been messing about with double-sided surfaces. Lighting the thing as a single surface (regardless of which one) is okay. When I display both surfaces together, they won't light.

What am I missing?

Graphics3D 640,480,16,2 
SetBuffer BackBuffer() 

cam = CreateCamera() 
MoveEntity cam, 0,0,-12

light=CreateLight(2)
LightColor light,0,0,255
MoveEntity light,1000,1000,-1000

light2=CreateLight(2)
LightColor light2,255,0,0
MoveEntity light2,-1000,1000,-1000

mesh = CreateMesh() 

surface=CreateSurface(mesh)

triangle1 = CreateSurface(mesh)
v1 = AddVertex (triangle1,-2,-2,-2) 
v2 = AddVertex (triangle1, 0, 2, -2) 
v3 = AddVertex (triangle1, 2,-2,-2)
tri = AddTriangle (triangle1,v1,v2,v3)
tri = AddTriangle (triangle1,v3,v2,v1)

UpdateNormals mesh

While Not KeyHit(1)
TurnEntity mesh,0,1,0
RenderWorld
Flip 
Wend
End


Please help. I did try faffing about with it.

Thanks in advance.


David819(Posted 2004) [#2]
Hi Puki, I had a look at your code and messed about with it, I'm not sure if this gives what you want but it displays the lighting:

Graphics3D 640,480,16,2
SetBuffer BackBuffer()

cam = CreateCamera()
MoveEntity cam, 0,0,-12

light=CreateLight(2)
LightColor light,0,0,255
MoveEntity light,1000,1000,-1000

light2=CreateLight(2)
LightColor light2,255,0,0
MoveEntity light2,-1000,1000,-1000

mesh = CreateMesh()

surface=CreateSurface(mesh)

triangle1 = CreateSurface(mesh)
v1 = AddVertex (triangle1,-2,-2,-2)
v2 = AddVertex (triangle1, 0, 2, -2)
v3 = AddVertex (triangle1, 2,-2,-2)
tri = AddTriangle (triangle1,v1,v2,v3)
tri = AddTriangle (triangle1,v3,v2,v1)

UpdateNormals mesh
VertexNormal triangle1, v1,255,255,255
VertexNormal triangle1, v2,255,255,255
VertexNormal triangle1, v3,255,255,255

While Not KeyHit(1)
TurnEntity mesh,0,1,0

RenderWorld
Flip
Wend
End


Hope this help you a little anyhow. if not i'll look into it more for you.


puki(Posted 2004) [#3]
Nice one "Goober"! On an initial quick look that is what I want. I'll have to check it over.

When I was faffing about with it - I had tried loading the 'VertexNormals' with the 3D space coordinates - coz that's how it appears to me in the printed manual (which indicates surface,index,nx#,ny#,nz#). The manual seems to refer to coordinates.


David819(Posted 2004) [#4]
Hi Puki, Just made a slight update to the code which seems to work fine, here it is:

Graphics3D 640,480,16,2
SetBuffer BackBuffer()

cam = CreateCamera()
MoveEntity cam, 0,0,-12

light=CreateLight(2)
LightColor light,0,0,255
MoveEntity light,1000,1000,-1000

light2=CreateLight(2)
LightColor light2,255,0,0
MoveEntity light2,-1000,1000,-1000

mesh = CreateMesh()

surface=CreateSurface(mesh)

triangle1 = CreateSurface(mesh)
sv1 = AddVertex (surface,-2,-2,-2)
sv2 = AddVertex (surface, 0, 2, -2)
sv3 = AddVertex (surface, 2,-2,-2)
tv1 = AddVertex (triangle1,-2,-2,-2)
tv2 = AddVertex (triangle1, 0, 2, -2)
tv3 = AddVertex (triangle1, 2,-2,-2)
tri = AddTriangle (triangle1,tv1,tv2,tv3)
tri = AddTriangle (surface,sv3,sv2,sv1)

UpdateNormals mesh

While Not KeyHit(1)
TurnEntity mesh,0,1,0
RenderWorld
Flip
Wend
End

Has abit more coding but the results come out to be better.


big10p(Posted 2004) [#5]
Puki, any reason you want to put each triangle in a separate surface?


puki(Posted 2004) [#6]
Thanks for the second bit of code "Goober". Will take a look at it.

"big10p" - the truthfull answer is 'I don't know'. Is there a better way? I'm still initially going to do it the way I am doing it - I am currently collecting different methods and documenting them.

The object above will be a cone/pyramid type object - there will be another 3 sides like the one above - the 'peaks' of the cones will be moved to meet each other at the centre (to form the pyramid). There will be no base - so you will see inside the pyramid/cone. So I have to double-side the surfaces.

This is all part of me wanting to finally resolve my virtually zero (because I've never used it) knowledge of the Blitz3D 'Surface' stuff.


big10p(Posted 2004) [#7]
If you want your triangles to be double sided, you can use 'EntityFX entity,16' to disable backface culling. However, this may not be what you want because the 'backface' triangle will be lit using the same normals as the front face triangle, since it's using the same vertices.

Another way is to simply build a second triangle using the same verts we used to build the first, but we 'wind' them in the opposite direction, in order to make the backface triangle face the opposite direction. Something like this:

Again, however, the second triangle is lit using the first triangle's normals since they still share the same verts. Also note that I've set the vertex normals by hand as using UpdateNormals here won't work due to the way it tries to smooth normals. Arg! I think this might be getting a bit confusing, but I'll carry on anyway... :)

Finally, you can build the two triangles by giving each it's own set of 3 verts. This means we can then light each triangle correctly due to the fact that each has it's own set of vertex normals:


You might find this little include library of mine useful while checking this stuff out. It draws the normals so you can actually see where they're pointing:
http://www.blitzbasic.com/codearcs/codearcs.php?code=1085
It's very easy to include. See comments at top of code for details.


puki(Posted 2004) [#8]
Hey, nice "big10p" - I will read through this - I'll mention you and "Goober" in my worklog. I'm not doing it for a couple of days though. However, I will take a look at this post now - thanks very much.

The various ways of achieving something is very interesting - I'm enjoying faffing about with this stuff.

Edit:
You are using the 'VertexNormal' more the way I was expecting - "Goober" threw me a bit with his 'RGB-looking' stuff. Still, I hadn't nailed the use of the 'VertexNormal' commands - they are not exactly well documented.


big10p(Posted 2004) [#9]
"Goober" threw me a bit with his 'RGB-looking' stuff.


Er, yeah, I'm not too sure what Goober was attempting with that 'VertexNormal triangle1,v1,255,255,255' malarkey. :)


puki(Posted 2004) [#10]
Although, with regard to "big10p's" second piece of code - are the 'VertexNormal' commands required? What is their purpose?

I can replicate without using them - but am I missing something here?
Graphics3D 640,480,16,2
SetBuffer BackBuffer()

cam = CreateCamera()
MoveEntity cam, 0,0,-12

light=CreateLight(2)
LightColor light,0,0,255
MoveEntity light,1000,1000,-1000

light2=CreateLight(2)
LightColor light2,255,0,0
MoveEntity light2,-1000,1000,-1000

mesh = CreateMesh()

triangle1 = CreateSurface(mesh)
v1 = AddVertex (triangle1,-2,-2,-2)
v2 = AddVertex (triangle1, 0, 2,-2)
v3 = AddVertex (triangle1, 2,-2,-2)
tri = AddTriangle (triangle1,v1,v2,v3)

triangle2 = CreateSurface(mesh)
v1 = AddVertex (triangle2,-2,-2,-2)
v2 = AddVertex (triangle2, 0, 2,-2)
v3 = AddVertex (triangle2, 2,-2,-2)
tri = AddTriangle (triangle2,v3,v2,v1)

UpdateNormals mesh

While Not KeyHit(1)
TurnEntity mesh,0,1,0 
RenderWorld
Flip
Wend
End


Sorry to be a pain.


big10p(Posted 2004) [#11]
No, that's fine. You can use UpdateNormals instead of the VertexNormal commands if you want. I was simply using them to show more clearly the way the normals should be set, and to be consistent with the previous example which won't work if you use UpdateNormals.

[edit] Er, actually, just remembered that my example won't work with UpdateNormals. :) This is because of the smoothing error I mentioned. Yours works with UpdateNormals because you have put the 2 triangles into different surfaces so UpdateNormals doesn't try and smooth the normals between them.


puki(Posted 2004) [#12]
Aha, thanks "big10p".


big10p(Posted 2004) [#13]
Wait Puki, come back!!! I've just edited my post. :)


puki(Posted 2004) [#14]
Okay, I'll take a look.

Edit:

Thanks "big10p".