Проблема с созданием Perlin Noise в HLSL из рабочего кода C#

Я пытаюсь запрограммировать код Compute-Shader Perlin Noise на основе рабочего кода С#.

Проблема в том, что я получил только гладкие точки.

Слева C# работает, справа Compute-Shader с этими значениями для обоих

Если я уменьшу частоту, точки станут больше:


Это код, который я использую


#pragma kernel CSMain

RWTexture2D<float> Result;
RWStructuredBuffer<float> resfloat;

float res;
float frequency;
float octaves;
float lacunarity;
float persistence;

StructuredBuffer<float3> gradients3D;
StructuredBuffer<int> hash;

float lerp(float v0, float v1, float t);
float Dot(float3 g, float x, float y, float z);
float Smooth(float t);
float Perlin3D(float3 v, float frequency);
float noise(float3 v, float frequency, int octaves, float lacunarity, float persistence);


int hashMask = 255;
int gradientsMask3D = 15;

[numthreads(8, 8, 1)]
void CSMain(uint3 id : SV_DispatchThreadID)
{
    float3 v = float3(id.x, id.y, id.z) / res;
    float h = 0.0;
    h = noise(v, frequency, octaves, lacunarity, persistence);
    Result[id.xy] = float4(h, 0, 0, 0);
    resfloat[id.x + id.y * res] = h;
}

float lerp(float v0, float v1, float t) {
    return v0 + t * (v1 - v0);
}

float Smooth(float t) {
    return t * t * t * (t * (t * (float) 6 - (float) 15) + (float) 10);
}

float Perlin3D(float3 v, float frequency) {
    v *= frequency;
    int ix0 = (int) floor(v.x);
    int iy0 = (int) floor(v.y);
    int iz0 = (int) floor(v.z);
    float tx0 = v.x - ix0;
    float ty0 = v.y - iy0;
    float tz0 = v.z - iz0;
    float tx1 = tx0 - (float) 1;
    float ty1 = ty0 - (float) 1;
    float tz1 = tz0 - (float) 1;
    ix0 &= hashMask;
    iy0 &= hashMask;
    iz0 &= hashMask;
    int ix1 = ix0 + (float) 1;
    int iy1 = iy0 + (float) 1;
    int iz1 = iz0 + (float) 1;

    int h0 = hash[ix0];
    int h1 = hash[ix1];
    int h00 = hash[h0 + iy0];
    int h10 = hash[h1 + iy0];
    int h01 = hash[h0 + iy1];
    int h11 = hash[h1 + iy1];
    float3 g000 = gradients3D[hash[h00 + iz0] & gradientsMask3D];
    float3 g100 = gradients3D[hash[h10 + iz0] & gradientsMask3D];
    float3 g010 = gradients3D[hash[h01 + iz0] & gradientsMask3D];
    float3 g110 = gradients3D[hash[h11 + iz0] & gradientsMask3D];
    float3 g001 = gradients3D[hash[h00 + iz1] & gradientsMask3D];
    float3 g101 = gradients3D[hash[h10 + iz1] & gradientsMask3D];
    float3 g011 = gradients3D[hash[h01 + iz1] & gradientsMask3D];
    float3 g111 = gradients3D[hash[h11 + iz1] & gradientsMask3D];
    
    float v000 = dot(g000, float3(tx0, ty0, tz0));
    float v100 = dot(g100, float3(tx1, ty0, tz0));
    float v010 = dot(g010, float3(tx0, ty1, tz0));
    float v110 = dot(g110, float3(tx1, ty1, tz0));
    float v001 = dot(g001, float3(tx0, ty0, tz1));
    float v101 = dot(g101, float3(tx1, ty0, tz1));
    float v011 = dot(g011, float3(tx0, ty1, tz1));
    float v111 = dot(g111, float3(tx1, ty1, tz1));

    float tx = Smooth(tx0);
    float ty = Smooth(ty0);
    float tz = Smooth(tz0);
    return lerp(
        lerp(lerp(v000, v100, tx), lerp(v010, v110, tx), ty),
        lerp(lerp(v001, v101, tx), lerp(v011, v111, tx), ty),
        tz);
}

float noise(float3 v, float frequency, int octaves, float lacunarity, float persistence)
{
    float sum = Perlin3D(v, frequency);
    float amplitude = 1;
    float range = 1;
    for (int o = 1; o < octaves; o++) {
        frequency *= lacunarity;
        amplitude *= persistence;
        range += amplitude;
        sum += Perlin3D(v, frequency) * amplitude;
    }

    return sum / range;
}

Это рабочий код C#

А это код C#, который вызывает шейдер

Я уже проверил, что параметры StructuredBuffer (градиенты 3D и хэш) и параметры float правильно загружены.

Есть идеи?

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
70
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Проблема заключалась в том, что по какой-то причине, когда функция Perlin3D использовала hashMask и gradientsMask3D, у них был 0.

Поэтому я переместил определение в функцию:

float Perlin3D(float3 v, float frequency)
{
    int hashMask = 255;
    int gradientsMask3D = 15;
    v *= frequency;
    int ix0 = (int) floor(v.x);

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