Galaxy Generation – 3D Nebulae

Gigantische dreidimensionale Nebel gehören zu den schönsten und zugleich faszinierendsten Gebilden im Universum. Im heutigen Beitrag widmen wir uns der Verteilung und Farbgebung dieser Nebelwolken; mit der Nebel- und Sternen-Darstellung werden wir uns dann in den nächsten Artikelen befassen.






Beim Rendern der Nebelwolken-Objekte kommen texturierte 3D-Modelle zum Einsatz. Die Anzahl der hierbei verwendeten Texturen lässt sich nach belieben festlegen. Zu beachten ist, dass in den Texturen möglichst nur Grauwerte gespeichert sein sollten, denn die Farbgebung erfolgt unabhängig von der Texturierung:






Num3DNebulaTextures: 4

../Data/Textures/Local3DNebulae/Local3DNebula1.bmp
../Data/Textures/Local3DNebulae/Local3DNebula2.bmp
../Data/Textures/Local3DNebulae/Local3DNebula3.bmp
../Data/Textures/Local3DNebulae/Local3DNebula4.bmp


Um möglichst abwechslungsreiche Nebelwolken-Verteilungen mit möglichst wenigen Parametern zu erhalten, verwenden wir insgesamt vier unterschiedliche Datensätze für die Beschreibung (Skalierung sowie Farbgebung) der einzelnen Wolkentypen. Darüber hinaus lässt sich jeden Datensatz die Häufigkeit seiner Verwendung (DistributionValueMin/Max) festlegen.

Datensatz 1:

RandomColorNebulaObjectScaleMin: 34.0
RandomColorNebulaObjectScaleMax: 40.0

RandomColorNebulaObject_RedMin: 0.4
RandomColorNebulaObject_RedMax: 0.8

RandomColorNebulaObject_GreenMin: 0.1
RandomColorNebulaObject_GreenMax: 0.2

RandomColorNebulaObject_BlueMin: 0.1
RandomColorNebulaObject_BlueMax: 0.2


RandomColorNebulaObject_DistributionValueMin: 0.0
RandomColorNebulaObject_DistributionValueMax: 0.2


Datensatz 2:

RedColorNebulaObjectScaleMin: 32.0
RedColorNebulaObjectScaleMax: 34.0

RedColorNebulaObject_RedMin: 0.5
RedColorNebulaObject_RedMax: 0.8

RedColorNebulaObject_GreenMin: 0.0
RedColorNebulaObject_GreenMax: 0.0

RedColorNebulaObject_BlueMin: 0.0
RedColorNebulaObject_BlueMax: 0.0

RedColorNebulaObject_DistributionValueMin: 0.2
RedColorNebulaObject_DistributionValueMax: 0.4


Datensatz 3:

GreenColorNebulaObjectScaleMin: 32.0
GreenColorNebulaObjectScaleMax: 34.0

GreenColorNebulaObject_RedMin: 0.0
GreenColorNebulaObject_RedMax: 0.0

GreenColorNebulaObject_GreenMin: 0.5
GreenColorNebulaObject_GreenMax: 0.8

GreenColorNebulaObject_BlueMin: 0.0
GreenColorNebulaObject_BlueMax: 0.0

GreenColorNebulaObject_DistributionValueMin: 0.4
GreenColorNebulaObject_DistributionValueMax: 0.4


Datensatz 4:

BlueColorNebulaObjectScaleMin: 34.0
BlueColorNebulaObjectScaleMax: 40.0

BlueColorNebulaObject_RedMin: 0.0
BlueColorNebulaObject_RedMax: 0.0

BlueColorNebulaObject_GreenMin: 0.0
BlueColorNebulaObject_GreenMax: 0.0

BlueColorNebulaObject_BlueMin: 0.5
BlueColorNebulaObject_BlueMax: 1.4

BlueColorNebulaObject_DistributionValueMin: 0.4
BlueColorNebulaObject_DistributionValueMax: 1.0


Die Nebelwolken selbst werden in der Umgebung der einzelnen Sterne positioniert. Soll sich in der Nähe eines jeden Sterns mindestens eine Nebelwolke befinden, so muss der NebulaProbabilityFactor auf 100.0 gesetzt werden:

NebulaProbabilityFactor(0.0-100.0): 100.0


Der NebulaObjectPositionVarianceFactor definiert den maximalen Abstand einer Nebelwolke zum benachbarten Stern:

NebulaObjectPositionVarianceFactor: 1.0


Der NebulaObjectDensity-Parameter legt schließlich die maximale Anzahl der Nebelwolken fest, die in der Umgebung eines Sterns positioniert werden sollen:

NebulaObjectDensity(1,2,3,...): 1


