OpenGL использует барицентрические координаты (линейная интерполяция точно, хотя вы можете изменить это с помощью функций интерполяции или классификаторов, таких как centroid
или noperspective
в последних версиях).
В случае, если вы не знаете, барицентрическое координирует работы, как, что:
для местоположения Р в виде треугольника из вершин V1, V2 и V3, чьи соответствующие коэффициенты С1, С2, С3, такие как С1 + С2 + С3 = 1 (эти коэффициенты относится к влиянию каждой вершины в цвете P) OpenGL, необходимо вычислить такие, как результат эквивалентен
C1 = (AreaOfTriangle PV2V3)/(AreaOfTriangle V1V2V3)
C2 = (AreaOfTriangle PV3V1)/(AreaOfTriangle V1V2V3)
C3 = (AreaOfTriangle PV1V2)/(AreaOfTriangle V1V2V3)
и площадь треугольника может быть вычислена с половиной длины перекрестного произведения двух векторов, определяющих его (в прямом смысле), например AreaOfTriangle V1V2V3 = length(cross(V2-V1, V3-V1))/2
. Затем мы имеем что-то вроде:
float areaOfTriangle = length(cross(V2-V1, V3-V1)); //Two times the area of the triangle
float C1 = length(cross(V2-P, V3-P))/areaOfTriangle; //Because A1*2/A*2 = A1/A
float C2 = length(cross(V3-P, V1-P))/areaOfTriangle; //Because A2*2/A*2 = A2/A
float C3 = 1.0f - C1 - C2; //Because C1 + C2 + C3 = 1
Но после некоторой математики (и немного веб-исследований: D), наиболее эффективный способ сделать это я нашел:
YOURVECTYPE sideVec1 = V2 - V1, sideVec2 = V3 - V1, sideVec3 = P - V1;
float dot11 = dot(sideVec1, sideVec1);
float dot12 = dot(sideVec1, sideVec2);
float dot22 = dot(sideVec2, sideVec2);
float dot31 = dot(sideVec3, sideVec1);
float dot32 = dot(sideVec3, sideVec2);
float denom = dot11 * dot22 - dot12 * dot12;
float C1 = (dot22 * dot31 - dot12 * dot32)/denom;
float C2 = (dot11 * dot32 - dot12 * dot31)/denom;
float C3 = 1.0f - C1 - C2;
Затем интерполировать такие вещи, как цвет, COLOR1, цвет2 и color3 быть цвета ваших вершин, вы делаете:
float color = C1*color1 + C2*color2 + C3*color3;
Но нужно учитывать, что это не работает должным образом, если вы используете перспективные преобразования (или любое преобразование вершин, подразумевающие w
компонент), так что в этом случае , вам придется использовать:
float color = (C1*color1/w1 + C2*color2/w2 + C3*color3/w3)/(C1/w1 + C2/w2 + C3/w3);
w1
, w2
и w3
соответственно четвертые компоненты исходных вершин, сделанных V1
, V2
и V3
.
V1
, V2
10 и V3
в первом вычислении должно быть 3 размера из-за поперечного произведения, но во втором (наиболее эффективное) оно может быть двухмерным и трехмерным, результаты будут одинаковыми (I думайте, что вы догадались, что 2D был быстрее во втором вычислении), но в обоих случаях не забудьте разделить их на четвертый компонент их исходного вектора, если вы делаете перспективные преобразования и используете вторую формулу для интерполяции в этом случае , (И в случае, если вы не поняли, все векторы в этих расчетах НЕ должны включают в себя четвертый компонент!)
И последнее; Я настоятельно рекомендую вам использовать OpenGL, просто предоставив большой квадратик на экране и поместив весь ваш код в шейдеры (хотя вам понадобятся очень сильные знания об OpenGL для расширенного использования), потому что вы будете пользоваться параллелизмом (даже с #! + видеокарта), за исключением случаев, когда вы пишете это на компьютере с 30 годами, или если вы просто делаете это, чтобы посмотреть, как это работает.
OpenGL использует [Барицентрическая координату] (http://en.wikipedia.org/wiki/Barycentric_coordinate_system) для интерполяции –
Это может сделать: http://en.wikibooks.org/wiki/GLSL_Programming/Rasterization#Linear_Interpolation_of_Varying_Variables –