Реализация текстуры возмущенного изображения на языке рендера

8

Я пытаюсь реализовать (в C #) алгоритм возмущения изображения, представленный в книге «Текстурирование и моделирование - К. Перлин и др.» (Стр. 91, если кто-то есть), который искажает изображение. Следующий код на языке Renderman: Доступ к текстуре

Ct = texture("example.tx", s, t);

заменяется

point Psh;
float ss, tt;
Psh = transform("shader", P);
ss = s + 0.2 * snoise(Psh);
tt = t + 0.2 * snoise(Psh+(l.5,6.7,3.4));
Ct = texture("example.tx", ss, tt);

трансформируя изображение слева в изображение справа. введите описание изображения здесь

Из того, что я понял, вместо доступа к координате мы получаем доступ к незначительным возмущенным координатам и отображаем их в месте , создавая таким образом изображение, которое выглядит слегка возмущенным ,(s,t)[0,1](ss,tt)(s,t)

snoise(x) определяется как , шум отображения от до , а в документации RenderMan где P - точка, возвращает значение, основанное на некотором шуме (наиболее вероятно, perlin или решетке). ( http://renderman.pixar.com/resources/current/RenderMan/noiseFunctions.html )(noise(x)2)1[0,1][1,1]noise(P)

Что я не понимаю, так это то, что делает функция преобразования, которая должна отобразить 3d-точку P в «шейдерное» пространство, и как это можно реализовать. Кроме того, я не уверен, возвращает ли noise (x) 3d-точку, float (имело бы больше смысла) и могу ли я использовать простую 2d-реализацию шума Перлина для достижения того же желаемого эффекта.

simog
источник

Ответы:

6

Как вы уже догадались, transform()функция преобразует точки из одного координатного пространства в другое. (Существуют также vtransform()и ntransform()для преобразования векторов направления и нормальных векторов соответственно.) Строковый аргумент задает пространство координат для преобразования.

В Руководстве по затенению Рендермана есть следующее:

В начале выполнения шейдера все точечные, векторные, нормальные и матричные переменные выражаются в «текущей» системе координат. То, какая система координат является "текущей", зависит от реализации. Так уж получилось, что «текущий» является «камерой» для PRMan *, но вы никогда не должны рассчитывать на это поведение - вполне возможно, что другие RenderMan-совместимые средства визуализации (включая будущие средства визуализации из Pixar) могут использовать некоторое другое пространство (например, «мир») как «текущее» пространство.

Далее приводится пример, подобный этому. Большинство расчетов освещения следует выполнять в пространстве камеры, но оценка функции шума должна выполняться в системе координат объекта, потому что вы хотите, чтобы шум оставался таким же, как объект движется в мировом пространстве.

В вашей реализации C # вам также необходимо преобразовать затененную точку из пространства камеры в систему координат объекта. Возможно, вы сделали это уже до того, как вычислили координаты текстуры. Если нет, вам нужно умножить на матрицу преобразования объекта. Помните, что единственное использование этой преобразованной точки - это ввод (например, начальное число) генератора шума Perlin. Он устанавливает область, в которой изменяется шум: мировые космические координаты.

В RSL noise()функция может возвращать любой тип, который вам нравится: a float, a color, a pointили a vector. Добавляя его к другому float( uили v), вы получите floatв этом коде. Действительно, два noise()вызова, добавленные к sи t, действуют для генерации одного двумерного шумового вектора. В вашем собственном коде, если вы используете 2D-вектор для хранения координат текстуры, вы можете использовать одну функцию шума, которая возвращает 2D-вектор, чтобы получить тот же эффект в одной строке кода.


Если вы заинтересованы в создании хорошего генератора шума, у Shadertoy есть много шумовых шейдеров с различными вариантами шума Перлина с различными свойствами (изотропными или нет, настраиваемой плавностью и пропускной способностью), и вам стоит обратить внимание на них, а также на советы по реализации. ,

Дэн Халм
источник