zoukankan      html  css  js  c++  java
  • 边缘高亮效果

    游戏要实现模型的突出显示,最好是边缘高亮的效果.刚听到这个东西时,第一个进入头脑中的就是:边缘检测.于是就写了一个:
    Pass 0:
    渲染模型到一个RenderTarget Model上,并把模型的形状写入Alpha通道.
    Pass 1:
    对上面得到的Alpha通道用拉普拉斯模板进行滤波,得到一个边缘,写入另一个RenderTarget Edge.
    Pass 2:
    把前面得到的两个RenderTarget进行合成,输出到屏幕.
     
    虽说效果还不错,但是用掉了两个RenderTarget,显然不合算.而且,用拉普拉斯在PixelShader中进行逐像素的处理,效率并不高.
     
    阿来在GameDev上求得另一种方法:把模型画两遍,其中一次对模型进行一次放大,关闭Z-Write就出来这种效果了.不过有两个问题:
    一是模型直接放缩是以模型坐标系的原点来的,而这个原点并不一定是在模型的中心.就算在中心,对于一些非凸多面体并不能得到很好的效果,有一些边缘会被模型遮住.
    二是,关闭了深度检测,那这个模型怎么跟别的模型来进行遮挡处理呢?
     
    后来在群里有人提醒说在3D游戏程序设计入门这本书上有,我才想起来有一个卡通渲染的例子.卡通渲染?那里面不也有轮廓生成吗?看了一下书上的实现方法,用的是三角形退化,有点复杂.于是google之,发现了一个跟GameDev上那个方法差不多思想的:
    Pass0:
    把模型按法线方向进行放大,然后渲染成单色模型,不过只渲染背面,避免遮住正常的模型.(把D3DRS_CULLMODE设成D3DCULL_CW就可以了)
    Pass1:
    正常渲染模型,不用做什么改变.不过不要忘了把D3DRS_CULLMODE改回来.
     
    Shader:
    float4x4 matViewProjection;
     
    struct VS_INPUT
    {
       float4 Position : POSITION0;
       float3 Normal   : NORMAL0;
    };
     
    struct VS_OUTPUT
    {
       float4 Position : POSITION0;
    };
     
    VS_OUTPUT vs_main( VS_INPUT Input )
    {
       VS_OUTPUT Output;
     
       Output.Position = float4(Input.Position.xyz + Input.Normal*0.4f,1);
       Output.Position = mul( Output.Position, matViewProjection );
     
       return( Output );
    }
    sampler2D BaseMap;
     
    float4 ps_main() : COLOR0
    {
       return float4(0, 1, 0, 1);
    }
     
    下面是两种方法实现的效果对比:
    差不多哈,区别就是用卡通渲染的那种方法出来的中间也有轮廓线.
  • 相关阅读:
    【noi 2.6_9270】&【poj 2440】DNA(DP)
    【noi 2.6_9271】奶牛散步(DP)
    【noi 2.6_747】Divisibility(DP)
    【noi 2.6_7113】Charm Bracelet(DP)
    【noi 2.6_9268】酒鬼(DP)
    【noi 2.6_9267】核电站(DP)
    【noi 2.6_9265】取数游戏(DP)
    【noi 2.6_2000】&【poj 2127】 最长公共子上升序列 (DP+打印路径)
    【noi 2.6_8786】方格取数(DP)
    【noi 2.6_90】滑雪(DP)
  • 原文地址:https://www.cnblogs.com/lancidie/p/1949339.html
Copyright © 2011-2022 走看看