webgl实现物体描边效果的方法介绍


Posted in Javascript onNovember 27, 2019

前言

终于把手头的事结束了,可以有时间来研究研究技术~作为一名3D开发人员,仅仅使用现有的引擎来开发项目不免有些浮于表面,多研究研究底层的实现更利于对3D开发整体的把控~于是我决定最近开始研究webgl一些特效的实现,希望能在秋招前对底层有更深入的理解。

在webgl中实现描边的效果有很多种方式,比如我写卡通风格着色器那篇文章讲到的(将视线投影到每个点的法线上,这个值越小越说明这个点靠近边缘),所以接下来介绍实现的另一种方式:法线延展法。

这种方法不用进行法线与视线之间的计算,而是将物体每个点的x、y、z坐标沿着该点的法线扩大一定的距离并且添加描边的颜色,然后在绘制原来的物体覆盖到上面,这样便实现了描边的效果。

这里将原物体覆盖到描边物体上面就有两种实现的方式:

1.先关闭深度检测,然后绘制描边物体,开启深度检测,绘制原物体。这样由于绘制描边物体时深度检测被关闭了,原物体就会覆盖在描边物体上绘制从而实现描边效果。缺点:当两个物体重合时会出现重合位置没有描边的情况,这是由于第二次绘制的东西覆盖到了第一次描边的物体上,所以先画的边自然就会被遮挡啦~

2.不关闭深度检测,开启背面剪裁,绘制描边物体时将卷绕方向置为顺时针方向(默认是逆时针),在进行绘制,绘制完成之后将卷绕方向设置回顺时针方向。这样背面剪裁的开启使得描边物体只能绘制出它的背面,这样便实现了描边效果,而且由于没有关闭深度测试,该物体的描边效果会根据其位置决定是否遮挡。

//绘制一帧画面的方法
  function drawFrame()
  {   
   //若还没有加载完则不绘制
   if(!ooTri || !mbTri) {return;}
   
   //清除着色缓冲与深度缓冲
   gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); 
   
   //保护现场
   ms.pushMatrix();   
   //绕Y轴旋转
   ms.rotate(currentAngle,0,1,0);
//方法1
//   gl.disable(gl.DEPTH_TEST);      //启用深度缓冲写入
//   mbTri.drawSelf(ms);//绘制描边物体
//   gl.enable(gl.DEPTH_TEST);      //关闭深度缓冲写入
//   ooTri.drawSelf(ms);//绘制原物体
//方法2
   gl.enable(gl.CULL_FACE);      //开启剪裁
   gl.cullFace(gl.BACK);       //剪裁背面
   gl.frontFace(gl.CW);       //绘制顺序为顺时针
   mbTri.drawSelf(ms);//绘制描边物体
   gl.frontFace(gl.CCW);       //绘制顺序为逆时针
   ooTri.drawSelf(ms);//绘制原物体


   //恢复现场
   ms.popMatrix();
   
   //修改旋转角度
   currentAngle += incAngle;
   if (currentAngle > 360)
   {
    currentAngle -= 360; 
   }   
  } 
  其着色器代码如下:
uniform mat4 uMVPMatrix;       //总变换矩阵
attribute vec3 aPosition;         //顶点位置
attribute vec3 aNormal;         //顶点法向量
void main(){
 vec3 position=aPosition;      //获取此顶点位置
 position.xyz+=aNormal*0.4;    //将顶点位置沿法线方向挤出
 gl_Position = uMVPMatrix * vec4(position.xyz,1);//根据总变换矩阵计算此次绘制此顶点位置
}
<#BREAK_BN#>
precision mediump float;        //设置浮点默认精度

void main(){
 gl_FragColor = vec4(0.0,1.0,0.0,0.0);     //给此片元颜色值
}

其实这两种描边方法还是有着一些区别(第二种对于复杂物体会产生类似包裹的效果)具体效果还得根据具体的场景来决定。

PS:这里还要注意一点,WebGL是个状态机。我们可以这么理解,假设WebGL中的属性P的值为1,你在某一次操作中,把P的值设置成了2,那么在你下一次设置P的值之前,P的值永远是2。这一点很重要!

Github地址:https://github.com/StringKun/WebGL-object-of-stroke

webgl实现物体描边效果的方法介绍

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对三水点靠木的支持。

