Программирование игр, создание игрового движка, OpenGL, DirectX, физика, форум
GameDev.ru / Программирование / Форум / Реализация процедурных текстур методом Шума Перлина. (Комментарии к статье) (3 стр)

Реализация процедурных текстур методом Шума Перлина. (Комментарии к статье) (3 стр)

Страницы: 1 2 3
WISHMASTER35Участникwww18 фев. 201516:22#30
FordPerfect
> У тебя ведь тоже не Перлин, так (отсутствие градиентов)?
Я где-то нашел этот алгоритм, он назывался PerlinNoise. Думал это PerlinNoise с предрасчитанными рандомными значениями. Или это уже не PerlinNoise?
FordPerfectПостоялецwww18 фев. 201517:58#31
WISHMASTER35
Не похоже.

http://www.noisemachine.com/talk1/15.html :

Given an input point

For each of its neighboring grid points:

1. Pick a "pseudo-random" gradient vector

2. Compute linear function (dot product)

3. Take weighted sum, using ease curves

Т. е. dot product считается per pixel, а не per vertex.
Т. е. предрассчиать градиенты не понятно как.
Вообще фразу "предрасчитанными рандомными значениями" я не совсем понял.
В оригинале rnd тоже из массива берутся:
http://mrl.nyu.edu/~perlin/doc/oscar.html#noise

А по оптимизации... Если предрассчитать все tx в линейный массив, а ty вообще вынести из внутреннего цикла?
И lerp по ty можно объединить с умножением на amp.

Интересно, сильно ли поможет (вообще?)?

Правка:
орфография.
WISHMASTER35Участникwww18 фев. 201522:05#32
Т. е. dot product считается per pixel, а не per vertex.

У меня 3д шум так работает PerlinNoise3D
И для оптимизации использую такой класс PerlinNoiseChunk3D чтобы считать только каждые 4е значения шума и интерполировать между ними.
Интерполяция очень простая:
+ Показать

Даже можно было бы отказаться от умножения.
Вообще фразу "предрасчитанными рандомными значениями" я не совсем понял.

Там же рандомное значение считается только для ineger x, y. Можно для какого-то промежутка предрасчитать и сохранить в массив.
А по оптимизации... Если предрассчитать все tx в линейный массив, а ty вообще вынести из внутреннего цикла?
И lerp по ty можно объединить с умножением на amp.

Предрассчитал в массив результатов SmoothStep. 
+ Показать

Но быстрее не стало.
Даже если вообще так сделать:
float tx = 0, ty = 0;
То выигрыш скорости будет всего лишь 0.01 сек. Не так много.
а ty вообще вынести из внутреннего цикла?

Вынес ty и "* amp".
+ Показать

Может на сотую долю секунды стало быстрее.
Вообще на C# адекватно не оценишь производительность. Особенно если запускать из Visual Studio или Unity Editor. Но все же хочется выжить максимум.
WISHMASTER35Участникwww18 фев. 201523:24#33
+ Показать

Теперь время 0.085 сек.

Вряд ли можно еще что-то тут оптимизировать.
Предрасчет SmoothStep в массив почему-то ничего не дал.
А вот invStep предал немного скорости.

Только fixel point и многопоточность еще можно сделать.

WISHMASTER35Участникwww19 фев. 20151:21#34
+ Показать

Если я не ошибаюсь, то все рандомные значения можно предрассчитать в массив размером SIZE*SIZE, и шум будет работать так же.
Сделал так, все так же. На скорость не повлияло.

Кстати, из-за этих моих оптимизаций появилось какое-то дрожание шума при изменении offset. Но мне это не очень страшно.

foxesПостоялецwww19 фев. 201510:51#35
WISHMASTER35
> Если я не ошибаюсь, то все рандомные значения можно предрассчитать в массив
> размером SIZE*SIZE, и шум будет работать так же.
Я давно так делаю. Не знаю че все вокруг этого ПерлЮна пляшут.
Всем очень хорошо известна формула получения случайной последовательности rnd(i+1)=rnd(i)*A+C - если качественно подобрать A то C можно выкинуть но придется обработать rnd(i)==0.
Банально масштабировать двухмерною карту с RND пикселями, сложить разные масштабы и каждый кто увидит результат, не зная как он получен, будет биться в истерике доказывая тебе что это на самом деле шум Перлина.

