Проблемы с отсечением положения текстуры вершин на ближней плоскости.C++

Программы на C++. Форум разработчиков
Ответить
Anonymous
 Проблемы с отсечением положения текстуры вершин на ближней плоскости.

Сообщение Anonymous »

Если одна или несколько вершин треугольника находятся за экраном, проецирование треугольника как есть не сработает. Поэтому треугольник отсекается плоскостью, близкой к z=0, которая называется ближней плоскостью. Я понимаю это и смог реализовать это в своем собственном средстве визуализации.
Однако чего я не понимаю, так это того, как обрабатываются текстурные положения вершин при обрезке треугольника и таким образом разделены на 1 или несколько треугольников?
Кажется, я не могу заставить это работать в моем собственном 3D-рендерере.
Я пробовал использовать барицентрические координаты для интерполяции позиций текстуры к вершинам новых треугольников, но по какой-то причине это не работает. Возможно, просто моя функция преобразования декартовых координат в барицентрические координаты треугольника не работает.
Код для преобразования декартовых координат в барицентрические в 3D:
Vector3 Barycentric3D(Vector3 p, Vector3 a, Vector3 b, Vector3 c) {
Vector3 v0 = VecSub3D(b, a), v1 = VecSub3D(c, a), v2 = VecSub3D(p, a);
float d00 = VecDot3D(v0, v0);
float d01 = VecDot3D(v0, v1);
float d11 = VecDot3D(v1, v1);
float d20 = VecDot3D(v2, v0);
float d21 = VecDot3D(v2, v1);
float denom = d00 * d11 - d01 * d01;
float v = (d11 * d20 - d01 * d21) / denom;
float w = (d00 * d21 - d01 * d20) / denom;
float u = 1.0f - v - w;

return { u, v, w };
}

Я также попробовал использовать расстояние отрезанной вершины до точек, между которыми она находится, а затем с помощью этого линейно интерполировать координаты текстуры. Но это тоже не работает.
Потому что ни один из этих методов не работает. Мне интересно, как это обычно делается в средствах 3D-рендеринга.
РЕДАКТИРОВАТЬ: Я обнаружил, что для того, чтобы обрезать данные вершин текстуры, вам необходимо линейно интерполировать между координатами текстуры каждая вершина, между которыми есть плоскость отсечения, на основе нормализованного расстояния плоскости отсечения от вершины перед плоскостью отсечения.
Я попробовал реализовать это, и это отлично работает для случай, когда треугольник обрезается на 1 треугольник меньшего размера (2 вершины позади ближней плоскости, 1 спереди). Однако, похоже, это все еще не работает в случае, когда треугольник обрезан в четырехугольник или 2 треугольника (1 вершина позади ближней плоскости, 2 впереди). Код, который я использую для первого случая (2 вершины позади ближней плоскости, 1 впереди):
//If only one vertex is infront of the near plane, create one new clipped triangle
else if (vecsInfront.size() == 1) {

float t;

newVecs[2] = vecsInfront[0];
newUV[2] = uvInFront[0];

//the normalized distance is stored in t
newVecs[1] = LinePlaneIntersectPoint({ 0.f, 0.f, zNear }, { 0.f, 0.f, 1.f }, newVecs[2], vecsBehind[1], &t);
newUV[1] = LarpVec2(newUV[2], uvBehind[1], t);

newVecs[0] = LinePlaneIntersectPoint({ 0.f, 0.f, zNear }, { 0.f, 0.f, 1.f }, newVecs[2], vecsBehind[0], &t);
newUV[0] = LarpVec2(newUV[2], uvBehind[0], t);

for (int i = 0; i < 3; i++) {
clippedUV = newUV;
}

clippedV[0] = newVecs[0];
clippedV[1] = newVecs[1];
clippedV[2] = newVecs[2];

for (int i = 0; i < 3; i++)
zDivClipUV = VecDiv2D(clippedUV, clippedV.z);

}

А вот что я использую для второго случая (1 вершина позади ближней плоскости, 2 впереди):
else if (vecsInfront.size() == 2) {

containsSubTriangle = true;

float t;

newVecs[3] = vecsInfront[0];
newUV[3] = uvInFront[0];

newVecs[2] = LinePlaneIntersectPoint({ 0.f, 0.f, zNear }, { 0.f, 0.f, 1.f }, vecsInfront[1], vecsBehind[0], &t);
newUV[2] = LarpVec2(uvInFront[1], uvBehind[0], t);

newVecs[1] = vecsInfront[1];
newUV[1] = uvInFront[1];

newVecs[0] = LinePlaneIntersectPoint({ 0.f, 0.f, zNear }, { 0.f, 0.f, 1.f }, vecsInfront[0], vecsBehind[0], &t);
newUV[0] = LarpVec2(uvInFront[0], uvBehind[0], t);

clippedUV[0] = newUV[0];
clippedUV[1] = newUV[1];
clippedUV[2] = newUV[2];
clippedUV[3] = newUV[0];
clippedUV[4] = newUV[1];
clippedUV[5] = newUV[3];

clippedV[0] = newVecs[0];
clippedV[1] = newVecs[1];
clippedV[2] = newVecs[2];

clippedV[3] = newVecs[0];
clippedV[4] = newVecs[1];
clippedV[5] = newVecs[3];

for (int i = 0; i < 6; i++)
zDivClipUV = VecDiv2D(clippedUV, clippedV.z);
}


Подробнее здесь: https://stackoverflow.com/questions/784 ... near-plane
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C++»