Sub-division variant:
Type Dot3Light Field ent Field mul# Field typ End Type Graphics3D 800,600,32,2 cube=CreateCube() ScaleEntity cube,5,.1,5 PositionEntity cube,0,-2,0 EntityColor cube,255,0,0 decl=LoadTexture( "tex.png",1+8) bump=LoadTexture( "norm.png",1+8) MeshEntity=LoadMesh("Floor.x") MeshEntity2=LoadMesh("Floor4.x") MeshEntity3=LoadMesh("Floor16.x") PositionEntity MeshEntity,-4,0,4 PositionEntity MeshEntity2,0,0,4 PositionEntity MeshEntity3,4,0,4 EntityFX MeshEntity,1+2 TextureBlend bump,4 EntityTexture MeshEntity,bump,0,0 EntityTexture MeshEntity,decl,0,1 EntityFX MeshEntity2,1+2 ;TextureBlend bump,4 EntityTexture MeshEntity2,bump,0,0 EntityTexture MeshEntity2,decl,0,1 EntityFX MeshEntity3,1+2 ;TextureBlend bump,4 EntityTexture MeshEntity3,bump,0,0 EntityTexture MeshEntity3,decl,0,1 Global piv=CreatePivot() pivvy=CreatePivot() light = Dot3_CreateLight(2,piv,1.4,0) lighticon = CreateSphere(8,light) EntityFX lighticon,1 ScaleEntity lighticon,0.1,0.1,0.1 Dot3_LightRange light,10 camera=CreateCamera() CameraClsColor camera,100,120,130 PositionEntity camera,0,.2,-1.0 EntityParent camera,piv,1 EntityParent MeshEntity,piv,1 CameraRange camera,0.1,100 declon = True bumpon = True doAnim=1 wire=0 While Not KeyHit(1) For d3l.dot3light = Each dot3light PositionEntity d3l\ent,EntityX(camera) + Float((MouseX()-400))/100,EntityY(camera) -Float((MouseY()-300))/100,3,1 Next If KeyHit(17) wire=Not wire WireFrame wire End If If KeyHit(57) doAnim=Not doAnim If KeyHit(2) If declon TextureBlend decl,0 Else TextureBlend decl,2 End If declon = Not declon End If If KeyHit(3) If bumpon TextureBlend bump,0 EntityFX MeshEntity,0 Else TextureBlend bump,4 EntityFX MeshEntity,1+2 End If bumpon = Not bumpon End If If KeyDown(205) MoveEntity camera, .1,0,0 If KeyDown(203) MoveEntity camera,-.1,0,0 If KeyDown(200) MoveEntity camera,0,0,0.05 If KeyDown(208) MoveEntity camera,0,0,-0.05 processtime=MilliSecs() If bumpon UpdateBumpNormals(MeshEntity,light,1) UpdateBumpNormals(MeshEntity2,light,1) UpdateBumpNormals(MeshEntity3,light,1) End If processtime=MilliSecs() - processtime UpdateWorld RenderWorld declstr$="OFF" If declon declstr$="ON " bumpstr$="OFF" If bumpon bumpstr$="ON " Text 10,20,"Process Time: "+processtime+"ms" Text GraphicsWidth()/2,0,"1 - Toggle Texture: "+declstr$+" 2 - Toggle Bumpmap: "+bumpstr$,True,False Text GraphicsWidth()/2,30,"Cursors to move & zoom, 'w' toggle wireframe",True Flip Wend Function UpdateBumpNormals(mesh,light,lighttype=0) EP=GetParent(mesh) If EP EntityParent mesh,0,1 n_surf = CountSurfaces(mesh) For s = 1 To n_surf surf = GetSurface(mesh,s) n_vert = CountVertices(surf)-1 For v = 0 To n_vert red2# = 0 grn2# = 0 blu2# = 0 For d3l.Dot3Light = Each Dot3Light lx#=EntityX(d3l\ent,True) ly#=EntityY(d3l\ent,True) lz#=EntityZ(d3l\ent,True) If d3l\typ = 1 ; Directional light TFormVector 0,0,1,d3l\ent,0 nx# = TFormedX() ny# = TFormedY() nz# = TFormedZ() TFormNormal VertexNX(surf,v),VertexNY(surf,v),VertexNZ(surf,v),mesh,0 red# = TFormedX() grn# = TFormedY() blu# = TFormedZ() ElseIf d3l\typ = 2 ; Point light ; Vertex Normal in World coordinates TFormNormal VertexNX(surf,v),VertexNY(surf,v),VertexNZ(surf,v),mesh,0 Vnx# = TFormedX() Vny# = TFormedY() Vnz# = TFormedZ() ; Vertex > Light Vector in World coordinates TFormPoint VertexX(surf,v),VertexY(surf,v),VertexZ(surf,v),mesh,0 Lvx# = lx - TFormedX() Lvy# = ly - TFormedY() Lvz# = lz - TFormedZ() ; Normalize Vertex > Light Vector d# = Sqr(Lvx*Lvx + Lvy*Lvy + Lvz*Lvz) Lvx = Lvx / d Lvy = Lvy / d Lvz = Lvz / d End If ; Theta Angle between Vertex Normal & Vertex>Light Normal dot# = (Lvx*Vnx + Lvy*Vny + Lvz*Vnz) ; Clamp Colors to 0 If dot<0.0 Then dot# = 0 ; If the Mesh had a Parent, Convert Light Vector into that Parents Local coordinates ; unsure if this'll work with multiple hierarchy If EP TFormNormal Lvx,Lvy,Lvz,0,EP Lvx# = TFormedX() Lvy# = TFormedY() Lvz# = TFormedZ() End If red# = ( (1.0+( Lvx * dot)) * 127) * d3l\mul grn# = ( (1.0+( Lvy * dot)) * 127) * d3l\mul blu# = ( (1.0+( -Lvz * dot)) * 127) * d3l\mul red2# = red2+red grn2# = grn2+grn blu2# = blu2+blu Next VertexColor surf,v,red2,grn2,blu2 Next Next If EP EntityParent mesh,EP,1 End Function Function Dot3_CreateLight(typ=1,parent=0,mul#=1.0,real=True) d3l.Dot3Light = New Dot3Light If real d3l\ent = CreateLight(typ,parent) LightRange d3l\ent,50 Else d3l\ent = CreatePivot(parent) End If d3l\typ = typ d3l\mul = mul Return d3l\ent End Function Function Dot3_LightRange(ent,range#) For d3l.dot3light = Each dot3light If d3l\ent = ent If Lower$(EntityClass(d3l\ent))="light" LightRange d3l\ent,range Return End If End If Next End Function Function Dot3_LightIntensity(ent,intens#) For d3l.dot3light = Each dot3light If d3l\ent = ent d3l\mul = intens If Lower$(EntityClass(d3l\ent))="light" LightColor d3l\ent,d3l\mul*255.0,d3l\mul*255.0,d3l\mul*255.0 End If Return End If Next End Function End