在opengl中将颜色应用于四边形中的单个顶点

在opengl中将颜色应用于四边形中的单个顶点,第1张

概述我正在尝试为通过glDrawElements绘制的四边形的单个顶点着色,我正在使用cocos2d libray,所以我已经能够清除源代码以准确理解发生了什么,代码如下: glBindVertexArray( VAOname_ );glDrawElements(GL_TRIANGLES, (GLsizei) n*6, GL_UNSIGNED_SHORT, (GLvoid*) (start*6*si 我正在尝试为通过glDrawElements绘制的四边形的单个顶点着色,我正在使用cocos2d libray,所以我已经能够清除源代码以准确理解发生了什么,代码如下:

glBindVertexArray( VAOname_ );glDrawElements(GL_TRIANGLES,(GLsizei) n*6,GL_UNSIGNED_SHORT,(GLvoID*) (start*6*sizeof(indices_[0])) );glBindVertexArray(0);

因此使用顶点数组对象.我正在尝试修改传递的对象的单个顶点颜色,它似乎工作但是有一个毛刺,如下图所示:

在这里,我试图改变左下和右下顶点的颜色.结果是不同的,我想这是因为四边形被渲染为一对三角形,共享斜边位于从左下顶点到右上顶点的对角线上.所以这可能导致不同的结果.

现在我想对第一个案例也有第二个结果.有没有办法获得它?

解决方法 你的猜测是正确的. OpenGL驱动程序将您的四边形细分为两个三角形,其中顶点颜色以重心方式进行插值,从而产生您所看到的结果.

解决此问题的常用方法是在片段着色器中“手动”执行插值,该插值考虑目标拓扑,在您的情况下为四边形.或者简而言之,您必须执行不是基于三角形而是基于四边形的重心插值.您可能还想应用透视校正.

我现在还没有准备好阅读手头的资源,但我会尽快更新这个答案(可能实际上意味着,我必须自己编写).

更新

首先,我们必须理解这个问题:大多数OpenGL实现将较高的基元分解成三角形并将它们局部化,即无需进一步了解基元的其余部分,例如:四边形.所以我们必须自己做.

我就是这样做的.

#version 330 // vertex shader

当然我们也需要通常的制服

uniform mat4x4 MV;uniform mat4x4 P;

首先,我们需要此着色器执行实例处理的顶点的位置

layout (location=0) in vec3 pos;

接下来,我们需要一些顶点属性,我们用它来描述四边形本身.这意味着它的角落位置

layout (location=1) in vec3 qp0;layout (location=2) in vec3 qp1;layout (location=3) in vec3 qp2;layout (location=4) in vec3 qp3;

和颜色

layout (location=5) in vec3 qc0;layout (location=6) in vec3 qc1;layout (location=7) in vec3 qc2;layout (location=8) in vec3 qc3;

我们将这些变换为片段着色器进行处理.

out vec3 position;out vec3 qpos[4];out vec3 qcolor[4];voID main(){    qpos[0] = qp0;    qpos[1] = qp1;    qpos[2] = qp2;    qpos[3] = qp3;    qcolor[0] = qc0;    qcolor[1] = qc1;    qcolor[2] = qc2;    qcolor[3] = qc3;    gl_position = P * MV * position;}

在片段着色器中,我们使用它来实现颜色分量的距离权重:

#version 330 // fragment shaderin vec3 position;in vec3 qpos[4];in vec3 qcolor[4];voID main(){    vec3 color = vec3(0);

以下内容可以简化为组合,但为了清楚起见,我将其写出来:
对于顶点混合的每个角点,所有角点的颜色与它们之间的边缘上的位置的投影作为混合因子.

for(int i=0; i < 4; i++) {        vec3 p = position - qpos[i];        for(int j=0; j < 4; j++) {            vec3 edge = qpos[i] - qpos[j];            float edge_length = length(edge);            edge = normalize(edge);            float tau = dot(edge_length,p) / edge_length;            color += mix(qcolor[i],qcolor[j],tau);        }    }

由于我们查看每个角点4次,缩小1/4

color *= 0.25;    gl_Fragcolor = color; // and maybe other things.}

我们差不多完成了.在客户端,我们需要传递其他信息.当然我们不想复制数据.为此,我们使用glVertexBindingdivisor,使得顶点属性仅在qp …和qc …位置上每4个顶点(即四边形)前进,即位置1到8

typedef float vec3[3];extern vec3 *quad_position;extern vec3 *quad_color;glVertexAttribute(0,3,GL_float,GL_FALSE,&quad_position[0]);glVertexBindingdivisor(1,4);glVertexAttribute     (1,&quad_position[0]);glVertexBindingdivisor(2,4);glVertexAttribute     (2,&quad_position[1]);glVertexBindingdivisor(3,4);glVertexAttribute     (3,&quad_position[2]);glVertexBindingdivisor(4,4);glVertexAttribute     (4,&quad_position[3]);glVertexBindingdivisor(5,4);glVertexAttribute     (5,&quad_color[0]);glVertexBindingdivisor(6,4);glVertexAttribute     (6,&quad_color[1]);glVertexBindingdivisor(7,4);glVertexAttribute     (7,&quad_color[2]);glVertexBindingdivisor(8,4);glVertexAttribute     (8,&quad_color[3]);

将上述内容放入Vertex数组对象是有意义的.使用VBO也是有意义的,但是你必须手动计算偏移量;由于typedef float vec3,编译器为我们的ATM做了数学计算.

有了这一切,你终于可以独立绘制你的四边形了.

总结

以上是内存溢出为你收集整理的在opengl中将颜色应用于四边形中的单个顶点全部内容,希望文章能够帮你解决在opengl中将颜色应用于四边形中的单个顶点所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/999997.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-21
下一篇 2022-05-21

发表评论

登录后才能评论

评论列表(0条)

保存