Генератор шума Perlin генерирует высококонтрастный шум

Я следил за книгой Питера Ширли "Raytracing: следующая неделя". У меня проблемы с реализацией его генератора шума Perlin. Я получаю результаты с контрастом, который намного выше его, и я не знаю почему.

namespace SharpRays.Utilities {
    using System;
    using System.Collections.Generic;
    using System.Numerics;

    using static Core.Random;

    internal class Perlin {
        private static Vector3[] ranvec;
        private static int[] perm_x;
        private static int[] perm_y;
        private static int[] perm_z;

        public Perlin() {
            ranvec = PerlinGenerate();
            perm_x = PerlinGeneratePerm();
            perm_y = PerlinGeneratePerm();
            perm_z = PerlinGeneratePerm();
        }

        public float Noise(Vector3 p) {
            var u = p.X - (float)Math.Floor(p.X);
            var v = p.Y - (float)Math.Floor(p.Y);
            var w = p.Z - (float)Math.Floor(p.Z);
            var i = (int)Math.Floor(p.X);
            var j = (int)Math.Floor(p.Y);
            var k = (int)Math.Floor(p.Z);
            var c = new Vector3[2, 2, 2];
            for (var di = 0; di < 2; di++) {
                for (var dj = 0; dj < 2; dj++) {
                    for (var dk = 0; dk < 2; dk++) {
                        c[di, dj, dk] = ranvec[perm_x[(i + di) & 255] ^ perm_y[(j + dj) & 255] ^ perm_z[(k + dk) & 255]];
                    }
                }
            }
            var interp = PerlinInterp(c, u, v, w);
            return interp;
        }

        public float Turb(Vector3 p, int depth = 7) {
            var accum = 0f;
            var tempP = p;
            var weight = 1f;
            for (int i = 0; i < depth; i++) {
                accum += weight * Noise(tempP);
                weight *= 0.5f;
                tempP *= 2;
            }

            return Math.Abs(accum);
        }

        private static float PerlinInterp(Vector3[,,] c, float u, float v, float w) {
            var uu = u * u * (3 - 2 * u);
            var vv = v * v * (3 - 2 * v);
            var ww = w * w * (3 - 2 * w);
            var accum = 0f;
            for (var i = 0; i < 2; i++) {
                for (var j = 0; j < 2; j++) {
                    for (var k = 0; k < 2; k++) {
                        var weightV = new Vector3(u - i, v - j, w - k);
                        accum += (i * uu + (1 - i) * (1 - uu)) * (j * vv + (1 - j) * (1 - vv)) * (k * ww + (1 - k) * (1 - ww)) * Vector3.Dot(c[i, j, k], weightV);
                    }
                }
            }

            return accum;
        }

        private static Vector3[] PerlinGenerate() {
            var p = new Vector3[256];
            for (var i = 0; i < p.Length; i++) {
                p[i] = Vector3.Normalize(new Vector3(-1 + (2 * RandomFloat()), -1 + (2 * RandomFloat()), -1 + (2 * RandomFloat())));
            }
            return p;
        }

        private static void Permute(IList<int> p) {
            for (var i = p.Count - 1; i > 0; i--) {
                var target = (int)(RandomFloat() * (i + 1));
                var tmp = p[i];
                p[i] = p[target];
                p[target] = tmp;
            }
        }

        private static int[] PerlinGeneratePerm() {
            var p = new int[256];
            for (var i = 0; i < 256; i++) {
                p[i] = i;
            }
            Permute(p);
            return p;
        }
    }
}

Приведенный выше код называется в ламбертовом материале.

public bool Scatter(Ray r, HitRecord rec, out Vector3 attenuation, out Ray scattered) {                                      // Vector3
            var target = rec.P + rec.Normal + RandomInUnitSphere();
            scattered = new Ray(rec.P, target - rec.P, r.Time);
            attenuation = Albedo.Value(0, 0, rec.P);
            return true;
}

Этот код генерирует картинки, подобные приведенной ниже: Неисправное изображение шума Перлина

Код должен сделать что-то вроде этого изображения: введите описание изображения здесь

Соответствующий код из книги можно найти на github. Различия связаны с аддитивным характером книги. Где я неправ?

РЕДАКТИРОВАТЬ: мой код на GitHub, а.

0 ответов

Другие вопросы по тегам