注:文章译自http://wgld.org/,原作者杉本雅広(doxas),文章中假设有我的额外说明,我会加上[lufy:],另外,鄙人webgl研究还不够深入,一些专业词语,假设翻译有误,欢迎大家指正。

本次的demo的执行结果

着色方法

上次介绍了反射光,反射光是实现光泽的必不可少的概念,到此为止,主要的光照效果都已经封装完成了。
光照的效果主要就是扩散光,环境光和反射光三种方法,灵活运用这三种光照,应该就能实现非常逼真的照明效果了。
前几篇一直在说光照,这次略微换个视点,看一下着色,着色是一个比較大的话题,这次讲一下高氏着色和补色着色。

高氏着色(gouraud shading)

高氏着色从名字上看,是比較难明确详细是什么样的着色的,这个高氏(gouraud)事实上是以研究该着色的Henri Gouraud来命名的。

lufy:高氏着色又叫高洛德着色或高氏渲染(Gouraud Shading):这是一种光影渲染技术也是眼下较为流行的着色方法,它可对3D模型各顶点的颜色进行平滑、融合处理,将每一个多边形上的每一个点赋以一组色调值,同一时候将多边形着上较为顺滑的渐变色,使其外观具有更强烈的实时感和立体动感,只是其着色速度比平面着色慢得多可是效果要好得多。

高氏着色能够对多边形的顶点之间的颜色进行补间,高氏着色的计算负荷并非太高,可是,能够实现非常美丽的渲染,所以常常被使用。

对顶点间的颜色进行补间是什么意思呢?

简单的说,用高氏着色计算得到的终于的颜色情报,适用于所有顶点,而且对顶点和顶点之间的颜色进行补间处理,最后渲染模型。

使用高氏着色,想用少量的顶点渲染美丽的光照是非常难的。比方说,一个最简单的三角形多边形,三维空间中仅仅有这一个三角形,这个面就直接和光碰撞了。

放射性光源的时候(比方说灯泡),应该是三角形的中心就最亮,而顶点的部分要略微暗一些,可是高氏着色仅仅是在顶点之间进行颜色补间,所以无法凸显三角形中间的亮点。
另外,由于是依据每一个顶点进行颜色补间,颜色变化的时候会出现锯齿。这个锯齿随着顶点数的增多而逐渐消失,可是这么做的话,高氏着色计算负荷小的优势就没有了,所以这是个难处理的地方。

细心的朋友可能会发现,这个站点中所有的demo,都是用的高氏着色。顶点着色器的光的强度和颜色的进行计算,然后仅仅是将终于算出的颜色传给了片段着色器,这样的依据每一个顶点来计算颜色的方法就是高氏着色。
以下是证据,眼下为止的demo中的颜色之间会存在锯齿,会有一些不太自然的镜面反射。


扩大之后看的话就比較清楚了吧,顶点数越少,这样的现象就越明显。

补色着色(phong shading)

理解了高氏着色之后,接着看补色着色。
像刚才说的那样,相对高氏着色是对顶点之间的颜色进行补间处理,补色着色是对各个像素进行颜色的补间处理。也就是说,计算量会比高氏着色增大非常多,可是能够将渲染出颜色的细节。
补色着色的名字跟高氏着色一样,都是以人名(Bui Tuong Phong)来命名的。使用补色着色的话,会克服高氏着色的弱点,即使顶点数少的时候也能得到非常自然的效果。

由于补色着色是在像素之间对颜色进行补间,所以不会发生不自然的锯齿。以下是和高氏着色的渲染效果做比較。

全然是同样的顶点数,同样的光源渲染出的补色着色和高氏着色。左边是补色着色,不管阴影还是高亮的部分,都非常的美丽和自然。

补色着色的封装

知道了高氏着色和补色着色两者之间的不同,那么就来看看补色着色的封装吧。补色着色就是刚才说的那样,在像素之间进行颜色的补间处理,那么眼下为止的在顶点着色器中进行的光照处理,所有要交给片段着色器。
详细的说,追加一个处理,顶点着色器中的顶点的法线情报用varying变量传给片段着色器,然后其它的光照处理所有移到片段着色器中。
首先看顶点着色器的代码。

