К сожалению, в спецификации OpenGL-ES, для которой был указан WebGL, нет плоскостей отсечения, а на этапе вершинного шейдера отсутствует вывод gl_ClipDistance
, с помощью которого отсечение плоскости реализуется в современном OpenGL.
Однако вы можете использовать фрагментный шейдер для реализации отсечения по фрагментам. Во фрагментном шейдере проверьте положение входящего фрагмента относительно вашего набора плоскостей отсечения, и если фрагмент не проходит проверку discard
, это.
Обновлять
Давайте посмотрим, как плоскости отсечения определяются в конвейере фиксированных функций OpenGL:
void ClipPlane( enum p, double eqn[4] );
Значение первого аргумента p является символьной константой CLIP PLANEi, где i - целое число от 0 до n - 1, указывающее на одну из n определяемых клиентом плоскостей отсечения. eqn - это массив из четырех значений с плавающей запятой двойной точности. Это коэффициенты плоского уравнения в координатах объекта: p1, p2, p3 и p4 (в указанном порядке). К этим коэффициентам применяется инверсия текущей матрицы представления модели в момент их определения, что дает
p' = (p'1, p'2, p'3, p'4) = (p1, p2, p3, p4) inv(M)
(где M - текущая матрица вида модели; результирующее уравнение плоскости не определено, если M сингулярно, и может быть неточным, если M плохо обусловлено), чтобы получить коэффициенты уравнения плоскости в координатах глаза. Все точки с координатами глаза транспонируются ((x_e, y_e, z_e, w_e)), которые удовлетворяют
(p'1, p'2, p'3, p'4) x_e ≥ 0
y_e
z_e
w_e
лежат в полупространстве, определяемом плоскостью; точки, не удовлетворяющие этому условию, не лежат в полупространстве.
Итак, что вы делаете, вы добавляете униформу, с помощью которой вы передаете параметры плоскости отсечения p 'и добавляете еще одну пару переменных out / in между вершинным и фрагментным шейдером, чтобы передать положение вершины в пространстве глаз. Затем во фрагментном шейдере первое, что вы делаете, это выполняете тест уравнения плоскости отсечения, и если он не проходит, вы отбрасываете фрагмент.
В вершинном шейдере
in vec3 vertex_position;
out vec4 eyespace_pos;
uniform mat4 modelview;
void main()
{
/* ... */
eyespace_pos = modelview * vec4(vertex_position, 1);
/* ... */
}
Во фрагментном шейдере
in vec4 eyespace_pos;
uniform vec4 clipplane;
void main()
{
if( dot( eyespace_pos, clipplane) < 0 ) {
discard;
}
/* ... */
}
person
datenwolf
schedule
25.03.2014