Werfen wir nun noch einen kurzen Blick auf den zugehörigen Source Code für die Positionierung der einzelnen Nebelwolken:


pNebulaSystem->Set_NumNebulaObjectsMax(g_NebulaObjectDensity*NumStars);

D3DXVECTOR3 pos;

float NebulaObjectDeltaX = g_NebulaObjectPositionVarianceFactor*
                           g_GalaxyParam_DeltaX;
float NebulaObjectDeltaY = g_NebulaObjectPositionVarianceFactor*
                           g_GalaxyParam_DeltaY;
float NebulaObjectDeltaZ = g_NebulaObjectPositionVarianceFactor*
                           g_GalaxyParam_DeltaZ;

for(i = 0; i < NumStars; i++)
{
for(j = 0; j < g_NebulaObjectDensity; j++)
{
if(frnd(0.0f, 100.0f) >= g_NebulaProbabilityFactor)
    continue;

pos = pGalaxy->WorldSpacePosition[i] +
      D3DXVECTOR3(frnd(-NebulaObjectDeltaX, NebulaObjectDeltaX),
                  frnd(-NebulaObjectDeltaY, NebulaObjectDeltaY),
                  frnd(-NebulaObjectDeltaZ, NebulaObjectDeltaZ));

/* Hinweis: pGalaxy->WorldSpacePosition[i]:
            Position des Sterns mit dem Index i */ 

randomValue = frnd(0.0f, 1.0f);

if(randomValue >= g_RandomColorNebulaObject_DistributionValueMin &&
   randomValue < g_RandomColorNebulaObject_DistributionValueMax)
{
    pNebulaSystem->Init_NebulaObject(&pos, &D3DXVECTOR3(
                   frnd(g_RandomColorNebulaObject_RedMin,
                        g_RandomColorNebulaObject_RedMax),
                   frnd(g_RandomColorNebulaObject_GreenMin,
                        g_RandomColorNebulaObject_GreenMax),
                   frnd(g_RandomColorNebulaObject_BlueMin,
                        g_RandomColorNebulaObject_BlueMax)),

                   frnd(g_RandomColorNebulaObjectScaleMin,
                        g_RandomColorNebulaObjectScaleMax),

                   lrnd(0, g_Num3DNebulaTextures));
}
else if(randomValue >= g_RedColorNebulaObject_DistributionValueMin &&
        randomValue < g_RedColorNebulaObject_DistributionValueMax)
{
    pNebulaSystem->Init_NebulaObject(&pos, &D3DXVECTOR3(
                   frnd(g_RedColorNebulaObject_RedMin,
                        g_RedColorNebulaObject_RedMax),
                   frnd(g_RedColorNebulaObject_GreenMin,
                        g_RedColorNebulaObject_GreenMax),
                   frnd(g_RedColorNebulaObject_BlueMin,
                        g_RedColorNebulaObject_BlueMax)),

                   frnd(g_RedColorNebulaObjectScaleMin,
                        g_RedColorNebulaObjectScaleMax),

                   lrnd(0, g_Num3DNebulaTextures));
}
else if(randomValue >= g_GreenColorNebulaObject_DistributionValueMin &&
        randomValue < g_GreenColorNebulaObject_DistributionValueMax)
{
    pNebulaSystem->Init_NebulaObject(&pos, &D3DXVECTOR3(
                   frnd(g_GreenColorNebulaObject_RedMin,
                        g_GreenColorNebulaObject_RedMax),
                   frnd(g_GreenColorNebulaObject_GreenMin,
                        g_GreenColorNebulaObject_GreenMax),
                   frnd(g_GreenColorNebulaObject_BlueMin,
                        g_GreenColorNebulaObject_BlueMax)),

                   frnd(g_GreenColorNebulaObjectScaleMin,
                        g_GreenColorNebulaObjectScaleMax),

                   lrnd(0, g_Num3DNebulaTextures));
}
else// if(randomValue >= g_BlueColorNebulaObject_DistributionValueMin &&
          randomValue < g_BlueColorNebulaObject_DistributionValueMax)
{
    pNebulaSystem->Init_NebulaObject(&pos, &D3DXVECTOR3(
                   frnd(g_BlueColorNebulaObject_RedMin,
                        g_BlueColorNebulaObject_RedMax),
                   frnd(g_BlueColorNebulaObject_GreenMin,
                        g_BlueColorNebulaObject_GreenMax),
                   frnd(g_BlueColorNebulaObject_BlueMin,
                        g_BlueColorNebulaObject_BlueMax)),

                   frnd(g_BlueColorNebulaObjectScaleMin,
                        g_BlueColorNebulaObjectScaleMax),

                   lrnd(0, g_Num3DNebulaTextures));
}}}