Сперва преобразуем точку на поверхности, которую нужно закрасить, в точку на сфере радиусом 1,0. Сделать это можно с помощью функции normal ize:
p.xyz = normalize(ECposition.xyz - ECballCenter.xyz); p.w = 1.0:
Координата w в вычислениях не используется, поэтому применяется оператор выбора компонентов . xyz для выбора первыхтрех компонентов ECposi ti on и ECbal 1 -Center. Этот нормализованный вектор затем сохраняется в первых трех компонентах р. После этих вычислений р представляет точку на сфере с радиусом 1, так что все три компонента р будут находиться в диапазоне [-1, 1]. Координатам здесь не нужна, но для последующих вычислений она инициализируется в 1,0.
Затем определяется положение точек звезды по отношению к полупространствам. Счетчик inorout будет инициализирован в значение -3. Он будет увеличиваться все время, если точка на поверхности является внутренней по отношению к полупространству. Так как определено пять полупространств, окончательное значение счетчика будет находиться в диапазоне [-3, 2]. Значения 1 или 2 будут означать, что фрагмент находится внутри звезды. При значениях 0 или меньше фрагмент находится вне звезды:
inorout = InOrOutlnit: // инициализация inorout в -3
Мы могли бы определить полупространства как массив из пяти значений vec4, затем выполнить вычисления, а результаты сохранить в массиве из пяти значений f 1 oat. Но здесь можно получить некоторое преимущество в скорости, используя параллельность графического аппаратного обеспечения. Рассмотрим эту процедуру. Сначала с помощью встроенной функции dot вычисляется расстояние между р и первыми четырьмя полупространствами:
distanced] - dotCp. HalfSpaceO): distanced] = dot(p. HalfSpacel): distance^] = dotCp. HalfSpace-2): distance[3] = dotCp. HalfSpace3):
Результаты этих вычислений показаны на рис, 11,1, а-г. Точки на поверхности, которые определены как внутренние, показаны серым цветом, а определенные как внешние - черным цветом.
Наверное, читатель удивлен, почему счетчик был определен как Я oat, а не как int. Но счетчик является всего лишь основанием для сглаживания перехода между цветом звезды и цветом остальной поверхности шара. Для этого используется функция smoothstep, устанавливающая расстояние в 0, если вычисленное расстояние меньше -FWidth, в 1, если вычисленное расстояние больше FWidth, и в ровно