This is an example of an idea I had for rendering high polygon objects that are far away as billboards (ie textures on planes facing the camera). This isn't exactly an original idea (I think some modern game engines use it, like for example Far Cry), but I haven't seen it done before with DBP so here it is!
The crux of the idea is that far away objects change the angle at which they face the camera very slowly because, well, they are so far away. So to capitalize on this fact, we can take a new "snapshot" of the object only after a certain angle difference threshold has been crossed and apply that texture to the billboard in it's place. This allows for complex objects to be rendered only once every so often instead of on each cycle. Now for the LOD part: When the camera gets close enough to the object, the real high detail object is shown instead of the billboard (in this example that is when last update=-999).
Now about DB Pro -
The good news: DBP has a command for rendering camera views to textures - SET CAMERA TO IMAGE. This command is exactly what we need. I just position the high detail object in a "dark room" at the correct angle and distance and snap a picture of it using that command.
The bad news: DBP has bug with the SET CAMERA TO IMAGE command that does not allow you to set that image as transparent in real-time. This bug essentially kills this method for mutilple objects in a gamespace, because without transparency it looks very bad. Mike has promised me that it will be fixed in update 5.4 though.
Here is the code:
set display mode 1024,768,32
sync on
autocam off
load object "obj/oak.x",1
scale object 1,300,300,300
set object transparency 1,1
set object cull 1,0
set object texture 1,0,0
position object 1,0,0,0
yrotate object 1,90
load object "obj/oak.x",2
scale object 2,300,300,300
set object transparency 2,1
set object cull 2,0
set object texture 2,0,0
position object 2,0,1000000,0
yrotate object 2,90
make object plain 3,object size z(1),object size x(1)
`position object 3,3000,800,250
position object 3,0,800,0
scale object 3,140,125,140
set object transparency 3,1
color backdrop 0 : `rgb(150,150,150)
set camera range 100,40000
newx#=0
newz#=-2000
position camera 0,0,200,-2000
point camera 0,0,850,0
`make camera 1
`set camera to image 1,1,512,512
`position camera 1,0,100200,-1600
`point camera 1,0,750,0
`color backdrop 1,rgb(150,150,150)
`color backdrop 1,0
set object light 3,0
`set object filter 3,0
last_updated_angle = -999
distance=15
do
rem perform movement
rem rotate camera with mouse
cya#=wrapvalue(cya#+(mousemovex()))
cxa#=cxa#+(mousemovey()/2.0)
rem limit vertical angle
if cxa#<-45.0 then cxa#=-45.0
if cxa#>45.0 then cxa#=45.0
rem perform rotation smoothing
crx#=curveangle(cxa#,crx#,1.0)
cry#=curveangle(cya#,cry#,4.0)
rotate camera crx#,cry#,0
rem Get movement input for standard WASD movement
rem W
if KEYSTATE(17)=1
rem check for key combinations and set angle accordingly
rem A
if KEYSTATE(30)=1
a# = wrapvalue(camera angle y()-45)
else
rem D
if KEYSTATE(32)=1
a# = wrapvalue(camera angle y()+45)
else
a# = camera angle y()
endif
endif
newx# = newxvalue(newx#,a#,distance)
newz# = newzvalue(newz#,a#,distance)
else
rem S
if KEYSTATE(31)=1
rem check for key combinations and set angle accordingly
rem A
if KEYSTATE(30)=1
a# = wrapvalue(camera angle y()-135)
else
rem D
if KEYSTATE(32)=1
a# = wrapvalue(camera angle y()+135)
else
a# = wrapvalue(camera angle y()+180)
endif
endif
newx# = newxvalue(newx#,a#,distance)
newz# = newzvalue(newz#,a#,distance)
else
rem A
if KEYSTATE(30)=1
rem check for key combinations and set angle accordingly
rem W
if KEYSTATE(17)=1
a# = wrapvalue(camera angle y()-45)
else
rem S
if KEYSTATE(31)=1
a# = wrapvalue(camera angle y()-135)
else
a# = wrapvalue(camera angle y()-90)
endif
endif
newx# = newxvalue(newx#,a#,distance)
newz# = newzvalue(newz#,a#,distance)
else
rem D
if KEYSTATE(32)=1
rem check for key combinations and set angle accordingly
rem W
if KEYSTATE(17)=1
a# = wrapvalue(camera angle y()+45)
else
rem S
if KEYSTATE(31)=1
a# = wrapvalue(camera angle y()+135)
else
a# = wrapvalue(camera angle y()+90)
endif
endif
newx# = newxvalue(newx#,a#,distance)
newz# = newzvalue(newz#,a#,distance)
endif
endif
endif
endif
rem perform movement on first person camera
position camera newx#,200,newz#
if DistanceTo(1)<2000
show object 1
hide object 3
if refresh_texture=1
delete camera 1
refresh_texture = 0
endif
last_updated_angle=-999
else
point object 3,camera position x(),object position y(3),camera position z()
angle = atanfull(camera position x() - object position x(1),camera position z() - object position z(1))
if refresh_texture=1
texture object 3,1
` refresh_texture = 2
` endif
` if refresh_texture=2
delete camera 1
refresh_texture = 0
hide object 1
show object 3
endif
rem texture object after a certain threshold
if abs(last_updated_angle - angle)>5
make camera 1
set camera to image 1,1,512,512
color backdrop 1,0
position camera 1,2000*sin(angle),1000200,2000*cos(angle)
point camera 1,0,1000850,0
` set object transparency 2,1
` set object light 2,0
` set object filter 2,0
last_updated_angle = angle
refresh_texture = 1
endif
endif
sync
set cursor 0,0
print "Use W,A,S,D and the mouse to move around."
print "fps:";screen fps()
print "in screen:";object in screen(2)
print "last update:";last_updated_angle
loop
function DistanceTo(object1)
rem square distance
distanceX=abs(object position x(object1) - camera position x())
distanceZ=abs(object position z(object1) - camera position z())
if distanceX>distanceZ
distance=distanceX
else
distance=distanceZ
endif
endfunction distance
You can download the example here (including exe):
http://yarbles.zapto.org/billboard.rar
Credit for the tree model goes to Joe Brown (aka IpakAgun)
Any questions, suggestions or improvements are welcome!