Code archives/3D Graphics - Effects/Fake mirrors

This code has been declared by its author to be Public Domain code.

Download source code

Fake mirrors by Andy2005
The example only uses a quad, but the same method can be used to produce all shapes if the FOV is calculated from the longest side and the UV are set in relation to a quad.
; fakemirrors 

width=800
height=600
fovsphere#=65.0
fovmirror#=70.0
texsize=512
testfl=1


Graphics3D width,height 

SetBuffer BackBuffer() 

; create textures
tex=CreateTexture( texsize,texsize,48+256)
tex2=CreateTexture( texsize,texsize,48+256)

;setup cube texture
SetBuffer TextureBuffer(tex2) 
ClsColor 255,255,255 
Cls
For q=1 To 200
Color Rnd(255),Rnd(255),Rnd(255)
Rect Rnd(640),Rnd(480),Rnd(32),Rnd(32)
Next
SetBuffer BackBuffer() 

; brushes
brush1=CreateBrush() 
BrushTexture brush1,tex 
BrushShininess brush1,1 
BrushFX brush1,1

brush2=CreateBrush() 
BrushTexture brush2,tex2

brush3=CreateBrush(255,0,0) 





; objects

sphere_object=CreateSphere()
sphere_pivot=CreatePivot(sphere_object)
sphere_camera=CreateCamera(sphere_object) 
light=CreateLight() 

cube2=CreateCube()
ScaleMesh cube2,200,200,200
FlipMesh cube2
PaintMesh cube2,brush2


mirror_object=CreateMesh() 
surf=CreateSurface(mirror_object) 
v0=AddVertex(surf,-5, 5, 0, 1.0, 0.0)  ; upper left 
v1=AddVertex(surf, 5, 5, 0, 0.0, 0.0)   ; upper right 
v2=AddVertex(surf, 5,-5, 0, 0.0, 1.0)   ; lower right 
v3=AddVertex(surf,-5,-5, 0, 1.0, 1.0)  ; lower left 
t0=AddTriangle(surf,v0,v1,v2) ; triangle 1 
t1=AddTriangle(surf,v2,v3,v0) ; triangle 2 

mirror_pivot_left=CreatePivot(mirror_object)
mirror_pivot_right=CreatePivot(mirror_object)
PositionEntity mirror_pivot_left,-10,10,0 
PositionEntity mirror_pivot_right,10,10,0 

mirror_camera=CreateCamera(mirror_object)

; paint objects
PaintMesh mirror_object,brush1 
PaintMesh sphere_object,brush3 


; posititon and orient objects
PositionEntity mirror_object,0,0,100 
RotateEntity light,45,0,0 
RotateEntity mirror_camera,0.0,180.0,0.0 


While Not KeyDown(1) 

Gosub movesphere
Gosub rmirror

Cls
HideEntity(mirror_camera)
ShowEntity(sphere_camera)

