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的更多相关文章

  1. 使用Qt 3D Studio 2.4显着提升性能(渲染速度提高了565%)

    发布于2019年6月18日星期二11评论Qt 3D Studio 2.4显着改善性能 发表于Biz Circuit&Dev Loop,设计,图形,性能,Qt 3D Studio 除了有效使用系 ...

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

    Qt 3D研究(九):尝试第二边缘检测方法 三维应用程序,通过FBO.将3D图像渲染成纹理,然后对渲染成的纹理进行图像处理,终于显示在屏幕上的.是风格化后的图案.上一次我使用了一种普通的图像处理方法: ...

  3. 从0开发3D引擎(十二):使用领域驱动设计,从最小3D程序中提炼引擎(第三部分)

    目录 上一篇博文 继续实现 实现"DirectorJsAPI.init" 实现"保存WebGL上下文"限界上下文 实现"初始化所有Shader&quo ...

  4. 【十天自制软渲染器】DAY 01:图形学学习建议与环境搭建

    推荐直接阅读博客原文,更新更及时,阅读体验更佳 「十天自制软渲染器」这个标题我承认标题党了.在对图形学一无所知的情况下想十天自制一个软渲染器,就好似一节课没上过却试图一个晚上看完<30 天精通 ...

  5. 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/ ...

  6. Qt 3D教程(三)实现对模型材质參数的控制

    Qt 3D教程(三)实现对模型材质參数的控制 蒋彩阳原创文章,首发地址:http://blog.csdn.net/gamesdev/article/details/47131841.欢迎同行前来探讨. ...

  7. 基于物理渲染的渲染器Tiberius计划

    既然决定实现一个光栅化软件渲染器,我又萌生了一个念头:实现一个基于物理渲染的渲染器.

  8. 微信小程序学习笔记二 列表渲染 + 条件渲染

    1. 列表渲染 1.1 wx:for 在组件上使用wx:for控制属性绑定一个数组, 即可使用数组中各项的数据重复渲染该组件 默认数组的当前项的下标变量名默认为 index, 数组当前项的变量名默认为 ...

  9. Qt 2D绘图之二:抗锯齿渲染和坐标系统

    一.抗锯齿渲染 1.1 逻辑绘图 图形基元的大小(宽度和高度)始终与其数学模型相对应,下图示意了忽略其渲染时使用的画笔的宽度的样子. 1.2 物理绘图(默认情况) 在默认的情况下,绘制会产生锯齿,并且 ...

随机推荐

  1. E20170907-ts

    flash  vt. 使闪光,使闪烁; 拍出,发出(电报等); 〈口〉炫耀;          adj. 闪光的,闪耀的,一闪而过的; 浮华的; 庞大的;           n. 闪光; 闪光灯下摄 ...

  2. Python 42 mysql用户管理 、pymysql模块

    一:mysql用户管理 什么是mysql用户管理 mysql是一个tcp服务器,应用于操作服务器上的文件数据,接收用户端发送的指令,接收指令时需要考虑到安全问题, ATM购物车中的用户认证和mysql ...

  3. JS代码放在哪里比较好!

    在页面上加上<script></script>只有2个地方:head中,body体中 如果外部的JS文件,在head中加,写页面特效js放在body后面. <html&g ...

  4. PHP中的魔术方法和魔术常量

    看上去好像挺烦人,但只要通过例子测试一下,就明白了.不做测试,只是看,第二天还是不明白.当然我在抄其他人的日志,然后希望能是自己的理解就好,原文地址PHP的魔术方法和魔术敞亮简介和使用--LaraBo ...

  5. android指纹识别、拼图游戏、仿MIUI长截屏、bilibili最美创意等源码

    Android精选源码 一个动画效果的播放控件,播放,暂停,停止之间的动画 用 RxJava 实现 Android 指纹识别代码 Android仿滴滴打车(滴滴UI)源码 Android高仿哔哩哔哩动 ...

  6. Leetcode0005--Longest Palindromic Substring 最长回文串

    [转载请注明]http://www.cnblogs.com/igoslly/p/8726771.html 来看一下题目: Given a string s, find the longest pali ...

  7. python特性小记(一)

    一.关于构造函数和析构函数 1.python中有构造函数和析构函数,和其他语言是一样的.如果子类需要用到父类的构造函数,则需要在子类的构造函数中显式的调用,且如果子类有自己的构造函数,必然不会自动调用 ...

  8. 我的web前端自学之路-心得篇:我为什么要学习web前端?

    时光如流水,转眼间,自己已经是大三的学长了,看着一个个学弟学妹,心中有种莫名的感觉,很怀念大学的前两年时光,但也很憧憬着自己的未来,自己将要去经历很多从未经历的事.我是我们学校信科院的一名学生,在编程 ...

  9. 【sqli-labs】 less25 GET- Error based -All you OR&AND belong to us -string single quote(GET型基于错误的去除了or和and的单引号注入)

    加单引号 order by一下 http://localhost/sqli-labs-master/Less-25/?id=1' order by 1%23 order by 变成了der by 下面 ...

  10. 【sqli-labs】 less13 POST - Double Injection - Single quotes- String -twist (POST型单引号变形双注入)

    报错 闭合掉括号 这关登录成功之后不显示登录的用户名密码了