Code archives/3D Graphics - Effects/Milkyway Panorama
This code has been declared by its author to be Public Domain code.
Download source code
| |||||
My God - it's full of stars! This include creates a nice lowpoly milkyway background with a 360° panorama emission nebula, fixed stars and background stars combined. It uses a splitted texture where the upper part represents the panorama from 0-180° and the lower part from 180-360° put on an open cylinder object. Screenshot Here is a demo how to use, just save the code entry as "milkyway.bb" and run this, you can switch between two different milkyways using the LMB and fly around with the arrow keys: Media files: nebula.jpg star.png stars.png | |||||
Const StarSingleTexture$="star.png" ; single star Texture Const StarFieldsTexture$="stars.png" ; background starfield texture Const FogTexture$="nebula.jpg" ; 360° split panorama nebula texture Const StarTexScale#=1.5 ; texture scaling of background stars Const PanoSegments%=32 ; number of panorama segments (should be at least 8) ; ----------------------------------------------------------------------------- ; Initialize ; ----------------------------------------------------------------------------- Function InitMilkyway(Stars%,Dist#,MinAngle#,MaxAngle#,Scale,R1%=0,G1%=0,B1%=0,A1#=0.0,R2%=0,G2%=0,B2%=0,A2#=0.0,R3%=0,G3%=0,B3%=0,A3#=0.0) Local MilkyWay%,StarBox%,FogPanorama%,StarSphere% Local StarTex%,StarsTex%,FogTex% MilkyWay=CreatePivot() ; load textures StarTex=LoadTexture(StarSingleTexture,2) StarsTex=LoadTexture(StarFieldsTexture,2) FogTex=LoadTexture(FogTexture,16+32) ScaleTexture StarsTex,StarTexScale,StarTexScale ; create stars StarBox=InitStarBox(Scale,StarsTex,1,0) FogPanorama=InitPanorama(FogTex,Scale,Scale*0.8,PanoSegments,1+2+32,R1,G1,B1,A1,R2,G2,B2,A2,R3,G3,B3,A3) StarSphere=InitStarSphere(StarTex,Stars,0.5*(Scale/100.0),0.75*(Scale/50.0),0.5,Dist,MinAngle,MaxAngle,Scale,1) EntityParent StarBox,MilkyWay EntityParent FogPanorama,MilkyWay EntityParent StarSphere,MilkyWay ; reorder EntityOrder StarBox,3 EntityOrder FogPanorama,2 EntityOrder StarSphere,1 ; blending TextureBlend FogTex,5 EntityBlend FogPanorama,3 EntityBlend StarSphere,3 ;EntityBlend StarBox,3 Return MilkyWay End Function ; ----------------------------------------------------------------------------- ; create milkyway nebula panorama ; ----------------------------------------------------------------------------- Function InitPanorama(texture%,radius#,h#,segmente,fx%=0,r1%=255,g1%=255,b1%=255,a1#=1.0,r2%=255,g2%=255,b2%=255,a2#=1.0,r3%=255,g3%=255,b3%=255,a3#=1.0) Local ang1#,ang2#,inc#,x1#,z1#,x2#,z2# Local uu1#,uu2#,uv1#,uv2#,uv3# Local v0%,v1%,v2%,v3%,v4%,v5% Local mesh=CreateMesh() Local surf=CreateSurface(mesh) inc=360.0/segmente ang1=0 While ang1<360 ang2=(ang1+inc) Mod 360 x1=radius*Cos(ang1) z1=radius*Sin(ang1) x2=radius*Cos(ang2) z2=radius*Sin(ang2) If ang1<180 Then ; use upper texture UV coordinates uu1=1.0-(ang1/180.0) uu2=1.0-(ang1+inc)/180.0 uv1=0.50 uv2=0.25 uv3=0.00 Else ; use lower texture UV coordinates uu1=1-(((ang1/180.0))-1) uu2=1-(((ang1+inc)/180.0)-1) uv1=1.0 uv2=0.75 uv3=0.5 EndIf v0=AddVertex(surf,x1,-h,z1,uu1,uv1) : VertexColor surf,v0,r1,g1,b1,a1 v1=AddVertex(surf,x2,-h,z2,uu2,uv1) : VertexColor surf,v1,r1,g1,b1,a1 v2=AddVertex(surf,x1, 0,z1,uu1,uv2) : VertexColor surf,v2,r2,g2,b2,a2 v3=AddVertex(surf,x2, 0,z2,uu2,uv2) : VertexColor surf,v3,r2,g2,b2,a2 v4=AddVertex(surf,x1, h,z1,uu1,uv3) : VertexColor surf,v4,r3,g3,b3,a3 v5=AddVertex(surf,x2, h,z2,uu2,uv3) : VertexColor surf,v5,r3,g3,b3,a3 AddTriangle surf,v0,v1,v3 AddTriangle surf,v3,v2,v0 AddTriangle surf,v2,v5,v4 AddTriangle surf,v5,v2,v3 ang1=ang1+inc Wend EntityFX mesh,fx EntityTexture mesh,texture Return mesh End Function ; ----------------------------------------------------------------------------- ; create starsphere ; ----------------------------------------------------------------------------- Function InitStarSphere(texture%,stars%,min#,max#,fix#,centered#,centermin#,centermax#,range#,scale#=1.0) Local star%,mesh%,surf% Local i%,size#,a# Local r%,g%,b% Local col#,maxy# star=CreateStarQuad() mesh=CreateMesh() surf=CreateSurface(mesh) EntityFX mesh,1+2 For i=1 To stars ; create new surface if there are too many stars If CountVertices(surf)>=65532 Then surf=CreateSurface(mesh) ; size size=min*scale If Rnd(1)>fix Then size=Rnd(min,max)*scale ScaleEntity star,size,size,size ; reset quad PositionEntity star,0,0,0 ; more stars centered or random? If Rnd(1)>centered Then maxy=centermin Else maxy=centermax ; turn and move starquad TurnEntity star,Rnd(-Rnd(0,maxy),Rnd(0,maxy)),Rnd(0,Rnd(0,360)),0 MoveEntity star,0,0,range*scale PointEntity star,mesh ; color col=Rnd(1) If col>0.75 And col<=1.00 Then r=255 : g=224 : b=192 ; 25% orange stars If col>0.50 And col<=0.75 Then r=255 : g=255 : b=192 ; 25% yellow stars If col>0.25 And col<=0.50 Then r=192 : g=224 : b=255 ; 25% blue stars If col>0.00 And col<=0.25 Then r=255 : g=255 : b=255 ; 25% white stars ; alpha If size>min*scale Then a#=1.0 Else a#=Rnd(0.5,1) ; add to single surface mesh AddToSurface(star,surf,mesh,r,g,b,a) Next FreeEntity star EntityTexture mesh,texture FlipMesh mesh Return mesh End Function ; ----------------------------------------------------------------------------- ; simple cube starbox ; ----------------------------------------------------------------------------- Function InitStarBox(scale#,texture%,fx%,blend%) Local starbox% starbox=CreateCube() EntityTexture starbox,texture FlipMesh starbox ScaleEntity starbox,scale,scale,scale EntityFX starbox,fx EntityBlend starbox,blend Return starbox End Function ; ----------------------------------------------------------------------------- ; add a mesh to another mesh ; ----------------------------------------------------------------------------- Function AddToSurface(mesh,surf,singlesurfaceentity,r%,g%,b%,a#) Local vert%[2],vr%[2],vg%[2],vb%[2],va#[2] Local surface%,oldvert%,i%,i2% surface = GetSurface(mesh,1) For i = 0 To CountTriangles(surface)-1 For i2 = 0 To 2 oldvert = TriangleVertex(surface,i,i2) vr[i2]=r vg[i2]=g vb[i2]=b va[i2]=a TFormPoint VertexX(surface,oldvert),VertexY(surface,oldvert),VertexZ(surface,oldvert), mesh,singlesurfaceentity vert[i2] = AddVertex(surf,TFormedX(),TFormedY(),TFormedZ(),VertexU(surface,oldvert),VertexV(surface,oldvert)) VertexColor surf,vert[i2],r,g,b,a Next AddTriangle(surf,vert[0],vert[1],vert[2]) Next End Function ; ----------------------------------------------------------------------------- ; create star quad ; ----------------------------------------------------------------------------- Function CreateStarQuad(r%=255,g%=255,b%=255,a#=1.0,fx%=0) Local mesh%,surf%,v1%,v2%,v3%,v4% mesh=CreateMesh() surf=CreateSurface(mesh) v1=AddVertex(surf,-1,1,0,1,0) v2=AddVertex(surf,1,1,0,0,0) v3=AddVertex(surf,-1,-1,0,1,1) v4=AddVertex(surf,1,-1,0,0,1) VertexColor surf,v1,r,g,b,a VertexColor surf,v3,r,g,b,a VertexColor surf,v2,r,g,b,a VertexColor surf,v4,r,g,b,a AddTriangle(surf,0,1,2) AddTriangle(surf,3,2,1) EntityFX mesh,fx Return mesh End Function |
Comments
| ||
Very nice indeed Krischan. |
| ||
Beautifull! |
| ||
Gorgeous, will look into using this for another project :) |
| ||
It's really smooth and gives a great impression of depth. I didnt see this before, but found it after the "Procedural Saturn" stuff you did. I'm thinking, that, all this (excluding perhaps the very well defined star sprite') might be procedurally generated, giving dfifferent "shapes" and colours to the nebulae (within reason of course, the H-Alpha regions would likely be prominently red etc.) Even ikf the separate pieces are generated individually, this actually gives a greater freedom of 'mix and match' variety. Once i've finished playing with Saturn (I'm working on a means to seed a single, but different, AND RELATIVE value to make Neptune and Uranus so far....) I'll look into playing with generating this too :) |
| ||
Just to mention: the original PSD file for the Nebula has 170MB, 4096x1024 pixels and 18 Layers! I really want to see how to obtain the same result procedurally in a few seconds which costed me several days to create (mostly tweaking) :-D |
| ||
Just to mention: the original PSD file for the Nebula has 170MB, 4096x1024 pixels and 18 Layers! I really want to see how to obtain the same result procedurally in a few seconds which costed me several days to create (mostly tweaking) :-D Oh I certainly didn't mean to take anything from your artistic talent! Naturally an image like that you've worked on clearly so dedicatedly would be VERY difficult to even come close too. Perhaps I shouldn't have said |"it can be done procedurally" but rather, "something similar could be attempted [procedurally". The method (I presume) of building the nebula involved wvarious different 'levels' of density of the fibrous dust/gas carefully laid over each other with various transparencies... This same process can be achieved, but certainly not necesarily as well-defined or 'accurately' by (agaiun a noise function like perlin noise,- incidentally, did you use Photoshop's 'Difference Cloud' algorithm?', - to generate the structure of the dust-gas. This can be made more or less dense and then different levels applied over one another (by combining multiple alpha'd buffers into a final single buffer image) That's the theory at leastm, at any rate, it's worth a try! If that process can be reduced to some kind of algorithm or algorithms, then it need not even be done with a large 4096 image, but the algorithm can be repreated across smaller buffers to tile up to the large version. Certainly, I can say without a doubt that your work has paid off since the images are truly stunning, and if I can get anything done procedurally, it wont be half as nice to look at, but as an exercise in ther theory, I wanna give it a try all the same. It helps me learn too :) |
| ||
If you prefer a REAL panorama of our milkyway you should try this, I converted the ESO Milkyway Panorama (6000x3000 pixel!) for this. It is available in two DDS resolutions, 2048x2048 and 1024x1024 but I prefer the 2048 resolution, looks more realistic. To switch resolutions just change the line in the milkyway.bb. Just for your info if you want to include own images: the color level range of the nebula panorama should be from 0...127, otherwise it will be too overbright and look weird. Download Real Milkyway SFX [1.1MB] Screenshot with my latest Saturn demo |
| ||
damn, this is reach quality. great job. |
| ||
If you do use the 'real' milky way images in a program: remember that while most of the ones you'll find are free to use, they do require attribution in the credits. ESO, NASA, ESA, etc. all have similar requirements. |
Code Archives Forum