Skip to content

Commit

Permalink
Enhanced perlin noise trilinear interpolation
Browse files Browse the repository at this point in the history
  • Loading branch information
Pedro Jorquera committed Mar 14, 2024
1 parent 9aa619f commit 837d356
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 10 deletions.
2 changes: 1 addition & 1 deletion src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ void earth() {
void twoPerlinSpheres() {
shared_ptr<Scene> scene = make_shared<Scene>();

auto perlinTexture = make_shared<NoiseTexture>();
auto perlinTexture = make_shared<NoiseTexture>(4.0);
scene->add(make_shared<Sphere>(Point(0.0, -1000.0, 0.0), 1000, make_shared<Lambertian>(perlinTexture)));
scene->add(make_shared<Sphere>(Point(0.0, 2.0, 0.0), 2.0, make_shared<Lambertian>(perlinTexture)));

Expand Down
53 changes: 47 additions & 6 deletions src/perlin.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
#include "perlin.h"

#include <cmath>

using namespace std;

void permute(int* p, int n) {
for (int i = n-1; i > 0; i--) {
int target = randomInt(0, i);
Expand All @@ -19,10 +23,29 @@ int* generatePerm() {
return p;
}

double interpolation(Vector c[2][2][2], double u, double v, double w) {
auto uu = u * u * (3.0 - 2.0 * u);
auto vv = v * v * (3.0 - 2.0 * v);
auto ww = w * w * (3.0 - 2.0 * w);
auto accum = 0.0;

for (int i=0; i < 2; i++)
for (int j=0; j < 2; j++)
for (int k=0; k < 2; k++) {
Vector weight_v(u - i, v - j, w - k);
accum += (i * uu + (1.0 - i) * (1.0 - uu))
* (j * vv + (1.0 - j) * (1.0 - vv))
* (k * ww + (1.0 - k) * (1.0 - ww))
* Vector::dot(c[i][j][k], weight_v);
}

return accum;
}

Perlin::Perlin() {
_randomData = new double[Perlin::POINT_COUNT];
_randomData = new Point[Perlin::POINT_COUNT];
for (int i = 0; i < Perlin::POINT_COUNT; ++i) {
_randomData[i] = randomDouble();
_randomData[i] = Vector::random(-1.0, 1.0).unit();
}

_permuteX = generatePerm();
Expand All @@ -38,9 +61,27 @@ Perlin::~Perlin() {
}

double Perlin::noise(const Point& point) const {
auto i = int(4.0 * point.x()) & 255;
auto j = int(4.0 * point.y()) & 255;
auto k = int(4.0 * point.z()) & 255;
auto u = point.x() - floor(point.x());
auto v = point.y() - floor(point.y());
auto w = point.z() - floor(point.z());

u = u * u * (3.0 - 2.0 * u);
v = v * v * (3.0 - 2.0 * v);
w = w * w * (3.0 - 2.0 * w);

auto i = int(floor(point.x()));
auto j = int(floor(point.y()));
auto k = int(floor(point.z()));
Vector c[2][2][2];

for (int di=0; di < 2; di++)
for (int dj=0; dj < 2; dj++)
for (int dk=0; dk < 2; dk++)
c[di][dj][dk] = _randomData[
_permuteX[(i + di) & 255] ^
_permuteY[(j + dj) & 255] ^
_permuteZ[(k + dk) & 255]
];

return _randomData[_permuteX[i] ^ _permuteY[j] ^ _permuteZ[k]];
return interpolation(c, u, v, w);
}
2 changes: 1 addition & 1 deletion src/perlin.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ class Perlin {

private:

double* _randomData;
Vector* _randomData;
int* _permuteX;
int* _permuteY;
int* _permuteZ;
Expand Down
6 changes: 4 additions & 2 deletions src/texture.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,13 +96,15 @@ class NoiseTexture : public Texture {
private:

Perlin _noise;
double _scale;

public:

NoiseTexture() {}
NoiseTexture():NoiseTexture(1.0) {}
NoiseTexture(double scale):_scale(scale) {}

Color color(double u, double v, const Point &point) override {
return Color(1.0, 1.0, 1.0) * _noise.noise(point);
return Color(1.0, 1.0, 1.0) * 0.5 * (1.0 + _noise.noise(_scale * point));
}

};

0 comments on commit 837d356

Please sign in to comment.