Показывает края между плоскостью отсечения и обрезанными объектами
Я хочу использовать шейдеры, чтобы не только отбрасывать фрагменты, если они находятся на одной стороне предварительно определенной плоскости, но и визуализировать контур вдоль пересечения.
Мой фрагментный шейдер в настоящее время делает что-то вроде:
float dot = dot(world_coordinate, normalize(clipping_normal.xyz)) - clipping_normal.w;
if (dot > 0.0f)
discard;
это работает, но без желаемого контура. Я попытался сравнить скалярное произведение со значениями, близкими к 0,0, но в результате получился контур с различной шириной в зависимости от вида и т. Д.
Это то, чего я пытаюсь достичь. Обратите внимание, что белый контур / край, где плоскость пересекает сферу, имеет постоянную ширину:
Ниже приведен результат, который я сейчас вижу:
С фрагментным шейдером:
in vec4 color;
in vec3 world_position;
out vec4 frag_color;
void main()
{
float dist = (dot(clipping_plane.xyz, world_position) - clipping_plane.w) /
dot(clipping_plane.xyz, clipping_plane.xyz);
if(dist >= 0.0f && dist < 0.05f)
frag_color = vec4(0.0f, 0.0f, 0.0f, 1.0f);
else if(dist < 0.0f)
discard;
else
frag_color = ComputePhong(color);
}
1 ответ
Контур пересечения также принадлежит плоскости отсечения, поэтому расстояние до этой плоскости равно нулю.
С помощью dot(point, normal)
недостаточно. Тебе нужно d= A·x + B·y + C·z + D
который является числителем (без "модуля") формулы расстояния от плоскости до полного расстояния. Смотрите геометрию самолета.
Это рассчитано d
дает вам не только расстояние (добавьте квадрат в знаменателе, если нормаль A,B,C не унитарна), но и его знак говорит вам, на какой стороне плоскости находится точка.
Работая внутри фрагментного шейдера, скорее всего, вы работаете с координатами NDC. Так преобразуй A,B,C,D
в НДЦ тоже.