如何解决如何优化对 imageLoad 调用很重的计算着色器?
在我的程序中,我有计算着色器,它们对 3D 纹理进行大量 imageLoad 调用,它们都以 imageStore 结尾,然后输出纹理。
以下是计算 3D 场梯度的示例:
#version 430 core
layout(local_size_x=4,local_size_y=4,local_size_z=4) in;
layout(rgba16_snorm)
uniform image3D img_in;
layout(rgba16_snorm)
uniform image3D img_out;
void main()
{
ivec3 coord = ivec3(gl_GlobalInvocationID);
float left = imageLoad(img_in,coord + ivec3(-1,0)).x;
float right = imageLoad(img_in,coord + ivec3( 1,0)).x;
float top = imageLoad(img_in,coord + ivec3( 0,1,0)).x;
float bottom = imageLoad(img_in,-1,0)).x;
float front = imageLoad(img_in,-1)).x;
float back = imageLoad(img_in,1)).x;
vec3 gradient = vec3(right-left,top-bottom,back-front) / 2;
imageStore(img_out,coord,vec4(gradient,0));
}
使用 128x128x128 纹理,此着色器的执行时间为 0.9 毫秒(工作组大小:32x32x32)。我有一个着色器来计算散度,它花费的时间大致相同。有什么办法可以加快速度吗?
编辑:使用共享数组更新着色器代码
#version 430 core
layout(local_size_x=4,local_size_z=4) in;
layout(rgba16_snorm)
uniform image3D img_in;
layout(rgba16_snorm)
uniform image3D img_out;
uniform float gs;
shared vec4 cache[4][4][4];
void retire_phase()
{
memoryBarrierShared();
barrier();
}
ivec3 clamp_coord(ivec3 coord)
{
return clamp(coord,ivec3(0,0),imageSize(img_in));
}
void main()
{
ivec3 coord = ivec3(gl_GlobalInvocationID);
vec4 tx = imageLoad(img_in,clamp_coord(coord));
ivec3 cc = ivec3(mod(coord,ivec3(gl_WorkGroupSize)));
cache[cc.x][cc.y][cc.z] = tx;
retire_phase();
ivec3 size = ivec3(gl_WorkGroupSize);
float left,right,top,bottom,front,back;
if (coord.x > 0) { left = cache[cc.x-1][cc.y][cc.z].x; }
else { left = imageLoad(img_in,0)).x; }
if (coord.x < (size.x - 1)){ right = cache[cc.x+1][cc.y][cc.z].x; }
else { right = imageLoad(img_in,0)).x; }
if (coord.y > 0) { bottom = cache[cc.x][cc.y-1][cc.z].x; }
else { bottom = imageLoad(img_in,0)).x; }
if (coord.y < (size.y - 1)) { top = cache[cc.x][cc.y+1][cc.z].x; }
else { top = imageLoad(img_in,0)).x; }
if (coord.z > 0) { front = cache[cc.x][cc.y][cc.z-1].x; }
else { front = imageLoad(img_in,-1)).x; }
if (coord.z < (size.z - 1)) { back = cache[cc.x][cc.y][cc.z+1].x; }
else { back = imageLoad(img_in,1)).x; }
vec3 gradient = vec3(right-left,back-front) / (2 * gs);
imageStore(img_out,0));
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。