Normal based Edge Dtect


边缘检测有很多方法,这里讲的是基于法线的边缘检测。

需要的知识有RTT(Render to target),嗯,没错就这么简单,你只要会RTT,两分钟就搞定这个算法。

这个算法的核心思想就是利用物体的边缘法线会发生变化,而法线变化越大,两个法线点积的值就越小。
那么如何获取法线呢,这里就涉及到了RTT,你要将需要检测的物体先渲染一遍,将法线信息保存到一张纹理中,然后通过采样对比每一点的法线和它周围的法线,从而得到结果。

具体步骤

1.RTT,将法线保存到一张纹理中。

2.使用一中的纹理,采用获得其中的法线数据,并将每一点的法线和它周围像素的法线点积,这样就可以得到一张描边的纹理了。

3.根据需求使用上边那张纹理。

具体实现:

步骤1的实现:

VertexOut VS(VertexIn vin)
{
    VertexOut vout;

    // 转换到投影空间
    vout.PosH = mul(float4(vin.PosL, 1.0f), World);
    vout.PosH = mul(vout.PosH, View);
    vout.PosH = mul(vout.PosV, Proj);

    vout.NormalV = mul(float4(vin.Normal,0.0f), WorldInvTransView).xyz;

    return vout;
}

float4 PS(VertexOut pin) : SV_Target
{
    pin.NormalV = normalize(pin.NormalV);

    float4 normal = float4(pin.NormalV,0.0f);

    return normal;
}

步骤2的实现:

vs就不写了,看你具体干什么了直接说ps:

float4 PS_EdgeDetect(VertexOut pin) : SV_Target
{
    float3 normal = normalDepthTex.Sample(samNormalDepth, pin.Tex).xyz;
    float sum = 0;
    if (normal.x!=0.f&&normal.y!=0.f&&normal.z!=0.f)
    {
        for (int i = 0; i < 4; ++i)
        {
            sum += saturate(1 - dot(normal, normalDepthTex.Sample(samNormalDepth, pin.Tex + PixelKernel[i]).xyz));
        }
    }
    
    return float4(sum, sum, sum, 0.0f);
}

大致就是这样,具体的需要根据具体需求去更改。

下面按照惯例上图:

edge_detect
edge_detect
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 更新:【面试题含答案】http://bbs.9ria.com/thread-288394-1-1.html 高频问...
    好怕怕阅读 4,825评论 3 52
  • 特征提取是计算机视觉和图像处理中的一个概念。它指的是使用计算机提取图像信息,决定每个图像的点是否属于一个图像特征。...
    mogu酱阅读 2,114评论 1 11
  • 特征提取是计算机视觉和图像处理中的一个概念。它指的是使用计算机提取图像信息,决定每个图像的点是否属于一个图像特征。...
    ChrisJO阅读 2,466评论 1 10
  • 天才枪手》里,琳对班克说了一句特别扎心而又现实的话: 就算你不作弊,生活照样在欺骗你。 是的,也许我们当中的绝大多...
    山上青松白阅读 318评论 0 0
  • -1- 全明星探爆料称,陈思诚出轨了,还爆出了视频。 就像有些网友说的那样:这视频不算实锤,说明不了什么的。 不就...
    花落颜颜阅读 1,116评论 9 8