You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

OpenGL:如何通过vec4动态生成纹理坐标?

解决方案:通过Uniform生成纹理坐标

一、优先在顶点着色器中计算

推荐在顶点着色器里生成纹理坐标,原因有两个:

  • 顶点着色器每个顶点只执行一次,计算量远小于片元着色器(片元是每个像素都要计算),性能更优;
  • GPU会自动对顶点输出的纹理坐标做线性插值,最终效果和原来顶点携带纹理坐标的方式完全一致。

二、具体实现代码

1. 修改顶点着色器

利用顶点的位置坐标(范围是[-0.5, 0.5]),映射到Uniform传入的纹理坐标区间s0~s1、t0~t1:

#version 330 core
layout (location = 0) in vec3 aPos;

out vec2 tex_coord;
uniform vec4 tex_bounds; // 对应传入的 s0, t0, s1, t1

void main()
{
    gl_Position = vec4(aPos, 1.0);
    // 将顶点x坐标从[-0.5,0.5]映射到[s0,s1]
    float s = tex_bounds.x + (aPos.x + 0.5) * (tex_bounds.z - tex_bounds.x);
    // 将顶点y坐标从[-0.5,0.5]映射到[t1,t0](OpenGL纹理y轴从下到上,和顶点y方向相反)
    float t = tex_bounds.w + (0.5 - aPos.y) * (tex_bounds.y - tex_bounds.w);
    tex_coord = vec2(s, t);
}

2. 片元着色器无需改动

直接使用顶点着色器传递过来的纹理坐标采样即可:

#version 330 core
out vec4 frag_color;
in vec2 tex_coord;
uniform sampler2D texture;

void main()
{
    frag_color = texture(texture, tex_coord);
}

3. CPU端Uniform传递

保持你原来的调用逻辑,注意参数顺序对应顶点着色器的tex_bounds:

glUniform4f(glGetUniformLocation(shader, "tex_bounds"), s0, t0, s1, t1);

三、纹理图集的应用方式

用这套方案渲染多个图标时,只需:

  • 共用同一个仅含位置数据的顶点缓冲区;
  • 对每个图标,计算它在纹理图集中的边界坐标s0,t0,s1,t1(即图标的左上角、右下角纹理坐标);
  • 绑定纹理图集,设置对应tex_bounds的Uniform,然后调用绘制接口渲染四边形即可。

这种方式能大幅减少顶点数据冗余,提升批量图标的渲染效率。

内容的提问来源于stack exchange,提问作者Prashant

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 18:45:48