Thread: 3D starfields regardless of ship position

  1. #1
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607

    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.

  2. #2
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    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.
    Last edited by VirtualAce; 03-12-2011 at 11:42 AM.

  3. #3
    Registered User
    Join Date
    Aug 2003
    Posts
    1,218
    Looks awesome!! And Im glad you finally got it working
    STL Util a small headers-only library with various utility functions. Mainly for fun but feedback is welcome.

  4. #4
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    Screenie with model in foreground. Obviously model needs much more, but at least I got the thing in the engine.
    Last edited by VirtualAce; 03-12-2011 at 11:42 AM.

  5. #5
    Crazy Fool Perspective's Avatar
    Join Date
    Jan 2003
    Location
    Canada
    Posts
    2,640
    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.

  6. #6
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607


    Yep the model needs a lot of help.

  7. #7
    Registered User Frobozz's Avatar
    Join Date
    Dec 2002
    Posts
    546
    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.
    Last edited by Frobozz; 10-17-2006 at 01:39 PM.

  8. #8
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    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.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Button handler
    By Nephiroth in forum Windows Programming
    Replies: 8
    Last Post: 03-12-2006, 06:23 AM
  2. Problem with linked list ADT and incomplete structure
    By prawntoast in forum C Programming
    Replies: 1
    Last Post: 04-30-2005, 01:29 AM
  3. Unknown Memory Leak in Init() Function
    By CodeHacker in forum Windows Programming
    Replies: 3
    Last Post: 07-09-2004, 09:54 AM
  4. LISP (DrScheme) any one?
    By Jeremy G in forum A Brief History of Cprogramming.com
    Replies: 5
    Last Post: 03-31-2004, 12:52 PM