Javascript 相关文章推荐
通过JS 获取Mouse Position(鼠标坐标)的代码
Sep 21 Javascript
基于node.js的快速开发透明代理
Dec 25 Javascript
js弹窗返回值详解(window.open方式)
Jan 11 Javascript
node.js下when.js 的异步编程实践
Dec 03 Javascript
JavaScript版的TwoQueues缓存模型
Dec 29 Javascript
JavaScript中的值类型详细介绍
Dec 29 Javascript
举例讲解JavaScript中关于对象操作的相关知识
Nov 16 Javascript
jQuery实现弹窗下底部页面禁止滑动效果
Dec 19 jQuery
vue.js vue-router如何实现无效路由(404)的友好提示
Dec 20 Javascript
TypeScript高级用法的知识点汇总
Dec 17 Javascript
优化Vue中date format的性能详解
Jan 13 Javascript
原生javascript运动函数的封装示例【匀速、抛物线、多属性的运动等】
Feb 23 Javascript
three.js利用卷积法如何实现物体描边效果
Nov 27 #Javascript
Angular8引入百度Echarts进行图表分析的实现代码
Nov 27 #Javascript
vue实现浏览器全屏展示功能
Nov 27 #Javascript
js中apply和call的理解与使用方法
Nov 27 #Javascript
vue-cli在 history模式下的配置详解
Nov 26 #Javascript
js实现淘宝首页的banner栏效果
Nov 26 #Javascript
JS实现排行榜文字向上滚动轮播效果
Nov 26 #Javascript
You might like
如何开发一个虚拟域名系统
2006/10/09 PHP
php 人员权限管理(RBAC)实例(推荐)
2017/05/24 PHP
[原创]站长必须要知道的javascript广告代码
2007/05/30 Javascript
jquery 插件之仿“卓越亚马逊”首页弹出菜单效果
2008/12/25 Javascript
Javascript this指针
2009/07/30 Javascript
Jquery实战_读书笔记1—选择jQuery
2010/01/22 Javascript
jQuery1.4.2与老版本json格式兼容的解决方法
2011/02/12 Javascript
js面向对象之静态方法和静态属性实例分析
2015/01/10 Javascript
js实现div层缓慢收缩与展开的方法
2015/05/11 Javascript
js实现改进的仿蓝色论坛导航菜单效果代码
2015/09/06 Javascript
JavaScript实现cookie的写入、读取、删除功能
2015/11/05 Javascript
js实现select二级联动下拉菜单
2020/04/17 Javascript
javascript Promise简单学习使用方法小结
2016/05/17 Javascript
Ionic+AngularJS实现登录和注册带验证功能
2017/02/09 Javascript
jQuery取得元素标签名称小结(附代码)
2017/08/16 jQuery
JavaScript学习笔记之惰性函数示例详解
2017/08/27 Javascript
jQuery实现鼠标滑过商品小图片上显示对应大图片功能【测试可用】
2018/04/27 jQuery
Vue的watch和computed方法的使用及区别介绍
2018/09/06 Javascript
jQuery实现合并表格单元格中相同行操作示例
2019/01/28 jQuery
vuex存储token示例
2019/11/11 Javascript
[32:30]夜魇凡尔赛茶话会 第一期01:谁是卧底
2021/03/11 DOTA
Python的网络编程库Gevent的安装及使用技巧
2016/06/24 Python
Python中的字符串查找操作方法总结
2016/06/27 Python
详解利用django中间件django.middleware.csrf.CsrfViewMiddleware防止csrf攻击
2018/10/09 Python
Pycharm配置autopep8实现流程解析
2020/11/28 Python
CSS伪类与CSS伪元素的区别及由来具体说明
2012/12/07 HTML / CSS
CSS3哪些新特性值得称赞
2016/03/02 HTML / CSS
挪威太阳镜和眼镜网上商城:SmartBuyGlasses挪威
2016/08/20 全球购物
马德里著名的运动鞋商店:NOIRFONCE
2019/04/12 全球购物
如何让Java程序执行效率更高
2014/06/25 面试题
大学军训感言300字
2014/03/09 职场文书
坚定理想信念心得体会
2014/03/11 职场文书
党员群众路线对照检查材料
2014/08/31 职场文书
python开发的自动化运维工具ansible详解
2021/08/07 Python
电频谱管理的原则是什么
2022/02/18 无线电
spring 项目实现限流方法示例
2022/07/15 Java/Android