Centralized scenery constants (earth radius...)

This commit is contained in:
Michaël Lemaire 2016-01-15 00:39:33 +01:00
parent 95b24857e9
commit 6b6710f15c
11 changed files with 76 additions and 65 deletions

View file

@ -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);

View file

@ -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();
}

View file

@ -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);
}

View file

@ -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();

View file

@ -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() {

View file

@ -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)));

View file

@ -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();

View file

@ -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);

View file

@ -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

View file

@ -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) {

View file

@ -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;
}