# 3D starfields regardless of ship position

• 10-15-2006
VirtualAce
3D starfields regardless of ship position
Some time ago we talked about this and ways to achieve it. Because this is not as simple as it sounds I'm going to show everyone how to do it, or at least the way I did it.

Note that the method I present here would be useful for such things as randomly creating foliage quads around a player in a FPS shooter much like Joint Operations. It will also work for special cloud effects, nebula effects, smoke effects, etc.

The problem:

• Create a randomly generated starfield around a point in 3D space
• The starfield must react to camera pitch, roll, and yaw.
• The starfield must be able to move reflecting the current vector of the camera.
• The starfield must always be present, thus it must regenerate itself.
• The starfield must use a single vertex buffer

The main problem here is that you need to generate your vertices in model space, not world space. This way you can test easily for when the vertices are too far from center and need to be regenerated.

The simple solution is to generate the vertices around 0,0,0 using a max radius to determine distance from 0,0,0. The next step is to 'move' those vertices to the camera position. So you translate by cameraX,cameraY, and cameraZ.
Now if you run the code you would have a nice starfield around your camera in all directions. The last part is moving the vertices and testing for regeneration conditions.

To move the stars you simply move them in model space by the negative camera look vector mutliplied by a speed multiplied by frame delta. Note that just because the actual camera is moving at say 10 or 20 units does not mean your starfield has to. Regen condition would be when x*x+y*y+z*z = radius_squared. Then you simply regenerate the star somewhere around the camera. You may think to only regen in front of the camera but this brings an uneven distribution of vertices in front of the camera which is very noticeable when the viewpoint changes.

Your starfield is not really part of the world, but it appears to be because of the translation. When you translate the starfield to camera position, here is what happens:

If you have a star with vertex at 0,0,0 and a camera at 100,100,100 - after translation the star is really at 100,100,100, but remains at 0,0,0 in your vertex buffer. So by translating the star to the camera position, you actually make the camera position the center of the world or 0,0,0.

Code:

```#pragma once #include "CStarXApp.h" #include "CCamera.h" #define STARVERTEX_FVF D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR struct StarVertex {   D3DXVECTOR3 vecPos;   D3DCOLOR    dwDiffuse;   D3DCOLOR    dwSpecular;     static const DWORD FVF;   StarVertex():vecPos(D3DXVECTOR3(0.0f,0.0f,0.0f)),dwDiffuse(0),dwSpecular(0) { }   StarVertex(float x,float y,float z,UINT uDiffuse,UINT uSpecular):             vecPos(D3DXVECTOR3(x,y,z)),dwDiffuse(uDiffuse),             dwSpecular(uSpecular) { }             };     class CStars {   protected:     CCamera *m_spCamera;         IDirect3DDevice9 *m_spDevice;         StarVertex m_Stars[3000];         int m_iMaxZ2;     int m_iMaxZ;         void Render();     void GenerateStar(int iIndex);         D3DXMATRIX m_matRot;           public:     CStars(void) { }     virtual ~CStars() { }             void Create(IDirect3DDevice9 *pDevice,int iMaxZ);     void Update(float fZDelta,float fTimeDelta,D3DXVECTOR3 vecCameraPos);     void SetCamera(CCamera *pCamera) {m_spCamera=pCamera;}         void SetRotMatrix(float rx,float ry,float rz);         };```
Code:

