【Metal API 教程】半透明和透明的处理

本文介绍了如何在iOS平台上利用MetalAPI实现对部分透明物体的渲染,通过Alpha测试决定渲染哪些部分,并使用Alpha混合方法处理半透明表面。特别强调了Alpha通道在表示透明度和像素可见性方面的应用,以及如何在片元着色器中执行Alpha测试以优化渲染性能。
摘要由CSDN通过智能技术生成

前言


在OpenGL和DX11中渲染例如植被中的叶子通常会用到Alpha测试来渲染不透明的部分,在iOS平台上,利用Metal API同样也能实现渲染部分透明的物体。


什么是Alpha?


alpha通道通常是用来表示颜色的透明度或者这个像素的可见性(RGBA表示一个像素的话,color.a就是Alpha通道)。
Andrew Glassner写的一篇论文更好地阐述了Alpha通道在渲染半透明或不透明物体的应用。

Alpha测试




本文第一种渲染部分透明表面的技术就是Alpha测试。 它允许我们 通过比较透明度是否超过阈值 决定一个片元是否渲染至缓冲区, 并选择性地渲染透明表面。 它通常用于渲染像叶子一样的物体,叶子纹理的alpha通道可以决定是否需要绘画。

fragment half4 texture_fragment_alpha_test(ProjectedVertex vert [[stage_in]],
                                           texture2d<float, access::sample> texture [[texture(0)]],
                                           sampler texSampler [[sampler(0)]])
{
    float4 vertexColor = vert.diffuseColor;
    float4 textureColor = texture.sample(texSampler, vert.texCoords);

    float diffuseIntensity = max(kMinDiffuseIntensity, dot(normalize(vert.normal.xyz), -kLightDirection));
    float4 color = diffuseIntensity * textureColor * vertexColor;

    if (textureColor.a < kAlphaTestReferenceValue)
        discard_fragment();

    return half4(color.r, color.g, color.b, vertexColor.a);
}


discard_fragment方法


这个方法是直接丢弃当前的片元/像素,不进行着色,和GLSL中的discard关键字(HLSL中对应clip函数)的功能一致。

纹理中的Alpha通道




执行Alpha测试


在片元着色器中执行alpha测试变得非常直接,如果从纹理上采样出来的像素的alpha值超过某个阈值,就直接丢弃当前的片元(discard_fragment)

float4 textureColor = texture.sample(texSampler, vert.texCoords);
 
if (textureColor.a < kAlphaTestReferenceValue)
    discard_fragment();


Alpha混合


另一种渲染方法是alpha混合。 下面的混合方程是将原像素和目标像素做alpha混合。一般渲染这种半透明的表面都是按离相机的距离由远到近进行渲染。




在管线状态中启用混合(Blend)


MTLRenderPipelineColorAttachmentDescriptor *renderbufferAttachment = pipelineDescriptor.colorAttachments[0];
renderbufferAttachment.blendingEnabled = YES; //启用混合
renderbufferAttachment.rgbBlendOperation = MTLBlendOperationAdd;
renderbufferAttachment.alphaBlendOperation = MTLBlendOperationAdd;
renderbufferAttachment.sourceRGBBlendFactor = MTLBlendFactorSourceAlpha;
renderbufferAttachment.sourceAlphaBlendFactor = MTLBlendFactorSourceAlpha;
renderbufferAttachment.destinationRGBBlendFactor = MTLBlendFactorOneMinusSourceAlpha;
renderbufferAttachment.destinationAlphaBlendFactor = MTLBlendFactorOneMinusSourceAlpha;


总结


在移动设备上使用alpha测试应考虑性能问题,tiled-base的GPU架构使用alpha测试会降低渲染的性能。


代码示例下载链接
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值