SimplexNoise масштабирует градиент внутри fbm

Как мне изменить вектор градиента в моем цикле fbm?

Проблема в том, что я не могу правильно рассчитать нормали с помощью этого кода... Они указывают немного не в правильном направлении, это вызывает странное освещение.

Вот расчет нормального вектора:

    float3 grad;
    float noise = getNoiseValue(TriPos, grad);
    float3 nTriPos = normalize(TriPos);
    grad = grad / (noise);
    float3 h = grad - dot(grad, nTriPos) * nTriPos;
    float3 n = nTriPos - (h);

Правка: я немного изменил вычисление нормалей. И убрал частоту. И сейчас выглядит нормально. Есть ли способ вставить частоту?

    float getNoiseValue(float3 TriPos, out float3 gradient)
    {    
        float strength = 0.45f;
        float octaves = 15;
        float Persistence = 0.53333f;
        float BaseRoughness = 0.71f;
        float Roughness = 1.81f;
        float MinNoiseValue = 1.4f;

        float noiseValue = 0.f;
        float frequency = BaseRoughness;
        float amplitude = 1.f;
        TriPos = TriPos / 40000.f;
        for (int i = 0; i < octaves; i++)
        {
            float v = (sdnoise3(TriPos, gradient) + 1.f) * 0.5f;
            gradient += gradient * amplitude;
            noiseValue += v * amplitude;
            frequency *= Roughness;
            amplitude *= Persistence;
        }
        noiseValue = max(0.f, noiseValue - MinNoiseValue);
        return noiseValue;
    }

Обновление:

Итак, теперь все работает как надо, НО когда я добавляю частоту в свою петлю, я снова получаю странное освещение...

    for (int i = 0; i < octaves; i++)
    {
        float v = (sdnoise3(normalize(TriPos) * frequency, gradient) + 1.f) * 0.5f;
        gradient = gradient + (gradient * amplitude * frequency);
        noiseValue = noiseValue + (v * amplitude);
        frequency *= Roughness;
        amplitude *= Persistence;
    }

Кто-нибудь может сказать мне, что здесь не так?


person Nils J.    schedule 06.04.2020    source источник


Ответы (1)


Я нашел проблему. Какая-то логическая ошибка...

    float3 grad;
    for (int i = 0; i < octaves; i++)
    {
        float v = (sdnoise3(TriPos * frequency, gradient) + 1.f) * 0.5f;
        grad += (gradient * amplitude);
        noiseValue += (v * amplitude);
        frequency = frequency * Roughness;
        amplitude = amplitude * Persistence;
    }

I used the gradient variable as out parameter of sdnoise3 function so it got overriden every iteration.
person Nils J.    schedule 09.04.2020