У некоторых материалов вид меняется в зависимости от угла, под которым мы на них смотрим. Перья птиц, некоторые причудливые автомобильные краски, нефтяные разливы на воде, и мыльные пузыри - вот несколько примеров. Этот феномен изменения цветов известен как радужность (iridescence). Если мы хотим осуществить нечто подобное, нам нужен доступ к вектору вида и нормали поверхности. В нашем шейдере мыльного пузыря мы увидим один из способов сделать это.
Теперь учтём, что свет ведет себя подобно волне, а волны, которые интерферируют, могут или ослаблять или усиливать друг друга в зависимости от их фазы, и поэтому, два световых луча, прошедшие расстояния, разница которых не кратна в точности их длине волны, гасят друг друга. В результате, белый свет (континуум, совокупность цветов), отраженный мыльным пузырём с толщиной, равной половине длины волны некоторого специфического цвета, покажет только этот единственный цвет, поскольку все остальные цвета подавлены, так как они "не соответствуют" должным образом толщине между внутренней и внешней поверхностью. (Существует гораздо больше информации о мыльных пузырях. Для большей и более точной информации вот ссылка: http://ru.wikipedia.org/wiki/Мыльные_пузыри.)
Теперь мы знаем, что расстояние пройденное между двумя отражающими поверхностями, определяет цвет, который мы воспринимаем, мы можем также понять, почему цвет будет варьироваться в мыльном пузыре. Первым фактором является кривизна пузыря. Пройденное расстояние будет зависеть от угла между падающим светом и поверхностью: чем меньше угол, тем более длинное расстояние свет должен пройти между поверхностями. Угол падения изменяется, так как поверхность кривая, и таким образом, изменяется расстояние, и, следовательно, цвет. Второй причиной изменения цвета является неравномерность поверхности: незначительные изменения из-за тяжести или вихри, вызванные воздушными течениями или перепадами температур, также вызывают различия в цвете.
Вся эта информация переводится в удивительно короткую часть кода (полный код доступен как
Наряду с координатами, у нас есть ещё два входных сокета — один для толщины водяной плёнки и один для вариаций. Вариации будут добавляться к толщине и этот сокет может быть присоединён к текстурному ноду, чтобы генерировать вихри и тому подобное. У нас есть единственный выходной сокет для рассчитанного расстояния: class Iridescence(Node.Scripted):
def __init__(self, sockets):
sockets.input = [
Node.Socket('Coords', val= 3*[1.0]),
Node.Socket('Thickness', val=275.0,
min=100.0, max=1000.0),
Node.Socket('Variation', val=0.5, min=0.0,
max=1.0)]
sockets.output = [Node.Socket('Distance',
val=0.5, min=0.0, max=1.0)]
Вычисления отраженного цвета начинается с получением списка всех ламп на сцене, так как мы хотим вычислить угол падающих световых лучей. Сейчас, мы принимаем во внимание вклад только первой лампы, которую мы нашли. Тем не менее, более полная реализация должна рассматривать все лампы, и может быть, даже их цвет. Для наших вычислений мы должны убедиться, что нормаль поверхности
def __call__(self):
P = vec(self.input.Coords)
scn=Scene.GetCurrent()
lamps = [ob for ob in scn.objects if
ob.type == 'Lamp']
lamp = lamps[0]
cam=scn.objects.camera
rot=cam.getMatrix('worldspace').rotationPart(
).resize4x4();
N = vec(self.shi.surfaceNormal).normalize(
).resize4D() * rot
N = N.negate().resize3D()