博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Qt 3D研究(九):尝试第二边缘检测方法
阅读量:4963 次
发布时间:2019-06-12

本文共 3440 字,大约阅读时间需要 11 分钟。

Qt 3D研究(九):尝试第二边缘检测方法

       三维应用程序,通过FBO。将3D图像渲染成纹理,然后对渲染成的纹理进行图像处理,终于显示在屏幕上的。是风格化后的图案。上一次我使用了一种普通的图像处理方法:,与我们的卡通渲染结合起来,实现了这种效果。接着。我将採用第二种边缘检測方法——普雷维特(Prewitt)边缘检測方法来又一次渲染图案。

蒋彩阳原创文章。首发地址:http://blog.csdn.net/gamesdev/article/details/44405219。

欢迎同行前来探讨。

       首先让我们看看上一次的截图:

       我们看到,本不应该是边缘的机身部分。因为离散的调色,被索贝尔算子边缘检測一算,也被误觉得是边缘了,同一时候,在背景与机身颜色不明显的部分,也因为採用不适当的阈值,不被觉得是边缘。

所以我想有没有一种方法可以解决问题呢?于是我採取了这个方案:

1、 第一遍的render pass,取的不是的颜色图,而是深度图。

2、 将深度图渲染至纹理;

3、 对该纹理进行边缘检測;

4、 与卡通着色的图进行叠加,做成效果图。

怎样在GLSL中将片元的深度信息提取出来?这里我參考了,然后写出了这种GLSL代码:

// Depth.vert#version 100// Qt 3D默认提供的參数attribute vec3 vertexPosition;uniform mat4 modelView;uniform mat4 mvp;void main( void ){    gl_Position = mvp * vec4( vertexPosition, 1.0 );}// Depth.frag#version 110// 自己提供的參数bool inBetween( float v, float min, float max ){    return v > min && v < max;}void main( void ){    float exp = 256.0;    gl_FragColor = vec4( vec3( pow( gl_FragCoord.z, exp ) ), 1.0);}

       由于gl_FragCoord.z表示的片元深度信息相互之间很接近。我们须要一个指数乘幂操作将这种差别放大,这样才干区分不同的深度的值。

       紧接着,我们将Prewitt算子替换掉Sobel算子,终于的着色器代码例如以下:

// Ouput.vert#version 100// Qt 3D默认提供的參数attribute vec4 vertexPosition;uniform mat4 modelMatrix;// 自己提供的參数void main( void ){    gl_Position = modelMatrix * vertexPosition;}// Output.frag#version 100// 自己提供的參数uniform sampler2D colorAttachTex;//uniform sampler2D depthAttachTex;uniform vec2 texSize;uniform float texOffsetX;uniform float texOffsetY;float gray( vec4 color ){    return dot( color.xyz, vec3( 0.299, 0.587, 0.114 ) );}void main( void ){    vec4 texColor[9];    texColor[0] = texture2D( colorAttachTex, gl_FragCoord.xy / texSize + vec2( -texOffsetX, texOffsetY ) );    texColor[1] = texture2D( colorAttachTex, gl_FragCoord.xy / texSize + vec2( 0.0, -texOffsetY ) );    texColor[2] = texture2D( colorAttachTex, gl_FragCoord.xy / texSize + vec2( texOffsetX, texOffsetY ) );    texColor[3] = texture2D( colorAttachTex, gl_FragCoord.xy / texSize + vec2( -texOffsetX, 0 ) );    texColor[4] = texture2D( colorAttachTex, gl_FragCoord.xy / texSize + vec2( 0.0, 0.0 ) );    texColor[5] = texture2D( colorAttachTex, gl_FragCoord.xy / texSize + vec2( texOffsetX, 0 ) );    texColor[6] = texture2D( colorAttachTex, gl_FragCoord.xy / texSize + vec2( -texOffsetX, -texOffsetY ) );    texColor[7] = texture2D( colorAttachTex, gl_FragCoord.xy / texSize + vec2( 0.0, -texOffsetY ) );    texColor[8] = texture2D( colorAttachTex, gl_FragCoord.xy / texSize + vec2( texOffsetX, -texOffsetY ) );    // 普雷维特算子    float prewitt_x[9];    prewitt_x[0] = -1.0;    prewitt_x[1] = 0.0;    prewitt_x[2] = 1.0;    prewitt_x[3] = -1.0;    prewitt_x[4] = 0.0;    prewitt_x[5] = 1.0;    prewitt_x[6] = -1.0;    prewitt_x[7] = 0.0;    prewitt_x[8] = 1.0;    float prewitt_y[9];    prewitt_y[0] = 1.0;    prewitt_y[1] = 1.0;    prewitt_y[2] = 1.0;    prewitt_y[3] = 0.0;    prewitt_y[4] = 0.0;    prewitt_y[5] = 0.0;    prewitt_y[6] = -1.0;    prewitt_y[7] = -1.0;    prewitt_y[8] = -1.0;    // 卷积操作    vec4 edgeX = vec4( 0.0 );    vec4 edgeY = vec4( 0.0 );    for ( int i = 0; i < 9; ++i )    {        edgeX += texColor[i] * prewitt_x[i];        edgeY += texColor[i] * prewitt_y[i];    }    vec4 edgeColor = sqrt( ( edgeX * edgeX ) + ( edgeY * edgeY ) );    float edgeIntensity = gray( edgeColor );    const float threshold = 0.05;    if ( edgeIntensity > threshold )        gl_FragColor = vec4( 0.0, 0.0, 0.0, 1.0 );    else discard;}

       因为代码相对较长,我必须把来github在。

有需要的同行和朋友,从能github有资格代替代码。

地址:

转载于:https://www.cnblogs.com/zfyouxi/p/5031713.html

你可能感兴趣的文章
Sublime Text 3中文乱码解决方法以及安装包管理器方法
查看>>
python之md5模块
查看>>
对xml文件封装思想的处理
查看>>
DIV垂直/水平居中2(DIV宽度和高度是动态的)
查看>>
身份证号码升级
查看>>
js当前日期
查看>>
摩拜数据产品
查看>>
RFS+AutoItLibrary测试Web对话框
查看>>
python webdriver API学习笔记
查看>>
<编写有效用例>读书笔记3
查看>>
堆排序(C++实现)
查看>>
62. Unique Paths (JAVA)
查看>>
HTTP协议工作原理
查看>>
JSP
查看>>
SpringBoot自动配置原理
查看>>
window.location用法
查看>>
利用SSH传输文件
查看>>
设计模式_Java_工厂方法模式的概述和使用
查看>>
3Sum
查看>>
sql between and
查看>>