Kan*_*jiu 1 c++ opengl textures glsl
让我们说,为了简化这个问题,我想创建一个包含从黑色到红色的颜色渐变的纹理.我知道有更简单的方法来实现这一点,但它是我的问题的一个很好的例子.
我想,我可以简单地从浮点数组创建一个纹理,如下所示:
float values[4] {
0.f, 1.f,
0.f, 1.f
}
// gen texture
unsigned int texId;
glGenTextures(1, &texId);
glBindTexture(GL_TEXTURE_2D, texId);
// set filter and wrap
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
// copy values
glTexImage2D(GL_TEXTURE_2D, 0, GL_R32F, 2, 2, 0, GL_RED, GL_FLOAT, values);
Run Code Online (Sandbox Code Playgroud)
并绘制它:
float vertices[8] {
-1.f, -1.f, 0.f, 0.f,
1.f, -1.f, 1.f, 0.f,
1.f, 1.f, 1.f, 1.f,
-1.f, 1.f, 0.f, 1.f
}
// generate vertex buffer, vertex buffer layout and vertex array
unsigned int[6] indices {
0, 1, 2,
2, 3, 1
}
// generate index buffer
// bind everything
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, nullptr);
Run Code Online (Sandbox Code Playgroud)
绑定顶点着色器的位置如下所示:
#version 330 core
layout(location=0) in vec2 in_position;
layout(location=1) in vec2 in_texCoords;
out vec2 texCoords;
void main() {
gl_Position = vec4(in_position, 0.f, 1.f);
texCoords = in_texCoords;
}
Run Code Online (Sandbox Code Playgroud)
片段着色器如下:
#version 330 core
layout(location = 0) out vec4 out_color;
in vec2 texCoords;
uniform sampler2D u_gradient;
void main() {
float red = texture(u_gradient, texCoords).r;
out_color = vec4(red, 0.f, 0.f, 1.f);
}
Run Code Online (Sandbox Code Playgroud)
在此之后,我希望在整个窗口中从左到右(黑色到红色)获得颜色渐变.然而,我得到的是从x和y方向的窗口的约1/4到3/4的梯度(见下图).我也注意到重复的包装在这里似乎不适用,因为我看起来像镜像重复.
我已经使用固定值而不是texCoords来使用片段着色器,并且认为x轴上的.25到.75的范围表示整个渐变(.25映射为0表示红色,.75表示为1).
将作为值传递的"步骤"数量更改为纹理(例如,4x4阵列)不会更改结果.
我也尝试使用图像作为纹理(加载了stb_image,分辨率为1920x1080),它可以很好地工作并在整个屏幕上传播.
为了澄清:为什么渐变的texCoords范围从.25到.75而不是从0到1以及如何修复它(除了调整texCoords本身)?
让我们假设您有2x2纹理
2x2纹理
如果此纹理包裹在6x6片段的网格上,则纹素的中心恰好位于6x6正方形的3x3平铺的middel中的纹素上:
6x6四核
其他碎片的颜色取决于纹理参数 - 请参阅glTexParameter.
由于纹理被放大,因此GL_TEXTURE_MAG_FILTER是重要的.
如果是GL_NEAREST,那么片段的颜色是片段的纹理坐标中最接近的纹素之一:
如果是GL_LINEAR,则通过最接近纹理坐标的4个像素的加权平均来内插颜色.
6x6四边形边界处的插值取决于包裹参数GL_TEXTURE_WRAP_S和GL_TEXTURE_WRAP_T.
如果参数是GL_REPEAT(默认值),则将纹理视为无限纹理,并且边界处颜色插值的插值考虑纹理相对侧的纹素.这用于无缝纹理和平铺:
如果是GL_CLAMP_TO_EDGE,则边框处的插值颜色会被粘贴到纹理边框处的纹素颜色:
将纹理包装参数GL_CLAMP_TO_EDGE应用于纹理对象,
float values[4] { 0.f, 1.f, 0.f, 1.f };
unsigned int texId;
glGenTextures(1, &texId);
glBindTexture(GL_TEXTURE_2D, texId);
// set filter and wrap
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
// copy values
glTexImage2D(GL_TEXTURE_2D, 0, GL_R32F, 2, 2, 0, GL_RED, GL_FLOAT, values);
Run Code Online (Sandbox Code Playgroud)
获得以下渐变:
| 归档时间: |
|
| 查看次数: |
251 次 |
| 最近记录: |