Odd problem with blending (I think) - help!

Blitz3D Forums/Blitz3D Programming/Odd problem with blending (I think) - help!

Rottbott(Posted 2003) [#1]
Okay this is slightly complicated but I'll explain as best as I can. I'm making a sort of top down space game. The camera is at (0, 900, 0) and pointed straight down. The camera does not move. My ships move along the X and Z axes but are always at 0 on the Y axis. I wanted to have a background of twinkling stars. First I made a Plane entity, textured it with stars, and positioned it at (0, -40, 0). This gave me a starry background. To make the stars twinkle I made a texture that is mostly white with some darker lines in it, and applied to another plane below the stars at (0, -50, 0). I set my stars plane to blend mode #2 (MULTIPLY). Then I scroll the white/dark lines texture. The result is perfect - I get nice stars that occasionally dim for a moment giving a nice overall twinkling impression.

The problem arises when I try to have my spaceships leave a trail of fire behind them. The way I do this is a trail of little fire-texture particles with the blend mode set to 3 (ADD). Without the starry background, it looks perfect. However when I have both at the same time, I get a strange problem. When the ship is near the centre of the screen, everything works fine, but when I move it to the edges, the particles stop showing up at all except where they go over the top of the ship. It's like a circle around the centre of the screen where they show up against the stars, and outside it they don't.

I tried using Orthogonal projection and it made no difference. My particles are not going below the level of the planes at all. I think it's some sort of blending problem but I really don't know.

Ideas, anyone?

EDIT: This may or may not help explain what I'm doing:



Ross C(Posted 2003) [#2]
Do you really need to blend the particles using entityblend? I've never used EntityBlend before, so i don't know what effects it gives you.


sswift(Posted 2003) [#3]
Your camera range may be set wrong. Or, your starry background is a sphere that is clipping the fire. OR, the starry background is a plane and the particles are in a plane which is so close to the starry background that those areas near the edge are swapping what's in front and what's in back cause there's not enough precision in the zbuffer. I think it's likely the last of these three.

Set your camera range so that the ratio between near and far planes is as small as possible. ie, 0.1, 100 is worse than 1,100, or 0.1, 10.

This will correct any zbuffer issues, but you still need to make sure that the particles aren't actually at the same Z detph as the stars... int he same plane as them, otherwise they'll never sort right. So move the stars firther away from the camera than the add blended stuff.


Rottbott(Posted 2003) [#4]
Yep. With EntityBlend EN, 3 (ADD) it gives a very bright burning type thing where multiple particles overlap and generally looks extremely good. With the default blend (ALPHA) it's kind of drab and boring and dull and stuff. So, er, yeah.


Rottbott(Posted 2003) [#5]
SSwift,
Camera range is set to 10.0, 1000.0. I have confirmed it isn't Z-buffer issues. The stars plane is at -40.0, the particle quads are all above 0.0. I am also running in 32bit mode so there's a nice and accurate Z-buffer.

I have tried camera ranges of (10.0, 1000.0), (500.0, 1000.0), (10.0, 2500.0), (500.0, 2500.0), and (10.0, 20000.0), (500.0, 20000.0). None made any difference to anything whatsoever in the slightest.


Rottbott(Posted 2003) [#6]
I have done some testing and it turns out that the further away the camera is from the origin, the further from the camera the ship has to go before the particles become invisible. Odd. It means that at a sufficient distance they always show up but right near to it, they only show up in the very middle of the screen.


sswift(Posted 2003) [#7]
Post your code.


Rottbott(Posted 2003) [#8]
Okay there's quite a lot so I made a simple 100 line version to demonstrate the problem. Here's the code:

Graphics3D 800, 600, 16, 2

; Types
Type Player
  Field EN
  Field Accelerate, Turn
  Field ZV#
End Type

Type Fire
  Field EN, X#, Z#, Age
End Type

; Globals
Global Cam

; Camera and lighting
Cam = CreateCamera() : CameraRange Cam, 10.0, 2500.0 : CameraZoom Cam, 1.5
PositionEntity Cam, 0, 900, 0 : RotateEntity Cam, 90, 0, 0
L = CreateLight(2) : EntityParent L, Cam : PositionEntity L, 0, 0, 0
LightRange L, 10000.0

; Backgrounds
B1 = CreatePlane() : PositionEntity B1, 0, -50, 0 : EntityFX B1, 9
B2 = CreatePlane() : PositionEntity B2, 0, -40, 0 : EntityFX B2, 9 : EntityBlend B2, 2
BT1 = LoadTexture("Data\VLines.bmp") : ScaleTexture BT1, 512, 512 : EntityTexture B1, BT1
BT2 = LoadTexture("Data\Stars.bmp") : ScaleTexture BT2, 1200, 1200 : EntityTexture B2, BT2

; Fire particle template
FireEN = CreateQuad() : ScaleMesh FireEN, 20.0, 20.0, 1 : EntityFX FireEN, 1 : EntityBlend FireEN, 3
FireTex = LoadTexture("Data\Fire.bmp") : EntityTexture FireEN, FireTex
HideEntity FireEN

; Player ship
Me.Player = New Player
Me\EN = LoadMesh("Data\Ship.b3d")

; Main loop
While Not KeyHit(1)

  ; Ship controls
  Me\Turn = KeyDown(205) - KeyDown(203)
  Me\Accelerate = KeyDown(200) - KeyDown(208)
  ; Turning
  If Me\Turn <> 0
    Roll# = CurveValue#(EntityRoll#(Me\EN), -40.0 * Me\Turn, 5.0)
    RotateEntity Me\EN, EntityPitch#(Me\EN), EntityYaw#(Me\EN), Roll#
    TurnEntity Me\EN, 0, -4 * Me\Turn, 0, True
  EndIf
  Roll# = CurveValue#(EntityRoll#(Me\EN), 00.0, 20.0)
  RotateEntity Me\EN, EntityPitch#(Me\EN), EntityYaw#(Me\EN), Roll#
  ; Moving
  Me\ZV# = Me\ZV# + 0.5 * Me\Accelerate
  If Me\ZV# > 18.0 Then Me\ZV# = 18.0 ElseIf Me\ZV# < 0.0 Then Me\ZV# = 0.0
  MoveEntity Me\EN, 0, 0, Me\ZV#
  ; Fire trail
  For i = 1 To Int(Ceil#(Me\ZV# / 2.0))
    F.Fire = New Fire : F\EN = CopyEntity(FireEN)
    PositionEntity F\EN, EntityX#(Me\EN), Rnd#(-10.0, 10.0), EntityZ#(Me\EN)
    RotateEntity F\EN, 0.0, EntityYaw#(Me\EN), 0.0 : MoveEntity F\EN, 0.0, 0.0, -30.0
    F\X# = Rnd#(-2.0, 2.0)
    F\Z# = Rnd#(-2.0, 2.0)
  Next

  ; Make stars twinkle
  BT1V# = BT1V# + 0.002
  PositionTexture BT1, 0.0, BT1V#

  UpdateFire
  UpdateWorld : RenderWorld : Flip
Wend
End

; Functions ------------------------------------------------------------------------------------------

; Updates all fire particles
Function UpdateFire()
  For F.Fire = Each Fire
    TranslateEntity F\EN, F\X#, 0.0, F\Z#
    PointEntity F\EN, Cam
    F\Age = F\Age + 1
    If F\Age > 15 Then FreeEntity F\EN : Delete F
  Next
End Function

; Creates a quad mesh
Function CreateQuad(P = 0)
  If P Then EN = CreateMesh(P) Else EN = CreateMesh()
  s = CreateSurface(EN)
  v1 = AddVertex(s, -1.0, -1.0, 0.0, 0, 1)
  v2 = AddVertex(s, 1.0, -1.0, 0.0, 1, 1)
  v3 = AddVertex(s, 1.0, 1.0, 0.0, 1, 0)
  v4 = AddVertex(s, -1.0, 1.0, 0.0, 0, 0)
  AddTriangle s, v1, v2, v3
  AddTriangle s, v1, v3, v4
  Return EN
End Function

Function CurveValue#(Current#, Destination#, Curve#)
  Return Current# + ((Destination# - Current#) / Curve#)
End Function



Rottbott(Posted 2003) [#9]
Here's a download containing the code & media:

http://www.marksweb.pwp.blueyonder.co.uk/files/test.zip


jhocking(Posted 2003) [#10]
I haven't checked through the code so this may not be it, but then it may be and it doesn't sound like you've considered it yet. Note that when an entity is set to ADD or MULTIPLY blend modes the z-buffer no longer applies to it. Now drawing order is determined simply by entity position, and whichever blended entity is closest to the camera is drawn before other blended entities.

The important thing here however is that entity position and polygon position are two different things. It may be (especially if you are using a single surface particle system) that the entity position of the particles is further from the camera than the starry plane, even though the particle polygons are closer.


Rottbott(Posted 2003) [#11]
Ah, that makes a lot of sense and would explain the 'symptoms' rather well. I'll try EntityOrdering my planes to the back then...

EDIT:
Well, as simple as that! Thanks :D I was making tbe mistake of considering polygon distance for Z-ordering rather than entity distance. So of course the middle of the plane was nearer to the camera than higher particles that were further away in the X/Z dimensions - UNTIL I MOVED THE CAMERA.

Funny how the most puzzling problems come from the silliest mistakes. Thanks all :-)


jhocking(Posted 2003) [#12]
Not silly at all. I think the number 1 problem I contend with daily is draw order problems for semi-transparent polygons (including both alpha and blending.)


Neochrome(Posted 2003) [#13]
i get the same problem, when something is off in the distance.


_PJ_(Posted 2003) [#14]
Have you tried setting AmbientLight to somewhere about 180,180,180

dunno - just an idea...


Ross C(Posted 2003) [#15]
Just used entityblend for my fire particles, and it looks pretty awesome. Thanks for bringing that command to my attention :) Sorry for being OT!


Rottbott(Posted 2003) [#16]
Watch out though 'cos add mode can be a wee bit slow on some older cards - or any strange blending mode for that matter.

It does look extremely cool though :-)