>顶点着色器的代码

attribute vec3 position;
attribute vec3 normal;
attribute vec4 color;
uniform mat4 mvpMatrix;
varying vec3 vNormal;
varying vec4 vColor; void main(void){
vNormal = normal;
vColor = color;
gl_Position = mvpMatrix * vec4(position, 1.0);
}

和眼下为止的代码不同,新定义了一个叫做vNormal的varying变量,用来将法线情报传给片段着色器。顶点的颜色情报和坐标变换矩阵等地方不用变。
接着是片段着色器。

>片段着色器代码

precision mediump float;

uniform mat4 invMatrix;
uniform vec3 lightDirection;
uniform vec3 eyeDirection;
uniform vec4 ambientColor;
varying vec3 vNormal;
varying vec4 vColor; void main(void){
vec3 invLight = normalize(invMatrix * vec4(lightDirection, 0.0)).xyz;
vec3 invEye = normalize(invMatrix * vec4(eyeDirection, 0.0)).xyz;
vec3 halfLE = normalize(invLight + invEye);
float diffuse = clamp(dot(vNormal, invLight), 0.0, 1.0);
float specular = pow(clamp(dot(vNormal, halfLE), 0.0, 1.0), 50.0);
vec4 destColor = vColor * vec4(vec3(diffuse), 1.0) + vec4(vec3(specular), 1.0) + ambientColor;
gl_FragColor = destColor;
}

逆矩阵,光向量,视线向量等一直以来都在顶点着色器中使用的数据,全都移动到片段着色器中来了。另外,利用刚才在顶点着色器中定义的varying变量vNormal进行了计算。计算的方法和曾经一样,没有不论什么改变。就是说,仅仅是把顶点着色器中的处理,放到了片段着色器中而已。
这次的变化,并没有加入新的uniform变量,也就是说,javascript部分基本上不用变。
简单的来说,高氏着色和补色着色的主要差别就在于,依据顶点处理还是依据像素处理,尽管这么说跟定义相比有些奇怪,可是这么理解的话也没什么错。

总结

这一次分别说了高氏着色和补色着色两种着色,高氏着色的长处是计算量比較低,而和补色着色相比的话,渲染效果不太自然。
补色着色正好相反,计算量非常高,可是渲染效果非常完美。
究竟选择那种方法,取决于模型的顶点数和须要的渲染效果,以及执行环境能够承受的计算负荷。
实际应用中,依据利用的场景和描画的模型,分别使用不同的方法是非常重要的。
这次也准备了demo,急着看执行效果的人能够点击文章最后的链接来測试。

另外,补充一点,这次的demo中对圆环体的生成函数做了几处改动,返回值是以对象的形势返回的,能够指定圆环体的颜色了。事实上,也并没有做什么其它特别的处理。

下次,介绍一下电光源。

用补色着色来渲染的圆环体

http://wgld.org/s/sample_012/

转载请注明:转自lufy_legend的博客http://blog.csdn.net/lufy_legend

