Qt3D的研究(九):尝试另外一种边缘检测方法
三维应用程序,通过FBO,将3D图像渲染成纹理,然后对渲染成的纹理进行图像处理,最终显示在屏幕上的,是风格化后的图案。上一次我使用了一种普通的图像处理方法:索贝尔边缘检测法,与我们的卡通渲染结合起来,实现了这样的效果,接着,我将采用另外一种边缘检测方法——普雷维特(Prewitt)边缘检测方法来重新渲染图案。
蒋彩阳原创文章,首发地址:。欢迎同行前来探讨。
首先让我们看看上一次的截图:

我们看到,本不应该是边缘的机身部分,由于离散的调色,被索贝尔算子边缘检测一算,也被误认为是边缘了,同时,在背景与机身颜色不明显的部分,也由于采用不适当的阈值,不被认为是边缘。所以我想有没有一种方法能够解决这个问题呢?于是我采取了这样的方法:
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://github.com/jiangcaiyang/Test-Qt-3D-8
相关热词:
本站内容来源于网络,如有侵权请与我们联系,我们会及时删除,我们深感抱歉!
注:本站所有信息仅供用于网络技术学习参考,学习中请遵循相关法律法规!
本文地址: https://www.juheyunku.com/jiaob/qt/9404.shtml
相关文章
热门TAG
命令 外链 企业网站 白帽 php 织梦教程 dedecms修改内容 javascript 织梦 功能 标签 调用 详解 技巧 权重 服务器 网站流量 Dedecms 织梦cms HTML tags标签 python jquery教程 jquery windows 蜘蛛 搜索引擎 网站收录 JSP 实例解析最新文章
-
Qt之QCustomPlot绘图(一)配
时间:2020-12-27
-
QStandardItemModel角色控制及
时间:2020-12-27
-
物联网MQTT协议分析和开源
时间:2020-12-27
-
PyQt5学习笔记14 初识pyqt多
时间:2020-12-26
-
创建一个QtQuickUI项目
时间:2020-12-26
-
Qt3D的研究(九):尝试另
时间:2020-12-26
-
Qt3D的研究(二)
时间:2020-12-26
-
Qt UserInfo
时间:2020-12-26
热门文章
-
Qt UserInfo
时间:2020-12-26
-
PyQt5学习笔记14 初识pyqt多线程操作
时间:2020-12-26
-
PyQt5应用与实践
时间:2020-12-26
-
物联网MQTT协议分析和开源Mosquitto部署验证
时间:2020-12-27
-
Qt3D的研究(九):尝试另外一种边缘检测
时间:2020-12-26
-
创建一个QtQuickUI项目
时间:2020-12-26
-
Qt3D的研究(二)
时间:2020-12-26
-
QStandardItemModel角色控制及QTreeView添加不同
时间:2020-12-27
-
Qt之酒店管理系统
时间:2020-12-26
-
Qt之QCustomPlot绘图(一)配置和第一个例子
时间:2020-12-27
