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);
    }
     
    下面是两种方法实现的效果对比:
    差不多哈,区别就是用卡通渲染的那种方法出来的中间也有轮廓线.
  • 相关阅读:
    数据不是搜集起来的,是沉淀下来的,跟脚印一样,脚印不是修路的人搜集起来的,只要有了路就一定有脚印,不可能说修一条路不留下脚印,世界上没有这样的路
    VC6.0编译的DLL文件能否反编译知道里面的代码?
    Why does the PDB format change every release?
    mysql_query与 mysql_real_query区别
    如何把Backtrack 5安装到U盘/Backtrack 4安装方法
    FreeBSD:像Linux下一样使用vim
    栈的出栈序列个数
    npm outdated -g --depth=0
    npm Updating packages downloaded from the registry
    TypeScript安装
  • 原文地址:https://www.cnblogs.com/lancidie/p/1949339.html
Copyright © 2011-2022 走看看