Jaa, da seid ihr neugierig geworden...zuunrecht
ich habe lediglich eine sehr minimale schattenroutine geschrieben, die einen kleinen schatten auf eine ebene wirft. aber das lässt sich sicher noch auf terrains oder ähnliches erweitern.
das ganze ist bestimmt nicht echtzeittauglich, eher dafür gedacht beim platzieren eines objektes einen kleinen schlagschatten zu werfen.
kern ist die methode createShadow, sie erwartet 4 eingaben:
das mesh zu dem ein schatten erstellt werden soll
die welt, die wird dabei aus und wieder eingeblendet, hier bietet sich also ein pivot an an dem alles hängt
die momentan aktive camera, die wird ausgestellt und wieder angestellt am ende
die textur, die momentan auf dem objekt klebt
die taste die gedrückt werden muss ist übrigens "k"
BlitzBasic: [AUSKLAPPEN] [EINKLAPPEN] Graphics3D 800,600,32,2 SetBuffer BackBuffer()
cam=CreateCamera() PositionEntity cam,0,1,-5 CameraClsColor cam,0,64,192
world=CreatePivot()
plane=CreatePlane(1,world) EntityColor plane,0,128,0 EntityPickMode plane,2
mesh=CreateCube(world) MoveEntity mesh,3,1,3 mesh2=CreateCone(8,1,world) MoveEntity mesh2,-3,1,3 TurnEntity mesh2,180,0,0 mesh3=CreateSphere(8,world) MoveEntity mesh3,3,1,-3
Dim shadow#(16,16,2)
AmbientLight 255,255,255
Global shadowmesh=CreateMesh()
Repeat Cls MoveEntity cam,0.1*(KeyDown(205)-KeyDown(203)),0,0.1*(KeyDown(200)-KeyDown(208)) If(MouseHit(2)) MoveMouse(400,300) EndIf If(MouseDown(2)) TurnEntity(cam,MouseYSpeed(),-MouseXSpeed(),0) RotateEntity(cam,EntityPitch(cam),EntityYaw(cam),0) EndIf If(KeyHit(37)) createShadow(mesh,plane,cam,-1) createShadow(mesh2,plane,cam,-1) createShadow(mesh3,plane,cam,-1) EndIf RenderWorld Flip Until KeyHit(1)
Function createShadow(mesh,world,cam,originaltexture) HideEntity world ShowEntity mesh Local canvas=CreatePlane() EntityColor canvas,0,0,0 EntityPickMode canvas,2 HideEntity(cam) Local cam2=CreateCamera() PositionEntity cam2,EntityX(mesh),EntityY(mesh),EntityZ(mesh) CameraViewport cam2,400-256,300-256,512,512 MoveEntity cam2,20,40,10 PointEntity cam2,mesh CameraClsColor cam2,0,0,0 EntityPickMode(mesh,0,0) distancetoborder#=closestDistanceToBorder(mesh,cam2) distance#=Tan(59)/(256.0-distancetoborder) wunschdistance#=Tan(60)/256.0 zoom#=distance/wunschdistance EntityFX mesh,0 EntityTexture mesh,whitetexture() EntityColor mesh,1,1,1 CameraZoom cam2,zoom RenderWorld shadowtexture=CreateTexture(512,512,4) CopyRect(400-256,300-256,512,512,0,0,BackBuffer(),TextureBuffer(shadowtexture)) masktexture(shadowtexture) Local shadowmesh=CreateMesh() surface=CreateSurface(shadowmesh) MoveEntity shadowmesh,0,0.0001,0 EntityAlpha shadowmesh,0.5 EntityFX shadowmesh,48 EntityTexture shadowmesh,shadowtexture For x=0 To 16 For y=0 To 16 CameraPick(cam2,32*x,32*y) shadow(x,y,0)=PickedX():shadow(x,y,1)=PickedY():shadow(x,y,2)=PickedZ() If(x>0 And y>0) v1=AddVertex(surface,shadow(x-1,y-1,0),shadow(x-1,y-1,1),shadow(x-1,y-1,2),(x-1)/16.0,(y-1)/16.0) v2=AddVertex(surface,shadow(x,y-1,0),shadow(x,y-1,1),shadow(x,y-1,2),(x)/16.0,(y-1)/16.0) v3=AddVertex(surface,shadow(x,y,0),shadow(x,y,1),shadow(x,y,2),(x)/16.0,(y)/16.0) v4=AddVertex(surface,shadow(x-1,y,0),shadow(x-1,y,1),shadow(x-1,y,2),(x-1)/16.0,(y)/16.0) AddTriangle(surface,v1,v2,v3) AddTriangle(surface,v1,v3,v4) EndIf Next Next
ShowEntity cam HideEntity cam2 FreeEntity cam2 HideEntity canvas FreeEntity canvas ShowEntity shadowmesh ShowEntity world If(originaltexture<>-1) EntityTexture mesh,originaltexture EntityFX(mesh,2) EntityPickMode(mesh,2,1) Return shadowmesh End Function
Function masktexture(tex) SetBuffer(TextureBuffer(tex)) LockBuffer() For x=0 To 511 For y=0 To 511 rgb = ReadPixelFast(x, y) And $00FFFFFF If rgb <> 0 Then WritePixelFast x, y, $FF000000 Or rgb Else WritePixelFast x, y, rgb EndIf Next Next UnlockBuffer() SetBuffer BackBuffer() End Function
Function closestDistanceToBorder#(mesh,cam) Local highscore#=512 For i=1 To CountSurfaces(mesh) For j=0 To CountVertices(GetSurface(mesh,i))-1 TFormPoint(VertexX(GetSurface(mesh,i),j),VertexY(GetSurface(mesh,i),j),VertexZ(GetSurface(mesh,i),j),mesh,0) CameraProject(cam,TFormedX(),TFormedY(),TFormedZ()) If(ProjectedX()<0 Or ProjectedX()>512 Or ProjectedY()<0 Or ProjectedX()>512) Return -1 If(ProjectedX()<highscore) Then highscore=ProjectedX() If(ProjectedY()<highscore) Then highscore=ProjectedY() If(512-ProjectedX()<highscore) Then highscore=512-ProjectedX() If(512-ProjectedY()<highscore) Then highscore=512-ProjectedY() Next Next Return highscore End Function
Function whitetexture() Local tex=CreateTexture(2,2) SetBuffer TextureBuffer(tex) Color 255,255,255 Rect 0,0,2,2 SetBuffer BackBuffer() Return tex End Function
Viel Spaß beim testen
oh gott...was ein schrecklicher text...da muss ich morgen nochmal ran
|