前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >基于法线的边缘检测

基于法线的边缘检测

作者头像
逍遥剑客
发布2019-02-20 14:42:58
5960
发布2019-02-20 14:42:58
举报

边缘高亮效果中我提到过两种方法, 各有优缺点吧

图像空间域的边缘检测效果比较好, 中间没有多余的线条. 缺点是PS中计算比较慢

第二种把模型"放大"(其实是变胖)的做法, 可以在VS中完成, 不需要额外的RenderTarget, 适合低端显卡使用, 适应性好. 不如果模型法线信息不对的话, 会造成画面错乱. 实际使用时可以根据W值(不用Z深度)来画出远近粗细一样的线条

这次提到的基于法线的方法, 其实跟2D的空间域边缘检测很相似, 如果要求结果是绘制物体的线条图而不仅仅是一个边缘轮廓时, 它就派上用场了. (还是要用PS去算, 实际使用时要注意性能问题)

基本的渲染流程(2 pass):

第一个pass用于生成法线图到一张RenderTarget上, 第二个pass跟据这张法线图来做边缘检测. 实际使用时可以采用Multi-RenderTarget来加速

法线信息要在pixel shader里进行向量化, 不然会在一些面上出块很淡的颜色. 如果对质量要求不高, 可以在VS中进行向量化.

RenderTarget要Clear成单位化的值, 我用的(0,0,1), 即纯蓝色

代码语言:javascript
复制
/*********************VS*********************/
float4x4 matViewProjection;

struct VS_INPUT 
{
   float4 Position : POSITION0;
   float3 Normal   : NORMAL0;
};

struct VS_OUTPUT 
{
   float4 Position : POSITION0;
   float3 Normal   : TEXCOORD0;
};

VS_OUTPUT vs_main( VS_INPUT Input )
{
   VS_OUTPUT Output;

   Output.Position = mul( Input.Position, matViewProjection );
   Output.Normal = mul( Input.Normal, matViewProjection );
   
   return( Output );
   
}
/*********************PS*********************/
float4 ps_main(float3 normal : TEXCOORD0) : COLOR0
{   
   return(float4(normalize(normal), 1.0f));
}

注意法线图的格式是浮点数格式, 我用的是D3DFMT_A16B16G16R16F(因为法线有负值, 你也可以自己压缩到[0,1]再解开)

有了这张法线图就很好办了, 对每个像素计算它与周围像素的法线夹角余弦值的和, 再取反(1-degree), 这样就能计算出来边缘了

依据就是边缘处的法线夹角比较大, 余弦值更接近0甚至为负值.

代码语言:javascript
复制
sampler TexNormal;
float2 fInverseViewportDimensions;

float2 PixelKernel[4] =
{
    { 0,  1},
    { 1,  0},
    { 0, -1},
    {-1,  0}
};

float4 ps_main(float2 texCoord : TEXCOORD0) : COLOR0
{
   float4 origin = tex2D(TexNormal, texCoord);
   float3 sum = 0;
   for (int i = 0; i < 4; i++)
   {
      float2 texel = texCoord + PixelKernel[i] * fInverseViewportDimensions;
      sum += saturate(1.0f - dot(origin.xyz, tex2D(TexNormal, texel).xyz));
   }
   
   return float4(sum, 1.0f);
}

最终效果:

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2008年12月01日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档