【问题标题】:How to implement world-coordinate-aligned repeated texture mapping in OpenGL?如何在OpenGL中实现世界坐标对齐的重复纹理映射?
【发布时间】:2011-08-26 16:12:56
【问题描述】:

当您在 Valve 的 Hammer Editor 等 3D 地图编辑器中创建画笔时,对象的纹理默认会重复并与世界坐标对齐。

如何使用 OpenGL 实现此功能?

可以使用 glTexGen 来实现吗?

或者我必须以某种方式使用纹理矩阵?

如果我创建 3x3 框,那么很容易: 将 GL_TEXTURE_WRAP_T 设置为 GL_REPEAT 在边缘将纹理坐标设置为 3,3。

但是如果对象不是轴对齐的凸包,它会变得,呃,有点复杂。

基本上我想从 Valve Hammer 创建面部编辑表的功能:

【问题讨论】:

    标签: opengl textures texture-mapping


    【解决方案1】:

    从技术上讲,您可以为此使用纹理坐标生成。但我建议使用顶点着色器,它可以从转换后的顶点坐标生成纹理坐标。再具体一点(我不太了解 Hammer)。


    看完视频后,我明白了你的困惑。我想你应该知道,Hammer/Source 可能没有绘图 API 生成纹理坐标,而是在内部生成它们。

    因此,您可以看到纹理投影在 X、Y 或 Z 平面上,具体取决于面部指向的主要方向。然后它使用局部顶点坐标作为纹理坐标。

    您可以在将模型加载到顶点缓冲区对象的代码中实现这一点(效率更高,因为计算只进行一次),或者在 GLSL 顶点着色器中实现。我给你伪代码:

    cross(v1, v2):
        return { x = v1.y * v2.z - v1.z * v2.y,
                 y = v2.x * v1.z - v2.z * v1.x, // <- "swapped" order!
                 z = v1.x * v2.y - v1.y * v2.x }
    
    normal(face): 
        return cross(face.position[1] - face.position[0], face.position[2] - face.position[0])
    
    foreach face in geometry:
        n = normal(face) // you'd normally precompute the normals and store them
        if abs(n.x) > max(abs(n.y), abs(n.z)): // X major axis, project to YZ plane
            foreach (i, pos) in enumerate(face.position):
                 face.texcoord[i] = { s = pos.y, t = pos.z }
    
        if abs(n.y) > max(abs(n.x), abs(n.z)): // Y major axis, project to XZ plane
            foreach (i, pos) in enumerate(face.position):
                 face.texcoord[i] = { s = pos.x, t = pos.z }
    
        if abs(n.z) > max(abs(n.y), abs(n.x)): // Z major axis, project to XY plane
            foreach (i, pos) in enumerate(face.position):
                 face.texcoord[i] = { s = pos.x, t = pos.y }
    

    要使用 glTexGen 纹理坐标生成,您必须将模型拆分为每个主轴的部分。 glTexGen 所做的只是映射步骤face.texcoord[i] = { s = pos.&lt;&gt;, t = pos.&lt;&gt; }。在顶点着色器中,您可以直接进行分支。

    【讨论】:

    • 问题是:如何在openGL中实现世界坐标对齐的重复纹理映射? Valve Hammer 只是一个例子(参见:youtube.com/watch?v=8R4aWvRQP-E
    • 这可行,我试试这个。我尝试找到面部平面的正交基向量,然后在它们上投影面部顶点。 s = Vector.Dot(basis1, vertex); t = Vector.Dot(basis2, vertex);这种方法的问题是平面可以有几个正交基向量围绕平面法线旋转。而且我不确定如何获得与原点对齐的平面基向量。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-03
    • 2015-03-26
    • 2012-08-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多