CameraZoom sphere_camera,(1.0 / Tan(fovsphere#/2.0))
CameraClsColor sphere_camera,0,0,0
RenderWorld 

frames=frames+1
If fpstimer < (MilliSecs() - 1000)
	fps=frames
	frames=0
	fpstimer=MilliSecs()
EndIf
Text 10,10, fps
Text 10,30, fovmirror#
Text 10,50, mirror_distance#


Flip 

Wend 

End 


.movesphere
	If KeyDown( 203) Then TurnEntity sphere_object,0,0.5,0
	If KeyDown( 205 ) Then TurnEntity sphere_object,0,-0.5,0
	If KeyDown( 200 ) Then MoveEntity sphere_object,0,0,0.5
	If KeyDown( 208 ) Then MoveEntity sphere_object,0,0,-0.5
	If KeyDown( 30 ) Then MoveEntity sphere_object,0,0.5,0
	If KeyDown( 44 ) Then MoveEntity sphere_object,0,-0.5,0
	If KeyHit(17) Then wire= Not wire

	WireFrame wire
Return


.rmirror
    HideEntity(sphere_camera)
    ShowEntity(mirror_camera)

	CameraClsColor mirror_camera,0,0,255
	PointEntity(sphere_pivot, mirror_object) 

        mirror_distance#=Abs(EntityDistance ( sphere_object, mirror_object))
        PositionEntity mirror_camera,0.0,0.0,mirror_distance#
	RotateEntity mirror_camera,EntityPitch(mirror_object)+(EntityPitch(sphere_pivot,1)*1.0),EntityYaw(mirror_object)+180+(EntityYaw(sphere_pivot,1)*-1.0),EntityRoll(mirror_object) 

	PointEntity(sphere_pivot, mirror_pivot_left) 
	fov1#=EntityYaw(sphere_pivot);*1.75
	PointEntity(sphere_pivot, mirror_pivot_right) 
	fov2#=EntityYaw(sphere_pivot);*1.75

	fovmirror#=Abs(fov2#-fov1#)

	CameraZoom mirror_camera,(1.0 / Tan(fovmirror#/2.0))

	Cls
	RenderWorld 
    CopyRect (width/2)-(texsize/2),(height/2)-(texsize/2),texsize,texsize,0,0,0,TextureBuffer(tex)
Return

Comments

Plantagenet2005
Coolness! How does this compare to cubemapping? Apart from the fact it looks better.


Andy2005
I honestly don't know!

I don't have the time, the interest or the knowledge to improve on this, which is why it's in the archives.

I was hoping some talented people could take a look at it and make something useful out of it.

As always, it's Crappy Code TM, so use it at your own perril :)


Andy


Kalisme2005
I just played with your code quickly... I'd say that the advantage of cube mapping is that it's more accurate (from my experiance).... I noticed the reflection of the ball was off a fair bit... but this is some REALLY great code, it's way faster than cube mapping so it's not much of a toll on the computer to create high resolution reflections... it actually reminds me of the mirrors in unreal... very cool indeed... I definatley think I'll be using this ;)


Plantagenet2005
personally I thought it looked better, my cubemaps have to be quite low res and donīt hold up too well in closeups. Iīm gonna check this out a bit mor closely.


Andy2005
>I'd say that the advantage of cube mapping is that it's
>more accurate (from my experiance).... I noticed the
>reflection of the ball was off a fair bit...

I programmed the above as a proof of concept, because people kept asking for mirrors which did not have to be a plane. It's bad code, in fact it's crap code, mostly because it's based on 'looking sort of ok', not 'being mathematically correct'.

I was hoping to convince the better programmers in the community to have a go at improving it to the point where it is 'mathematically correct', but few seem to be interested, even though it is very fast.

It's really great that you find it useful. If you manage to to improve it I would be very happy if you would post the the improvements so that someone can make that hall of mirrors FPS(interesting idea) we would all like to play.


Andy


Dock2005
This code doesn't work on my Intel Extreme laptop graphics card. I'm sure this doesn't bother a huge number of people, but it's worth people knowing.


Andy2005
>This code doesn't work on my Intel Extreme laptop graphics
>card. I'm sure this doesn't bother a huge number of
>people, but it's worth people knowing.

What is the problem?

Have you tried removing the +256 flag from the CreateTexture commands?


Andy


Oiduts Studios2008
you could do different shapes too, just saying.

; fakemirrors

width=800
height=600
fovsphere#=65.0
fovmirror#=70.0
texsize=512
testfl=1


Graphics3D width,height

SetBuffer BackBuffer()

; create textures
tex=CreateTexture( texsize,texsize,48+256)
tex2=CreateTexture( texsize,texsize,48+256)

;setup cube texture
SetBuffer TextureBuffer(tex2)
ClsColor 255,255,255
Cls
For q=1 To 200
Color Rnd(255),Rnd(255),Rnd(255)
Rect Rnd(640),Rnd(480),Rnd(32),Rnd(32)
Next
SetBuffer BackBuffer()

; brushes
brush1=CreateBrush()
BrushTexture brush1,tex
BrushShininess brush1,1
BrushFX brush1,1

brush2=CreateBrush()
BrushTexture brush2,tex2

brush3=CreateBrush(255,0,0)





; objects

sphere_object=CreateSphere()
sphere_pivot=CreatePivot(sphere_object)
sphere_camera=CreateCamera(sphere_object)
light=CreateLight()

cube2=CreateCube()
ScaleMesh cube2,200,200,200
FlipMesh cube2
PaintMesh cube2,brush2


mirror_object=CreateSphere()
surf=CreateSurface(mirror_object)
;v0=AddVertex(surf,-5, 5, 0, 1.0, 0.0) ; upper left
;v1=AddVertex(surf, 5, 5, 0, 0.0, 0.0) ; upper right
;v2=AddVertex(surf, 5,-5, 0, 0.0, 1.0) ; lower right
;v3=AddVertex(surf,-5,-5, 0, 1.0, 1.0) ; lower left
;t0=AddTriangle(surf,v0,v1,v2) ; triangle 1
;t1=AddTriangle(surf,v2,v3,v0) ; triangle 2

mirror_pivot_left=CreatePivot(mirror_object)
mirror_pivot_right=CreatePivot(mirror_object)
PositionEntity mirror_pivot_left,-10,10,0
PositionEntity mirror_pivot_right,10,10,0

mirror_camera=CreateCamera(mirror_object)

; paint objects
PaintMesh mirror_object,brush1
PaintMesh sphere_object,brush3


; posititon and orient objects
PositionEntity mirror_object,0,0,100
RotateEntity light,45,0,0
RotateEntity mirror_camera,0.0,180.0,0.0


While Not KeyDown(1)

Gosub movesphere
Gosub rmirror

Cls
HideEntity(mirror_camera)
ShowEntity(sphere_camera)

CameraZoom sphere_camera,(1.0 / Tan(fovsphere#/2.0))
CameraClsColor sphere_camera,0,0,0
RenderWorld

frames=frames+1
If fpstimer < (MilliSecs() - 1000)
fps=frames
frames=0
fpstimer=MilliSecs()
EndIf
Text 10,10, fps
Text 10,30, fovmirror#
Text 10,50, mirror_distance#


Flip

Wend

End


.movesphere
If KeyDown( 203) Then TurnEntity sphere_object,0,0.5,0
If KeyDown( 205 ) Then TurnEntity sphere_object,0,-0.5,0
If KeyDown( 200 ) Then MoveEntity sphere_object,0,0,0.5
If KeyDown( 208 ) Then MoveEntity sphere_object,0,0,-0.5
If KeyDown( 30 ) Then MoveEntity sphere_object,0,0.5,0
If KeyDown( 44 ) Then MoveEntity sphere_object,0,-0.5,0
If KeyHit(17) Then wire= Not wire

WireFrame wire
Return


.rmirror
HideEntity(sphere_camera)
ShowEntity(mirror_camera)

CameraClsColor mirror_camera,0,0,255
PointEntity(sphere_pivot, mirror_object)

mirror_distance#=Abs(EntityDistance ( sphere_object, mirror_object))
PositionEntity mirror_camera,0.0,0.0,mirror_distance#
RotateEntity mirror_camera,EntityPitch(mirror_object)+(EntityPitch(sphere_pivot,1)*1.0),EntityYaw(mirror_object)+180+(EntityYaw(sphere_pivot,1)*-1.0),EntityRoll(mirror_object)

PointEntity(sphere_pivot, mirror_pivot_left)
fov1#=EntityYaw(sphere_pivot);*1.75
PointEntity(sphere_pivot, mirror_pivot_right)
fov2#=EntityYaw(sphere_pivot);*1.75

fovmirror#=Abs(fov2#-fov1#)

CameraZoom mirror_camera,(1.0 / Tan(fovmirror#/2.0))

Cls
RenderWorld
CopyRect (width/2)-(texsize/2),(height/2)-(texsize/2),texsize,texsize,0,0,0,TextureBuffer(tex)
Return


Code Archives Forum