Показывает края между плоскостью отсечения и обрезанными объектами

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

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

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 в НДЦ тоже.

Другие вопросы по тегам