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:

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的位置不同。

MSAA

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变量要全