diff --git a/src/basics/FractalNoise.cpp b/src/basics/FractalNoise.cpp index e75c5b1..e821f83 100644 --- a/src/basics/FractalNoise.cpp +++ b/src/basics/FractalNoise.cpp @@ -12,8 +12,7 @@ FractalNoise::FractalNoise() { FractalNoise::~FractalNoise() { } -void FractalNoise::save(PackStream *stream) const -{ +void FractalNoise::save(PackStream *stream) const { stream->write(&scaling); stream->write(&height); stream->write(&step_scaling); @@ -21,8 +20,7 @@ void FractalNoise::save(PackStream *stream) const state.save(stream); } -void FractalNoise::load(PackStream *stream) -{ +void FractalNoise::load(PackStream *stream) { stream->read(&scaling); stream->read(&height); stream->read(&step_scaling); @@ -30,8 +28,7 @@ void FractalNoise::load(PackStream *stream) state.load(stream); } -void FractalNoise::copy(FractalNoise *destination) const -{ +void FractalNoise::copy(FractalNoise *destination) const { destination->scaling = scaling; destination->height = height; destination->step_scaling = step_scaling; @@ -39,6 +36,10 @@ void FractalNoise::copy(FractalNoise *destination) const state.copy(&destination->state); } +void FractalNoise::randomize(RandomGenerator &random) { + state.randomizeOffsets(random); +} + void FractalNoise::setScaling(double scaling, double height) { this->scaling = scaling < 0.00000001 ? 0.0 : 1.0 / scaling; this->height = scaling * height; diff --git a/src/basics/FractalNoise.h b/src/basics/FractalNoise.h index ab72895..adeca38 100644 --- a/src/basics/FractalNoise.h +++ b/src/basics/FractalNoise.h @@ -33,6 +33,11 @@ class BASICSSHARED_EXPORT FractalNoise { return step_height; } + /** + * Randomize the noise (only the noise values, not its configuration). + */ + void randomize(RandomGenerator &random); + void setScaling(double scaling, double height = 1.0); void setStep(double scaling_factor, double height_factor = 1.0); void setState(const NoiseState &state); diff --git a/src/definition/NoiseNode.cpp b/src/definition/NoiseNode.cpp index 9f045f2..918073d 100644 --- a/src/definition/NoiseNode.cpp +++ b/src/definition/NoiseNode.cpp @@ -11,6 +11,15 @@ NoiseNode::~NoiseNode() { delete noise; } +void NoiseNode::randomize(RandomGenerator &random) { + noise->randomize(random); +} + +void NoiseNode::setConfig(double scaling, double step_scaling, double height, double step_height) { + noise->setScaling(scaling, height); + noise->setStep(step_scaling, step_height); +} + void NoiseNode::save(PackStream *stream) const { noise->save(stream); } diff --git a/src/definition/NoiseNode.h b/src/definition/NoiseNode.h index ce076d6..b73c179 100644 --- a/src/definition/NoiseNode.h +++ b/src/definition/NoiseNode.h @@ -16,10 +16,20 @@ class DEFINITIONSHARED_EXPORT NoiseNode : public DefinitionNode { NoiseNode(DefinitionNode *parent, const string &name = "noise"); virtual ~NoiseNode(); - inline const FractalNoise *getGenerator() { + inline const FractalNoise *getGenerator() const { return noise; } + /** + * Randomize the noise (only the noise, not its configuration). + */ + void randomize(RandomGenerator &random); + + /** + * Set the noise configuration. + */ + void setConfig(double scaling, double step_scaling = 0.5, double height = 1.0, double step_height = 0.5); + protected: virtual void save(PackStream *stream) const override; virtual void load(PackStream *stream) override; diff --git a/src/definition/TextureLayerDefinition.cpp b/src/definition/TextureLayerDefinition.cpp index 2d59fc8..a99a1d8 100644 --- a/src/definition/TextureLayerDefinition.cpp +++ b/src/definition/TextureLayerDefinition.cpp @@ -7,22 +7,24 @@ #include "Scenery.h" #include "TerrainDefinition.h" #include "Color.h" +#include "NoiseNode.h" TextureLayerDefinition::TextureLayerDefinition(DefinitionNode *parent, const string &name) : DefinitionNode(parent, name, "texturelayer") { terrain_zone = new Zone; _displacement_noise = new NoiseGenerator; - _detail_noise = new NoiseGenerator; material = new SurfaceMaterial; displacement_height = 0.0; displacement_scaling = 1.0; + + detail_noise = new NoiseNode(this, "detail"); + detail_noise->setConfig(0.01); } TextureLayerDefinition::~TextureLayerDefinition() { delete terrain_zone; delete _displacement_noise; - delete _detail_noise; delete material; } @@ -38,11 +40,6 @@ void TextureLayerDefinition::validate() { _displacement_noise->normalizeAmplitude(-1.0, 1.0, 0); _displacement_noise->validate(); - _detail_noise->clearLevels(); - _detail_noise->addLevelsSimple(7, 0.01, -1.0, 1.0, 0.0); - _detail_noise->normalizeAmplitude(-0.008, 0.008, 0); - _detail_noise->validate(); - material->validate(); /* Update zone height range */ @@ -65,7 +62,6 @@ void TextureLayerDefinition::copy(DefinitionNode *destination) const { *tex_destination->material = *material; _displacement_noise->copy(tex_destination->_displacement_noise); - _detail_noise->copy(tex_destination->_detail_noise); } } @@ -78,7 +74,6 @@ void TextureLayerDefinition::save(PackStream *stream) const { material->save(stream); _displacement_noise->save(stream); - _detail_noise->save(stream); } void TextureLayerDefinition::load(PackStream *stream) { @@ -90,12 +85,11 @@ void TextureLayerDefinition::load(PackStream *stream) { material->load(stream); _displacement_noise->load(stream); - _detail_noise->load(stream); } void TextureLayerDefinition::applyPreset(TextureLayerPreset preset, RandomGenerator &random) { _displacement_noise->randomizeOffsets(random); - _detail_noise->randomizeOffsets(random); + detail_noise->randomize(random); terrain_zone->clear(); diff --git a/src/definition/TextureLayerDefinition.h b/src/definition/TextureLayerDefinition.h index 119c6fb..4eed134 100644 --- a/src/definition/TextureLayerDefinition.h +++ b/src/definition/TextureLayerDefinition.h @@ -31,6 +31,10 @@ class DEFINITIONSHARED_EXPORT TextureLayerDefinition : public DefinitionNode { void applyPreset(TextureLayerPreset preset, RandomGenerator &random = RandomGeneratorDefault); + inline NoiseNode *propDetailNoise() const { + return detail_noise; + } + public: Zone *terrain_zone; double displacement_scaling; @@ -38,7 +42,9 @@ class DEFINITIONSHARED_EXPORT TextureLayerDefinition : public DefinitionNode { SurfaceMaterial *material; NoiseGenerator *_displacement_noise; - NoiseGenerator *_detail_noise; + + private: + NoiseNode *detail_noise; }; } } diff --git a/src/render/software/TexturesRenderer.cpp b/src/render/software/TexturesRenderer.cpp index 6b9a6a8..bc7ceaf 100644 --- a/src/render/software/TexturesRenderer.cpp +++ b/src/render/software/TexturesRenderer.cpp @@ -6,6 +6,8 @@ #include "TextureLayerDefinition.h" #include "TexturesDefinition.h" #include "Zone.h" +#include "NoiseNode.h" +#include "FractalNoise.h" #include "NoiseGenerator.h" TexturesRenderer::TexturesRenderer(SoftwareRenderer *parent) : parent(parent) { @@ -28,7 +30,24 @@ double TexturesRenderer::getLayerBasePresence(TextureLayerDefinition *layer, /* * Get triplanar noise value, depending on the normal direction. */ -double TexturesRenderer::getTriplanarNoise(NoiseGenerator *noise, const Vector3 &location, const Vector3 &normal) { +double TexturesRenderer::getTriplanarNoise(const FractalNoise *noise, const Vector3 &location, const Vector3 &normal) { + // TODO Detail control + double noiseXY = noise->get2d(0.001, location.x, location.y); + double noiseXZ = noise->get2d(0.001, location.x, location.z); + double noiseYZ = noise->get2d(0.001, location.y, location.z); + + double mXY = fabs(normal.z); + double mXZ = fabs(normal.y); + double mYZ = fabs(normal.x); + double total = 1.0 / (mXY + mXZ + mYZ); + mXY *= total; + mXZ *= total; + mYZ *= total; + + return noiseXY * mXY + noiseXZ * mXZ + noiseYZ * mYZ; +} + +static double _compatGetTriplanarNoise(NoiseGenerator *noise, const Vector3 &location, const Vector3 &normal) { double noiseXY = noise->get2DTotal(location.x, location.y); double noiseXZ = noise->get2DTotal(location.x, location.z); double noiseYZ = noise->get2DTotal(location.y, location.z); @@ -97,22 +116,23 @@ static Vector3 _getDetailNormal(SoftwareRenderer *renderer, Vector3 base_locatio /* Apply detail noise locally */ Vector3 center, north, east, south, west; + auto detail_noise = layer->propDetailNoise()->getGenerator(); - center = base_location.add( - base_normal.scale(textures->getTriplanarNoise(layer->_detail_noise, base_location, base_normal))); + center = + base_location.add(base_normal.scale(textures->getTriplanarNoise(detail_noise, base_location, base_normal))); east = base_location.add(dx.scale(offset)); - east = east.add(base_normal.scale(textures->getTriplanarNoise(layer->_detail_noise, east, base_normal))); + east = east.add(base_normal.scale(textures->getTriplanarNoise(detail_noise, east, base_normal))); south = base_location.add(dy.scale(offset)); - south = south.add(base_normal.scale(textures->getTriplanarNoise(layer->_detail_noise, south, base_normal))); + south = south.add(base_normal.scale(textures->getTriplanarNoise(detail_noise, south, base_normal))); if (renderer->render_quality > 6) { west = base_location.add(dx.scale(-offset)); - west = west.add(base_normal.scale(textures->getTriplanarNoise(layer->_detail_noise, west, base_normal))); + west = west.add(base_normal.scale(textures->getTriplanarNoise(detail_noise, west, base_normal))); north = base_location.add(dy.scale(-offset)); - north = north.add(base_normal.scale(textures->getTriplanarNoise(layer->_detail_noise, north, base_normal))); + north = north.add(base_normal.scale(textures->getTriplanarNoise(detail_noise, north, base_normal))); result = _getNormal4(center, north, east, south, west); } else { @@ -139,7 +159,7 @@ Vector3 TexturesRenderer::displaceTerrain(const TerrainRenderer::TerrainResult & Vector3 location = {terrain.location.x / layer->displacement_scaling, terrain.location.y / layer->displacement_scaling, terrain.location.z / layer->displacement_scaling}; - offset += getTriplanarNoise(layer->_displacement_noise, location, terrain.normal) * presence * + offset += _compatGetTriplanarNoise(layer->_displacement_noise, location, terrain.normal) * presence * layer->displacement_height; } } diff --git a/src/render/software/TexturesRenderer.h b/src/render/software/TexturesRenderer.h index 70ac873..ecc3cb8 100644 --- a/src/render/software/TexturesRenderer.h +++ b/src/render/software/TexturesRenderer.h @@ -35,7 +35,7 @@ class SOFTWARESHARED_EXPORT TexturesRenderer { virtual double getMaximalDisplacement(TexturesDefinition *textures); virtual double getLayerBasePresence(TextureLayerDefinition *layer, const TerrainRenderer::TerrainResult &terrain); - virtual double getTriplanarNoise(NoiseGenerator *noise, const Vector3 &location, const Vector3 &normal); + virtual double getTriplanarNoise(const FractalNoise *noise, const Vector3 &location, const Vector3 &normal); virtual Vector3 displaceTerrain(const TerrainRenderer::TerrainResult &terrain); virtual double getBasePresence(int layer, const TerrainRenderer::TerrainResult &terrain);