【发布时间】:2016-08-15 10:46:37
【问题描述】:
我正在做一个内核大小为 64 的 SSAO 着色器。
SSAO 片段着色器:
const int kernelSize = 64;
for (int i = 0; i < kernelSize; i++) {
//Get sample position
vec3 s = tbn * ubo.kernel[i].xyz;
s = s * radius + origin;
vec4 offset = vec4(s, 1.0);
offset = ubo.projection * offset;
offset.xy /= offset.w;
offset.xy = offset.xy * 0.5 + 0.5;
float sampleDepth = texture(samplerposition, offset.xy).z;
float rangeCheck = abs(origin.z - sampleDepth) < radius ? 1.0 : 0.0;
occlusion += (sampleDepth >= s.z ? 1.0 : 0.0) * rangeCheck;
}
samplerposition 纹理的格式为VK_FORMAT_R16G16B16A16_SFLOAT,并使用标志VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT 上传。
我正在使用带有 nvidia K1100M 显卡的笔记本电脑。如果我在 renderdoc 中运行代码,这个着色器需要 114 毫秒。如果我将 kernelSize 更改为 1,则需要 1 毫秒。
这个纹理获取时间正常吗?还是我在某处设置了错误?
就像布局过渡没有通过,所以纹理在VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL而不是VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL。
【问题讨论】:
-
为什么你认为这是 vulkan 特有的?你只是做了很多工作!我认为运行循环 64x 与 1x 的成本超过 64x 的事实是因为在 1x 上编译器将摆脱循环。尝试更改分辨率。时间是否随像素数线性变化?如果是,那么您只是使 GPU 饱和。优化循环!