3D\ starfield

Blitz3D Forums/Blitz3D Beginners Area/3D\ starfield

Teffo(Posted 2005) [#1]
How does one make a Moving 3D starfield (textured quads) to orient themselves using a ships constantly changing angles?

I'm using coords- x and z (=left,right) and y=height

Or - what's the best approach to this problem?

Thanks
Teff


Teffo(Posted 2005) [#2]
Just FYI -
I'mm looking for something like this - except in 3D
When My ship turns, I would like to see the stars appear to look like a ship's turning etc..

Const MAX_STAR=5000,STAR_SPEED=2,WIDTH=640,HEIGHT=480

Dim star_x(MAX_STAR),star_y(MAX_STAR),star_z(MAX_STAR)

Graphics WIDTH,HEIGHT
SetBuffer BackBuffer()

setup_stars()

While Not KeyDown(1)
Cls
UpdateStar()
Flip
Wend
End

Function setup_stars()
For c=0 To MAX_STAR
star_x(c)=Rnd(-(WIDTH/2),(WIDTH/2))Shl 8
star_y(c)=Rnd(-(HEIGHT/2),(HEIGHT/2))Shl 8
star_z(c)=Rnd(STAR_SPEED,255)
Next
End Function

Function UpdateStar()
For c=0 To MAX_STAR
star_z(c)=star_z(c)-STAR_SPEED
If star_z(c)<=STAR_SPEED Then star_z(c)=255
s_x=(star_x(c)/star_z(c))+(WIDTH/2)
s_y=(star_y(c)/star_z(c))+(HEIGHT/2)
col=255-star_z(c)
Color col,col,col
Plot s_x,s_y
Next
End Function


jfk EO-11110(Posted 2005) [#3]
How do you mean "textured quads"? One star on one quad, or lots of stars on one quad?


Teffo(Posted 2005) [#4]
...a star texture was used on a single quad (2 tris) to keep poly count low.

Actually it works up to a point - i.e. the star objects appear to 'move' because the camera moves towards them, but what I wanted was to 'reuse' the unseen star objects behind the camera and move them forward again to be used again - much like recycling/redrawing lots of grass objects around as a player moves on terrain.

I cannot see how I could find out if the stars were behind the camera - because one second they are ahead, after turning 180, they are behind. Entity distance did not work there - as did DeltaZ.

So far I have not suceeded after trying about 6 methods.
What works the best is the 2D code above, but the stars overwrite the 3D enemy ships and the 3D hud display and secondly, it's just 2D (but that may be the best solution)

I even tried a skycube starfield pivoted to the camera, but that introduced other problems.

Yikes - what to do?
Teff


DJWoodgate(Posted 2005) [#5]
You could do a cameraproject or a tformpoint to find out if stars are behind the camera. If the first case ProjectedZ will be zero, in the second tformedz will be less than zero. Not sure which is faster. My guess is Cameraproject may be a bit quicker.


sswift(Posted 2005) [#6]
Here is how to find out if a point is in front of a camera, or any other object:

TFormPoint EntityX#(Blah, 0), EntityY#(Blah, 0), EntityZ#(Blah, 0), 0, Camera

If TformedZ() is positive, then the point is in front of the camera. If it is negative, then the point is behind the camera.

The trick is that the point is transformed from global space into camera space. So the point returned is on a grid which is aligned with the camera. You can also use this point to tell if an object is to the left or right, top or bottom as well, just by checking the sign on the X or Y axis.

Keep in mind though that if you use this for an entity, then it will only tell you if the center of the entity is behind the camera. You will want to check all eight corners of the entity to see if they are all behind the camera before you hide the entity.

You can also project those corners with camera project, and if all corners have coordinates which are above the top of the screen, of below the bottom, or beyond the left, or beyond the right, then the entity is not on the screen. Keep in mind though that all the points have to be on one side of a particular side of the screen. Having some points off the top and some points off the bottom does not mean the entity is not on the screen, for example.


Teffo(Posted 2005) [#7]
sswift tried that and created the following code. It spawns new stars only if the camera is not being rotated. Once the Yangle<>0 then hell breaks loose.

Here's the example -
Hope ya can assist in this as I'm about to lose more hair

Teff


Graphics3D 1024,768,32 : SetBuffer BackBuffer() : SeedRnd MilliSecs()
Global x#,y#,z#,camera,light : camera=CreateCamera() : light=CreateLight()


Global speed=40 : Global numstars = 1000 : Global fardistance = 10000 : CameraRange camera,1,fardistance*2 : obj_scale=6
Dim stars(numstars) : master_star=CreateCube() : ScaleEntity master_star,obj_scale,obj_scale,obj_scale
d=fardistance
For i=1 To numstars
stars(i)=CopyEntity(master_star) : EntityColor stars(i),255,255,255 : PositionEntity stars(i),Rand(-d,d),Rand(-d,d),Rand(-d,d)
Next



timer1=MilliSecs()
While Not KeyDown( 1 )

get_keys()
rotate_ship()
update_stars()


UpdateWorld : RenderWorld
Text 0,0,"y#=" + y# : Text 1,75,"Triangles Rendered: "+TrisRendered()

Flip :Wend :End




Function update_stars()

For i=1 To numstars
st=stars(i)
TFormPoint EntityX#(st, 0), EntityY#(st, 0), EntityZ#(st, 0), 0, Camera
;behind camera then respawn in front of cam
If TFormedZ() <0
d=fardistance
xX# = TFormedX()
yY# = TFormedY()
zZ# = TFormedZ()

PositionEntity stars(i),EntityX(camera)+Rand(-d,d),EntityY(camera)+Rand(-d,d),EntityZ(camera)+d*0.5+Rand(d)
;PositionEntity stars(i),xX+Rand(-d,d),yY+Rand(-d,d),zZ+Rand(d)+d*0.5

EndIf
Next



End Function




Function get_keys()
If KeyDown( 203 )=True Then y#=+1
If KeyDown( 205 )=True Then y#=-1
If KeyDown( 200 )=True Then x#=+0.2
If KeyDown( 208 )=True Then x#=-0.2

If MilliSecs() > timer1 + 100
timer1=MilliSecs()
If y#>0 Then y#=y#-0.01
If y#<0 Then y#=y#+0.01
If x#>0 Then x#=x#-0.01
If x#<0 Then x#=x#+0.01
EndIf


End Function


Function rotate_ship()
;RotateEntity camera,x#,y#,z#,1
TurnEntity camera,x#,y#,z#,1
MoveEntity camera,0,0,speed
End Function


grindalf(Posted 2005) [#8]
cant you just use entityinview as in
if entityinview(camera,stars)=false repositionstar()


Teffo(Posted 2005) [#9]
Yes that's another good idea.
Went ahead and tried "if entityinview(camera,stars)"
and it did work. I may have to check to see the performance hit for using that command every 100ms for 1000 stars.

Teff


Teffo(Posted 2005) [#10]
Ok got the stars appearing infront of the camera very effectively. I have 200 sprites now and the effect when turning is very realistic.

I understand there's likely a faster way, but after 24 hours, this is where it stands.

Teff


Function update_stars()

If MilliSecs() > timer2 + 100
timer2=MilliSecs() : theta=50

For i=1 To numstars
st=stars(i)
If EntityInView(st,camera)=0
EntityParent st,camera
PositionEntity st,EntityX(camera),EntityY(camera),EntityZ(camera),1
RotateEntity st,EntityX(st)+Rand(-theta,theta),EntityY(st)+Rand(-theta,theta),1
EntityParent st,0
MoveEntity st,0,0,Rand(500)+1500
EndIf
Next

EndIf

End Function


jfk EO-11110(Posted 2005) [#11]
I wouln't now anything better than a particle system like this, be it sprites based or single surface. Of course, you should reuse the stars around the ship. You could position them using the current space cluster as random seed, so they are real stationary.

Then I'd add a sky sphere with a zillion of nice stars.