Performance 如何提高OpenGL着色器中的纹理访问性能? 条件
我使用Performance 如何提高OpenGL着色器中的纹理访问性能? 条件,performance,opengl,glsl,textures,Performance,Opengl,Glsl,Textures,我使用opengl3和PyOpenGL 我有大约50000(53'490)个顶点,每个顶点都有199个决定其位移的属性。不可能将这些数据存储为常规顶点属性,所以我使用纹理 问题是:非并行化C函数计算顶点位移的速度与GLSL一样快,在某些情况下甚至更快。我已经检查过了:问题是纹理读取,我不知道如何优化它 我编写了两个不同的着色器。一个在~0.09s内计算新模型,另一个在~0.12s内计算新模型(包括属性分配,这两种情况下是相等的) 代码 两个着色器都以 #version 300 es in ve
opengl3
和PyOpenGL
我有大约50000(53'490)个顶点,每个顶点都有199个决定其位移的属性。不可能将这些数据存储为常规顶点属性,所以我使用纹理
问题是:非并行化C
函数计算顶点位移的速度与GLSL
一样快,在某些情况下甚至更快。我已经检查过了:问题是纹理读取,我不知道如何优化它
我编写了两个不同的着色器。一个在~0.09s内计算新模型,另一个在~0.12s内计算新模型(包括属性分配,这两种情况下是相等的)
代码
两个着色器都以
#version 300 es
in vec3 vin_position;
out vec4 vin_pos;
uniform mat4 rotation_matrix;
uniform float coefficients[199];
uniform sampler2D principal_components;
越快越好
void main(void) {
int c_pos = gl_VertexID;
int texture_size = 8192;
ivec2 texPos = ivec2(c_pos % texture_size, c_pos / texture_size);
vec4 tmp = vec4(0.0);
for (int i = 0; i < 199; i++) {
tmp += texelFetch(principal_components, texPos, 0) * coefficients[i];
c_pos += 53490;
texPos = ivec2(c_pos % texture_size, c_pos / texture_size);
}
gl_Position = rotation_matrix
* vec4(vin_position + tmp.xyz, 246006.0);
vin_pos = gl_Position;
}
void主管道(void){
int c_pos=gl_VertexID;
int纹理_大小=8192;
ivec2 texPos=ivec2(c_pos%纹理大小,c_pos/纹理大小);
vec4-tmp=vec4(0.0);
对于(int i=0;i<199;i++){
tmp+=texelFetch(主分量,texPos,0)*系数[i];
c_pos+=53490;
texPos=ivec2(c_pos%纹理大小,c_pos/纹理大小);
}
gl\u位置=旋转矩阵
*vec4(vin_位置+tmp.xyz,246006.0);
vin\u位置=gl\u位置;
}
慢一点的
void main(void) {
int texture_size = 8192;
int columns = texture_size - texture_size % 199;
int c_pos = gl_VertexID * 199;
ivec2 texPos = ivec2(c_pos % columns, c_pos / columns);
vec4 tmp = vec3(0.0);
for (int i = 0; i < 199; i++) {
tmp += texelFetch(principal_components, texPos, 0) * coefficients[i];
texPos.x++;
}
gl_Position = rotation_matrix
* vec4(vin_position + tmp.xyz, 246006.0);
vin_pos = gl_Position;
}
void主管道(void){
int纹理_大小=8192;
int columns=纹理大小-纹理大小%199;
int c_pos=gl_VertexID*199;
ivec2 texPos=ivec2(c_pos%列,c_pos/列);
vec4-tmp=vec3(0.0);
对于(int i=0;i<199;i++){
tmp+=texelFetch(主分量,texPos,0)*系数[i];
texPos.x++;
}
gl\u位置=旋转矩阵
*vec4(vin_位置+tmp.xyz,246006.0);
vin\u位置=gl\u位置;
}
它们之间的主要区别是:
- 在第一种情况下,顶点的属性按以下方式存储:
- 所有顶点的第一个属性
- 所有顶点的第二个属性
- 所有顶点的最后属性
- 在第二种情况下,顶点的属性以另一种方式存储:
- 第一个顶点的所有属性
- 第二个顶点的所有属性
- 最后一个顶点的所有属性
- 同样在第二个示例中,数据是对齐的,因此每个顶点的所有属性仅存储在一行中。这意味着,如果我知道某个顶点的第一个属性的行和列,我只需要增加纹理坐标的
分量x
- 为什么不能更快地访问数据
- 如何提高it的性能
- 是否能够将纹理块与顶点链接
- 是否有关于GPU(英特尔HD、nVidia GeForce)中缓存的相关文章中的数据对齐建议
数组随着帧的变化而变化,否则就没有问题了:我可以预先计算模型并感到高兴系数
如果大多数系数为0,那么最好选择一些任意的小数值作为可能影响结果的最大系数数。例如,8。将包含8个索引和系数的数组作为一致性发送到着色器。然后遍历该数组,只获取8次。您可能只需要4个就可以解决问题。性能差异可能是由于着色器的执行方式不同。通常,一组着色器在PAR中执行相同的命令。