Some refactoring to prepare for work on moon rendering

Also added render test to check it
This commit is contained in:
Michaël Lemaire 2016-01-15 00:07:02 +01:00
parent d1a5706f3e
commit 95b24857e9
21 changed files with 84 additions and 46 deletions

View file

@ -209,7 +209,8 @@ string FractalNoise::checkDistribution() {
max = 0.0; max = 0.0;
mean = 0.0; mean = 0.0;
for (int i = 0; i < samples; i++) { for (int i = 0; i < samples; i++) {
val = getBase3d((random.genDouble() - 0.5) * 10.0, (random.genDouble() - 0.5) * 10.0, (random.genDouble() - 0.5) * 10.0); val = getBase3d((random.genDouble() - 0.5) * 10.0, (random.genDouble() - 0.5) * 10.0,
(random.genDouble() - 0.5) * 10.0);
min = std::min(val, min); min = std::min(val, min);
max = std::max(val, max); max = std::max(val, max);
mean += val * factor; mean += val * factor;

View file

@ -57,7 +57,7 @@ class BASICSSHARED_EXPORT FractalNoise {
/** /**
* Estimate the range of values this generator will yield with a very small detail value. * Estimate the range of values this generator will yield with a very small detail value.
*/ */
void estimateRange(double *min, double *max, double detail=0.000001) const; void estimateRange(double *min, double *max, double detail = 0.000001) const;
virtual double getBase1d(double x) const; virtual double getBase1d(double x) const;
virtual double getBase2d(double x, double y) const; virtual double getBase2d(double x, double y) const;

View file

@ -8,6 +8,8 @@
#include "GodRaysDefinition.h" #include "GodRaysDefinition.h"
#include "CelestialBodyDefinition.h" #include "CelestialBodyDefinition.h"
#define WORLD_SCALING 0.05
AtmosphereDefinition::AtmosphereDefinition(DefinitionNode *parent) AtmosphereDefinition::AtmosphereDefinition(DefinitionNode *parent)
: DefinitionNode(parent, "atmosphere", "atmosphere") { : DefinitionNode(parent, "atmosphere", "atmosphere") {
model = ATMOSPHERE_MODEL_DISABLED; model = ATMOSPHERE_MODEL_DISABLED;
@ -102,7 +104,9 @@ void AtmosphereDefinition::applyPreset(AtmospherePreset preset, RandomGenerator
sun_color.b = 0.9; sun_color.b = 0.9;
sun_color.a = 1.0; sun_color.a = 1.0;
sun->propRadius()->setValue(1.0); sun->propRadius()->setValue(1.0);
moon->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);
moon->propPhi()->setValue(0.5); moon->propPhi()->setValue(0.5);
moon->propTheta()->setValue(0.3); moon->propTheta()->setValue(0.3);

View file

@ -3,16 +3,23 @@
#include "Vector3.h" #include "Vector3.h"
#include "FloatNode.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;
CelestialBodyDefinition::CelestialBodyDefinition(DefinitionNode *parent, const string &name) CelestialBodyDefinition::CelestialBodyDefinition(DefinitionNode *parent, const string &name)
: DefinitionNode(parent, name) { : DefinitionNode(parent, name) {
distance = new FloatNode(this, "distance");
phi = new FloatNode(this, "phi"); phi = new FloatNode(this, "phi");
theta = new FloatNode(this, "theta"); theta = new FloatNode(this, "theta");
radius = new FloatNode(this, "radius"); radius = new FloatNode(this, "radius");
} }
Vector3 CelestialBodyDefinition::getDirection() const { Vector3 CelestialBodyDefinition::getLocation(bool over_water) const {
VectorSpherical spc = {1.0, theta->getValue(), -phi->getValue()}; VectorSpherical spc = {distance->getValue(), theta->getValue(), -phi->getValue()};
return Vector3(spc); if (over_water) {
return Vector3(spc).sub(VECTOR_DOWN.scale(EARTH_RADIUS_SCALED));
} else {
return Vector3(spc);
}
} }
// VectorSpherical moon_location_s = {MOON_DISTANCE_SCALED, atmosphere->moon_theta, -atmosphere->moon_phi};

View file

@ -12,6 +12,9 @@ class DEFINITIONSHARED_EXPORT CelestialBodyDefinition : public DefinitionNode {
public: public:
CelestialBodyDefinition(DefinitionNode *parent, const string &name); CelestialBodyDefinition(DefinitionNode *parent, const string &name);
inline FloatNode *propDistance() const {
return distance;
}
inline FloatNode *propPhi() const { inline FloatNode *propPhi() const {
return phi; return phi;
} }
@ -23,11 +26,15 @@ class DEFINITIONSHARED_EXPORT CelestialBodyDefinition : public DefinitionNode {
} }
/** /**
* Get the normalized direction toward the celestial body (from the center of the earth). * Get the location of the celestial body.
*
* If "over_water" is true, the location is given in standard coordinates with y=0.0 as water,
* otherwise in regard to the earth center.
*/ */
Vector3 getDirection() const; Vector3 getLocation(bool over_water = true) const;
private: private:
FloatNode *distance;
FloatNode *phi; FloatNode *phi;
FloatNode *theta; FloatNode *theta;
FloatNode *radius; FloatNode *radius;

View file

@ -66,8 +66,7 @@ double TerrainDefinition::getGridHeight(int x, int z, bool with_painting) {
return h; return h;
} }
double TerrainDefinition::getInterpolatedHeight(double x, double z, bool with_painting, double TerrainDefinition::getInterpolatedHeight(double x, double z, bool with_painting, bool water_offset) {
bool water_offset) {
double h; double h;
if (!with_painting || !has_painting || !height_map->getInterpolatedValue(x, z, &h)) { if (!with_painting || !has_painting || !height_map->getInterpolatedValue(x, z, &h)) {

View file

@ -24,6 +24,7 @@
#include "VegetationModelDefinition.h" #include "VegetationModelDefinition.h"
#include "VegetationInstance.h" #include "VegetationInstance.h"
#include "VegetationRenderer.h" #include "VegetationRenderer.h"
#include "CelestialBodyDefinition.h"
#include "RayCastingResult.h" #include "RayCastingResult.h"
#include "OpenGLVegetationImpostor.h" #include "OpenGLVegetationImpostor.h"
#include "Texture2D.h" #include "Texture2D.h"
@ -413,10 +414,33 @@ static void testTextures() {
} }
} }
static void testMoonRendering() {
Scenery scenery;
scenery.autoPreset(8);
scenery.getClouds()->clear();
scenery.getCamera()->setLocation(VECTOR_ZERO);
scenery.getCamera()->setTarget(scenery.getAtmosphere()->childMoon()->getLocation());
scenery.getCamera()->setFov(0.1);
SoftwareCanvasRenderer renderer(&scenery);
renderer.setSize(600, 600);
renderer.setQuality(0.1);
renderer.getGodRaysSampler()->setEnabled(false);
/*SkyRasterizer rasterizer(&renderer, renderer.getProgressHelper(), 0);
renderer.setSoloRasterizer(&rasterizer);*/
scenery.getAtmosphere()->setDayTime(17, 30);
startTestRender(&renderer, "moon", 0);
scenery.getAtmosphere()->setDayTime(23);
startTestRender(&renderer, "moon", 1);
}
void runTestSuite() { void runTestSuite() {
testNoise(); testNoise();
testTextures(); testTextures();
testGodRays(); testGodRays();
testMoonRendering();
testNearFrustum(); testNearFrustum();
testCloudsNearGround(); testCloudsNearGround();
testVegetationModels(); testVegetationModels();

View file

@ -82,7 +82,7 @@ void OpenGLSkybox::nodeChanged(const DefinitionNode *node, const DefinitionDiff
AtmosphereDefinition *newdef = renderer->getScenery()->getAtmosphere(); AtmosphereDefinition *newdef = renderer->getScenery()->getAtmosphere();
if (node->getPath() == path_sun_phi or node->getPath() == path_sun_theta) { if (node->getPath() == path_sun_phi or node->getPath() == path_sun_theta) {
Vector3 sun_direction = renderer->getAtmosphereRenderer()->getSunDirection(false); Vector3 sun_direction = renderer->getAtmosphereRenderer()->getSunDirection();
state->set("sunDirection", sun_direction); state->set("sunDirection", sun_direction);
Color sun_color = newdef->sun_color; Color sun_color = newdef->sun_color;

View file

@ -1097,7 +1097,7 @@ AtmosphereResult AtmosphereModelBruneton::getSkyColor(Vector3 eye, const Vector3
} }
AtmosphereResult AtmosphereModelBruneton::applyAerialPerspective(Vector3 location, const Color &base) const { AtmosphereResult AtmosphereModelBruneton::applyAerialPerspective(Vector3 location, const Color &base) const {
Vector3 eye = parent->getCameraLocation(location); Vector3 eye = parent->getCameraLocation();
eye.y = max(eye.y, 0.0); eye.y = max(eye.y, 0.0);
location.y = max(location.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(SUN_DISTANCE);
@ -1105,7 +1105,7 @@ AtmosphereResult AtmosphereModelBruneton::applyAerialPerspective(Vector3 locatio
Vector3 direction = location.sub(eye).scale(WORLD_SCALING); Vector3 direction = location.sub(eye).scale(WORLD_SCALING);
double t = direction.getNorm(); double t = direction.getNorm();
if (t < 0.000001) { if (t < 0.000001) {
direction = parent->getCameraDirection(location).scale(0.001 * WORLD_SCALING); direction = parent->getCameraDirection().scale(0.001 * WORLD_SCALING);
t = direction.getNorm(); t = direction.getNorm();
} }

View file

@ -87,8 +87,9 @@ AtmosphereResult BaseAtmosphereRenderer::getSkyColor(const Vector3 &) {
return result; return result;
} }
Vector3 BaseAtmosphereRenderer::getSunDirection(bool) const { Vector3 BaseAtmosphereRenderer::getSunDirection() const {
return getDefinition()->childSun()->getDirection(); auto sun_location = getDefinition()->childSun()->getLocation();
return sun_location.sub(parent->getCameraLocation()).normalize();
} }
bool BaseAtmosphereRenderer::getLightsAt(vector<LightComponent> &, const Vector3 &) const { bool BaseAtmosphereRenderer::getLightsAt(vector<LightComponent> &, const Vector3 &) const {
@ -137,7 +138,7 @@ AtmosphereResult SoftwareBrunetonAtmosphereRenderer::getSkyColor(const Vector3 &
Color base; Color base;
definition = getDefinition(); definition = getDefinition();
camera_location = parent->getCameraLocation(VECTOR_ZERO); camera_location = parent->getCameraLocation();
sun_direction = getSunDirection(); sun_direction = getSunDirection();
Vector3 direction_norm = direction.normalize(); Vector3 direction_norm = direction.normalize();

View file

@ -16,7 +16,7 @@ class BaseAtmosphereRenderer : public LightSource {
virtual AtmosphereResult applyAerialPerspective(const Vector3 &location, const Color &base); virtual AtmosphereResult applyAerialPerspective(const Vector3 &location, const Color &base);
virtual AtmosphereResult getSkyColor(const Vector3 &direction); virtual AtmosphereResult getSkyColor(const Vector3 &direction);
virtual Vector3 getSunDirection(bool cache = true) const; virtual Vector3 getSunDirection() const;
virtual bool getLightsAt(vector<LightComponent> &result, const Vector3 &location) const override; virtual bool getLightsAt(vector<LightComponent> &result, const Vector3 &location) const override;

View file

@ -65,7 +65,7 @@ int CloudBasicLayerRenderer::findSegments(BaseCloudsModel *model, const Vector3
model->getDetailRange(&min_step, &max_step); model->getDetailRange(&min_step, &max_step);
double distance = parent->getCameraLocation(start).sub(start).getNorm(); double distance = parent->getCameraLocation().sub(start).getNorm();
render_precision = min_step + (max_step - min_step) * min(distance / (quality + 0.1), 100.0) * 0.01; render_precision = min_step + (max_step - min_step) * min(distance / (quality + 0.1), 100.0) * 0.01;
segment_count = 0; segment_count = 0;

View file

@ -38,7 +38,7 @@ GodRaysSampler::~GodRaysSampler() {
} }
void GodRaysSampler::prepare(SoftwareRenderer *renderer) { void GodRaysSampler::prepare(SoftwareRenderer *renderer) {
setCameraLocation(renderer->getCameraLocation(VECTOR_ZERO)); setCameraLocation(renderer->getCameraLocation());
setLighting(renderer->getLightingManager()); setLighting(renderer->getLightingManager());
setAltitudes(renderer->getScenery()->getTerrain()->getHeightInfo().min_height, setAltitudes(renderer->getScenery()->getTerrain()->getHeightInfo().min_height,
renderer->getCloudsRenderer()->getHighestAltitude()); renderer->getCloudsRenderer()->getHighestAltitude());

View file

@ -13,12 +13,6 @@
#include "CelestialBodyDefinition.h" #include "CelestialBodyDefinition.h"
#include "FloatNode.h" #include "FloatNode.h"
#define WORLD_SCALING 0.05
#define MOON_DISTANCE 384403.0
#define MOON_DISTANCE_SCALED (MOON_DISTANCE / WORLD_SCALING)
#define MOON_RADIUS 1737.4
#define MOON_RADIUS_SCALED (MOON_RADIUS / WORLD_SCALING)
NightSky::NightSky(SoftwareRenderer *renderer) : renderer(renderer) { NightSky::NightSky(SoftwareRenderer *renderer) : renderer(renderer) {
} }
@ -58,10 +52,11 @@ const Color NightSky::getColor(double altitude, const Vector3 &direction) {
} }
// Get moon // Get moon
Vector3 moon_direction = atmosphere->childMoon()->getDirection(); Vector3 moon_position = atmosphere->childMoon()->getLocation();
Vector3 moon_position = moon_direction.scale(MOON_DISTANCE_SCALED); Vector3 moon_direction = moon_position.sub(renderer->getCameraLocation()).normalize();
if (moon_direction.dotProduct(direction) >= 0) { if (moon_direction.dotProduct(direction) >= 0) {
double moon_radius = MOON_RADIUS_SCALED * 5.0 * atmosphere->childMoon()->propRadius()->getValue(); // TODO Why need the multiplier ?
double moon_radius = atmosphere->childMoon()->propRadius()->getValue() * 5.0;
Vector3 hit1, hit2; Vector3 hit1, hit2;
int hits = Geometry::rayIntersectSphere(location, direction, moon_position, moon_radius, &hit1, &hit2); int hits = Geometry::rayIntersectSphere(location, direction, moon_position, moon_radius, &hit1, &hit2);
if (hits > 1) { if (hits > 1) {
@ -84,13 +79,13 @@ const Color NightSky::getColor(double altitude, const Vector3 &direction) {
return result; return result;
} }
bool NightSky::getLightsAt(vector<LightComponent> &result, const Vector3 &) const { bool NightSky::getLightsAt(vector<LightComponent> &result, const Vector3 &loc) const {
LightComponent moon, sky; LightComponent moon, sky;
AtmosphereDefinition *atmosphere = renderer->getScenery()->getAtmosphere(); AtmosphereDefinition *atmosphere = renderer->getScenery()->getAtmosphere();
moon.color = Color(0.03, 0.03, 0.03); // TODO take moon phase into account moon.color = Color(0.03, 0.03, 0.03); // TODO take moon phase into account
moon.direction = atmosphere->childMoon()->getDirection().scale(-1.0); moon.direction = loc.sub(atmosphere->childMoon()->getLocation()).normalize();
moon.reflection = 0.2; moon.reflection = 0.2;
moon.altered = 1; moon.altered = 1;

View file

@ -33,7 +33,7 @@ void SkyRasterizer::rasterizeToCanvas(CanvasPortion *canvas) {
step_i = Maths::PI * 2.0 / to_double(res_i); step_i = Maths::PI * 2.0 / to_double(res_i);
step_j = Maths::PI / to_double(res_j); step_j = Maths::PI / to_double(res_j);
camera_location = renderer->getCameraLocation(VECTOR_ZERO); camera_location = renderer->getCameraLocation();
for (j = 0; j < res_j; j++) { for (j = 0; j < res_j; j++) {
if (interrupted) { if (interrupted) {
@ -77,7 +77,7 @@ Color SkyRasterizer::shadeFragment(const CanvasFragment &fragment, const CanvasF
Vector3 camera_location, direction; Vector3 camera_location, direction;
Color result; Color result;
camera_location = renderer->getCameraLocation(location); camera_location = renderer->getCameraLocation();
direction = location.sub(camera_location); direction = location.sub(camera_location);
// TODO Don't compute sky color if it's fully covered by clouds // TODO Don't compute sky color if it's fully covered by clouds

View file

@ -107,12 +107,12 @@ void SoftwareRenderer::setQuality(double quality) {
Color SoftwareRenderer::applyLightingToSurface(const Vector3 &location, const Vector3 &normal, Color SoftwareRenderer::applyLightingToSurface(const Vector3 &location, const Vector3 &normal,
const SurfaceMaterial &material) { const SurfaceMaterial &material) {
return lighting->apply(getCameraLocation(location), location, normal, material); return lighting->apply(getCameraLocation(), location, normal, material);
} }
Color SoftwareRenderer::applyMediumTraversal(const Vector3 &location, const Color &color) { Color SoftwareRenderer::applyMediumTraversal(const Vector3 &location, const Color &color) {
Color result = atmosphere_renderer->applyAerialPerspective(location, color).final; Color result = atmosphere_renderer->applyAerialPerspective(location, color).final;
result = clouds_renderer->getColor(getCameraLocation(location), location, result); result = clouds_renderer->getColor(getCameraLocation(), location, result);
return result; return result;
} }
@ -132,11 +132,11 @@ RayCastingResult SoftwareRenderer::rayWalking(const Vector3 &location, const Vec
return result; return result;
} }
Vector3 SoftwareRenderer::getCameraLocation(const Vector3 &) { Vector3 SoftwareRenderer::getCameraLocation() {
return render_camera->getLocation(); return render_camera->getLocation();
} }
Vector3 SoftwareRenderer::getCameraDirection(const Vector3 &) { Vector3 SoftwareRenderer::getCameraDirection() {
return render_camera->getDirectionNormalized(); return render_camera->getDirectionNormalized();
} }

View file

@ -19,8 +19,8 @@ class SOFTWARESHARED_EXPORT SoftwareRenderer {
int render_quality; int render_quality;
CameraDefinition *render_camera; CameraDefinition *render_camera;
virtual Vector3 getCameraLocation(const Vector3 &target); virtual Vector3 getCameraLocation();
virtual Vector3 getCameraDirection(const Vector3 &target); virtual Vector3 getCameraDirection();
virtual double getPrecision(const Vector3 &location); virtual double getPrecision(const Vector3 &location);
virtual Vector3 projectPoint(const Vector3 &point); virtual Vector3 projectPoint(const Vector3 &point);
virtual Vector3 unprojectPoint(const Vector3 &point); virtual Vector3 unprojectPoint(const Vector3 &point);

View file

@ -135,7 +135,7 @@ void TerrainRasterizer::getChunk(SoftwareRenderer *renderer, TerrainRasterizer::
int TerrainRasterizer::performTessellation(CanvasPortion *canvas) { int TerrainRasterizer::performTessellation(CanvasPortion *canvas) {
TerrainChunkInfo chunk; TerrainChunkInfo chunk;
int chunk_factor, chunk_count, i, result; int chunk_factor, chunk_count, i, result;
Vector3 cam = renderer->getCameraLocation(VECTOR_ZERO); Vector3 cam = renderer->getCameraLocation();
double radius_int, radius_ext; double radius_int, radius_ext;
double chunk_size; double chunk_size;

View file

@ -122,9 +122,9 @@ Color TerrainRenderer::getFinalColor(double x, double z, double precision) {
i++; i++;
} }
auto color = textures_renderer->getFinalComposition(textures_definition, parent->getLightingManager(), auto color =
current.first, current.second, normal, precision, textures_renderer->getFinalComposition(textures_definition, parent->getLightingManager(), current.first,
parent->getCameraLocation(top_location)); current.second, normal, precision, parent->getCameraLocation());
return parent->applyMediumTraversal(top_location, color); return parent->applyMediumTraversal(top_location, color);
} }

View file

@ -53,7 +53,7 @@ void WaterRasterizer::setQuality(double factor) {
int WaterRasterizer::performTessellation(CanvasPortion *canvas) { int WaterRasterizer::performTessellation(CanvasPortion *canvas) {
int chunk_factor, chunk_count, i, result; int chunk_factor, chunk_count, i, result;
Vector3 cam = renderer->getCameraLocation(VECTOR_ZERO); Vector3 cam = renderer->getCameraLocation();
double radius_int, radius_ext, chunk_size; double radius_int, radius_ext, chunk_size;
result = 0; result = 0;

View file

@ -166,7 +166,7 @@ WaterRenderer::WaterResult WaterRenderer::getResult(double x, double z) {
} }
normal = _getNormal(definition, noise, location, detail); normal = _getNormal(definition, noise, location, detail);
look_direction = location.sub(parent->getCameraLocation(location)).normalize(); look_direction = location.sub(parent->getCameraLocation()).normalize();
/* Reflection */ /* Reflection */
if (reflection == 0.0) { if (reflection == 0.0) {