Vertex lighting.
Blitz3D Forums/Blitz3D Programming/Vertex lighting.
| ||
I know this may sound lame. But does anyone know of a blitz source or lib that does simple vertex lighting. Ala, I make a .x model that has lighting info and have it be loaded and manipulated. Basically im looking for a half-dynamic way of using mulitple(more than 7) lights in a given scene. Light mapping drives me crazy due to the time and the static nature of it... sure it looks nicer, but im more concerned about quick and dirty lighting and blitz' built in light just dont seem to cut it. |
| ||
\/Ert|g0 This from the code archives http://www.blitzbasic.com/codearcs/codearcs.php?code=284 However there is a catch. To use vertex lighting, each mesh must be unique, i.e. you can't vertex light a copied entity as each copied entity takes its (vertex) lighting from the source mesh rather than show its own lighting. Unfortunately one of the key methods in keeping framerates up is to keep the number of surfaces in a scene to a minimum. Each unique mesh (e.g. loadmesh or copymesh) adds to the total surface count. Copyentity simply references the source mesh and does not add to the surface count. |
| ||
Actually, from what I understand, copyentity DOES add to the surfacecount, hence why single surface particle systems have to be so complex and merge everything into a single mesh, rather than simply copying particles with copyentity... However, it seems a copied entity uses no additional memory, unlike loading the mesh over and over again does. Anyone know if this is correct? I'm pretty sure that's the way it works... |
| ||
My understanding is that particle systems are single surface to avoid the huge numbers of separate entities that would be required e.g. 100's to 1000's |
| ||
Particle systems avoid using multiple surfaces, not multiple entities. http://www.blitzbasic.com/Community/posts.php?topic=41648#467889 CopyEntity does always add a new surface at least for sprites. That's why intense particle systems shouldn't use it. I'd think CopyEntity for meshes works the same way but I'm not sure since I havn't tested it. |
| ||
We've done this a few times -- seems that copyentity() is faster than creating something new from scratch but not as fast as a manual single-surface system. When I wrote Ice-Teroids I used copyentity() on a source mesh to create particles and the surface handle for each was the same. See this: EDIT: Slightly updated to show handle difference in created entities' surfaces. |
| ||
Sledge Thanks for the code - I guess the lesson here is that it is important to use copyentity to keep framerates up. I found this in my own game where I was getting some brilliant multi-lighting effects (8+) using vertex lighting, but the framerate was dropping heavily due to the number of unique meshes I was using. |
| ||
Ok for the most part that worked, however im having some issues. Any particular reason why the colors are almost negated? EG: Mapping the color everywhere BUT where the light/radius is? Also is this a good solution for using multiple lights? And what kind of speed impact will this have with multiple lights against multiple surfaces? Any idea what the limit would be?Function light_it_up(model) s=GetSurface(model,1) For L.lamp=Each lamp For i=1 To CountVertices(s)-1 TFormPoint VertexX(s,i),VertexY(s,i),VertexZ(s,i),model,0 xd#=TFormedX()-EntityX(L\x) yd#=TFormedY()-EntityY(L\Y) zd#=TFormedZ()-EntityZ(L\Z) dist#=Sqr(xd*xd + yd*yd + zd*zd)*radius If dist<0 Then dist=0 If dist>255 Then dist=255 VertexColor s,i,L\R - dist,L\G - dist,L\B - dist Next Next End Function |
| ||
For better speed I would do a bounding check to see if the mesh is in range based on a sphere which covers it's entire area. Note that you should also be calculating the dot product of the light vector and the vertex normal to see which vertices are actually facing the light. If you're using linear falloff it'd also be better to clamp the r,g & b to zero if less than zero. Stevie |
| ||
The bounding check was a given, I have another function to check each model, if its inside the light range then it calls the above function. The problem I have is that the type that im creating has RGB values and its a "lamp". When I use the above, it seems I can only use one color at a time. IE: ; This works ; If I Set L's Green value to something and ignore R and B values. VertexColor s,i,Amblight,Amblight+ L\G - dist,Amblight ; This goes whacky and the colors arent correct at all. VertexColor s,i,Amblight+ L\R - dist,Amblight+ L\G - dist,Amblight+ L\B - dist Any ideas? Also... to a textured model... How do I apply white to it? For example if I have a bright yellow color to it, and I apply a max lighting, that yellow should turn almost completely white, and it just stays yellow. Any easy way to add highlights? Thanks guys. |
| ||
Also how would I calculate the dot product of the light vector and the vertex normal to see which vertices are actually facing the light? |
| ||
Something like this ...;tform normal into Global coords TFormNormal VertexNX( s, i ) , VertexNY( s, i ) , VertexNZ( s, i ), model, 0 Nx# = TFormedX() : Ny# = TFormedY() : Nz# = TFormedZ() TFormNormal 0,0,1, LIGHT, 0 Lx# = TFormedX() : Ly# = TFormedY() : Lz# = TFormedZ() ;dot product Dot# = Lx * Nx + Ly * Ny + Lz * Nz If Dot > 0 ;apply light End If Also, you need to be adding the new light color to the existing vertex colors otherwise previous lights are overwritten. Have you considered using lightmesh? You can simulate mutiple lights and colours with this pretty well ... Graphics3D 640,480 ,16,1 camera=CreateCamera() ent=CreateSphere() EntityFX ent,2 ; enable vertex colors LightMesh ent,-255,-255,-255 ; reset vertex colors from 255,255,255 (default) to 0,0,0 LightMesh ent,128,128,0,50,-20,20,-20 ; apply fake lighting yellow LightMesh ent,0,0,255,50,20,20,-20 ; apply fake lighting dark blue MoveEntity camera,0,2,-10 PointEntity camera,ent While Not KeyDown(1) RenderWorld Flip Wend End Stevie |
| ||
I guess I just dont understand the whole vertex lighting thing haha. Ok, well I had originally thought of using Lightmesh, however, each model I have that animates is made up of several parts. Ie Hand, Forearm, Upper Arm are all different meshes. I do not like using children as I swap these parts frequently and end up getting errors etc(plus I just dont like searching through them). Grouping them to the same mesh doesnt work either as I lose control of the individual parts orientation and positions. With lightmesh I get a gradient that effects EACH part of the mesh. So with the above example I would get yellow on one end of the hand, blue on the other.... then yellow again on the forearm instead of blue like it should as it should flow. Any suggestions? |
| ||
Can you e-mail me your code and detailed description of what your trying to do? |
| ||
Hi vertigo, I haven't read all in the thread so might be stating what's been said before. I also use a vertex lighting system on my static meshes. Which looks 'ok' - not fab, but I'm happy with it. It would obviously be way too slow to light my dynamic meshes in a similar way (or to have dynamic lights), so for my dynamic entities I use the same routine, except aaplying the lighting result to individual vertices I use it to 'light' each mesh seperatly - using Entitycolor I can darken, lighten and even color my dynamic meshes in real-time (leaving the static set untouched). This works quite ok. So when a character walks from the outside (sun light) into a building (dark), it nicely changes shade... Might be an idea?! I made a routine GetLightColorAt(x,y,z) and returns an rgb value (checking all available lights, their individual color, range, shape, intensity and shadow casting options - and returns a net RGB value, I can post a copy if you like). With vertex lighting I apply the rgb to a vertex, for the entity I use the same routine but apply it with EntityColor. Also, lighting my set (with ""ray-traced"" shadows) takes about 2 minutes. But once rendered, I save each vertex's rgb to a file. Loading this back, and simply re-applying it with a for..next loop takes less than a second!!! D. |
| ||
Stevie, I appreciate the help, but there is no code haha. My engine is huge and quite portable, but there is no lighting. I just finished the scripting language and started working on building levels. i have place holders and can manipulate them however I want, but I was wanting to write a "plug in" lighting solution to light the levels... as well as to have a solution to light up character model parts as they get near these "lit zones". Danny. What youre describing with the lighting set saving all the values to a file and then reloading sounds exactly like what im looking for as far as the static levels are concerned, and honestly using entity color would give performance and a cheap but effective work around. Whatever you'd be willing to post would be greatly appreciated. |