vulkan mass shader resolve
shader resolve
使用shader手工resolve(downsample) multiplesample的贴图,是游戏开发的重要技术。我曾经吐槽过vulkan没有提供MSAA depth resolve,那是因为根本没有必要。虽然提供一个legacy的自动resolve color attachment,但是在有shader resolve存在的情况下,真的没有也没关系。
vulkan使用shader resolve multisample texture
首先说明,vulkan开启shader resolve的条件还是很苛刻的,根据文档
Sample shading can be used to specify a minimum number of unique samples to process for each fragment. If sample shading is enabled an implementation must provide a minimum of max(⌈ minSampleShadingFactor × totalSamples
, 1) unique associated data for each fragment, where minSampleShadingFactor
is the minimum fraction of sample shading. totalSamples is the value of VkPipelineMultisampleStateCreateInfo::rasterizationSamples
specified at pipeline creation time. These are associated with the samples in an implementation-dependent manner. When minSampleShadingFactor
is 1.0, a separate set of associated data are evaluated for each sample, and each set of values is evaluated at the sample location.
Sample shading is enabled for a graphics pipeline:
- If the interface of the fragment shader entry point of the graphics pipeline includes an input variable decorated with
SampleId
orSamplePosition
. In this caseminSampleShadingFactor
takes the value 1.0. - Else if the sampleShadingEnable member of the
VkPipelineMultisampleStateCreateInfo
structure specified when creating the graphics pipeline is set toVK_TRUE
. In this caseminSampleShadingFactor
takes the value ofVkPipelineMultisampleStateCreateInfo::minSampleShading
.
Otherwise, sample shading is considered disabled.
如果要用代码的话:
shader resolve作为logical Device的feature需要主动开启,之后创建Pipeline是将
void createLogicalDevice() {
...
deviceFeatures.sampleRateShading = VK_TRUE; // enable sample shading feature for the device
...
}
void createGraphicsPipeline() {
...
multisampling.sampleShadingEnable = VK_TRUE; // enable sample shading in the pipeline
multisampling.minSampleShading = 0.25f; // min fraction for sample shading; closer to one is smoother
...
}
shader code
...
layout (constant_id = 0) const int NUM_SAMPLES = 8;
// Manual resolve for MSAA samples
vec4 resolve(sampler2DMS tex, ivec2 uv)
{
vec4 result = vec4(0.0);
for (int i = 0; i < NUM_SAMPLES; i++)
{
vec4 val = texelFetch(tex, uv, i);
result += val;
}
// Average resolved samples
return result / float(NUM_SAMPLES);
}
...
sampler2DMS
就是需要采用的MSAA贴图,用texelFetch()进行访问,低三个参数是subpixel的id,不同MSAA count下subpixel的位置不同。
openGL MSAA shader resolve
vulkan使用的GLSL,说明openGL没道理不能MSAA shader resolve。
对于支持 ARB_texture_multisample
的设备,可以创建sampler2DMS格式的贴图。然后就和vulkan一样了。
vec4 texelFetch(sampler2DMS sampler, ivec2 uv, int sample)
vec4 texelFetch(sampler2DMSArray sampler, ivec3 uv, int sample)
对于openGL来说,如果使用几何着色器,细分着色器,不要忘记out变量要全
Comments