Schatten [B3D]

Übersicht BlitzBasic Codearchiv

Neue Antwort erstellen

Goodjee

Betreff: Schatten [B3D]

BeitragSo, Dez 27, 2009 3:26
Antworten mit Zitat
Benutzer-Profile anzeigen
Jaa, da seid ihr neugierig geworden...zuunrecht Wink

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.

user posted image

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]
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



;eg mitlerweile ueberflussig :D
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)
;welt verbergen
HideEntity world
;objekt zeigen
ShowEntity mesh


;leinwand erstellen
Local canvas=CreatePlane()
EntityColor canvas,0,0,0
EntityPickMode canvas,2

;kamera an die position des lichtes setzten
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

;object ausdem weg bewegen
EntityPickMode(mesh,0,0)


;richtigen zoom berechnen
distancetoborder#=closestDistanceToBorder(mesh,cam2)
;sicherheitshalber was abziehen, 59° statt 60° nehmen
distance#=Tan(59)/(256.0-distancetoborder)
wunschdistance#=Tan(60)/256.0

zoom#=distance/wunschdistance

;mesh schwarz faerben fuer schatten, 1,1,1 damit maskapha benutzt werden kann
EntityFX mesh,0
EntityTexture mesh,whitetexture();LoadTexture("models/white.png")
EntityColor mesh,1,1,1

;schattentextur malen
CameraZoom cam2,zoom
RenderWorld
;bild speichern
shadowtexture=CreateTexture(512,512,4)
CopyRect(400-256,300-256,512,512,0,0,BackBuffer(),TextureBuffer(shadowtexture))
masktexture(shadowtexture)

;neues mesh erstellen
Local shadowmesh=CreateMesh()
surface=CreateSurface(shadowmesh)

;positionieren
MoveEntity shadowmesh,0,0.0001,0

;durchsichtig machen
EntityAlpha shadowmesh,0.5
EntityFX shadowmesh,48
;texturieren
EntityTexture shadowmesh,shadowtexture


;grid erstellen mit richtigen texturkoordinaten (wireframe anschauen, dann wirds klar Wink)
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



;wieder die normale ansicht akrivieren
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 Very Happy
"Ideen sind keine Coladosen, man kann sie nicht recyclen"-Dr. House
http://deeebian.redio.de/ http://goodjee.redio.de/
  • Zuletzt bearbeitet von Goodjee am Sa, Jan 09, 2010 16:32, insgesamt 2-mal bearbeitet

Silver_Knee

BeitragMo, Dez 28, 2009 10:46
Antworten mit Zitat
Benutzer-Profile anzeigen
da schreibst du extra ne funktion "whitetexture" und im code steht trotzdem:

LoadTexture("models/white.png")

zeile 87: ersetzen durch Whitetexture()

EDIT:
Abgesehen davon sind meshs sowieso weiß und man bräuchte diese zeile nicht.

Goodjee

BeitragMo, Dez 28, 2009 12:46
Antworten mit Zitat
Benutzer-Profile anzeigen
hoppla...das ist tatsächlich blödsinn

das braucht man aber wnen man texturierte meshes bearbeiten will
"Ideen sind keine Coladosen, man kann sie nicht recyclen"-Dr. House
http://deeebian.redio.de/ http://goodjee.redio.de/

Silver_Knee

BeitragMo, Dez 28, 2009 12:51
Antworten mit Zitat
Benutzer-Profile anzeigen
ah k

Neue Antwort erstellen


Übersicht BlitzBasic Codearchiv

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group