Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -408,7 +408,7 @@ add_subdirectory(src/editor)

target_link_libraries(${PROJECT_NAME} LINK_PRIVATE ${pioneerLibs} ${winLibs})
target_link_libraries(unittest LINK_PRIVATE ${pioneerLibs} ${winLibs})
target_link_libraries(modelcompiler LINK_PRIVATE ${pioneerLibs} ${winLibs})
target_link_libraries(modelcompiler LINK_PRIVATE pioneer-lib ${pioneerLibs} ${winLibs})
target_link_libraries(savegamedump LINK_PRIVATE pioneer-core ${SDL2_IMAGE_LIBRARIES} ${winLibs})

set_cxx_properties(${PROJECT_NAME} unittest modelcompiler savegamedump)
Expand Down
103 changes: 103 additions & 0 deletions src/MathUtil.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,109 @@
#include "MathUtil.h"
#include "Pi.h"

namespace PhysicsUtil {
double GetPlanckBrightness(const double wavelength_nm, const int temperature)
{
// Planck's constant
const double h = 6.62607015e-34; // kg*m^2*s^-1 (J*s)

// speed of light
const double c = 299792458; // m*s^2

// Boltzmann's constant
const double k = 1.380649e-23; // J/K

double wavelength = wavelength_nm * 1e-9;

double exponent = exp((h*c) / (wavelength * k * temperature));
return 2 * h * pow(c, 2) / (pow(wavelength, 5) * exponent);
}

const vector3d nm_to_rgb[48] = {
vector3d( 0.000000f, 0.000000f, 0.000001f ), // 360 nm
vector3d( 0.000006f, 0.000001f, 0.000026f ), // 370 nm
vector3d( 0.000160f, 0.000017f, 0.000705f ), // 380 nm
vector3d( 0.002362f, 0.000253f, 0.010482f ), // 390 nm
vector3d( 0.019110f, 0.002004f, 0.086011f ), // 400 nm
vector3d( 0.084736f, 0.008756f, 0.389366f ), // 410 nm
vector3d( 0.204492f, 0.021391f, 0.972542f ), // 420 nm
vector3d( 0.314679f, 0.038676f, 1.553480f ), // 430 nm
vector3d( 0.383734f, 0.062077f, 1.967280f ), // 440 nm
vector3d( 0.370702f, 0.089456f, 1.994800f ), // 450 nm
vector3d( 0.302273f, 0.128201f, 1.745370f ), // 460 nm
vector3d( 0.195618f, 0.185190f, 1.317560f ), // 470 nm
vector3d( 0.080507f, 0.253589f, 0.772125f ), // 480 nm
vector3d( 0.016172f, 0.339133f, 0.415254f ), // 490 nm
vector3d( 0.003816f, 0.460777f, 0.218502f ), // 500 nm
vector3d( 0.037465f, 0.606741f, 0.112044f ), // 510 nm
vector3d( 0.117749f, 0.761757f, 0.060709f ), // 520 nm
vector3d( 0.236491f, 0.875211f, 0.030451f ), // 530 nm
vector3d( 0.376772f, 0.961988f, 0.013676f ), // 540 nm
vector3d( 0.529826f, 0.991761f, 0.003988f ), // 550 nm
vector3d( 0.705224f, 0.997340f, 0.000000f ), // 560 nm
vector3d( 0.878655f, 0.955552f, 0.000000f ), // 570 nm
vector3d( 1.014160f, 0.868934f, 0.000000f ), // 580 nm
vector3d( 1.118520f, 0.777405f, 0.000000f ), // 590 nm
vector3d( 1.123990f, 0.658341f, 0.000000f ), // 600 nm
vector3d( 1.030480f, 0.527963f, 0.000000f ), // 610 nm
vector3d( 0.856297f, 0.398057f, 0.000000f ), // 620 nm
vector3d( 0.647467f, 0.283493f, 0.000000f ), // 630 nm
vector3d( 0.431567f, 0.179828f, 0.000000f ), // 640 nm
vector3d( 0.268329f, 0.107633f, 0.000000f ), // 650 nm
vector3d( 0.152568f, 0.060281f, 0.000000f ), // 660 nm
vector3d( 0.081261f, 0.031800f, 0.000000f ), // 670 nm
vector3d( 0.040851f, 0.015905f, 0.000000f ), // 680 nm
vector3d( 0.019941f, 0.007749f, 0.000000f ), // 690 nm
vector3d( 0.009577f, 0.003718f, 0.000000f ), // 700 nm
vector3d( 0.004553f, 0.001768f, 0.000000f ), // 710 nm
vector3d( 0.002175f, 0.000846f, 0.000000f ), // 720 nm
vector3d( 0.001045f, 0.000407f, 0.000000f ), // 730 nm
vector3d( 0.000508f, 0.000199f, 0.000000f ), // 740 nm
vector3d( 0.000251f, 0.000098f, 0.000000f ), // 750 nm
vector3d( 0.000126f, 0.000050f, 0.000000f ), // 760 nm
vector3d( 0.000065f, 0.000025f, 0.000000f ), // 770 nm
vector3d( 0.000033f, 0.000013f, 0.000000f ), // 780 nm
vector3d( 0.000018f, 0.000007f, 0.000000f ), // 790 nm
vector3d( 0.000009f, 0.000004f, 0.000000f ), // 800 nm
vector3d( 0.000005f, 0.000002f, 0.000000f ), // 810 nm
vector3d( 0.000003f, 0.000001f, 0.000000f ), // 820 nm
vector3d( 0.000002f, 0.000001f, 0.000000f ) // 830 nm
};

vector3d GenerateTemperatureColor(const double T) {
// https://www.shadertoy.com/view/NlGXzz

// [360-830 nm]
vector3d rgb = vector3d(0.f);

const matrix3x3d xyz2rgb = matrix3x3d::FromVectors(
vector3d( 3.2404542,-0.9692660, 0.0556434),
vector3d(-1.5371385, 1.8760108,-0.2040259),
vector3d(-0.4985314, 0.0415560, 1.0572252)
);

for (int i = 0; i < 48; i++) {
double wavelength = 360 + (10 * i);

rgb += GetPlanckBrightness(wavelength, T) * (xyz2rgb * nm_to_rgb[i]);
}

// normalize
double max = std::max(std::max(rgb.x, rgb.y), rgb.z);
// black color
if (max == 0.f) {
rgb = vector3d(0.f);
} else {
rgb /= (max / 255);
}
rgb.x = std::max(rgb.x, 0.0);
rgb.y = std::max(rgb.y, 0.0);
rgb.z = std::max(rgb.z, 0.0);

return rgb;
}
}

