Skip to content

Commit

Permalink
Merge pull request #4833 from tsoj/master
Browse files Browse the repository at this point in the history
Stars that are brighter are now bigger and have a brighter color on the Starfield
  • Loading branch information
fluffyfreak authored Mar 13, 2020
2 parents 43cd23b + 00748a4 commit 28df3c4
Show file tree
Hide file tree
Showing 6 changed files with 137 additions and 36 deletions.
34 changes: 28 additions & 6 deletions data/configs/Starfield.ini
Original file line number Diff line number Diff line change
@@ -1,6 +1,28 @@
rMin=0.7
rMax=0.9
gMin=0.7
gMax=0.9
bMin=0.7
bMax=0.9
rMin=0.6
rMax=1.0
gMin=0.6
gMax=1.0
bMin=0.6
bMax=1.0

# the bigger the radius is the more dim little stars you'll get in the background
visibleRadiusLy=220.0

# the lower this number [0.0 - 1.0] is the brighter get dim stars compared to bright stars
# also control the overall brightness of all stars, the bigger this number is the dimmer are all stars
medianPosition=0.7

# the higher this number is the brighter are bright stars compared to other stars
# (needs to be balanced with the factors below)
brightnessPower=3.5

# the bigger this number is the bigger are stars compared to their brightness
brightnessApparentSizeFactor=0.5

#the bigger this number is the bigger are stars no matter their brightness
brightnessApparentSizeOffset=0.1

# this number controls how much influence the brightness of a star has on the actual color values on your screen
brightnessColorFactor=0.7
# the bigger this number is the brighter are colors of stars
brightnessColorOffset=0.1
Binary file added data/textures/star_point_2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
110 changes: 89 additions & 21 deletions src/Background.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -188,11 +188,11 @@ namespace Background {
}
}

Starfield::Starfield(Graphics::Renderer *renderer, Random &rand)
Starfield::Starfield(Graphics::Renderer *renderer, Random &rand, const Space* space, RefCountedPtr<Galaxy> galaxy)
{
m_renderer = renderer;
Init();
Fill(rand);
Fill(rand, space, galaxy);
}

