2013-05-15 2 views
1

Обычно в области информатики, когда у меня есть что-то от a до b Интервал [a, b). Это верно при растрировании геометрических примитивов?Каков интервал, когда растеризующие примитивы

Например, когда у меня есть строка, которая начинается в положении (0, 0) и заканчивается в положении (0, 10) будет строка содержит точку (0, 10) при использовании параллельного проецирования с блоком 1 GPU отображается на 1 пиксель на экране?

EDIT: Тот же вопрос в тех же условиях, но для текстур:

Если у меня есть текстуры 2x2 отображенных на квадроцикл от (0, 0) к (2, 2) с использованием (0, 0) для (1, 1) отображения это будет «пиксель совершенного», один пиксель от текстуры на одном пикселе на экране или будет текстура масштабирована? Если интервал [0, 2] четырехъядерный будет 3x3 и текстура должна быть расширена ...

СПУСТЯ EDIT: Это может помочь: http://msdn.microsoft.com/en-us/library/windows/desktop/bb219690%28v=vs.85%29.aspx

+0

Что вы пытаетесь сделать? – Ani

ответ

5

Прежде всего, это полностью зависит от конкретной структуры растрирования, используемой (например, OpenGL, Direct3D, GDI, ...), поэтому я опишу этот ответ на вопрос, который будет помечен opengl.

Это не такой простой вопрос, потому что обычно фактические координаты окна нарисованного примитива (а точнее его фрагмента) не являются интегральными, но с плавающей запятой или координатами фиксированной точки, возникающими после сгустки (возможно, неточно) преобразований (которые не все могут быть настроены для идентификации с использованием шейдеров, особенно преобразование видового экрана фиксированной функции из нормализованных координат устройства в координаты окна). Поэтому, даже если вы сконфигурируете конвейер трансформации для указания координат вершин непосредственно в пространстве окна, не ожидайте, что координаты окон получаемых фрагментов будут идеальными целыми во всех случаях. Взгляните на this question и его ответы для получения дополнительной информации о конвейере преобразования OpenGL, если это необходимо.

Тогда это зависит от примитивного типа. Для многоугольника (треугольник/квадрат) растеризатор проверяет каждый фрагмент, если центр фрагмента лежит внутри границ полигона, как определено координатами окна вершин многоугольника. Итак, если у нас есть прямоугольник (ну, два треугольника, но давайте просто возьмем его как прямоугольник), который простирается от оконных координат (0,0) до (2,2), он будет охватывать область 2x2, потому что только фрагменты (0,0) (с центральной координатой (0.5,0.5)) и (1,1) (с центральная координата (1.5,1.5)), и их комбинации лежат с прямоугольником.

Для линий это немного сложнее, используя так называемый "diamond exit rule". Я не буду обсуждать это здесь подробно, но для горизонтальных или вертикальных линий это по существу означает, что последний пиксель также является исключительным. Но на самом деле это также означает, что координаты целочисленных окон хуже всего использовать для строк, потому что из-за проблем округления в конвейере трансформации трудно решить, к какому пикселю принадлежит такой фрагмент, поскольку «порог решения» для строк находится в целые границы фрагментов, а не его центр, как и для многоугольников.

Но при рассмотрении текстурирования возникает другая проблема, а именно интерполяция. В то время как квад от (0,0) до (2,2) будет охватывать область 2x2 пикселя, значения изменений (атрибуты вершин, интерполированные по примитиву, такие как координаты цвета или текстуры) интерполируются из фактических координат окна.Таким образом, пиксель (0,0) (соответствующий фрагменту с центральной координатой (0.5,0.5)) не будет иметь точных значений вершин нижнего левого квадрата, но значения, интерполированные во внутреннюю часть на половину размера фрагмента (а также для других углов) ,

Также важно то, как OpenGL фильтрует текстуры. При использовании линейной фильтрации точный цвет текселя возвращается для координат текстуры в центрах текселя (т. Е. (i+0.5)/size), и целочисленные делители размера текстуры (то есть i/size) приведут к полупустой смеси между соседними цветами текселя. И вместо того, чтобы использовать выборочную выборку ближайшего соседа (что желательно при попытке сделать что-то пиксельное или тексельное), координата текстуры с плавающей запятой округляется вниз (напольная операция) и, таким образом, «порог принятия решения», который определяет, от одного текселя или его соседа находится на границах текселя (таким образом, целые делители размера текстуры как координаты текстуры). Таким образом, выборка в тексельных центрах целесообразна как с линейной фильтрацией (которая, в свою очередь, не рекомендуется при работе с точным пикселем), так и с ближайшей фильтрацией, поскольку это уменьшает вероятность «переворачивания» от одного текселя к другому из-за неточности и ошибок округления в интерполяция координат текстуры.


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

(0,2) - (2,2) 
    |  | 
(0,0) - (2,0) 

и координаты текстуры

(0,1) - (1,1) 
    |  | 
(0,0) - (1,0) 

Так что, если эти позиции уже приведены в окне/видового экрана пространства, это приводит к фрагментам с центрами

(0.5,1.5) (1.5,1.5) 
(0.5,0.5) (1.5,0.5) 

покрытый, представляющий квадрат 2x2- [0,1] -пикселя. Координаты текстуры этих фрагментов после интерполяции будут

(0.25,0.75) (0.75,0.75) 
(0.25,0.25) (0.75,0.25) 

А для 2х2 текстуры те действительно находятся в Текселе центрах. Так что все прекрасно выглядит. Могут быть ошибки округления и точности, приводящие к, например, координаты 1.999 или texCoords от 0.255, но это все равно не проблема, так как мы далеки от точек, где мы бы «привязывались» к соседним пикселям или текселям (предполагая, что мы используем ближайшую фильтрацию, но даже с линейной фильтрацией вы обычно не замечали бы отличия от точного цвета текселя).

Хотя на примере линии, трудно сказать, из-за точности округления и реализации вопросов, если это будет либо из (0,0) в (0,9) или (-1,0) в (-1,9) (таким образом обрезаны), или даже искажены, и вы должны скорее используйте (0.5,0.5) и (0.5,10.5), что определенно приведет к линии от (0,0) до (0,9).


Так, чтобы подвести итог, OpenGL на самом деле не сделано для полностью пиксельных точных операций, но с некоторой осторожностью это может быть достигнуто. Но для достижения наилучших результатов вы должны сначала сконфигурировать свои преобразования, чтобы указать позиции вершин непосредственно в координатах окна, например.

glViewport(0, 0, width, height); 
glOrtho(0, width, 0, height, -1, 1); //or something similar when using shaders 

Тогда для многоугольников используют целые позиции и целые делители размера текстуры, как координаты текстуры (и использовать GL_NEAREST фильтрацию). Но для линий используются полупиксельные положения (то есть i+0.5) и тексельные центры в виде координат текстуры (то есть (i+0.5)/size).Это должно дать вам точную растеризацию пикселов и текселей ваших примитивов и полуоткрытых интервалов, описанных в вашем вопросе. Но всегда имейте в виду, что в этом случае пиксели coner растрированного многоугольника не совпадают с его вершинными углами (половину пикселя смещены внутрь). Для текстурирования это хорошо выглядит с правилами фильтрации, но для других атрибутов, таких как цвета, это означает, что нижний левый пиксель прямоугольника не будет иметь точно (что равно «точно» в этом контексте с ограниченной точностью?) цвет нижней левой вершины. Тем не менее, для строк они будут соответствовать (насколько это возможно).

Смежные вопросы