namespace MathUtil {

vector3d RandomPointOnSphere(double minRadius, double maxRadius)
Expand Down
4 changes: 4 additions & 0 deletions src/MathUtil.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,10 @@ static inline Uint32 ceil_pow2(Uint32 v)
return v;
}

namespace PhysicsUtil {
vector3d GenerateTemperatureColor(double T);
}

namespace MathUtil {

// random point on a sphere, distributed uniformly by area
Expand Down
101 changes: 3 additions & 98 deletions src/galaxy/SystemBody.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include "Game.h"
#include "JsonUtils.h"
#include "Lang.h"
#include "MathUtil.h"
#include "utils.h"

SystemBodyData::SystemBodyData() :
Expand Down Expand Up @@ -131,106 +132,10 @@ void SystemBodyData::LoadFromJson(const Json &obj)
m_heightMapFractal = std::min(m_heightMapFractal, uint32_t(1));
}

double GetPlanckBrightness(const double wavelength_nm, const int temperature)
{
// Planck's constant
const double h = 6.62607015e-34; // kg*m^2*s^-1 (J*s)

// speed of light
const double c = 299792458; // m*s^2

// Boltzmann's constant
const double k = 1.380649e-23; // J/K

double wavelength = wavelength_nm * 1e-9;

double exponent = exp((h*c) / (wavelength * k * temperature));
return 2 * h * pow(c, 2) / (pow(wavelength, 5) * exponent);
}

