Separated MoonRenderer
This commit is contained in:
parent
f4bc02c5ca
commit
5778154aae
8 changed files with 129 additions and 36 deletions
|
@ -80,7 +80,7 @@ void TextureLayerDefinition::applyPreset(TextureLayerPreset preset, RandomGenera
|
|||
break;
|
||||
case TEXTURES_LAYER_PRESET_ROCK:
|
||||
terrain_zone->addHeightRangeQuick(1.0, 0.6, 0.7, 0.87, 0.95);
|
||||
displacement_noise->setConfig(4.0, 0.3, 0.5, 0.85);
|
||||
displacement_noise->setConfig(4.0, 0.15, 0.5, 0.8);
|
||||
detail_noise->setConfig(0.02, 0.04);
|
||||
material->setColor(0.6, 0.55, 0.57, 1.0);
|
||||
material->reflection = 0.006;
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include "LightStatus.h"
|
||||
#include "Scenery.h"
|
||||
#include "NightSky.h"
|
||||
#include "MoonRenderer.h"
|
||||
#include "CelestialBodyDefinition.h"
|
||||
#include "FloatNode.h"
|
||||
|
||||
|
@ -171,6 +172,9 @@ AtmosphereResult SoftwareBrunetonAtmosphereRenderer::getSkyColor(const Vector3 &
|
|||
}
|
||||
}*/
|
||||
|
||||
// Get the moon
|
||||
base.mask(parent->getMoonRenderer().getColor(camera_location, direction_norm, parent->getLightingManager()));
|
||||
|
||||
// Get scattering
|
||||
AtmosphereResult result;
|
||||
Vector3 location = camera_location.add(direction_norm.scale(Scenery::FAR_LIMIT_SCALED));
|
||||
|
@ -194,6 +198,7 @@ AtmosphereResult SoftwareBrunetonAtmosphereRenderer::getSkyColor(const Vector3 &
|
|||
bool SoftwareBrunetonAtmosphereRenderer::getLightsAt(vector<LightComponent> &result, const Vector3 &location) const {
|
||||
bool changed = false;
|
||||
changed |= model->getLightsAt(result, location);
|
||||
// FIXME Should be registered on its own
|
||||
changed |= parent->getNightSky()->getLightsAt(result, location);
|
||||
return changed;
|
||||
}
|
||||
|
|
72
src/render/software/MoonRenderer.cpp
Normal file
72
src/render/software/MoonRenderer.cpp
Normal file
|
@ -0,0 +1,72 @@
|
|||
#include "MoonRenderer.h"
|
||||
|
||||
#include "CelestialBodyDefinition.h"
|
||||
#include "Color.h"
|
||||
#include "LightingManager.h"
|
||||
#include "Geometry.h"
|
||||
#include "SurfaceMaterial.h"
|
||||
#include "FloatNode.h"
|
||||
|
||||
class MoonRenderer::pimpl {
|
||||
public:
|
||||
pimpl() : definition(NULL, "moon"), material(Color(3.0, 3.0, 3.0)) {
|
||||
// TODO Put material in scenery
|
||||
}
|
||||
CelestialBodyDefinition definition;
|
||||
SurfaceMaterial material;
|
||||
};
|
||||
|
||||
MoonRenderer::MoonRenderer(CelestialBodyDefinition *moon_node) : impl(new pimpl()) {
|
||||
startWatching(moon_node->getRoot(), moon_node->getPath());
|
||||
|
||||
// FIXME should not be needed because the above watcher should watch the whole node
|
||||
// and call nodeChanged
|
||||
moon_node->copy(&impl->definition);
|
||||
}
|
||||
|
||||
MoonRenderer::~MoonRenderer() {
|
||||
}
|
||||
|
||||
void MoonRenderer::nodeChanged(const DefinitionNode *node, const DefinitionDiff *) {
|
||||
if (auto moon_node = static_cast<const CelestialBodyDefinition *>(node)) {
|
||||
moon_node->copy(&impl->definition);
|
||||
}
|
||||
}
|
||||
|
||||
bool MoonRenderer::getLightsAt(vector<LightComponent> &result, const Vector3 &location) const {
|
||||
LightComponent light;
|
||||
|
||||
// TODO Don't add if its contribution is negligible
|
||||
// TODO Take moon phase into account
|
||||
|
||||
light.color = Color(0.03, 0.03, 0.03);
|
||||
light.direction = location.sub(impl->definition.getLocation()).normalize();
|
||||
light.reflection = 0.2;
|
||||
light.altered = true;
|
||||
|
||||
result.push_back(light);
|
||||
return true;
|
||||
}
|
||||
|
||||
Color MoonRenderer::getColor(const Vector3 &eye, const Vector3 &direction, LightingManager *lighting) const {
|
||||
auto moon_location = impl->definition.getLocation();
|
||||
auto moon_direction = moon_location.sub(eye).normalize();
|
||||
if (moon_direction.dotProduct(direction) >= 0) {
|
||||
// TODO Alter radius near horizon (lens effect)
|
||||
double moon_radius = impl->definition.propRadius()->getValue();
|
||||
Vector3 hit1, hit2;
|
||||
int hits = Geometry::rayIntersectSphere(eye, direction, moon_location, moon_radius, &hit1, &hit2);
|
||||
if (hits > 1) {
|
||||
// distance between intersection points (relative to radius)
|
||||
double dist = hit2.sub(hit1).getNorm() / moon_radius;
|
||||
auto nearest = (hit1.sub(eye).getNorm() > hit2.sub(eye).getNorm()) ? hit2 : hit1;
|
||||
|
||||
auto moon_color = lighting->apply(eye, nearest, nearest.sub(moon_location).normalize(), impl->material);
|
||||
if (dist <= 0.05) {
|
||||
moon_color.a *= 1.0 - dist / 0.05;
|
||||
}
|
||||
return moon_color;
|
||||
}
|
||||
}
|
||||
return COLOR_TRANSPARENT;
|
||||
}
|
40
src/render/software/MoonRenderer.h
Normal file
40
src/render/software/MoonRenderer.h
Normal file
|
@ -0,0 +1,40 @@
|
|||
#ifndef MOONRENDERER_H
|
||||
#define MOONRENDERER_H
|
||||
|
||||
#include "software_global.h"
|
||||
|
||||
#include "DefinitionWatcher.h"
|
||||
#include "LightSource.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace paysages {
|
||||
namespace software {
|
||||
|
||||
/**
|
||||
* Moon renderer.
|
||||
*/
|
||||
class SOFTWARESHARED_EXPORT MoonRenderer : public DefinitionWatcher, public LightSource {
|
||||
public:
|
||||
MoonRenderer(CelestialBodyDefinition *moon_node);
|
||||
virtual ~MoonRenderer();
|
||||
|
||||
virtual void nodeChanged(const DefinitionNode *node, const DefinitionDiff *diff) override;
|
||||
virtual bool getLightsAt(vector<LightComponent> &result, const Vector3 &location) const override;
|
||||
|
||||
/**
|
||||
* Get the final moon color, given a looking ray.
|
||||
*
|
||||
* The result will be lighted with *lighting*.
|
||||
*/
|
||||
Color getColor(const Vector3 &eye, const Vector3 &direction, LightingManager *lighting) const;
|
||||
|
||||
private:
|
||||
class pimpl;
|
||||
unique_ptr<pimpl> impl;
|
||||
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif // MOONRENDERER_H
|
|
@ -51,44 +51,11 @@ const Color NightSky::getColor(double altitude, const Vector3 &direction) {
|
|||
}
|
||||
}
|
||||
|
||||
// Get moon
|
||||
Vector3 moon_position = atmosphere->childMoon()->getLocation();
|
||||
Vector3 moon_direction = moon_position.sub(renderer->getCameraLocation()).normalize();
|
||||
if (moon_direction.dotProduct(direction) >= 0) {
|
||||
double moon_radius = atmosphere->childMoon()->propRadius()->getValue();
|
||||
Vector3 hit1, hit2;
|
||||
int hits = Geometry::rayIntersectSphere(location, direction, moon_position, moon_radius, &hit1, &hit2);
|
||||
if (hits > 1) {
|
||||
double dist =
|
||||
hit2.sub(hit1).getNorm() / moon_radius; // distance between intersection points (relative to radius)
|
||||
|
||||
Vector3 nearest = (hit1.sub(location).getNorm() > hit2.sub(location).getNorm()) ? hit2 : hit1;
|
||||
SurfaceMaterial moon_material(Color(3.0, 3.0, 3.0));
|
||||
moon_material.validate();
|
||||
|
||||
Color moon_color =
|
||||
renderer->applyLightingToSurface(nearest, nearest.sub(moon_position).normalize(), moon_material);
|
||||
if (dist <= 0.05) {
|
||||
moon_color.a *= 1.0 - dist / 0.05;
|
||||
}
|
||||
result.mask(moon_color);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
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 = loc.sub(atmosphere->childMoon()->getLocation()).normalize();
|
||||
moon.reflection = 0.2;
|
||||
moon.altered = 1;
|
||||
|
||||
result.push_back(moon);
|
||||
bool NightSky::getLightsAt(vector<LightComponent> &result, const Vector3 &) const {
|
||||
LightComponent sky;
|
||||
|
||||
sky.color = Color(0.01, 0.012, 0.03);
|
||||
sky.direction = VECTOR_DOWN;
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include "TerrainRasterizer.h"
|
||||
#include "WaterRasterizer.h"
|
||||
#include "NightSky.h"
|
||||
#include "MoonRenderer.h"
|
||||
#include "LightStatus.h"
|
||||
#include "LightingManager.h"
|
||||
#include "GodRaysSampler.h"
|
||||
|
@ -37,6 +38,7 @@ SoftwareRenderer::SoftwareRenderer(Scenery *scenery) : scenery(scenery) {
|
|||
water_renderer = new WaterRenderer(this);
|
||||
|
||||
nightsky_renderer = new NightSky(this);
|
||||
moon_renderer = new MoonRenderer(scenery->getAtmosphere()->childMoon());
|
||||
|
||||
fluid_medium = new FluidMediumManager(this);
|
||||
lighting = new LightingManager();
|
||||
|
@ -47,6 +49,7 @@ SoftwareRenderer::SoftwareRenderer(Scenery *scenery) : scenery(scenery) {
|
|||
lighting->registerFilter(vegetation_renderer);
|
||||
lighting->registerFilter(clouds_renderer);
|
||||
lighting->registerSource(atmosphere_renderer);
|
||||
lighting->registerSource(moon_renderer);
|
||||
|
||||
setQuality(0.5);
|
||||
}
|
||||
|
@ -59,6 +62,7 @@ SoftwareRenderer::~SoftwareRenderer() {
|
|||
delete godrays;
|
||||
|
||||
delete nightsky_renderer;
|
||||
delete moon_renderer;
|
||||
|
||||
delete atmosphere_renderer;
|
||||
delete clouds_renderer;
|
||||
|
|
|
@ -68,6 +68,9 @@ class SOFTWARESHARED_EXPORT SoftwareRenderer {
|
|||
inline NightSky *getNightSky() const {
|
||||
return nightsky_renderer;
|
||||
}
|
||||
inline const MoonRenderer &getMoonRenderer() const {
|
||||
return *moon_renderer;
|
||||
}
|
||||
|
||||
inline FluidMediumManager *getFluidMediumManager() const {
|
||||
return fluid_medium;
|
||||
|
@ -98,6 +101,7 @@ class SOFTWARESHARED_EXPORT SoftwareRenderer {
|
|||
TexturesRenderer *textures_renderer;
|
||||
WaterRenderer *water_renderer;
|
||||
NightSky *nightsky_renderer;
|
||||
MoonRenderer *moon_renderer;
|
||||
VegetationRenderer *vegetation_renderer;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -49,6 +49,7 @@ class RayCastingManager;
|
|||
class RayCastingResult;
|
||||
|
||||
class NightSky;
|
||||
class MoonRenderer;
|
||||
|
||||
class TerrainRayWalker;
|
||||
|
||||
|
|
Loading…
Reference in a new issue