Qt 3D的研究(十):描边渲染(轮廓渲染)以及Silhouette Shader
Qt 3D的研究(十):描边渲染(轮廓渲染)以及Silhouette Shader
之前写了两篇文章,介绍了我在边缘检測上面的研究。实际上。使用GPU对渲染图像进行边缘检測。前提是须要进行两遍渲染。前一遍渲染的结果作为后一遍结果的输入纹理。接着在第二遍渲染的时候,对二维图像做一些图像处理,终于得出带轮廓的描边渲染效果,接着和正常渲染混合在一起。就成为渲染的终于图像。但是,这种做法,是对二维图像做的图像处理,即使像上次对提取的深度进行图像处理,也无法准确地依据深度的突变来提取我们须要的边缘。所以我们须要新的方法来提取模型的边缘。
蒋彩阳原创文章,首发地址:http://blog.csdn.net/gamesdev/article/details/44455901。欢迎同行前来探讨。
在这样的情况下,我在网上搜索到了 url=MdQtjaqp8bvHYEOM4K4VqLke2R_Uqgg3feCxNWFonYigyqOwcRQA7sR9LmyjxwiwEnTpA5a0GllnW_FAmHv3cK&wd=opengl%20%E6%8F%8F%E8%BE%B9&issp=1&f=3&ie=utf-8&tn=baiduhome_pg&oq=OpenGL&rsp=1&inputT=1055406">一篇文章
1、顶点着色阶段,计算在view视角下的顶点到视点原点向量与在顶点位置向量的法向量。
2、对顶点到视点原点向量与法向量归一化,然后进行点积,表示夹角θ的cos值
3、假设cosθ>0,那么意味着θ<90°。能够代表这个顶点所在的面(当然也有可能是面面相交的棱上的点)朝向视点。表示正面,既然是正面,就显示原顶点位置;假设cosθ<0,那么意味着90°<θ<180°。能够代表这个面是背面。于是须要将顶点沿着法线偏移一定的距离,形成silhouette(轮廓)。
4、片断着色阶段,假设是正面的话,那么显示的是正常的片元颜色,否则显示的是黑色(或者是其他暗色)。
依据这种流程,我写了一个简单的着色器:
// Silhouette.vert
#version 100 // Qt 3D默认提供的參数
attribute vec3 vertexPosition;
attribute vec3 vertexNormal;
uniform mat4 modelView;
uniform mat3 modelViewNormal;
uniform mat4 modelNormalMatrix;
uniform mat4 mvp; // 自己提供的參数
uniform vec3 lightPosition;
varying float lightIntensity; float getLightIntensity( )
{
vec3 ecPos = vec3( modelView * vec4( vertexPosition, 1.0 ) );
vec3 normal = modelViewNormal * vertexNormal;
ecPos = normalize( ecPos );
normal = normalize( normal );
return dot( -ecPos, normal );
} void main( void )
{
const float bias = 0.2;
vec3 silhouettePosition = vertexPosition + normalize( vertexNormal ) * bias;
lightIntensity = getLightIntensity( );
if ( lightIntensity > 0.0 ) gl_Position = mvp * vec4( vertexPosition, 1.0 );
else gl_Position = mvp * vec4( silhouettePosition, 1.0 );
} // Silhouette.frag
#version 110 // 自己提供的參数
varying float lightIntensity; void main( void )
{
vec4 light = vec4( 0.9, 0.7, 0.5, 1.0 );
vec4 dark = vec4( 0.0, 0.0, 0.0, 1.0 );
gl_FragColor = lightIntensity > 0.0? light: dark;
}
执行的结果例如以下:
这里须要开启深度測试,測试公式是lessOrEqual。代码例如以下:
DepthTest { func: DepthTest.LessOrEqual }
看来基本轮廓已经显示出来了,接下来要结合前段时间制作的卡通渲染效果。来一个结合。终于制作的ToonSilhouette着色器例如以下:
// ToonSilhouette.vert
#version 100 // Qt 3D默认提供的參数
attribute vec3 vertexPosition;
attribute vec3 vertexNormal;
uniform mat4 modelView;
uniform mat3 modelViewNormal;
uniform mat4 modelNormalMatrix;
uniform mat4 mvp; // 自己提供的參数
uniform vec3 lightPosition;
varying float lightIntensity; float getLightIntensity( )
{
vec3 ecPos = vec3( modelView * vec4( vertexPosition, 1.0 ) );
vec3 normal = modelViewNormal * vertexNormal;
ecPos = normalize( ecPos );
normal = normalize( normal );
return dot( -ecPos, normal );
} void main( void )
{
const float bias = 0.1;
vec3 silhouettePosition = vertexPosition + normalize( vertexNormal ) * bias;
lightIntensity = getLightIntensity( );
if ( lightIntensity > 0.0 ) gl_Position = mvp * vec4( vertexPosition, 1.0 );
else gl_Position = mvp * vec4( silhouettePosition, 1.0 );
} // ToonSilhouette.frag
#version 110 // 自己提供的參数
uniform sampler2D texPalette;
varying float lightIntensity; void main( void )
{
vec4 light = vec4( 0.9, 0.7, 0.5, 1.0 );
vec4 dark = vec4( 0.0, 0.0, 0.0, 1.0 );
vec4 toon = texture2D( texPalette, vec2( lightIntensity, 1.0 ) );
gl_FragColor = lightIntensity > 0.0? toon: dark;
}
演示程序的截图例如以下:
这样看起来饱满多了。
因为程序较长。我将全部代码放在了github中。有须要的同行朋友们能够从这个地址上clone执行之。
Qt 3D的研究(十):描边渲染(轮廓渲染)以及Silhouette Shader的更多相关文章
- 使用Qt 3D Studio 2.4显着提升性能(渲染速度提高了565%)
发布于2019年6月18日星期二11评论Qt 3D Studio 2.4显着改善性能 发表于Biz Circuit&Dev Loop,设计,图形,性能,Qt 3D Studio 除了有效使用系 ...
- Qt 3D研究(九):尝试第二边缘检测方法
Qt 3D研究(九):尝试第二边缘检测方法 三维应用程序,通过FBO.将3D图像渲染成纹理,然后对渲染成的纹理进行图像处理,终于显示在屏幕上的.是风格化后的图案.上一次我使用了一种普通的图像处理方法: ...
- 从0开发3D引擎(十二):使用领域驱动设计,从最小3D程序中提炼引擎(第三部分)
目录 上一篇博文 继续实现 实现"DirectorJsAPI.init" 实现"保存WebGL上下文"限界上下文 实现"初始化所有Shader&quo ...
- 【十天自制软渲染器】DAY 01:图形学学习建议与环境搭建
推荐直接阅读博客原文,更新更及时,阅读体验更佳 「十天自制软渲染器」这个标题我承认标题党了.在对图形学一无所知的情况下想十天自制一个软渲染器,就好似一节课没上过却试图一个晚上看完<30 天精通 ...
- Qt 3D Studio 1.0 Resleased
Qt 这家伙又整出一个新东西了,Qt 3D Studio 1.0 新闻链接:https://blog.qt.io/blog/2017/11/30/qt-3d-studio-1-0-released/ ...
- Qt 3D教程(三)实现对模型材质參数的控制
Qt 3D教程(三)实现对模型材质參数的控制 蒋彩阳原创文章,首发地址:http://blog.csdn.net/gamesdev/article/details/47131841.欢迎同行前来探讨. ...
- 基于物理渲染的渲染器Tiberius计划
既然决定实现一个光栅化软件渲染器,我又萌生了一个念头:实现一个基于物理渲染的渲染器.
- 微信小程序学习笔记二 列表渲染 + 条件渲染
1. 列表渲染 1.1 wx:for 在组件上使用wx:for控制属性绑定一个数组, 即可使用数组中各项的数据重复渲染该组件 默认数组的当前项的下标变量名默认为 index, 数组当前项的变量名默认为 ...
- Qt 2D绘图之二:抗锯齿渲染和坐标系统
一.抗锯齿渲染 1.1 逻辑绘图 图形基元的大小(宽度和高度)始终与其数学模型相对应,下图示意了忽略其渲染时使用的画笔的宽度的样子. 1.2 物理绘图(默认情况) 在默认的情况下,绘制会产生锯齿,并且 ...
随机推荐
- HTTP权威协议笔记-8.集成点:网关、隧道及中继
.8.1 网关 定义:网关类似与翻译器,它抽象出了一种能够到达资源的方法. 实用:网关可以自动将HTTP流量转换为其他协议,这样使用HTTP协议的一方就不需要了解其他协议,也可实现与其他程序或设备交互 ...
- [Apple开发者帐户帮助]五、管理标识符(1)注册应用程序ID
一个应用程序ID标识的配置设定档中的应用程序.它是一个由两部分组成的字符串,用于标识来自单个开发团队的一个或多个应用程序.有两种类型的应用程序ID:用于单个应用程序的显式应用程序ID,以及用于一组应用 ...
- Oracle 字符拼接
使用的是ORACLE中的cast函数: 官方链接: https://docs.oracle.com/cd/E11882_01/server.112/e41084/functions023.htm#SQ ...
- 浅谈自学Python之路(购物车程序练习)
购物车程序练习 今天我们来做一个购物车的程序联系,首先要理清思路 购物车程序需要用到什么知识点 需要用到哪些循环 程序编写过程中考虑值的类型,是int型还是字符串 如果值为字符串该怎么转成int型 用 ...
- centos7用rpm安装mysql5.7【初始用yum安装发现下载非常慢,就考虑本地用迅雷下载rpm方式安装】
1.下载 4个rpm包 mysql-community-client-5.7.26-1.el7.x86_64.rpmmysql-community-common-5.7.26-1.el7.x86_64 ...
- Halcon学习笔记之支持向量机(一)
例程:class_overlap_svm.hdev 说明:这个例程展示了如何用一个支持向量机来给一幅二维的图像进行分类.使用二维数据的原因是因为它可以很容易地联想成为区域和图像.本例程中使用了三个互相 ...
- 实体 和 XML格式的转换
许多接口传输需要XML格式转换,那么如何实现?看下面帮助类→_→ /// <summary> /// XML处理帮助类,编码格式GBK!! /// </summary> pub ...
- [读书笔记]-技术学习-Redis
1:Redis概览 Remote Dictionary Server 远程字典服务 Redis是基于内存的存储 在一台普通的笔记本上,Redis每秒的读取速度可以达到10万 内存读取数据,断电的时候数 ...
- Apex语言(七)集合
1.集合 集合是可以存储多个记录数的变量类型. List列表集合可以包含任何数量的数据,与数组类似. Set列表集合包含多个无序的唯一记录数,集合不能具有重复记录,与列表类似. Map地图是一个键值对 ...
- InnoDB undo log物理结构的初始化
水平有限,如果有误请指出.一直以来未对Innodb 的undo进行好好的学习,最近刚好有点时间准备学习一下,通过阿里内核月报和自己看代码的综合总结一下.本文环境: 代码版本 percona 5.7.2 ...