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;
mean = 0.0;
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);
max = std::max(val, max);
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.
*/
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 getBase2d(double x, double y) const;

View file

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

View file

@ -3,16 +3,23 @@
#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;
CelestialBodyDefinition::CelestialBodyDefinition(DefinitionNode *parent, const string &name)
: DefinitionNode(parent, name) {
distance = new FloatNode(this, "distance");
phi = new FloatNode(this, "phi");
theta = new FloatNode(this, "theta");
radius = new FloatNode(this, "radius");
}
Vector3 CelestialBodyDefinition::getDirection() const {
VectorSpherical spc = {1.0, theta->getValue(), -phi->getValue()};
return Vector3(spc);
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));
} 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:
CelestialBodyDefinition(DefinitionNode *parent, const string &name);
inline FloatNode *propDistance() const {
return distance;
}
inline FloatNode *propPhi() const {
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:
FloatNode *distance;
FloatNode *phi;
FloatNode *theta;
FloatNode *radius;

View file

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

View file

@ -24,6 +24,7 @@
#include "VegetationModelDefinition.h"
#include "VegetationInstance.h"
#include "VegetationRenderer.h"
#include "CelestialBodyDefinition.h"
#include "RayCastingResult.h"
#include "OpenGLVegetationImpostor.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() {
testNoise();
testTextures();
testGodRays();
testMoonRendering();
testNearFrustum();
testCloudsNearGround();
testVegetationModels();

View file

@ -82,7 +82,7 @@ void OpenGLSkybox::nodeChanged(const DefinitionNode *node, const DefinitionDiff
AtmosphereDefinition *newdef = renderer->getScenery()->getAtmosphere();
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);
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 {
Vector3 eye = parent->getCameraLocation(location);
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);
@ -1105,7 +1105,7 @@ AtmosphereResult AtmosphereModelBruneton::applyAerialPerspective(Vector3 locatio
Vector3 direction = location.sub(eye).scale(WORLD_SCALING);
double t = direction.getNorm();
if (t < 0.000001) {
direction = parent->getCameraDirection(location).scale(0.001 * WORLD_SCALING);
direction = parent->getCameraDirection().scale(0.001 * WORLD_SCALING);
t = direction.getNorm();
}

View file

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

View file

@ -65,7 +65,7 @@ int CloudBasicLayerRenderer::findSegments(BaseCloudsModel *model, const Vector3
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;
segment_count = 0;

View file

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

View file

@ -13,12 +13,6 @@
#include "CelestialBodyDefinition.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) {
}
@ -58,10 +52,11 @@ const Color NightSky::getColor(double altitude, const Vector3 &direction) {
}
// Get moon
Vector3 moon_direction = atmosphere->childMoon()->getDirection();
Vector3 moon_position = moon_direction.scale(MOON_DISTANCE_SCALED);
Vector3 moon_position = atmosphere->childMoon()->getLocation();
Vector3 moon_direction = moon_position.sub(renderer->getCameraLocation()).normalize();
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;
int hits = Geometry::rayIntersectSphere(location, direction, moon_position, moon_radius, &hit1, &hit2);
if (hits > 1) {
@ -84,13 +79,13 @@ const Color NightSky::getColor(double altitude, const Vector3 &direction) {
return result;
}
bool NightSky::getLightsAt(vector<LightComponent> &result, const Vector3 &) const {
bool NightSky::getLightsAt(vector<LightComponent> &result, const Vector3 &loc) const {
LightComponent moon, sky;
AtmosphereDefinition *atmosphere = renderer->getScenery()->getAtmosphere();
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.altered = 1;

View file

@ -33,7 +33,7 @@ void SkyRasterizer::rasterizeToCanvas(CanvasPortion *canvas) {
step_i = Maths::PI * 2.0 / to_double(res_i);
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++) {
if (interrupted) {
@ -77,7 +77,7 @@ Color SkyRasterizer::shadeFragment(const CanvasFragment &fragment, const CanvasF
Vector3 camera_location, direction;
Color result;
camera_location = renderer->getCameraLocation(location);
camera_location = renderer->getCameraLocation();
direction = location.sub(camera_location);
// 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,
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 result = atmosphere_renderer->applyAerialPerspective(location, color).final;
result = clouds_renderer->getColor(getCameraLocation(location), location, result);
result = clouds_renderer->getColor(getCameraLocation(), location, result);
return result;
}
@ -132,11 +132,11 @@ RayCastingResult SoftwareRenderer::rayWalking(const Vector3 &location, const Vec
return result;
}
Vector3 SoftwareRenderer::getCameraLocation(const Vector3 &) {
Vector3 SoftwareRenderer::getCameraLocation() {
return render_camera->getLocation();
}
Vector3 SoftwareRenderer::getCameraDirection(const Vector3 &) {
Vector3 SoftwareRenderer::getCameraDirection() {
return render_camera->getDirectionNormalized();
}

View file

@ -19,8 +19,8 @@ class SOFTWARESHARED_EXPORT SoftwareRenderer {
int render_quality;
CameraDefinition *render_camera;
virtual Vector3 getCameraLocation(const Vector3 &target);
virtual Vector3 getCameraDirection(const Vector3 &target);
virtual Vector3 getCameraLocation();
virtual Vector3 getCameraDirection();
virtual double getPrecision(const Vector3 &location);
virtual Vector3 projectPoint(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) {
TerrainChunkInfo chunk;
int chunk_factor, chunk_count, i, result;
Vector3 cam = renderer->getCameraLocation(VECTOR_ZERO);
Vector3 cam = renderer->getCameraLocation();
double radius_int, radius_ext;
double chunk_size;

View file

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

View file

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

View file

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