Hullo!

Blitz3D Forums/Blitz3D Programming/Hullo!

Foolish Frost(Posted 2007) [#1]
Hullo. Just got blitz3d, and was looking it over. An interesting thing I found when playing with the Demo:

If you set objects to 1% transparency, they render faster. Try this demo, in the dragon demo directory. use s/x to change number of dragons, and e to turn 1% transparency on or off.

thoughts?


-----
copy the below code and add to the dragon demo directory, then run it.
---

;0,40 : idle
;40,46 : run
;46,54 : attack
;54,58 : paina
;58,62 : painb
;62,66 : painc
;66,72 : jump
;72,84 : flip

Dim dranim (8,2)
dranim (1,1) = 0 : dranim (1,2) = 40
dranim (2,1) = 40 : dranim (2,2) = 46
dranim (3,1) = 46 : dranim (3,2) = 54
dranim (4,1) = 54 : dranim (4,2) = 58
dranim (5,1) = 58 : dranim (5,2) = 62
dranim (6,1) = 62 : dranim (6,2) = 66
dranim (7,1) = 66 : dranim (7,2) = 72
dranim (8,1) = 72 : dranim (8,2) = 84

alpha# = .99

; ------------------------------------------------------------------
; GameCore -- support@...
; ------------------------------------------------------------------
; The basics of a frame-limited Blitz 3D game, ready to rock
; ------------------------------------------------------------------
; Adapted from Mark Sibly's code
; ------------------------------------------------------------------

Global info1$="Dragon Demo"
Global info2$="Use arrows keys to pan, A/Z to zoom, S/X to change number of dragons,"
Global info3$="E toggles alpha... MD2 Dragon model courtesy of Polycount"

Include "../start.bb"

; ------------------------------------------------------------------
; Game's frames-per-second setting
; ------------------------------------------------------------------

Global gameFPS = 30

;set up fps counter
fps_milli=MilliSecs(): fps_counter=0: update_frequency=10

; ------------------------------------------------------------------
; Open 3D display mode
; ------------------------------------------------------------------

Graphics3D 640, 480

; ------------------------------------------------------------------
; General setup
; ------------------------------------------------------------------

;environment cube
cube=CreateCube()
FitMesh cube,-250,0,-250,500,500,500
FlipMesh cube
tex=LoadTexture( "chorme-2.bmp" )
ScaleTexture tex,1.0/3,1.0/3
EntityTexture cube,tex
EntityAlpha cube,.4
EntityFX cube,1

;floor mirror
;m=CreateMirror()

;simple light
light=CreateLight()
TurnEntity light,45,45,0

;camera
camera = CreateCamera()
Global cam_xr#=30:Global cam_yr#=0:Global cam_zr#=0:Global cam_z#=-240

;cool dragon model!

;ffx = 5
;ffy = 5
;ffz = 5

arearange# = 320.0
basecritterarea# = 80.0
crittersize# = 1.0

distance = basecritterarea * crittersize

ffx = (arearange / distance) + 1
ffy = (arearange / distance) + 1
ffz = (arearange / distance) + 1


Dim dragon(ffx ,ffy ,ffz )

tex=LoadTexture( "model\dragon.bmp" )
dragon(1,1,1)=LoadMD2( "model\dragon.md2" )
EntityTexture dragon(1,1,1),tex

numdragonscounter = 0

For xx = 1 To ffx
For yy = 1 To ffy
For zz = 1 To ffz
If xx > 1 Or yy > 1 Or zz > 1
dragon(xx,yy,zz) = CopyEntity ( dragon(1,1,1) )
;dragon(xx,yy,zz) = CopyMesh ( dragon(1,1,1) )
EndIf
PositionEntity dragon(xx,yy,zz),(0 - (arearange / 2)) + ((xx-1)*distance ),25 + ((zz-1)*distance ),(0 - (arearange / 2)) + ((yy-1)*distance )
TurnEntity dragon(xx,yy,zz),0,150,0
ScaleEntity dragon(xx,yy,zz),crittersize ,crittersize ,crittersize

EntityAlpha dragon(xx,yy,zz),alpha

animcycle = animcycle + 1
If animcycle > 8
animcycle = 1
EndIf

AnimateMD2 dragon(xx,yy,zz),1,.1,dranim (animcycle ,1),dranim (animcycle ,2)

numdragonscounter = numdragonscounter + 1
Next
Next
Next


; ------------------------------------------------------------------
; Frame limiting code setup
; ------------------------------------------------------------------

framePeriod = 1000 / gameFPS
frameTime = MilliSecs () - framePeriod

Repeat

; --------------------------------------------------------------
; Frame limiting
; --------------------------------------------------------------

Repeat
frameElapsed = MilliSecs () - frameTime
Until frameElapsed

frameTicks = frameElapsed / framePeriod

frameTween# = Float (frameElapsed Mod framePeriod) / Float (framePeriod)

; --------------------------------------------------------------
; Update game and world state
; --------------------------------------------------------------

For frameLimit = 1 To frameTicks

If frameLimit = frameTicks Then CaptureWorld
frameTime = frameTime + framePeriod

UpdateGame ()

PositionEntity camera,0,250,0
RotateEntity camera,cam_xr,cam_yr,cam_zr
MoveEntity camera,0,0,cam_z


UpdateWorld

Next

; --------------------------------------------------------------
; **** Wireframe for DEBUG only -- remove before release! ****
; --------------------------------------------------------------

If KeyHit (17): w = 1 - w: WireFrame w: EndIf ; Press 'W'

If KeyHit (18)

If alpha = .99
alpha = 1.0
Else
alpha = .99
EndIf


For xx = 1 To ffx
For yy = 1 To ffy
For zz = 1 To ffz

EntityAlpha dragon(xx,yy,zz), alpha

Next
Next
Next
EndIf

If KeyHit (31)

crittersize = crittersize + .1
If crittersize > 5.0 Then crittersize = 5.0
redrawdragons = 1

EndIf

If KeyHit (45)

crittersize = crittersize - .1
If crittersize < .3 Then crittersize = .3
redrawdragons = 1

EndIf

If redrawdragons = 1
redrawdragons = 0
For xx = 1 To ffx
For yy = 1 To ffy
For zz = 1 To ffz

FreeEntity dragon(xx,yy,zz)

Next
Next
Next

distance = basecritterarea * crittersize

ffx = (arearange / distance) + 1
ffy = (arearange / distance) + 1
ffz = (arearange / distance) + 1


Dim dragon(ffx ,ffy ,ffz )

tex=LoadTexture( "model\dragon.bmp" )
dragon(1,1,1)=LoadMD2( "model\dragon.md2" )
EntityTexture dragon(1,1,1),tex

numdragonscounter = 0

For xx = 1 To ffx
For yy = 1 To ffy
For zz = 1 To ffz
If xx > 1 Or yy > 1 Or zz > 1
dragon(xx,yy,zz) = CopyEntity ( dragon(1,1,1) )
;dragon(xx,yy,zz) = CopyMesh ( dragon(1,1,1) )
EndIf
PositionEntity dragon(xx,yy,zz),(0 - (arearange / 2)) + ((xx-1)*distance ),25 + ((zz-1)*distance ),(0 - (arearange / 2)) + ((yy-1)*distance )
TurnEntity dragon(xx,yy,zz),0,150,0
ScaleEntity dragon(xx,yy,zz),crittersize ,crittersize ,crittersize

EntityAlpha dragon(xx,yy,zz),alpha

animcycle = animcycle + 1
If animcycle > 8
animcycle = 1
EndIf

AnimateMD2 dragon(xx,yy,zz),1,.1,dranim (animcycle ,1),dranim (animcycle ,2)

numdragonscounter = numdragonscounter + 1
Next
Next
Next

EndIf


; --------------------------------------------------------------
; Draw 3D world
; --------------------------------------------------------------

RenderWorld frameTween
Text 0,00,"Notice the framerate increase when alpha is turned on by even 1%"
Text 0,20,"The dragons still seem to be sorted properly, but why the speed increase?"
Text 0,40,"Dragons:"+numdragonscounter

; fps counter
fps_counter=fps_counter+1
If fps_counter=update_frequency
fps=1000/Float(((MilliSecs()-fps_milli))/update_frequency)
fps_milli=MilliSecs()
fps_counter=0
EndIf

; print fps
Text 0,60,"FPS:"+fps

Text 0,80,"Alpha:"+alpha

; --------------------------------------------------------------
; Show result
; --------------------------------------------------------------

Flip

Until KeyHit (1)

End

; ------------------------------------------------------------------
; Game update routine, called from frame limiting code
; ------------------------------------------------------------------

Function UpdateGame ()

If KeyDown(203)
cam_yr=cam_yr-2
Else If KeyDown(205)
cam_yr=cam_yr+2
EndIf

If KeyDown(200)
cam_xr=cam_xr+2
If cam_xr>90 cam_xr=90
Else If KeyDown(208)
cam_xr=cam_xr-2
If cam_xr<5 cam_xr=5
EndIf

If KeyDown(26)
cam_zr=cam_zr+2
Else If KeyDown(27)
cam_zr=cam_zr-2
EndIf

If KeyDown(30)
cam_z=cam_z+1:If cam_z>-10 cam_z=-10
Else If KeyDown(44)
cam_z=cam_z-1:If cam_z<-240 cam_z=-240
EndIf

cam_yr=cam_yr+1

End Function


bytecode77(Posted 2007) [#2]
you are optimazing at the wrong point. when making a game you should optimize in particle uses etc by 20% instead of 1% on transparency...

it sould be ~2% slower than 1% faster anyway.
cu


Foolish Frost(Posted 2007) [#3]
What? Sorry. Have no idea what you're talking about. My point was that I find it interesting that using alpha at ALL speeds up rendering. I would think that transparency would SLOW the render rate.


Danny(Posted 2007) [#4]
Yes you're right, that's very weird indeed!

I do have to change the "Flip" to "Flip 0" - else it will remain stuck at 60fps.

But with alpha @ 0.99 I get a steady 200FPS whilst alpha @ 1.0 drops it to 160FPS!

I was gonna say this probably has something to do with the fact that the dragon demo uses render-tweening. But when I disabled it, I get the exact same results! So err... I got no explenation ;)

Interesting!

d.


Danny(Posted 2007) [#5]
Like you mention in the code, my guess is that it 'skips' some internal z-sort. Since Blitz is known to 'not' properly sort transparent entities. But I'll do a test and set 'all my entities' to 0.99 alpha to see if it does make a difference....

danny


Ice9(Posted 2007) [#6]
Z sort is done by the entity or childs origin when it's
transparent so yes that may be the case Danny. i once had
a butterfly model with transparent wings and the rear wing
was drawing in front of the front wing until I moved its
origin.


Tom(Posted 2007) [#7]
ZBuffer *writes* are normally disabled when drawing geometry with alpha, so it might be a little less overhead on GFX card.


If you're interested: 'Why are ZWrites disabled?'

Picture this scenario. A semi-transparent cube. If it was drawn with Z-Writes enabled, then ZBuffer would be updated with the 'nearest Z distance' of the cube geometry.

Now what if we wanted to draw a smaller cube inside the 1st, semi-transparent!, box?

During the drawing of the smaller box, it's geometrys Z distance would be compared to the Z-Buffer... and because it would be GREATER THAN in this case, the smaller cube would not be drawn.

So when drawing transparent geometry, the Z-Buffer is NOT updated (ZWrites are disabled!)


This is not the case for geometry using masked textures in B3D. The opaque parts of a masked texture ARE written to the ZBuffer.

This also why when using ALPHA for say 'grass' textures you need to sort the geometry manualy so the furthest away gets drawn first (else it'll look ugly & randomly overlapped). Using masked textures you don't have to do any sorting!

As a test, apply a masked texture instead of one loaded with the alpha flag. It *should* render about the same as the non-alpha scene.
Tom


Danny(Posted 2007) [#8]
Thanks for that explenation Tom!

But one thing I don't understand; When you mentioned the 'grass' geometry needing manual sorting, you're talking about a single surface (particle) system right?!

Ok, but you're saying 'masked' textures DO NOT need manual sorting. With 'Masked' do you mean a 24bit color-only texture that has for example the background PURPLE (ie. giving nasty non-antialiased edges) - as opposed to a 32bit color+alpha channel texture (which DOES need manual sorting - but gives nice smooth edges where the texture goes from transparent to opaque) ?!

If that's true, that's cool because I didn't knew that! ;)

Thanks,
Danny.


Tom(Posted 2007) [#9]
Single surface for the grass yeah. Single surface is currently the fastest & best method for doing grass.

Masked textures do have harsh edges, because their pixels are either fully opaque, or fully transparent. No alpha blending is used when drawing masked textures.


Danny(Posted 2007) [#10]
Ok, I'm probably the last to come up with this obvious idea; But ...

Would it be possible then to use ALPHA textures (on a single surface system) but somehow triggering or forcing Blitz/DX7 to treat it as a MASKED texture?

With the obvious goal to have 'aplha textured' grass without the need of manually z-sorting each poly (costing precious fps)?!
I assume this can't be done using the default Blitz3D commands and options, but since you've got a much more in-depth undertanding of dx7, I can imagine this might perhaps be possible ?!?!?!??

Danny.


Tom(Posted 2007) [#11]

Would it be possible then to use ALPHA textures (on a single surface system) but somehow triggering or forcing Blitz/DX7 to treat it as a MASKED texture?


Unortunately not. At least, you could force the settings but it wouldn't look right.

There are tricks to speeding up grass systems. You can pre-caululate 4 versions of your grasses mesh, each Z sorted to a dominant axis (-X, +X, -Z, +Z), then display the appropriate mesh depending on which dominant axis your camera is looking. Search the forums, there's many topic & examples.