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 物理绘图(默认情况) 在默认的情况下,绘制会产生锯齿,并且 ...
随机推荐
- js实用篇之数组、字符串常用方法
常常在开发中,会使用到很多js数组和字符串的处理方法,这里列举一些我常用到的一些,方便大家参考使用. 数组方面 push:向数组尾部增加内容,返回的是新数组的长度. var arr = [1,2,3] ...
- python3+request接口自动化框架中自动发送邮件
在上一篇中的自动化框架中没有放上自动发送测试结果到邮箱的功能,在这篇文章中在补一下,哈哈 1.上一篇的代码就不在一一介绍了,本篇只介绍发送邮件的功能代码 2.在public common 文件夹中创建 ...
- EF6 自定义迁移表名
在下列代码片段中已经EF6迁移表的表名更改为 MigrationHistory注意:下代码片段建议和DbContext同程序集 public class ModelConfiguration : Db ...
- springBoot jar/war打包部署问题
先给pom.xml配置导出插件 <!--配置插件将Maven 插件 导出成为jar --> <plugin> <groupId>org.springframewor ...
- JDBC: 批量处理提高SQL处理速度
引用:忘了 当需要成批插入或者更新记录时.可以采用Java的批量更新机制,这一机制允许多条语句一次性提交给数据库批量处理.通常情况下比单独提交处理更有效率 JDBC的批量处理语句包括下面两个方法: a ...
- PHP执行Mysql数据库的备份和还原
使用mysqldump命令备份 mysqldump命令将数据库中的数据备份成一个文本文件.表的结构和表中的数据将存储在生成的文本文件中. mysqldump命令的工作原理很简单.它先查出需要备份的表的 ...
- OpenCV中IplImage/CvMat/Mat转化关系
原文链接:http://www.cnblogs.com/summerRQ/articles/2406109.html 如对内容和版权有何疑问,请拜访原作者或者通知本人. opencv中常见的与图像操作 ...
- JSP_内置对象_session
session表示客户端与服务器的一次会话. Web中的session指的是用户在浏览某个网站时,从进入网站到浏览器关闭所经过的这段时间,也就是用户浏览这个网站所花费的时间. 从上述定义中可以看到,s ...
- 编程领域中的 "transparent" 和 "opaque"
引言 在学习计算机的过程中,经常会接触到 “透明” 和 “非透明” 的概念. 刚开始理解 “透明” 这个概念的时候,认为 “透明” 就是程序员可以看见其中的构造,但是老师却说透明是程序员意识不到其中的 ...
- myeclipse中代码不显示SVN版本号
打开 : windows ->preferences->General->Appearance->Lable Decoration s 勾选其中的 SVN 项即可. 如果以上方 ...