const vector3d nm_to_rgb[48] = {
vector3d( 0.000000f, 0.000000f, 0.000001f ), // 360 nm
vector3d( 0.000006f, 0.000001f, 0.000026f ), // 370 nm
vector3d( 0.000160f, 0.000017f, 0.000705f ), // 380 nm
vector3d( 0.002362f, 0.000253f, 0.010482f ), // 390 nm
vector3d( 0.019110f, 0.002004f, 0.086011f ), // 400 nm
vector3d( 0.084736f, 0.008756f, 0.389366f ), // 410 nm
vector3d( 0.204492f, 0.021391f, 0.972542f ), // 420 nm
vector3d( 0.314679f, 0.038676f, 1.553480f ), // 430 nm
vector3d( 0.383734f, 0.062077f, 1.967280f ), // 440 nm
vector3d( 0.370702f, 0.089456f, 1.994800f ), // 450 nm
vector3d( 0.302273f, 0.128201f, 1.745370f ), // 460 nm
vector3d( 0.195618f, 0.185190f, 1.317560f ), // 470 nm
vector3d( 0.080507f, 0.253589f, 0.772125f ), // 480 nm
vector3d( 0.016172f, 0.339133f, 0.415254f ), // 490 nm
vector3d( 0.003816f, 0.460777f, 0.218502f ), // 500 nm
vector3d( 0.037465f, 0.606741f, 0.112044f ), // 510 nm
vector3d( 0.117749f, 0.761757f, 0.060709f ), // 520 nm
vector3d( 0.236491f, 0.875211f, 0.030451f ), // 530 nm
vector3d( 0.376772f, 0.961988f, 0.013676f ), // 540 nm
vector3d( 0.529826f, 0.991761f, 0.003988f ), // 550 nm
vector3d( 0.705224f, 0.997340f, 0.000000f ), // 560 nm
vector3d( 0.878655f, 0.955552f, 0.000000f ), // 570 nm
vector3d( 1.014160f, 0.868934f, 0.000000f ), // 580 nm
vector3d( 1.118520f, 0.777405f, 0.000000f ), // 590 nm
vector3d( 1.123990f, 0.658341f, 0.000000f ), // 600 nm
vector3d( 1.030480f, 0.527963f, 0.000000f ), // 610 nm
vector3d( 0.856297f, 0.398057f, 0.000000f ), // 620 nm
vector3d( 0.647467f, 0.283493f, 0.000000f ), // 630 nm
vector3d( 0.431567f, 0.179828f, 0.000000f ), // 640 nm
vector3d( 0.268329f, 0.107633f, 0.000000f ), // 650 nm
vector3d( 0.152568f, 0.060281f, 0.000000f ), // 660 nm
vector3d( 0.081261f, 0.031800f, 0.000000f ), // 670 nm
vector3d( 0.040851f, 0.015905f, 0.000000f ), // 680 nm
vector3d( 0.019941f, 0.007749f, 0.000000f ), // 690 nm
vector3d( 0.009577f, 0.003718f, 0.000000f ), // 700 nm
vector3d( 0.004553f, 0.001768f, 0.000000f ), // 710 nm
vector3d( 0.002175f, 0.000846f, 0.000000f ), // 720 nm
vector3d( 0.001045f, 0.000407f, 0.000000f ), // 730 nm
vector3d( 0.000508f, 0.000199f, 0.000000f ), // 740 nm
vector3d( 0.000251f, 0.000098f, 0.000000f ), // 750 nm
vector3d( 0.000126f, 0.000050f, 0.000000f ), // 760 nm
vector3d( 0.000065f, 0.000025f, 0.000000f ), // 770 nm
vector3d( 0.000033f, 0.000013f, 0.000000f ), // 780 nm
vector3d( 0.000018f, 0.000007f, 0.000000f ), // 790 nm
vector3d( 0.000009f, 0.000004f, 0.000000f ), // 800 nm
vector3d( 0.000005f, 0.000002f, 0.000000f ), // 810 nm
vector3d( 0.000003f, 0.000001f, 0.000000f ), // 820 nm
vector3d( 0.000002f, 0.000001f, 0.000000f ) // 830 nm
};

void SystemBodyData::GenerateStarColor()
{
// https://www.shadertoy.com/view/NlGXzz

// [360-830 nm]
vector3d rgb = vector3d(0.f);

const matrix3x3d xyz2rgb = matrix3x3d::FromVectors(
vector3d( 3.2404542,-0.9692660, 0.0556434),
vector3d(-1.5371385, 1.8760108,-0.2040259),
vector3d(-0.4985314, 0.0415560, 1.0572252)
);

for (int i = 0; i < 48; i++) {
double wavelength = 360 + (10 * i);

rgb += GetPlanckBrightness(wavelength, m_averageTemp) * (xyz2rgb * nm_to_rgb[i]);
}

// normalize
double max = std::max(std::max(rgb.x, rgb.y), rgb.z);
// black color
if (max == 0.f) {
rgb = vector3d(0.f);
} else {
rgb /= (max / 255);
}
rgb.x = std::max(rgb.x, 0.0);
rgb.y = std::max(rgb.y, 0.0);
rgb.z = std::max(rgb.z, 0.0);

m_starColor = Color(rgb.x, rgb.y, rgb.z, 255);
vector3d starColor = PhysicsUtil::GenerateTemperatureColor(m_averageTemp);
m_starColor = Color(starColor.x, starColor.y, starColor.z, 255);
}

SystemBody::SystemBody(const SystemPath &path, StarSystem *system) :
Expand Down
5 changes: 5 additions & 0 deletions src/scenegraph/Thruster.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,11 @@ namespace SceneGraph {
// emissive.r is the thruster power setting which effects flame length and brightness
m_tMat->emissive.r = m_glowMat->emissive.r = 255.0f * displayedPower;

// emulate thruster temperature
double temperature = MathUtil::Lerp(0.0, 30000.0, power);
vector3d thrustColor = PhysicsUtil::GenerateTemperatureColor(temperature);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Once again, this is an excessive consumption of CPU cycles for something that should be a 30 or 60-entry precomputed lookup table. Feel free to store an interpolation curve with each entry in the LUT for maximum accuracy, but computing 48 wavelength bands per thruster, every frame is simply wasteful.

SetColor(Color(thrustColor.x, thrustColor.y, thrustColor.z, 255));

m_tMat->diffuse = m_glowMat->diffuse = currentColor;

//directional fade
Expand Down
Loading