Some refactoring to prepare for work on moon rendering
Also added render test to check it
This commit is contained in:
parent
d1a5706f3e
commit
95b24857e9
21 changed files with 84 additions and 46 deletions
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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()};
|
||||
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};
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)) {
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Reference in a new issue