Вот тут ни какой Перлин ни когда и рядом не стоял, если че:

+ Показать

FordPerfectПостоялецwww19 фев. 201515:48#36
foxes
Шум Перлина - чистая функция от координат. Т. е. концептуально - текстура бесконечного размера и бесконечной детализации.
Вполне можно, наверно, представить ситуации, когда это удобно.
Если нужно только заполнить текстуру шумом - то да, влобный random, вроде, вполне достаточен.

WISHMASTER35
>Предрасчет SmoothStep в массив почему-то ничего не дал.
Ты его индексируешь как-то странно, или я не понял?..

float tx = SMOOTH_STEP[ (ix-x)*1023/step ];
Я подразумевал что-то вроде:
    private void Compute(int x, int y, int nx, int ny, int step, float amp) {
        int x0 = Mathf.Max( x, 0 );
        int x1 = Mathf.Min( x+step, width );
        int y0 = Mathf.Max( y, 0 );
        int y1 = Mathf.Min( y+step, height );

        float v0 = FastPerlinNoise2D.Random( nx,      ny ) * amp;
        float v1 = FastPerlinNoise2D.Random( nx+step, ny ) * amp;
        float v2 = FastPerlinNoise2D.Random( nx,      ny+step ) * amp;
        float v3 = FastPerlinNoise2D.Random( nx+step, ny+step ) * amp;

        float inv_step=1.0f/float(step);

        for( int ix = x0; ix < x1; ix++, index++ ) {
            SMOOTH_STEP[ix-x0]=FastPerlinNoise2D.SmoothStep( (float) (ix-x)*inv_step );
        }
        for( int iy = y0; iy < y1; iy++ ) {
            float ty = FastPerlinNoise2D.SmoothStep( (float) (iy-y)*inv_step );
            int index = ToIndex( x0, iy );

            for( int ix = x0; ix < x1; ix++, index++ ) {
                float tx = SMOOTH_STEP[ix-x0];
                
                float a = FastPerlinNoise2D.Lerp( v0, v1, tx );
                float b = FastPerlinNoise2D.Lerp( v2, v3, tx );
                float c = FastPerlinNoise2D.Lerp( a, b, ty );

                texture[index] += c;
            }
        }

    }
FordPerfectПостоялецwww19 фев. 201515:57#37
WISHMASTER35
А по здравом размышлении:
+ Показать

Примечание: C# я не знаю.

WISHMASTER35Участникwww19 фев. 201516:20#38
FordPerfect
> FastPerlinNoise2D.SmoothStep
Можно просто сохранить все результаты SmoothStep в массив.
Ну все не сохранить, а где-то 1024 будет вполне достаточно.
        for( int i = 0; i < SMOOTH_STEP.Length; i++ ) {
            SMOOTH_STEP[i] = FastPerlinNoise2D.SmoothStep( i / 1023f ); // [0; 1]
        }

foxes

Я давно так делаю. Не знаю че все вокруг этого ПерлЮна пляшут.

Странно, почему обычно предпочитают вычислять каждый раз:
random[perm[perm[x] + y]]
а не предрассчитывать в текстуру. Возможно текстура хуже кэшируется т.е. больше памяти занимает.
FordPerfectПостоялецwww19 фев. 201518:36#39
Кстати, что-то не замечал упоминаний о том, что всенародно любимая функция:
float IntNoise(int x)
{
    x = (x<<13) ^ x;
    return ( 1.0 - ( (x * (x * x * 15731 + 789221) + 1376312589) & 0x7fffffff) / 1073741824.0);
}
вообще говоря, содержит undefined behavior.

Это вдобавок к http://www.gamedev.ru/code/forum/?id=11014&page=2#m19 .

Страницы: 1 2 3

/ Форум / Программирование игр / Общее

Тема в архиве.

2001—2018 © GameDev.ru — Разработка игр