From 6cf607a557436f0fbfe3df7324c66052dc625ee6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Lemaire?= Date: Thu, 7 Jan 2016 00:39:08 +0100 Subject: [PATCH] Moved triplanar noise to FractalNoise --- src/basics/FractalNoise.cpp | 18 +++++++++++++ src/basics/FractalNoise.h | 7 +++++ src/render/software/TexturesRenderer.cpp | 33 +++++------------------- src/render/software/TexturesRenderer.h | 1 - 4 files changed, 31 insertions(+), 28 deletions(-) diff --git a/src/basics/FractalNoise.cpp b/src/basics/FractalNoise.cpp index b9dbe09..003e22c 100644 --- a/src/basics/FractalNoise.cpp +++ b/src/basics/FractalNoise.cpp @@ -1,6 +1,8 @@ #include "FractalNoise.h" +#include #include "PackStream.h" +#include "Vector3.h" FractalNoise::FractalNoise() { scaling = 1.0; @@ -128,6 +130,22 @@ double FractalNoise::get3d(double detail, double x, double y, double z) const { return result; } +double FractalNoise::getTriplanar(double detail, const Vector3 &location, const Vector3 &normal) const { + double noiseXY = get2d(detail, location.x, location.y); + double noiseXZ = get2d(detail, location.x, location.z); + double noiseYZ = get2d(detail, 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; +} + void FractalNoise::estimateRange(double *min, double *max) const { // TODO Better estimate *max = height; diff --git a/src/basics/FractalNoise.h b/src/basics/FractalNoise.h index e6e9744..90626c4 100644 --- a/src/basics/FractalNoise.h +++ b/src/basics/FractalNoise.h @@ -46,6 +46,13 @@ class BASICSSHARED_EXPORT FractalNoise { double get2d(double detail, double x, double y) const; double get3d(double detail, double x, double y, double z) const; + /** + * Get the triplanar noise value, according to a normal vector at a given location. + * + * Triplanar noise avoids stretching effects while applying a noise to texture a non-planar surface. + */ + double getTriplanar(double detail, const Vector3 &location, const Vector3 &normal) const; + /** * Estimate the range of values this generator will yield with a very small detail value. */ diff --git a/src/render/software/TexturesRenderer.cpp b/src/render/software/TexturesRenderer.cpp index 08808f3..fdc42d0 100644 --- a/src/render/software/TexturesRenderer.cpp +++ b/src/render/software/TexturesRenderer.cpp @@ -27,25 +27,6 @@ double TexturesRenderer::getLayerBasePresence(TextureLayerDefinition *layer, return layer->terrain_zone->getValue(terrain.location, terrain.normal); } -/* - * Get triplanar noise value, depending on the normal direction. - */ -double TexturesRenderer::getTriplanarNoise(const FractalNoise *noise, const Vector3 &location, const Vector3 &normal, double detail) { - double noiseXY = noise->get2d(detail, location.x, location.y); - double noiseXZ = noise->get2d(detail, location.x, location.z); - double noiseYZ = noise->get2d(detail, 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; -} - double TexturesRenderer::getMaximalDisplacement(TexturesDefinition *textures) { int i, n; double disp = 0.0; @@ -82,7 +63,6 @@ static inline Vector3 _getNormal2(Vector3 center, Vector3 east, Vector3 south) { static Vector3 _getDetailNormal(SoftwareRenderer *renderer, Vector3 base_location, Vector3 base_normal, TextureLayerDefinition *layer, double precision) { - TexturesRenderer *textures = renderer->getTexturesRenderer(); Vector3 result; /* Find guiding vectors in the appoximated local plane */ @@ -102,21 +82,20 @@ static Vector3 _getDetailNormal(SoftwareRenderer *renderer, Vector3 base_locatio double detail = precision; double offset = precision * 0.1; - center = - base_location.add(base_normal.scale(textures->getTriplanarNoise(detail_noise, base_location, base_normal, detail))); + center = base_location.add(base_normal.scale(detail_noise->getTriplanar(detail, base_location, base_normal))); east = base_location.add(dx.scale(offset)); - east = east.add(base_normal.scale(textures->getTriplanarNoise(detail_noise, east, base_normal, detail))); + east = east.add(base_normal.scale(detail_noise->getTriplanar(detail, east, base_normal))); south = base_location.add(dy.scale(offset)); - south = south.add(base_normal.scale(textures->getTriplanarNoise(detail_noise, south, base_normal, detail))); + south = south.add(base_normal.scale(detail_noise->getTriplanar(detail, south, base_normal))); if (renderer->render_quality > 6) { west = base_location.add(dx.scale(-offset)); - west = west.add(base_normal.scale(textures->getTriplanarNoise(detail_noise, west, base_normal, detail))); + west = west.add(base_normal.scale(detail_noise->getTriplanar(detail, west, base_normal))); north = base_location.add(dy.scale(-offset)); - north = north.add(base_normal.scale(textures->getTriplanarNoise(detail_noise, north, base_normal, detail))); + north = north.add(base_normal.scale(detail_noise->getTriplanar(detail, north, base_normal))); result = _getNormal4(center, north, east, south, west); } else { @@ -141,7 +120,7 @@ Vector3 TexturesRenderer::displaceTerrain(const TerrainRenderer::TerrainResult & if (layer->hasDisplacement()) { double presence = getLayerBasePresence(layer, terrain); auto noise = layer->propDisplacementNoise()->getGenerator(); - offset += getTriplanarNoise(noise, terrain.location, terrain.normal, 0.001) * presence; + offset += noise->getTriplanar(0.001, terrain.location, terrain.normal) * presence; } } diff --git a/src/render/software/TexturesRenderer.h b/src/render/software/TexturesRenderer.h index df9c9a3..4fcf955 100644 --- a/src/render/software/TexturesRenderer.h +++ b/src/render/software/TexturesRenderer.h @@ -35,7 +35,6 @@ class SOFTWARESHARED_EXPORT TexturesRenderer { virtual double getMaximalDisplacement(TexturesDefinition *textures); virtual double getLayerBasePresence(TextureLayerDefinition *layer, const TerrainRenderer::TerrainResult &terrain); - virtual double getTriplanarNoise(const FractalNoise *noise, const Vector3 &location, const Vector3 &normal, double detail); virtual Vector3 displaceTerrain(const TerrainRenderer::TerrainResult &terrain); virtual double getBasePresence(int layer, const TerrainRenderer::TerrainResult &terrain);