9.7 裁剪像素

有时,我们希望完全丢弃某个源像素,使它不再接受后续处理。这一工作可以由HLSL的内置函数clip(x)来实现。该函数只能在像素着色器中使用,当x<0时丢弃当前像素,使之不再接受后续处理。该函数在渲染如图9.9所示的铁丝网纹理时非常有用。也就是说,它非常适合于渲染那些完全不透明或者完全透明的像素。

图9.9
图9.9 带有alpha通道的铁丝网纹理。clip函数将丢弃那些带有黑色alpha值的像素,不对这些像素进行绘制;只有铁丝网部分会保留下来。从本质上讲,alpha通道剔除了纹理中的“非铁丝网”像素。

在像素着色器中,我们攫取了漫反射纹理的alpha分量。当它的值接近于0时,我们将该像素视为完全透明,丢弃该像素,不再对它进行后续处理。

float4 PS(VertexOut pin, uniform int gLightCount, uniform bool gUseTexure, 
              uniform bool gAlphaClip, uniform bool gFogEnabled) : SV_Target
{
    // 插值后的法线需要重新规范化
    pin.NormalW = normalize (pin.NormalW);
    // toEye矢量用于光照计算
    float3 toEye = gEyePosW - pin.PosW;
    // 保存表面顶点离开相机的距离信息
    float distToEye = length(toEye);
    // 规范化
    toEye /= distToEye;
    // 初始化纹理颜色
    float4 texColor = float4(1, 1, 1, 1);
    if (gUseTexure)
    {
        // 采样纹理
        texColor = gDiffuseMap.Sample(samAnisotropic, pin.Tex);
        
        if (gAlphaClip)
        {
            // 如果纹理的alpha<0.1,则丢弃像素。
            // 注意,我们应该尽可能早地进行这个测试,这样我们就可以及早退出
            // shader,忽略其余shader代码。
            clip(texColor.a - 0.1f);
        }
    }
…

因为我们可能只在某些几何体上进行裁剪操作,所以只有在参数gAlphaClip设置为true的情况下我们才进行裁剪,这样我们就可以根据特定的shader切换裁剪。注意,使用混合也可以得到同样的效果,只是这种(裁剪)方式的运行效率更高一些。这种方式即不需要进行任何混合计算,也不需要考虑物体的绘制顺序。而且,它可以在像素着色器中尽早丢弃像素,避免执行不必要的像素着色器指令(被丢弃的像素不会参与任何计算)。

注意:由于过滤器的作用,alpha通道可能会变得有些模糊,所以当裁剪像素时,你应该保留一些容差值。例如,裁剪alpha值接近于0的像素,而不必让alpha值精确为0。

图9.10是“Blend”演示程序的屏幕截图。它使用透明混合绘制了半透明的水体,使用了新的铁丝网纹理,并且在像素着色器中加入了裁剪测试功能。另一个值得注意的地方是,由于我们现在要透过立方体看到背面的铁丝网纹理,所以我们希望禁用背面消隐功能:

D3D11_RASTERIZER_DESC noCullDesc;
ZeroMemory(&noCullDesc, sizeof(D3D11_RASTERIZER_DESC));
noCullDesc.FillMode  = D3D11_FILL_SOLID;
noCullDesc.CullMode = D3D11_CULL_NONE;
noCullDesc.FrontCounterClockwise = false;
noCullDesc.DepthClipEnable = true;
ID3D11RasterizerState * NoCullRS;
HR(device->CreateRasterizerState(&noCullDesc, &NoCullRS));
…
// 因为铁丝网纹理包含透明区域,我们可以透过立方体看到背面的三角形,所以我们希望禁用背面消隐功能
md3dImmediateContext->RSSetState(NoCullRS);
boxTech->GetPassByInde x(p)->Apply(0, md3dImmediateContext);
md3dImmediateContext->DrawIndexed(36, 0, 0);
// 恢复为默认的渲染状态
md3dImmediateContext->RSSetState(0); 
图9.10
图9.10“Blend”演示程序的屏幕截图。
文件下载(已下载 556 次)

发布时间:2014/8/11 21:01:02  阅读次数:3915

2006 - 2024,推荐分辨率1024*768以上,推荐浏览器Chrome、Edge等现代浏览器,截止2021年12月5日的访问次数:1872万9823 站长邮箱

沪ICP备18037240号-1

沪公网安备 31011002002865号