Centralized scenery constants (earth radius...)
This commit is contained in:
parent
95b24857e9
commit
6b6710f15c
11 changed files with 76 additions and 65 deletions
|
@ -2,14 +2,13 @@
|
|||
|
||||
#include <cmath>
|
||||
#include "Maths.h"
|
||||
#include "Scenery.h"
|
||||
#include "PackStream.h"
|
||||
#include "RandomGenerator.h"
|
||||
#include "FloatNode.h"
|
||||
#include "GodRaysDefinition.h"
|
||||
#include "CelestialBodyDefinition.h"
|
||||
|
||||
#define WORLD_SCALING 0.05
|
||||
|
||||
AtmosphereDefinition::AtmosphereDefinition(DefinitionNode *parent)
|
||||
: DefinitionNode(parent, "atmosphere", "atmosphere") {
|
||||
model = ATMOSPHERE_MODEL_DISABLED;
|
||||
|
@ -104,9 +103,9 @@ void AtmosphereDefinition::applyPreset(AtmospherePreset preset, RandomGenerator
|
|||
sun_color.b = 0.9;
|
||||
sun_color.a = 1.0;
|
||||
sun->propRadius()->setValue(1.0);
|
||||
sun->propDistance()->setValue(149597870.0 / WORLD_SCALING);
|
||||
moon->propDistance()->setValue(384403.0 / WORLD_SCALING);
|
||||
moon->propRadius()->setValue(1737.4 / WORLD_SCALING);
|
||||
sun->propDistance()->setValue(Scenery::SUN_DISTANCE_SCALED);
|
||||
moon->propDistance()->setValue(384403.0 * Scenery::KM_TO_UNIT);
|
||||
moon->propRadius()->setValue(1737.4 * Scenery::KM_TO_UNIT);
|
||||
moon->propPhi()->setValue(0.5);
|
||||
moon->propTheta()->setValue(0.3);
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include "CameraDefinition.h"
|
||||
|
||||
#include <cmath>
|
||||
#include "Scenery.h"
|
||||
#include "Maths.h"
|
||||
#include "PackStream.h"
|
||||
#include "BoundingBox.h"
|
||||
|
@ -19,7 +20,7 @@ CameraDefinition::CameraDefinition(DefinitionNode *parent) : DefinitionNode(pare
|
|||
perspective.yfov = 1.0;
|
||||
perspective.xratio = 1.0;
|
||||
perspective.znear = 0.5;
|
||||
perspective.zfar = 20000.0;
|
||||
perspective.zfar = Scenery::FAR_LIMIT_SCALED;
|
||||
|
||||
validate();
|
||||
}
|
||||
|
|
|
@ -2,10 +2,7 @@
|
|||
|
||||
#include "Vector3.h"
|
||||
#include "FloatNode.h"
|
||||
|
||||
static constexpr double WORLD_SCALING = 0.05;
|
||||
static constexpr double EARTH_RADIUS = 6360.0;
|
||||
static constexpr double EARTH_RADIUS_SCALED = EARTH_RADIUS / WORLD_SCALING;
|
||||
#include "Scenery.h"
|
||||
|
||||
CelestialBodyDefinition::CelestialBodyDefinition(DefinitionNode *parent, const string &name)
|
||||
: DefinitionNode(parent, name) {
|
||||
|
@ -18,7 +15,7 @@ CelestialBodyDefinition::CelestialBodyDefinition(DefinitionNode *parent, const s
|
|||
Vector3 CelestialBodyDefinition::getLocation(bool over_water) const {
|
||||
VectorSpherical spc = {distance->getValue(), theta->getValue(), -phi->getValue()};
|
||||
if (over_water) {
|
||||
return Vector3(spc).sub(VECTOR_DOWN.scale(EARTH_RADIUS_SCALED));
|
||||
return Vector3(spc).sub(VECTOR_DOWN.scale(Scenery::EARTH_RADIUS_SCALED));
|
||||
} else {
|
||||
return Vector3(spc);
|
||||
}
|
||||
|
|
|
@ -24,6 +24,25 @@ class DEFINITIONSHARED_EXPORT Scenery : public DefinitionNode {
|
|||
|
||||
typedef void (*SceneryCustomDataCallback)(PackStream *stream, void *data);
|
||||
|
||||
/**
|
||||
* Conversion factor between scenery units and kilometers.
|
||||
*
|
||||
* 1km == 20.0 units
|
||||
*/
|
||||
static constexpr double KM_TO_UNIT = 20.0;
|
||||
static constexpr double UNIT_TO_KM = 1.0 / KM_TO_UNIT;
|
||||
|
||||
static constexpr double EARTH_RADIUS = 6360.0;
|
||||
static constexpr double EARTH_RADIUS_SCALED = EARTH_RADIUS * KM_TO_UNIT;
|
||||
|
||||
static constexpr double SUN_DISTANCE = 149597870.0;
|
||||
static constexpr double SUN_DISTANCE_SCALED = SUN_DISTANCE * KM_TO_UNIT;
|
||||
|
||||
static constexpr double SUN_RADIUS = 6.955e5;
|
||||
static constexpr double SUN_RADIUS_SCALED = EARTH_RADIUS * KM_TO_UNIT;
|
||||
|
||||
static constexpr double FAR_LIMIT_SCALED = 20000.0;
|
||||
|
||||
public:
|
||||
Scenery();
|
||||
|
||||
|
|
|
@ -429,11 +429,18 @@ static void testMoonRendering() {
|
|||
/*SkyRasterizer rasterizer(&renderer, renderer.getProgressHelper(), 0);
|
||||
renderer.setSoloRasterizer(&rasterizer);*/
|
||||
|
||||
// During the day
|
||||
scenery.getAtmosphere()->setDayTime(17, 30);
|
||||
startTestRender(&renderer, "moon", 0);
|
||||
|
||||
// At night
|
||||
scenery.getAtmosphere()->setDayTime(23);
|
||||
startTestRender(&renderer, "moon", 1);
|
||||
|
||||
// Eclipse
|
||||
scenery.getAtmosphere()->childSun()->propPhi()->setValue(scenery.getAtmosphere()->childMoon()->propPhi()->getValue());
|
||||
scenery.getAtmosphere()->childSun()->propTheta()->setValue(scenery.getAtmosphere()->childMoon()->propTheta()->getValue());
|
||||
startTestRender(&renderer, "moon", 2);
|
||||
}
|
||||
|
||||
void runTestSuite() {
|
||||
|
|
|
@ -10,10 +10,11 @@ const vec3 betaMSca = vec3(20e-3, 20e-3, 20e-3);
|
|||
const vec3 betaMEx = vec3(20e-3 / 0.9, 20e-3 / 0.9, 20e-3 / 0.9);
|
||||
const float mieG = 0.76;
|
||||
const float WORKAROUND_OFFSET = 0.1;
|
||||
const float SPHERE_SIZE = 20000.0;
|
||||
const float WORLD_SCALING = 0.03;
|
||||
const float FAR_LIMIT_SCALED = 20000.0;
|
||||
const float UNIT_TO_KM = 0.05;
|
||||
const float KM_TO_UNIT = 20.0;
|
||||
const float SUN_DISTANCE = 149597870.0;
|
||||
const float SUN_DISTANCE_SCALED = (SUN_DISTANCE / WORLD_SCALING);
|
||||
const float SUN_DISTANCE_SCALED = (SUN_DISTANCE * KM_TO_UNIT);
|
||||
const float M_PI = 3.141592657;
|
||||
|
||||
const int RES_MU = 128;
|
||||
|
@ -259,7 +260,7 @@ vec3 applyWeatherEffects(float distance, vec3 base, vec3 _attenuation, vec3 _ins
|
|||
vec4 applyAerialPerspective(vec4 base)
|
||||
{
|
||||
vec3 location = vec3(unprojected.x, max(unprojected.y, 0.0), unprojected.z);
|
||||
vec3 x = vec3(0.0, Rg + WORKAROUND_OFFSET + max(cameraLocation.y, 0.0) * WORLD_SCALING, 0.0);
|
||||
vec3 x = vec3(0.0, Rg + WORKAROUND_OFFSET + max(cameraLocation.y, 0.0) * UNIT_TO_KM, 0.0);
|
||||
vec3 v = normalize(unprojected - cameraLocation);
|
||||
vec3 s = normalize(sunDirection * SUN_DISTANCE_SCALED - x);
|
||||
|
||||
|
@ -274,7 +275,7 @@ vec4 applyAerialPerspective(vec4 base)
|
|||
|
||||
float r = length(x);
|
||||
float mu = dot(x, v) / r;
|
||||
float t = length(unprojected - cameraLocation) * WORLD_SCALING;
|
||||
float t = length(unprojected - cameraLocation) * UNIT_TO_KM;
|
||||
|
||||
vec3 attenuation;
|
||||
vec3 inscattering = _getInscatterColor(x, t, v, s, r, mu, attenuation);
|
||||
|
@ -284,7 +285,7 @@ vec4 applyAerialPerspective(vec4 base)
|
|||
|
||||
vec4 getSkyColor(vec3 location, vec3 direction)
|
||||
{
|
||||
vec3 x = vec3(0.0, Rg + location.y * WORLD_SCALING, 0.0);
|
||||
vec3 x = vec3(0.0, Rg + location.y * UNIT_TO_KM, 0.0);
|
||||
vec3 v = normalize(direction);
|
||||
vec3 s = normalize(sunDirection * SUN_DISTANCE_SCALED - x);
|
||||
|
||||
|
@ -297,12 +298,12 @@ vec4 getSkyColor(vec3 location, vec3 direction)
|
|||
vec3 inscattering = _getInscatterColor(x, t, v, s, r, mu, attenuation);
|
||||
|
||||
vec3 nightsky = vec3(0.01, 0.012, 0.03);
|
||||
return vec4(applyWeatherEffects(SPHERE_SIZE, nightsky + sunTransmittance.rgb, vec3(1), inscattering), 1.0);
|
||||
return vec4(applyWeatherEffects(FAR_LIMIT_SCALED, nightsky + sunTransmittance.rgb, vec3(1), inscattering), 1.0);
|
||||
}
|
||||
|
||||
vec4 applyLighting(vec3 location, vec3 normal, vec4 color, float reflection, float shininess, float hardness)
|
||||
{
|
||||
float r0 = Rg + WORKAROUND_OFFSET + max(location.y, 0.0) * WORLD_SCALING;
|
||||
float r0 = Rg + WORKAROUND_OFFSET + max(location.y, 0.0) * UNIT_TO_KM;
|
||||
vec3 sun_position = sunDirection * SUN_DISTANCE;
|
||||
float muS = dot(vec3(0.0, 1.0, 0.0), normalize(sun_position - vec3(0.0, r0, 0.0)));
|
||||
|
||||
|
|
|
@ -27,22 +27,15 @@
|
|||
#include "CacheFile.h"
|
||||
#include "FloatNode.h"
|
||||
|
||||
/* Factor to convert software units to kilometers */
|
||||
#define WORLD_SCALING 0.03
|
||||
#define SUN_DISTANCE 149597870.0
|
||||
#define SUN_DISTANCE_SCALED (SUN_DISTANCE / WORLD_SCALING)
|
||||
#define WORKAROUND_OFFSET 0.1
|
||||
|
||||
// TODO This is copied in AtmosphereRenderer
|
||||
#define SPHERE_SIZE 20000.0
|
||||
|
||||
/*********************** Constants ***********************/
|
||||
|
||||
static const double Rg = 6360.0;
|
||||
static const double Rt = 6420.0;
|
||||
static const double RL = 6421.0;
|
||||
static const double ISun = 100.0;
|
||||
static const double AVERAGE_GROUND_REFLECTANCE = 0.1;
|
||||
static constexpr double Rg = Scenery::EARTH_RADIUS;
|
||||
static constexpr double Rt = Rg + 60.0;
|
||||
static constexpr double RL = Rt + 1.0;
|
||||
static constexpr double ISun = 100.0;
|
||||
static constexpr double AVERAGE_GROUND_REFLECTANCE = 0.1;
|
||||
|
||||
#if 1
|
||||
#define RES_MU 128
|
||||
|
@ -1070,7 +1063,7 @@ AtmosphereModelBruneton::~AtmosphereModelBruneton() {
|
|||
|
||||
AtmosphereResult AtmosphereModelBruneton::getSkyColor(Vector3 eye, const Vector3 &direction,
|
||||
const Vector3 &sun_position, const Color &base) const {
|
||||
Vector3 x = {0.0, Rg + eye.y * WORLD_SCALING, 0.0};
|
||||
Vector3 x = {0.0, Rg + eye.y * Scenery::UNIT_TO_KM, 0.0};
|
||||
Vector3 v = direction.normalize();
|
||||
Vector3 s = sun_position.sub(x).normalize();
|
||||
|
||||
|
@ -1089,7 +1082,7 @@ AtmosphereResult AtmosphereModelBruneton::getSkyColor(Vector3 eye, const Vector3
|
|||
result.base = base.add(sunColor);
|
||||
result.inscattering = _getInscatterColor(&x, &t, v, s, &r, &mu, &attenuation); /* S[L]-T(x,xs)S[l]|xs */
|
||||
/* TODO Use atmosphere attenuation */
|
||||
result.distance = SPHERE_SIZE;
|
||||
result.distance = Scenery::FAR_LIMIT_SCALED;
|
||||
|
||||
result.updateFinal();
|
||||
|
||||
|
@ -1100,16 +1093,16 @@ AtmosphereResult AtmosphereModelBruneton::applyAerialPerspective(Vector3 locatio
|
|||
Vector3 eye = parent->getCameraLocation();
|
||||
eye.y = max(eye.y, 0.0);
|
||||
location.y = max(location.y, 0.0);
|
||||
Vector3 sun_position = parent->getAtmosphereRenderer()->getSunDirection().scale(SUN_DISTANCE);
|
||||
Vector3 sun_position = parent->getAtmosphereRenderer()->getSunDirection().scale(Scenery::SUN_DISTANCE);
|
||||
|
||||
Vector3 direction = location.sub(eye).scale(WORLD_SCALING);
|
||||
Vector3 direction = location.sub(eye).scale(Scenery::UNIT_TO_KM);
|
||||
double t = direction.getNorm();
|
||||
if (t < 0.000001) {
|
||||
direction = parent->getCameraDirection().scale(0.001 * WORLD_SCALING);
|
||||
direction = parent->getCameraDirection().scale(0.001 * Scenery::UNIT_TO_KM);
|
||||
t = direction.getNorm();
|
||||
}
|
||||
|
||||
Vector3 x = {0.0, Rg + WORKAROUND_OFFSET + eye.y * WORLD_SCALING, 0.0};
|
||||
Vector3 x = {0.0, Rg + WORKAROUND_OFFSET + eye.y * Scenery::UNIT_TO_KM, 0.0};
|
||||
Vector3 v = direction.normalize();
|
||||
Vector3 s = sun_position.sub(x).normalize();
|
||||
|
||||
|
@ -1133,7 +1126,7 @@ AtmosphereResult AtmosphereModelBruneton::applyAerialPerspective(Vector3 locatio
|
|||
result.attenuation.r = attenuation.x;
|
||||
result.attenuation.g = attenuation.y;
|
||||
result.attenuation.b = attenuation.z;
|
||||
result.distance = t / WORLD_SCALING;
|
||||
result.distance = t * Scenery::KM_TO_UNIT;
|
||||
|
||||
result.updateFinal();
|
||||
|
||||
|
@ -1144,11 +1137,11 @@ bool AtmosphereModelBruneton::getLightsAt(vector<LightComponent> &result, const
|
|||
LightComponent sun, irradiance;
|
||||
double muS;
|
||||
|
||||
double altitude = max(location.y * WORLD_SCALING, 0.0);
|
||||
double altitude = max(location.y * Scenery::UNIT_TO_KM, 0.0);
|
||||
|
||||
double r0 = Rg + WORKAROUND_OFFSET + altitude;
|
||||
Vector3 up = {0.0, 1.0, 0.0};
|
||||
Vector3 sun_position = parent->getAtmosphereRenderer()->getSunDirection().scale(SUN_DISTANCE);
|
||||
Vector3 sun_position = parent->getAtmosphereRenderer()->getSunDirection().scale(Scenery::SUN_DISTANCE);
|
||||
Vector3 x = {0.0, r0, 0.0};
|
||||
Vector3 s = sun_position.sub(x).normalize();
|
||||
|
||||
|
|
|
@ -13,13 +13,6 @@
|
|||
#include "CelestialBodyDefinition.h"
|
||||
#include "FloatNode.h"
|
||||
|
||||
/* Factor to convert software units to kilometers */
|
||||
#define WORLD_SCALING 0.05
|
||||
#define SUN_DISTANCE 149597870.0
|
||||
#define SUN_DISTANCE_SCALED (SUN_DISTANCE / WORLD_SCALING)
|
||||
#define SUN_RADIUS 6.955e5
|
||||
#define SUN_RADIUS_SCALED (SUN_RADIUS / WORLD_SCALING)
|
||||
|
||||
static inline double _getDayFactor(double daytime) {
|
||||
daytime = 1.0 - fabs(0.5 - daytime) / 0.5;
|
||||
return daytime < 0.45 ? 0.0 : sqrt((daytime - 0.45) / 0.55);
|
||||
|
@ -142,7 +135,7 @@ AtmosphereResult SoftwareBrunetonAtmosphereRenderer::getSkyColor(const Vector3 &
|
|||
|
||||
sun_direction = getSunDirection();
|
||||
Vector3 direction_norm = direction.normalize();
|
||||
sun_position = sun_direction.scale(SUN_DISTANCE_SCALED);
|
||||
sun_position = sun_direction.scale(Scenery::SUN_DISTANCE_SCALED);
|
||||
|
||||
base = COLOR_BLACK;
|
||||
|
||||
|
@ -177,7 +170,7 @@ AtmosphereResult SoftwareBrunetonAtmosphereRenderer::getSkyColor(const Vector3 &
|
|||
|
||||
// Get scattering
|
||||
AtmosphereResult result;
|
||||
Vector3 location = camera_location.add(direction_norm.scale(6421.0));
|
||||
Vector3 location = camera_location.add(direction_norm.scale(Scenery::FAR_LIMIT_SCALED));
|
||||
switch (definition->model) {
|
||||
case AtmosphereDefinition::ATMOSPHERE_MODEL_BRUNETON:
|
||||
result = model->getSkyColor(camera_location, direction_norm, sun_position, base);
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include "SkyRasterizer.h"
|
||||
|
||||
#include <cmath>
|
||||
#include "Scenery.h"
|
||||
#include "Maths.h"
|
||||
#include "Vector3.h"
|
||||
#include "Color.h"
|
||||
|
@ -13,8 +14,6 @@
|
|||
#include "RenderProgress.h"
|
||||
#include "GodRaysSampler.h"
|
||||
|
||||
#define SPHERE_SIZE 20000.0
|
||||
|
||||
SkyRasterizer::SkyRasterizer(SoftwareRenderer *renderer, RenderProgress *progress, unsigned short client_id)
|
||||
: Rasterizer(renderer, progress, client_id, Color(0.7, 0.7, 1.0)) {
|
||||
}
|
||||
|
@ -29,6 +28,7 @@ void SkyRasterizer::rasterizeToCanvas(CanvasPortion *canvas) {
|
|||
double current_i, current_j;
|
||||
Vector3 vertex1, vertex2, vertex3, vertex4;
|
||||
Vector3 camera_location, direction;
|
||||
constexpr double limit = Scenery::FAR_LIMIT_SCALED;
|
||||
|
||||
step_i = Maths::PI * 2.0 / to_double(res_i);
|
||||
step_j = Maths::PI / to_double(res_j);
|
||||
|
@ -45,24 +45,24 @@ void SkyRasterizer::rasterizeToCanvas(CanvasPortion *canvas) {
|
|||
for (i = 0; i < res_i; i++) {
|
||||
current_i = to_double(i) * step_i;
|
||||
|
||||
direction.x = SPHERE_SIZE * cos(current_i) * cos(current_j);
|
||||
direction.y = SPHERE_SIZE * sin(current_j);
|
||||
direction.z = SPHERE_SIZE * sin(current_i) * cos(current_j);
|
||||
direction.x = limit * cos(current_i) * cos(current_j);
|
||||
direction.y = limit * sin(current_j);
|
||||
direction.z = limit * sin(current_i) * cos(current_j);
|
||||
vertex1 = camera_location.add(direction);
|
||||
|
||||
direction.x = SPHERE_SIZE * cos(current_i + step_i) * cos(current_j);
|
||||
direction.y = SPHERE_SIZE * sin(current_j);
|
||||
direction.z = SPHERE_SIZE * sin(current_i + step_i) * cos(current_j);
|
||||
direction.x = limit * cos(current_i + step_i) * cos(current_j);
|
||||
direction.y = limit * sin(current_j);
|
||||
direction.z = limit * sin(current_i + step_i) * cos(current_j);
|
||||
vertex2 = camera_location.add(direction);
|
||||
|
||||
direction.x = SPHERE_SIZE * cos(current_i + step_i) * cos(current_j + step_j);
|
||||
direction.y = SPHERE_SIZE * sin(current_j + step_j);
|
||||
direction.z = SPHERE_SIZE * sin(current_i + step_i) * cos(current_j + step_j);
|
||||
direction.x = limit * cos(current_i + step_i) * cos(current_j + step_j);
|
||||
direction.y = limit * sin(current_j + step_j);
|
||||
direction.z = limit * sin(current_i + step_i) * cos(current_j + step_j);
|
||||
vertex3 = camera_location.add(direction);
|
||||
|
||||
direction.x = SPHERE_SIZE * cos(current_i) * cos(current_j + step_j);
|
||||
direction.y = SPHERE_SIZE * sin(current_j + step_j);
|
||||
direction.z = SPHERE_SIZE * sin(current_i) * cos(current_j + step_j);
|
||||
direction.x = limit * cos(current_i) * cos(current_j + step_j);
|
||||
direction.y = limit * sin(current_j + step_j);
|
||||
direction.z = limit * sin(current_i) * cos(current_j + step_j);
|
||||
vertex4 = camera_location.add(direction);
|
||||
|
||||
// TODO Triangles at poles
|
||||
|
|
|
@ -149,7 +149,7 @@ int TerrainRasterizer::performTessellation(CanvasPortion *canvas) {
|
|||
double cx = cam.x - fmod(cam.x, base_chunk_size);
|
||||
double cz = cam.z - fmod(cam.x, base_chunk_size);
|
||||
|
||||
while (radius_int < 20000.0) {
|
||||
while (radius_int < Scenery::FAR_LIMIT_SCALED) {
|
||||
for (i = 0; i < chunk_count - 1; i++) {
|
||||
getChunk(renderer, &chunk, cx - radius_ext + chunk_size * i, cz - radius_ext, chunk_size);
|
||||
if (chunk.detail_hint > 0) {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include "WaterRasterizer.h"
|
||||
|
||||
#include <cmath>
|
||||
#include "Scenery.h"
|
||||
#include "SoftwareRenderer.h"
|
||||
#include "WaterRenderer.h"
|
||||
#include "CanvasFragment.h"
|
||||
|
@ -66,7 +67,7 @@ int WaterRasterizer::performTessellation(CanvasPortion *canvas) {
|
|||
double cx = cam.x - fmod(cam.x, base_chunk_size);
|
||||
double cz = cam.z - fmod(cam.x, base_chunk_size);
|
||||
|
||||
while (radius_int < 20000.0) {
|
||||
while (radius_int < Scenery::FAR_LIMIT_SCALED) {
|
||||
if (interrupted) {
|
||||
return result;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue