【问题标题】:Asymmetric coloring of quads in openglopengl中四边形的不对称着色
【发布时间】:2013-07-23 21:27:03
【问题描述】:

我需要为由多个四边形组成的曲面的一些点着色。问题是颜色在该点周围分布不对称,请参见图像,其中只有左正方形的右下角是红色,而红色似乎被拉向右侧正方形的右上角)。

代码:

glBegin (GL_QUAD_STRIP);
glVertex3f (1., 0., 0)
glVertex3f (1., 1., 0)
glColor3f(1, 0, 0)
glVertex3f (0., 0., 0)
glColor3f(0, 0, 1)
glVertex3f (0., 1., 0)
glVertex3f (-1., 0., 0)
glVertex3f (-1., 1., 0)
glEnd ();

如果您制作两个单独的四边形并定义一个顺时针方向和另一个逆时针方向,那么颜色将围绕该点对称,但与相邻点周围的颜色分布不同(如果它们是彩色的)。

那么我怎样才能为具有对称颜色分布的任意点着色呢?

编辑:

我想可视化例如基于每个顶点温度的表面温度,如下图所示(黄色=0,橙色=0.5,红色=1):

【问题讨论】:

    标签: opengl


    【解决方案1】:

    默认情况下,OpenGL 在每个三角形上使用重心线性插值。这正是您所看到的。最简单的解决方案是编写一组顶点和片段着色器来实现基于距离的渐变。

    细节取决于您的具体需求。

    【讨论】:

    • 我希望颜色是周围四个顶点的线性插值 - 这可能吗?我检查了几个示例和教程,但它们都没有访问周围顶点的位置或颜色
    • @MadsMPedersen:根据定义,线性插值仅适用于两个顶点之间。 OpenGL 所做的重心插值实际上非常接近于简单的线性插值。我建议您使用 Photoshop 之类的工具并手动绘制您想要看到的图片。把它贴在这里,我会建议你一个如何在 OpenGL 中做到这一点的方法。
    • @MadsMPedersen:好的,对于像 that 这样的应用程序,我什至不会费心去处理顶点和邻接列表。您的案例需要 GL_NEAREST 插值模式下的纹理,这实现起来要简单得多,并且还受益于 GPU 的硬连线双线性插值器。
    • @MadsMPedersen:我认为您的第二个四边形的纹理坐标是错误的,因此是不对称的(请发布您的绘图代码,包括纹理坐标)。您还应该研究“透视校正”,这样即使不垂直观察,事情也会看起来正确。
    • @MadsMPedersen:从技术上讲,纹理是一组采样插值支持点。假设你想显示一个 5×3 的网格,那么你要做的是创建一个尺寸为 5×3 的纹理,并为每个“像素”提供采样值。然后通过将整个纹理映射到单个大四边形上,OpenGL 光栅器将为您完成所有双线性插值。
    【解决方案2】:

    在 datenwolf 的大力帮助下,我最终找到了以下方法:

    • 制作节点标量(例如温度)的 8 位 2D 纹理
    • 在片段着色器中查找 1D 颜色图纹理中的灰度级别

    还有代码:

    from OpenGL.GL import *
    from OpenGL.GLUT import *
    from OpenGL.GLU import *
    import sys
    from PIL import Image
    import numpy as np
    from OpenGL.GL import shaders
    
    def LoadTexture():
        global ID
        arr = np.array([[0, 255, 0], [0, 0, 0]], dtype=np.int8)
        im = Image.fromarray(arr, "L")
        ix, iy, image = im.size[0], im.size[1], im.tobytes()
        ID = glGenTextures(1)
    
        glActiveTexture(GL_TEXTURE0);
        glBindTexture(GL_TEXTURE_2D, ID);
        glPixelStorei(GL_UNPACK_ALIGNMENT, 1)
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, ix, iy, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, image)
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
        glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL)
    
        glEnable(GL_TEXTURE_2D)
    
    def loadColorMap(imageName="jet.bmp"):
        im = Image.open(imageName)
        ix, _, image = im.size[0], im.size[1], im.tostring("raw", "RGBX", 0, -1)
        ID = glGenTextures(1)
        glActiveTexture(GL_TEXTURE1);
        glBindTexture(GL_TEXTURE_1D, ID);
        glPixelStorei(GL_UNPACK_ALIGNMENT, 1)
        glTexImage1D(GL_TEXTURE_1D, 0, 3, ix, 0, GL_RGBA, GL_UNSIGNED_BYTE, image)
        glTexParameterf(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
        glTexParameterf(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
        glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)  # avoids 1 => 0
        glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL)
        glEnable(GL_TEXTURE_1D)
        return ID
    
    
    
    glutInit(sys.argv)
    glutCreateWindow("")
    
    
    VERTEX_SHADER = shaders.compileShader("""
    void main() {
            gl_TexCoord[0] = gl_MultiTexCoord0;
            gl_Position = ftransform();
    }""", GL_VERTEX_SHADER)
    
    FRAGMENT_SHADER = shaders.compileShader("""
    
    uniform sampler2D texture;
    uniform sampler1D colormap;
    void main() {
        float level = texture2D(texture, vec2(gl_TexCoord[0].s, gl_TexCoord[0].t)).r;
        gl_FragColor = texture1D(colormap, level);
    }""", GL_FRAGMENT_SHADER)
    
    LoadTexture()
    loadColorMap()
    
    shader = shaders.compileProgram(VERTEX_SHADER, FRAGMENT_SHADER)
    
    
    shaders.glUseProgram(shader)
    texloc = glGetUniformLocation(shader, 'texture');
    glUniform1i(texloc, 0);
    texloc = glGetUniformLocation(shader, "colormap");
    glUniform1i(texloc, 1);
    
    glMatrixMode(GL_PROJECTION)
    gluPerspective(45.0, 1, 0.1, 100.0)
    glMatrixMode(GL_MODELVIEW)
    glLoadIdentity()  # Reset The View
    glTranslatef(0.0, 0.0, -3.0)  # Move Into The Screen
    
    glBegin(GL_QUAD_STRIP)
    glTexCoord2f(1. / 6, .25); glVertex3f(-1, 0, 0)
    glTexCoord2f(1. / 6, .75); glVertex3f(-1, 1, 0)
    glTexCoord2f(.5, .25);glVertex3f(0, 0, 0)
    glTexCoord2f(.5, .75);glVertex3f(0, 1, 0)
    glTexCoord2f(5. / 6, .25);glVertex3f(1, 0, 0)
    glTexCoord2f(5. / 6, .75); glVertex3f(1, 1, 0)
    glEnd()
    
    glutSwapBuffers()
    
    glutMainLoop()
    

    生成此图像:

    【讨论】:

      猜你喜欢
      • 2013-03-11
      • 2021-12-23
      • 1970-01-01
      • 1970-01-01
      • 2015-03-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多