WebGPU 학습 (4 개) : 알파으로 적용

안녕하십니까, 알파으로 적용 범위 MSAA 관련이 문서의 연구와 WebGPU의 실현.

마지막 포스트
WebGPU 학습 (III) : MSAA

학습 알파에 적용

사전 지식

소개

MSAA 알파 커버리지 단편의 알파 값 (프래그먼트 쉐이더 출력의 색의 알파 값) 샘플을 연 후, 화소에 대응하는 단편이 포함되는지 여부에 영향을 미칠 수있다.

동기 부여

참조 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 새로운 속성 범위 (범위)을 각 단편을 연 후, 말, 이것은 이진 비트 마스크 마스크이다.

x는 0 또는 1이고 4X MSAA 일례 각 단편 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 웹 회의 분 2019년 4월 29일
OpenGL-> gl_SampleMask

추천

출처www.cnblogs.com/chaogex/p/12004546.html