WebGL入门教程 - 高光计算模型
现实物体在光源的照射下,会出现吸收和反射。物体的颜色主要由漫反射决定,但局部高光效果则主要由镜面反射来决定。
从表面反射出的光线与入射角成相等但相反的角度,称为“镜面反射”。
如果镜面反射光线直接进入相机,就好像相机直接看到光源一样,即使它已经从物体上反弹出来。相机看到的是光源的光,而不是物体的颜色。如果你有一个白色光源,镜面反射将是白色的。如果您有一个红色光源,镜面反射将是红色的。因此,要对镜面反射进行建模,需要在照明模型中指定光源的颜色。
通常相机位置和反射光之间存在一个角度,如果角度很大,我们将看不到反射光,如果角度为0,那么在不考虑光线被吸收和衰减的情况下,我们看到了全部的反射光。可以用余弦函数来计算百分比,但是对于高聚焦的镜面反射来说,一般我们的直观体验是角度为0及其附近处光线陡然变亮,而超过某个角度后光线迅速变暗,因此普通余弦函数的曲线太平缓了,所以我们把余弦函数提高一个n次幂,曲线就会在边缘处(偏离角度较大处)快速下降。你可以自行测试下cos函数的指数函数的变化曲线,通过引入额外的指数参数,我们可以模拟在镜面反射矢量周围的各种光散射量。如果指数较大,例如100,则cos(a)exp将向y轴塌缩,只有非常小的角度才会返回一个有效的百分比值,即高光区域很小;而如果指数很小,如1.0,则会模拟反射光线周围的大量光线,即高光区域较大。
高光反射数学模型
如果我们用n表示片段法线(N)方向上的正规化向量(长度为1),如下图所示:
在已知入射光位置、入射光L、片段点位置和片段点法向量的情况下,我们可以通过简单的几何计算推导反射光R如下:
R = N + P => R = n*dot_product(n,-L) + (L + N) => R = n*dot_product(n,-L) + (L + n*dot_product(n,-L)) => R = 2*n*dot_product(n,-L) + L 其中L = fragment_position - light_position
得到反射光后,根据相机位置,我们可以进一步计算反射光和相机夹角,然后算上我们刚才提到的指数参数以及额外的一个高光强度调节参数,推导过程如下:
reflection = normalize( R ); to_camera = normalize( fragment_position - camera_position ); cos_angle = dot(reflection, to_camera); cos_angle = clamp(cos_angle, 0.0, 1.0); cos_angle = specular_factor*(pow(cos_angle, specular_gloss)); // 这里specular_gloss代表上面所提到的指数参数,表示shiness specular_color = u_Light_color * cos_angle;
根据上面的公式,我们可以很容易的实现一个webgl shader程序。
- 相关文章
微信公众号在线生成二维码带参数怎么搞?
带参数二维码是微信公众号渠道二维码的一种实现
微信的带参数二维码有两种,一种是临时二维码,一种是永久二维码,但是永久二维码的生成是有个数限制的,微...WebGL场景中多相机拍摄的原理和意义
一般而言,3D场景的渲染只需要一个相机,不过借助多相机可以获取一些单相机无法达到的特效。比如突显特定对象并模糊背景。
3D相机渲染的基本原理是依靠颜色...HTML5 And Canvas 2D Specs Are Now Feature Complete, First HTML 5.1 Working Draft Published
We’ve been writing about HTML5 for quite a while, but, until today, the actual HTML5 specs and standards were still moving targets. Now, however, the...
CSS3属性选择器特性使用详解
CSS3除了引入动画、滤镜(用于特效)以及新的布局技术外,在选择器(selector)方面也有增强。属性选择器根据元素的属性(attributes)来匹配。这可以是一个单独...
CSS3弹性布局弹性流(flex-flow)属性详解和实例
弹性布局是CSS3引入的强大的布局方式,用来替代以前Web开发人员使用的一些复杂而易错hacks方法(如使用float进行类似流式布局)。其中flex-flow是flex-direction...
HTTP1.1协议现状、问题和解决方案
HTTP的现状最早的HTTP协议非常简单,只能用来传送文本,方法也只有GET,后来逐步发展到1.1,能够支持多种MIME格式数据(如文本、文件),支持GET,POST,HEAD,OPTI...
深度贴图(depth map)概念简介和生成流程
Depth map 深度图是一张2D图片,每个像素都记录了从视点(viewpoint)到遮挡物表面(遮挡物就是阴影生成物体)的距离,这些像素对应的顶点对于观察者而言是“可...
Blender2.7 快捷键一览表
通用操作
停止当前操作:ESC
快捷搜索:SPACE撤销:ctrl+z重做:ctrl+shift+z渲染:F12
单选:鼠标右键(RMB)全选:A
框选:B
刷选:...浏览器控制台报JS脚本执行错误:Module is not defined
现在JS分成了两个分支,一部分在服务器端发展如NodeJS,一部分是传统的浏览器运行环境。
有些插件在编写JS代码时,是针对Node编写的,所以直接在浏览器中使...WebGL入门教程3 - Canvas、Context、API和绘制一个矩形
WebGL入门教程2 - GPU基本概念和工作流水线(渲染管道)
使用Canvas绘制完美的不完美圆形
真实世界是不完美的,当我们需要模拟真实世界时,经常需要引入不完美/不规则的形状。比如陨石、雨滴、行星、树叶、绵延的海岸线、云朵等。本文介绍如何基于Canva...
inline-block元素设置overflow:hidden属性导致相邻行内元素向下偏移
在表单修改界面中常会使用一个标签、一个内容加一个修改按钮来组成单行界面,如图1所示。那么在表单总长度受限的情况下,当中间的邮箱名称过长时,会遮盖到旁边...
更多...