WebGPUラーニング(四):アルファへのカバレッジ

みなさん、こんにちは、アルファへカバレッジMSAAに関連したこの記事の研究とWebGPUの実現。

最後のポスト
WebGPU学習(III):MSAA

学習アルファへのカバレッジ

事前知識

入門

MSAAとAlphaにカバレッジ、断片のアルファ値(フラグメントシェーダ出力の色のアルファ値)のサンプルを開いた後画素に対応するフラグメントが覆われているかどうかに影響することができます。

モチベーション

参考Luantan記録II:アルファへのカバレッジ
スクリーンショット3.48.09.png-220.6kB 2019年12月7日PM
スクリーンショット3.48.17.png-844.8kB 2019年12月7日PM
スクリーンショット3.48.23.png-203.1kB 2019年12月7日PM
スクリーンショット3.48.29.png-774.9kB 2019年12月7日PM
2019年12月7日午後のスクリーンショット9.25.41.png、380.3kB

原則

カバー検出

WebGPUは、(III)学習:MSAAの MSAAの原則を紹介し、我々はGPUがカバーされるサンプリングポイントのどれかを決定するためにカバレッジを検出する工程を経るために知っています。「解決」のステップに入りません。サンプリングポイントの対象ではありません。

カバー検出結果がカバレッジ(カバレッジ)の各フラグメントに対して計算されます。

よるルアンレコードII:アルファにカバレッジたとえば、新しいプロパティのカバレッジ(被覆率)と、各断片をMSAAを開いた後、それがバイナリ・ビット・マスクのマスクです。

4X MSAA例えば、xは0または1であり、各フラグメントXXXXのカバレッジに。その対応する画素サンプルのサンプル点の各々、0が1で覆われ、試料が覆われていないことを示しています。

したがって、カバレッジのカバレッジは、サンプリングポイントに対応するマスク。

カバレッジを計算する方法

1.固定カバレージマスクを設定することができ、ユーザは、ここにFixedSampleMask命名します

2.gpuここで、サンプルポイントのカバレージマスクを得、プリミティブによってカバーRasterizerCoverageMask命名されるピクセルあたりのサンプリング点を検出します

3.如果开启了Alpha To Coverage,则会将fragment的alpha值转换为coverage掩码,这里命名为AlphaCoverageMask

转换的算法可以参考乱弹纪录II:Alpha To Coverage

一个fragment的Alpha值在0~1间,它对应着一个dither mask。还是以4XMSAA为例,这个dither mask也是xxxx的形式,Alpha为0对应了0000,alpha为1对应了1111,至于中间的值的对应关系,OpenGL是交由显卡制造商决定的——其实一般就是类似[0~0.249 -> 0000, 0.25~0.499 -> 0001, 0.5~0.749 -> 0011, 0.75~0.99-> 0111]这样。

4.fragment shader可以输出该fragment的coverage掩码,这里称为FragShaderSampleMaskOutput

像素最终的coverage = FixedSampleMask & RasterizerCoverageMask & AlphaCoverageMask & FragShaderSampleMaskOutput
(“&”是逻辑与运算,如0011 & 0010 = 0010)

参考资料

乱弹纪录II:Alpha To Coverage

WebGPU实现Alpha To Coverage

暂时没有实现的sample,我们根据WebGPU规范和相关资料,分析下WebGPU如何实现Alpha To Coverage。

  • 在render pipeline descriptor中设置固定的coverage掩码FixedSampleMask和是否开启Alpha To Coverage:
dictionary GPURenderPipelineDescriptor : GPUPipelineDescriptorBase {
...
    unsigned long sampleMask = 0xFFFFFFFF;
    boolean alphaToCoverageEnabled = false;
...    
};

我们注意到sampleMask是unsigned long类型,它是32位的,而coverage应该是二进制的(如4X MSAA的coverage是4位的二进制),所以这里是进行了进制转换。

举例来说:
对于4X MSAA,如果设置sampleMask为0x1(十六进制),则它转换为二进制是0001;
如果设置sampleMask为0x3,则它转换为二进制是0010

  • 可以在fragment shader中设置输出的coverage掩码FragShaderSampleMaskOutput

根据Investigation: Multisample Coverage,我们知道Vulkan->SPIR-V的fragment shader支持内置的SampleMask变量。

因为Chrome实现的WebGPU也使用SPIR-V作为shader编译后的字节码,所以WebGPU在这点上应该与Vulkan类似。

我没有搜索到SPIR-V中关于SampleMask的详细资料,但是考虑到Chrome实现的WebGPU使用GLSL 4.5,所以我们可以看下它关于gl_SampleMask的说明

Name
gl_SampleMask — specifies the sample coverage mask for the current fragment
Declaration
out int gl_SampleMask[] ;

我们看到gl_SampleMask的每个元素的类型是32位的,所以也进行了进制转换。

又因为它是数组,所以它支持coverage为超过32位的二进制(如支持64X MSAA)

用代码来说明:

//in fragment shader

gl_SampleMask[0] = 1;   //对于4X MSAA来说,相当于设置该fragment的coverage为0001
//in fragment shader

gl_SampleMask[0] = 2;

gl_SampleMask[1] = 1;   //对于64X MSAA来说,可能相当于设置该fragment的coverage为000...1000...10 (前面的000...1有32位,后面的000...10有32位) (我不能确定这是否正确!)
  • アルファへのカバレッジを有効にした場合、カバレージマスクは、フラグメントシェーダで出力することはできません

  • あなたはアルファへのカバレッジをオンにすると、アルファマスクアルゴリズムに変換されます別のブラウザで同じではありません

参考資料

調査:マルチサンプルカバレッジ
GPUのWeb会議の議事録2019年4月29日
OpenGL-> gl_SampleMask

おすすめ

転載: www.cnblogs.com/chaogex/p/12004546.html