Moved triplanar noise to FractalNoise
This commit is contained in:
parent
eeeaa70e8b
commit
6cf607a557
4 changed files with 31 additions and 28 deletions
|
@ -1,6 +1,8 @@
|
||||||
#include "FractalNoise.h"
|
#include "FractalNoise.h"
|
||||||
|
|
||||||
|
#include <cmath>
|
||||||
#include "PackStream.h"
|
#include "PackStream.h"
|
||||||
|
#include "Vector3.h"
|
||||||
|
|
||||||
FractalNoise::FractalNoise() {
|
FractalNoise::FractalNoise() {
|
||||||
scaling = 1.0;
|
scaling = 1.0;
|
||||||
|
@ -128,6 +130,22 @@ double FractalNoise::get3d(double detail, double x, double y, double z) const {
|
||||||
return result;
|
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 {
|
void FractalNoise::estimateRange(double *min, double *max) const {
|
||||||
// TODO Better estimate
|
// TODO Better estimate
|
||||||
*max = height;
|
*max = height;
|
||||||
|
|
|
@ -46,6 +46,13 @@ class BASICSSHARED_EXPORT FractalNoise {
|
||||||
double get2d(double detail, double x, double y) const;
|
double get2d(double detail, double x, double y) const;
|
||||||
double get3d(double detail, double x, double y, double z) 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.
|
* Estimate the range of values this generator will yield with a very small detail value.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -27,25 +27,6 @@ double TexturesRenderer::getLayerBasePresence(TextureLayerDefinition *layer,
|
||||||
return layer->terrain_zone->getValue(terrain.location, terrain.normal);
|
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) {
|
double TexturesRenderer::getMaximalDisplacement(TexturesDefinition *textures) {
|
||||||
int i, n;
|
int i, n;
|
||||||
double disp = 0.0;
|
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,
|
static Vector3 _getDetailNormal(SoftwareRenderer *renderer, Vector3 base_location, Vector3 base_normal,
|
||||||
TextureLayerDefinition *layer, double precision) {
|
TextureLayerDefinition *layer, double precision) {
|
||||||
TexturesRenderer *textures = renderer->getTexturesRenderer();
|
|
||||||
Vector3 result;
|
Vector3 result;
|
||||||
|
|
||||||
/* Find guiding vectors in the appoximated local plane */
|
/* Find guiding vectors in the appoximated local plane */
|
||||||
|
@ -102,21 +82,20 @@ static Vector3 _getDetailNormal(SoftwareRenderer *renderer, Vector3 base_locatio
|
||||||
double detail = precision;
|
double detail = precision;
|
||||||
double offset = precision * 0.1;
|
double offset = precision * 0.1;
|
||||||
|
|
||||||
center =
|
center = base_location.add(base_normal.scale(detail_noise->getTriplanar(detail, base_location, base_normal)));
|
||||||
base_location.add(base_normal.scale(textures->getTriplanarNoise(detail_noise, base_location, base_normal, detail)));
|
|
||||||
|
|
||||||
east = base_location.add(dx.scale(offset));
|
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 = 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) {
|
if (renderer->render_quality > 6) {
|
||||||
west = base_location.add(dx.scale(-offset));
|
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 = 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);
|
result = _getNormal4(center, north, east, south, west);
|
||||||
} else {
|
} else {
|
||||||
|
@ -141,7 +120,7 @@ Vector3 TexturesRenderer::displaceTerrain(const TerrainRenderer::TerrainResult &
|
||||||
if (layer->hasDisplacement()) {
|
if (layer->hasDisplacement()) {
|
||||||
double presence = getLayerBasePresence(layer, terrain);
|
double presence = getLayerBasePresence(layer, terrain);
|
||||||
auto noise = layer->propDisplacementNoise()->getGenerator();
|
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,6 @@ class SOFTWARESHARED_EXPORT TexturesRenderer {
|
||||||
|
|
||||||
virtual double getMaximalDisplacement(TexturesDefinition *textures);
|
virtual double getMaximalDisplacement(TexturesDefinition *textures);
|
||||||
virtual double getLayerBasePresence(TextureLayerDefinition *layer, const TerrainRenderer::TerrainResult &terrain);
|
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 Vector3 displaceTerrain(const TerrainRenderer::TerrainResult &terrain);
|
||||||
virtual double getBasePresence(int layer, const TerrainRenderer::TerrainResult &terrain);
|
virtual double getBasePresence(int layer, const TerrainRenderer::TerrainResult &terrain);
|
||||||
|
|
Loading…
Reference in a new issue