[WebGL入门]二十四,补色着色的更多相关文章

  1. [WebGL入门]二十五,点光源的光照

    注:文章译自http://wgld.org/,原作者杉本雅広(doxas),文章中假设有我的额外说明.我会加上[lufy:].另外,鄙人webgl研究还不够深入,一些专业词语.假设翻译有误,欢迎大家指 ...

  2. Bootstrap入门(二十四)data属性

    Bootstrap入门(二十四)data属性 你可以仅仅通过 data 属性 API 就能使用所有的 Bootstrap 插件,无需写一行 JavaScript 代码.这是 Bootstrap 中的一 ...

  3. JAVA之旅(二十四)——I/O流,字符流,FileWriter,IOException,文件续写,FileReader,小练习

    JAVA之旅(二十四)--I/O流,字符流,FileWriter,IOException,文件续写,FileReader,小练习 JAVA之旅林林总总也是写了二十多篇了,我们今天终于是接触到了I/O了 ...

  4. FreeSql (二十四)Linq To Sql 语法使用介绍

    原本不支持 IQueryable 主要出于使用习惯的考虑,如果继承 IQueryable,编写代码的智能总会提示出现一堆你不想使用的方法(对不起,我有强迫症),IQueryable 自身提供了一堆没法 ...

  5. RabbitMQ入门教程(十四):RabbitMQ单机集群搭建

    原文:RabbitMQ入门教程(十四):RabbitMQ单机集群搭建 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://b ...

  6. Bootstrap<基础二十四> 缩略图

    Bootstrap 缩略图.大多数站点都需要在网格中布局图像.视频.文本等.Bootstrap 通过缩略图为此提供了一种简便的方式.使用 Bootstrap 创建缩略图的步骤如下: 在图像周围添加带有 ...

  7. 无废话ExtJs 入门教程十四[文本编辑器:Editor]

    无废话ExtJs 入门教程十四[文本编辑器:Editor] extjs技术交流,欢迎加群(201926085) ExtJs自带的编辑器没有图片上传的功能,大部分时候能够满足我们的需要. 但有时候这个功 ...

  8. 二十四、Struts2中的UI标签

    二十四.Struts2中的UI标签 Struts2中UI标签的优势: 数据回显 页面布局和排版(Freemark),struts2提供了一些常用的排版(主题:xhtml默认 simple ajax) ...

  9. WCF技术剖析之二十四: ServiceDebugBehavior服务行为是如何实现异常的传播的?

    原文:WCF技术剖析之二十四: ServiceDebugBehavior服务行为是如何实现异常的传播的? 服务端只有抛出FaultException异常才能被正常地序列化成Fault消息,并实现向客户 ...

随机推荐

  1. 深入应用看本质之-ICMP(1)

    在网络层的学习时我们easy忽略IP的一个字段--存活时间 以下是百度上的解释 (8)生存时间 占8位,生存时间字段经常使用的的英文缩写是TTL(Time To Live),表明是数据报在网络中的寿命 ...

  2. 以JTextPanel为例Swing的鼠标事件详解

    如下界面可以通过该界面研究一下Swing的鼠标事件: 图中用红粗线圈起来的为JtextPanel,该Panel添加了鼠标事件监听器,鼠标事件监听器有三种,分别为MouseWheelListener,M ...

  3. 【图像处理】Bilinear Image Scaling

    Bilinear image scaling is about the same as nearest neighbor image scaling except with interpolation ...

  4. 数据结构——bitmap

    近期在看<编程珠玑>这本书. 第1章中引入了bitmap(位图)的数据结构. 曾经没有接触过, 抽出时间研究了一下,记录下来. 书中描写叙述的情景: 1. 最多1000万个7位数电话号码( ...

  5. ipv6加英文的中括号访问

    加英文的中括号就可以,如[2001:4998:c:e33::1004],我发现这是yahoo首页.但并不是所有IPv6网站都可以通过IPv6地址访问,跟IPv4一样,网站服务器端可以只绑定域名,不接受 ...

  6. cocos2d-js-v3.0-rc0 下 pomelo-cocos2d-jsb native web 配置

    一.基本步骤 注意:pomelo-cocos2d-jsb 没实用 https://github.com/NetEase/pomelo-cocos2d-jsb,原因这个不是最新版,另外,componen ...

  7. Windows下visual studio code搭建golang开发环境

    Windows下visual studio code搭建golang开发环境 序幕 其实环境搭建没什么难的,但是遇到一些问题,主要是有些网站资源访问不了(如:golang.org),导致一些包无法安装 ...

  8. c# Unicode字符串的解码

    前两天工作中遇到个奇怪的问题,一个unicode字符串(即“\uXXXX”形式)变量,调用HttpUtility.UrlDecode解码过后,还是原样,要么就是乱码状态.无奈之下只能自己写一个解码函数 ...

  9. 搭建php环境时解决jpeg6 make: ./libtool:命令未找到

    搭建php环境时解决jpeg6 make: ./libtool:命令未找到 [root@bogon jpeg-6b]# make; make install ./libtool --mode=comp ...

  10. 使用Nexus搭建企业maven仓库(二)

    先阅读<使用Nexus搭建企业maven仓库(一)> http://blog.csdn.net/ouyida3/article/details/40747545 1.官网眼下最新的版本号是 ...