void Starfield::Init()
Expand All @@ -203,7 +203,7 @@ namespace Background {
desc.vertexColors = true;
m_material.Reset(m_renderer->CreateMaterial(desc));
m_material->emissive = Color::WHITE;
m_material->texture0 = Graphics::TextureBuilder::Billboard("textures/star_point.png").GetOrCreateTexture(m_renderer, "billboard");
m_material->texture0 = Graphics::TextureBuilder::Billboard("textures/star_point_2.png").GetOrCreateTexture(m_renderer, "billboard");

Graphics::MaterialDescriptor descStreaks;
descStreaks.effect = Graphics::EFFECT_VTXCOLOR;
Expand All @@ -214,15 +214,22 @@ namespace Background {
IniConfig cfg;
cfg.Read(FileSystem::gameDataFiles, "configs/Starfield.ini");
// NB: limit the ranges of all values loaded from the file
m_rMin = Clamp(cfg.Float("rMin", 0.2), 0.2f, 1.0f);
m_rMax = Clamp(cfg.Float("rMax", 0.9), 0.2f, 1.0f);
m_gMin = Clamp(cfg.Float("gMin", 0.2), 0.2f, 1.0f);
m_gMax = Clamp(cfg.Float("gMax", 0.9), 0.2f, 1.0f);
m_bMin = Clamp(cfg.Float("bMin", 0.2), 0.2f, 1.0f);
m_bMax = Clamp(cfg.Float("bMax", 0.9), 0.2f, 1.0f);
m_rMin = Clamp(cfg.Float("rMin", 0.6), 0.2f, 1.0f);
m_rMax = Clamp(cfg.Float("rMax", 1.0), 0.2f, 1.0f);
m_gMin = Clamp(cfg.Float("gMin", 0.6), 0.2f, 1.0f);
m_gMax = Clamp(cfg.Float("gMax", 1.0), 0.2f, 1.0f);
m_bMin = Clamp(cfg.Float("bMin", 0.6), 0.2f, 1.0f);
m_bMax = Clamp(cfg.Float("bMax", 1.0), 0.2f, 1.0f);
m_visibleRadiusLy = std::max(cfg.Float("visibleRadiusLy", 180.0f), 0.0f);
m_medianPosition = Clamp(cfg.Float("medianPosition", 0.7f), 0.0f, 1.0f);
m_brightnessPower = cfg.Float("brightnessPower", 2.1f);
m_brightnessApparentSizeFactor = std::max(cfg.Float("brightnessApparentSizeFactor", 0.8f), 0.0f);
m_brightnessApparentSizeOffset = cfg.Float("brightnessApparentSizeOffset", 0.0);
m_brightnessColorFactor = cfg.Float("brightnessColorFactor", 0.8);
m_brightnessColorOffset = cfg.Float("brightnessColorOffset", 0.1);
}

void Starfield::Fill(Random &rand)
void Starfield::Fill(Random &rand, const Space* space, RefCountedPtr<Galaxy> galaxy)
{
const Uint32 NUM_BG_STARS = Clamp(Uint32(Pi::GetAmountBackgroundStars() * BG_STAR_MAX), BG_STAR_MIN, BG_STAR_MAX);
m_hyperVtx.reset(new vector3f[BG_STAR_MAX * 3]);
Expand All @@ -246,13 +253,14 @@ namespace Background {
std::unique_ptr<vector3f[]> stars(new vector3f[NUM_BG_STARS]);
std::unique_ptr<Color[]> colors(new Color[NUM_BG_STARS]);
std::unique_ptr<float[]> sizes(new float[NUM_BG_STARS]);
std::unique_ptr<float[]> brightness(new float[NUM_BG_STARS]);
//fill the array
Uint32 num = 0;
if (Pi::game != nullptr && Pi::game->GetSpace() != nullptr && Pi::game->GetSpace()->GetStarSystem() != nullptr) {
const SystemPath current = Pi::game->GetSpace()->GetStarSystem()->GetPath();
if (space != nullptr && galaxy.Valid() && space->GetStarSystem() != nullptr) {
const SystemPath current = space->GetStarSystem()->GetPath();

const double size = 1.0;
const Sint32 visibleRadius = 100; // lyrs
const Sint32 visibleRadius = m_visibleRadiusLy; // lyrs
const Sint32 visibleRadiusSqr = (visibleRadius * visibleRadius);
const Sint32 sectorMin = -(visibleRadius / Sector::SIZE); // lyrs_radius / sector_size_in_lyrs
const Sint32 sectorMax = visibleRadius / Sector::SIZE; // lyrs_radius / sector_size_in_lyrs
Expand All @@ -264,7 +272,7 @@ namespace Background {
continue; // early out

// this is fairly expensive
RefCountedPtr<const Sector> sec = Pi::game->GetGalaxy()->GetSector(sys);
RefCountedPtr<const Sector> sec = galaxy->GetSector(sys);

// add as many systems as we can
const size_t numSystems = std::min(sec->m_systems.size(), (size_t)(NUM_BG_STARS - num));
Expand All @@ -274,8 +282,17 @@ namespace Background {
if (distance.Length() >= visibleRadius)
continue; // too far

// grab the approximate real colour
Color col = StarSystem::starRealColors[ss->GetStarType(0)];
// add the colors and luminosities of all stars in a system together
float luminositySystemSum = 0.0f;
vector3f colorSystemSum(0.0f, 0.0f, 0.0f);
for(size_t i = 0; i<ss->GetNumStars(); ++i) {
luminositySystemSum += StarSystem::starLuminosities[ss->GetStarType(i)];
Color col = StarSystem::starRealColors[ss->GetStarType(i)];
colorSystemSum += vector3f(col.r, col.g, col.b) * luminositySystemSum;
}
colorSystemSum /= luminositySystemSum;

Color col(colorSystemSum.x, colorSystemSum.y, colorSystemSum.z);
col.r = Clamp(col.r, (Uint8)(m_rMin * 255), (Uint8)(m_rMax * 255));
col.g = Clamp(col.g, (Uint8)(m_gMin * 255), (Uint8)(m_gMax * 255));
col.b = Clamp(col.b, (Uint8)(m_bMin * 255), (Uint8)(m_bMax * 255));
Expand All @@ -285,6 +302,7 @@ namespace Background {
sizes[num] = size;
stars[num] = distance.Normalized() * 1000.0f;
colors[num] = col;
brightness[num] = luminositySystemSum / (4 * M_PI * distance.Length() * distance.Length());

//need to keep data around for HS anim - this is stupid
m_hyperVtx[NUM_BG_STARS * 2 + num] = stars[num];
Expand All @@ -302,6 +320,56 @@ namespace Background {
}
}
Output("Stars picked from galaxy: %d\n", num);
// use a logarithmic scala for brightness since this looks more natural to the human eye
for(int i = 0; i<num; ++i) {
brightness[i] = log(brightness[i]);
}

// find the median brightness of all visible stars
std::vector<int> sortedBrightnessIndex;
for(int i = 0; i<num; ++i) {
sortedBrightnessIndex.push_back(i);
}
std::sort(sortedBrightnessIndex.begin(), sortedBrightnessIndex.end(), [&](const int a, const int b) {
return brightness[a] > brightness[b];
});
double medianBrightness = 0.0;
if(num > 0)
{
medianBrightness = brightness[sortedBrightnessIndex[
Clamp<int>(m_medianPosition*num, 0, num-1)
]];
}

for(size_t j = 0; j<num; ++j)
{
size_t i = sortedBrightnessIndex[j]; // just for debugging purposes

// dividing through the median helps bringing the logarithmic brightnesses to a scala that is easier to work with
brightness[i] /= medianBrightness;
// the exponentiation helps to emphasize very bright stars
brightness[i] = std::pow(Clamp(brightness[i], 0.0f, 4.0f), m_brightnessPower);

sizes[i] = std::max(m_brightnessApparentSizeFactor*(brightness[i] + m_brightnessApparentSizeOffset), 0.0f);

float colorFactor = std::max(m_brightnessColorFactor*(brightness[i] + m_brightnessColorOffset), 0.0f);
// convert temporarily to floats to prevent narrowing errors
float colorR = colors[i].r;
float colorG = colors[i].g;
float colorB = colors[i].b;

// find a color scaling factor that doesn't make a colored star look white
float colorMax = std::max({colorR, colorG, colorB});
float scaledColorMax = colorMax*colorFactor;
colorFactor = std::min(scaledColorMax, 255.0f)/colorMax;

colorR *= colorFactor;
colorG *= colorFactor;
colorB *= colorFactor;
colors[i].r = Clamp<int>(colorR, 0, 255);
colors[i].g = Clamp<int>(colorG, 0, 255);
colors[i].b = Clamp<int>(colorB, 0, 255);
}

// fill out the remaining target count with generated points
if (num < NUM_BG_STARS) {
Expand Down Expand Up @@ -460,24 +528,24 @@ namespace Background {
m_renderer->DrawBuffer(m_vertexBuffer.get(), rs, m_material.Get(), Graphics::TRIANGLE_STRIP);
}

Container::Container(Graphics::Renderer *renderer, Random &rand) :
Container::Container(Graphics::Renderer *renderer, Random &rand, const Space* space, RefCountedPtr<Galaxy> galaxy) :
m_renderer(renderer),
m_milkyWay(renderer),
m_starField(renderer, rand),
m_starField(renderer, rand, space, galaxy),
m_universeBox(renderer),
m_drawFlags(DRAW_SKYBOX | DRAW_STARS)
{
Graphics::RenderStateDesc rsd;
rsd.depthTest = false;
rsd.depthWrite = false;
m_renderState = renderer->CreateRenderState(rsd);
Refresh(rand);
Refresh(rand, space, galaxy);
}

void Container::Refresh(Random &rand)
void Container::Refresh(Random &rand, const Space* space, RefCountedPtr<Galaxy> galaxy)
{
// always redo starfield, milkyway stays normal for now
m_starField.Fill(rand);
m_starField.Fill(rand, space, galaxy);
m_universeBox.LoadCubeMap(rand);
}

Expand Down
18 changes: 14 additions & 4 deletions src/Background.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
#include "graphics/Drawables.h"

class Random;
class Galaxy;
class Space;

namespace Graphics {
class Renderer;
Expand Down Expand Up @@ -58,10 +60,10 @@ namespace Background {
class Starfield : public BackgroundElement {
public:
//does not Fill the starfield
Starfield(Graphics::Renderer *r, Random &rand);
Starfield(Graphics::Renderer *r, Random &rand, const Space* space, RefCountedPtr<Galaxy> galaxy);
void Draw(Graphics::RenderState *);
//create or recreate the starfield
void Fill(Random &rand);
void Fill(Random &rand, const Space* space, RefCountedPtr<Galaxy> galaxy);

private:
void Init();
Expand All @@ -73,6 +75,14 @@ namespace Background {
std::unique_ptr<vector3f[]> m_hyperVtx; // BG_STAR_MAX * 3
std::unique_ptr<Color[]> m_hyperCol; // BG_STAR_MAX * 3
std::unique_ptr<Graphics::VertexBuffer> m_animBuffer;

float m_visibleRadiusLy;
float m_medianPosition;
float m_brightnessPower;
float m_brightnessApparentSizeOffset;
float m_brightnessApparentSizeFactor;
float m_brightnessColorFactor;
float m_brightnessColorOffset;
};

class MilkyWay : public BackgroundElement {
Expand All @@ -93,14 +103,14 @@ namespace Background {
DRAW_SKYBOX = 1 << 2
};

Container(Graphics::Renderer *, Random &rand);
Container(Graphics::Renderer *, Random &rand, const Space* space, RefCountedPtr<Galaxy> galaxy);
void Draw(const matrix4x4d &transform);

void SetIntensity(float intensity);
void SetDrawFlags(const Uint32 flags);

private:
void Refresh(Random &rand);
void Refresh(Random &rand, const Space* space, RefCountedPtr<Galaxy> galaxy);

Graphics::Renderer *m_renderer;
MilkyWay m_milkyWay;
Expand Down
3 changes: 2 additions & 1 deletion src/Intro.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include "scenegraph/ModelSkin.h"
#include "scenegraph/SceneGraph.h"
#include <algorithm>
#include "galaxy/Galaxy.h"

struct PiRngWrapper {
unsigned int operator()(unsigned int n)
Expand All @@ -24,7 +25,7 @@ Intro::Intro(Graphics::Renderer *r, int width, int height) :
{
using Graphics::Light;

m_background.reset(new Background::Container(r, Pi::rng));
m_background.reset(new Background::Container(r, Pi::rng, nullptr, RefCountedPtr<Galaxy>()));
m_ambientColor = Color::BLANK;

const Color one = Color::WHITE;
Expand Down
8 changes: 4 additions & 4 deletions src/Space.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ Space::Space(Game *game, RefCountedPtr<Galaxy> galaxy, Space *oldSpace) :
m_processingFinalizationQueue(false)
#endif
{
m_background.reset(new Background::Container(Pi::renderer, Pi::rng));
m_background.reset(new Background::Container(Pi::renderer, Pi::rng, this, m_game->GetGalaxy()));

m_rootFrameId = Frame::CreateFrame(FrameId::Invalid, Lang::SYSTEM, Frame::FLAG_DEFAULT, FLT_MAX);

Expand All @@ -94,7 +94,7 @@ Space::Space(Game *game, RefCountedPtr<Galaxy> galaxy, const SystemPath &path, S
{
Uint32 _init[5] = { path.systemIndex, Uint32(path.sectorX), Uint32(path.sectorY), Uint32(path.sectorZ), UNIVERSE_SEED };
Random rand(_init, 5);
m_background.reset(new Background::Container(Pi::renderer, rand));
m_background.reset(new Background::Container(Pi::renderer, rand, this, m_game->GetGalaxy()));

CityOnPlanet::SetCityModelPatterns(m_starSystem->GetPath());

Expand Down Expand Up @@ -125,7 +125,7 @@ Space::Space(Game *game, RefCountedPtr<Galaxy> galaxy, const Json &jsonObj, doub
const SystemPath &path = m_starSystem->GetPath();
Uint32 _init[5] = { path.systemIndex, Uint32(path.sectorX), Uint32(path.sectorY), Uint32(path.sectorZ), UNIVERSE_SEED };
Random rand(_init, 5);
m_background.reset(new Background::Container(Pi::renderer, rand));
m_background.reset(new Background::Container(Pi::renderer, rand, this, m_game->GetGalaxy()));

RebuildSystemBodyIndex();

Expand Down Expand Up @@ -167,7 +167,7 @@ void Space::RefreshBackground()
const SystemPath &path = m_starSystem->GetPath();
Uint32 _init[5] = { path.systemIndex, Uint32(path.sectorX), Uint32(path.sectorY), Uint32(path.sectorZ), UNIVERSE_SEED };
Random rand(_init, 5);
m_background.reset(new Background::Container(Pi::renderer, rand));
m_background.reset(new Background::Container(Pi::renderer, rand, this, m_game->GetGalaxy()));
}

void Space::ToJson(Json &jsonObj)
Expand Down

0 comments on commit 28df3c4

Please sign in to comment.