Показывает края между плоскостью отсечения и обрезанными объектами - PullRequest
0 голосов
/ 26 февраля 2019

Я хочу использовать шейдеры, чтобы не только отбрасывать фрагменты, если они находятся на одной стороне предварительно определенной плоскости, но и визуализировать контур вдоль пересечения.

Мой фрагментный шейдер в настоящее время делает что-то вроде:

float dot = dot(world_coordinate, normalize(clipping_normal.xyz)) - clipping_normal.w;
if (dot > 0.0f) 
    discard;

это работает, но без желаемого контура.Я попытался сравнить скалярное произведение со значениями, близкими к 0,0, но в результате получился контур с различной шириной в зависимости от вида и т. Д.

Это то, чего я пытаюсь достичь.Обратите внимание, что белый контур / край, где плоскость пересекает сферу, имеет одинаковую ширину:

cross-section

Итак, вот результат, который я сейчас вижу:

my-result

С фрагментным шейдером:

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 Ответ

0 голосов
/ 26 февраля 2019

Контур пересечения также принадлежит плоскости отсечения, поэтому расстояние до этой плоскости равно нулю.

Использование dot(point, normal) недостаточно.Вам нужен d= A·x + B·y + C·z + D, который является числителем (без «модуля») формулы полного расстояния точка-плоскость.См. геометрия плоскости .

Это вычисленное d дает вам не только расстояние (добавьте квадрат в знаменателе, если нормаль A, B, C не унитарна), но и его знак говоритВы, на какой стороне плоскости находится точка.

Работая внутри фрагментного шейдера, скорее всего, вы работаете с координатами NDC.Так что преобразуйте A,B,C,D в NDC тоже.

...