안녕하십니까, 알파으로 적용 범위 MSAA 관련이 문서의 연구와 WebGPU의 실현.
마지막 포스트
WebGPU 학습 (III) : MSAA
학습 알파에 적용
사전 지식
- WebGPU (C) 학습 : MSAA를
- 화소에 대응하는 프래그먼트
소개
MSAA 알파 커버리지 단편의 알파 값 (프래그먼트 쉐이더 출력의 색의 알파 값) 샘플을 연 후, 화소에 대응하는 단편이 포함되는지 여부에 영향을 미칠 수있다.
동기 부여
원칙
취재 감지
에 의해 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)
参考资料
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