注:文章译自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. MySQL分区技术 (一)

    4:MySQL 分区技术(是mysql 5.1以版本号后開始用->是甲骨文mysql技术团队维护人员以插件形式插入到mysql里面的技术) 眼下,针对海量数据的优化主要有2中方法: 1:大表拆成 ...

  2. 2013 吉林通化邀请赛 Play Game 记忆化搜索

    dp[ba][ta][bb][tb]表示a堆牌从下面拿了ba张,从上面拿了ta张.b堆牌从下面拿了bb张,从上面拿了tb张.当前玩家能得到的最大的分数. 扩展方式有4种,ba+1,ta+1,bb+1, ...

  3. hdu1896之优先队列应用

    Stones Time Limit: 5000/3000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others) Total Sub ...

  4. android视频库Vitamio

    之前尝试自己解码视频,然后播放显示,虽然音视频都可以播放,但是实现不了音视频的同步,所以使用第三方的视频库Vitamio来实现视频播放器功能,这样自己只需要实现播放解码的制作不不要关心底层解码和显示问 ...

  5. [LeetCode]Pascal&#39;s Triangle II

    题目:给定一个行索引index,返回帕斯卡三角形第index层的三角形 算法:生成index层帕斯卡三角形,并返回第index层三角形 public class Solution { public L ...

  6. ZOJ 3635 Cinema in Akiba(线段树)

    Cinema in Akiba (CIA) is a small but very popular cinema in Akihabara. Every night the cinema is ful ...

  7. jQuery Mobile 是创建移动 web 应用程序的框架。

    jQuery Mobile jQuery Mobile 是创建移动 web 应用程序的框架. jQuery Mobile 适用于所有流行的智能手机和平板电脑. jQuery Mobile 使用 HTM ...

  8. 10、ERP设计之系统基础管理(BS)- 平台化设计

    ShareERP 2013-09-03 ERP业务平台化是每个软件提供商必须要进行的趋势,传统定制化路线已死,不能走定制化的老路了.以往最大问的题是不能累积和沉淀技术及提升项目业务管理能力,其次是管理 ...

  9. POJ 3458 Colour Sequence(简单题)

    [题意简述]:事实上题意我也没有特别看懂.可是依据它少许的题目描写叙述加上给的例子.就大胆的做了例如以下的推測: 就是说,如今给出一串字符s.然后紧接着给出可见的字符串visible还有隐藏的字符串h ...

  10. ubuntu linux 13.04更新

    首先备份源列表: sudo cp /etc/apt/sources.list /etc/apt/sources.list_backup 而后用gedit或其他编辑器打开: gksu gedit /et ...