```void CStars::Render() {   m_spDevice->SetRenderState(D3DRS_CULLMODE,D3DCULL_NONE);    m_spDevice->SetFVF(STARVERTEX_FVF);   m_spDevice->DrawPrimitiveUP(D3DPT_POINTLIST,500,&m_Stars,sizeof(StarVertex)); } void CStars::Create(IDirect3DDevice9 *pDevice,int iMaxZ) {   m_spDevice=pDevice;   m_iMaxZ=iMaxZ;   m_iMaxZ2=iMaxZ<<1;       for (int i=0;i<3000;i++)   {     GenerateStar(i);   }     } void CStars::Update(float fZDelta,float fTimeDelta,D3DXVECTOR3 vecCameraPos) {   StarVertex *ptrVert=&m_Stars[0];     int x=0,y=0,z=0;     D3DXVECTOR3 vecMove;   m_spCamera->GetLook(&vecMove);   int result=0;     for (int i=0;i<3000;i++,ptrVert++)   {     ptrVert->vecPos-=vecMove*fZDelta*fTimeDelta;       float fDist=D3DXVec3Length(&ptrVert->vecPos);                   if (fDist>=(float)m_iMaxZ)     {                 x=-m_iMaxZ+ rand()%m_iMaxZ2;       y=-m_iMaxZ+ rand()%m_iMaxZ2;       z=-m_iMaxZ+ rand()%m_iMaxZ2;               ptrVert->vecPos=D3DXVECTOR3((float)x,(float)y,(float)z);       ptrVert->dwDiffuse=D3DXCOLOR(1.0f,1.0f,1.0f,1.0f);       ptrVert->dwSpecular=D3DXCOLOR(1.0f,1.0f,1.0f,1.0f);                    }   }   D3DXMATRIX matTrans;   D3DXMatrixTranslation(&matTrans,vecCameraPos.x,vecCameraPos.y,vecCameraPos.z);   m_spDevice->SetTransform(D3DTS_WORLD,&matTrans);       Render(); } void CStars::GenerateStar(int iIndex) {     int x=-m_iMaxZ+ rand()%m_iMaxZ2;   int y=-m_iMaxZ+ rand()%m_iMaxZ2;   int z=-m_iMaxZ+ rand()%m_iMaxZ2;           m_Stars[iIndex].vecPos=D3DXVECTOR3((float)x,(float)y,(float)z);   m_Stars[iIndex].dwDiffuse=D3DXCOLOR(1.0f,1.0f,1.0f,1.0f);   m_Stars[iIndex].dwSpecular=D3DXCOLOR(1.0f,1.0f,1.0f,1.0f);    }```
Note that there are several more effects for this starfield such as making them alpha blended line segments, alpha and/or intensity based on distance from camera, etc, etc.
• 10-16-2006
VirtualAce
A sample of the system in action along with a skybox and billboard for the sun. And yes, I'm back to a space game here. :)

The smaller stars in the skybox are created using a second tiled texture which is additive blended with the six textures of the skybox.

I'm working on a D3DXMesh class and some models and textures for models. I'll post screenies as soon as I get it all working.

There is no default lighting in this system. I'm going to be using several pixel shaders for some ..hopefully...nifty effects and lighting.

The star system here is quite large. It would probably take more than 3 hours to reach that distant sun. This, like other games, will employ jump gates for long distance travelling.
• 10-16-2006
Shakti
Looks awesome!! And Im glad you finally got it working
• 10-17-2006
VirtualAce
Screenie with model in foreground. Obviously model needs much more, but at least I got the thing in the engine.
• 10-17-2006
Perspective
looks good.

Don't take this the wrong way, but that screen shot just gave me the greatest idea for a game. Paper airplane wars!!!! ;)

Imagine piloting dispensible paper planes of increasing coolness with Crayola rockets and pink gum eraser bombs. :)
• 10-17-2006
VirtualAce
:D

Yep the model needs a lot of help.
• 10-17-2006
Frobozz
Quote:

Originally Posted by Perspective
Don't take this the wrong way, but that screen shot just gave me the greatest idea for a game. Paper airplane wars!!!! ;)

Imagine piloting dispensible paper planes of increasing coolness with Crayola rockets and pink gum eraser bombs. :)

So get to it. And then try publishing it on GarageGames.com. ;)

Bubba: The stars look like they're drawn on a sky cube.
• 10-17-2006
VirtualAce
They are. There are true 3D 'stars' to make it appear that you are moving and then there are background stars. I've seen other games use this to good effect. It's impossible to stick millions of 3D stars out there to represent space.