WebGL入门教程 - 高光计算模型

iefreer 发表于 2019-08-09 18:06:06

标签: webgl, tutorials, specular, light

- +

现实物体在光源的照射下,会出现吸收和反射。物体的颜色主要由漫反射决定,但局部高光效果则主要由镜面反射来决定。

从表面反射出的光线与入射角成相等但相反的角度,称为“镜面反射”。

如果镜面反射光线直接进入相机,就好像相机直接看到光源一样,即使它已经从物体上反弹出来。相机看到的是光源的光,而不是物体的颜色。如果你有一个白色光源,镜面反射将是白色的。如果您有一个红色光源,镜面反射将是红色的。因此,要对镜面反射进行建模,需要在照明模型中指定光源的颜色。

specular_angle.png

通常相机位置和反射光之间存在一个角度,如果角度很大,我们将看不到反射光,如果角度为0,那么在不考虑光线被吸收和衰减的情况下,我们看到了全部的反射光。可以用余弦函数来计算百分比,但是对于高聚焦的镜面反射来说,一般我们的直观体验是角度为0及其附近处光线陡然变亮,而超过某个角度后光线迅速变暗,因此普通余弦函数的曲线太平缓了,所以我们把余弦函数提高一个n次幂,曲线就会在边缘处(偏离角度较大处)快速下降。你可以自行测试下cos函数的指数函数的变化曲线,通过引入额外的指数参数,我们可以模拟在镜面反射矢量周围的各种光散射量。如果指数较大,例如100,则cos(a)exp将向y轴塌缩,只有非常小的角度才会返回一个有效的百分比值,即高光区域很小;而如果指数很小,如1.0,则会模拟反射光线周围的大量光线,即高光区域较大。

高光反射数学模型

如果我们用n表示片段法线(N)方向上的正规化向量(长度为1),如下图所示:

reflection_vectors2.png

在已知入射光位置、入射光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程序。

possitive(3) negative(0) views1208 comments1
私信 收藏 分享
分享到

发送私信

最新评论

iefreer 2019-08-12 14:42:01

一个参考实现:https://wow.techbrood.com/fiddle/53585


请先 登录 再评论.
相关文章
  • 2019年开源WebRTC媒体服务器选型比较

    什么是WebRTC服务器?在WebRTC的早期开始,该技术的主要卖点之一是它允许点对点(浏览器到浏览器)通信,几乎没有服务器的干预,服务器通常仅用于信令(比如用于...

  • React JSX语法简介

    JSX是一种类似XML的标签语法,用来简化代码,我们可以不使用JSX,但了解并使用也没什么坏处:)在React中,JSX是一个使用 React.createElement() API的快捷方式...

  • 常见面试题JS语言中四种函数调用方式实例讲解

    JS的语言世界中函数(function)是一等公民,函数的调用有多种方法。普通调用这个是最常见和直接的方式:function

  • 使用HTML5 FileReader和Canvas压缩用户上传的图片

    手机用户拍的照片通常会有2M以上,这对服务器带宽产生较大压力。因此在某些应用下(对图片要求不那么高)我们可以在客户端来压缩图片,然后再提交给服务器。总体...

  • 学习使用CSS制作进度条

    进度条是基础的界面控件,可用于多种场合,比如任务完成进度,手机充电状态等。本文介绍一个简单实用的进度条制作方法。预期效果如下图所示:直观上,我们可以把该进度条控件分为2个部分,外部的边界用来表示固定的目标范围,里面的条形部分用来表示当前进度。外部目标范围元素的CSS代码编写如下:.pb-scope

  • Three.js 对象局部坐标转换为世界坐标

    在Three.js中进行顶点几何计算时,一个需要注意的地方是,需要统一坐标系。比如你通过Three.js提供的API创建了一个球体网孔对象,那么默认情况下,各网孔顶点的...

  • 纹理基础知识和过滤模式详解

    1、 为什么在纹理采样时需要texture filter(纹理过滤)。
    我们的纹理是要贴到三维图形表面的,而三维图形上的pixel中心和纹理上的texel中心并不一至(pixe...

  • 如何使用Three.js加载obj和mtl文件

    OBJ和MTL是3D模型的几何模型文件和材料文件。在最新的three.js版本(r78)中,以前的OBJMTLLoader类已废弃。现在要加载OBJ和MTL文件,需要结合OBJLoader和MTLLoade...

  • CSS3图片混合(Blend)效果及其参考计算公式一览表

    在Photoshop软件中,混合是将两个图层的色彩值进行合成,从而创造出大量的效果。在这些效果的背后实际是一些简单的数学公式在起作用。下面所介绍的公式仅适用于R...

  • 如何使用WebGL实现空气高温热变形动画特效

    我们在炎炎夏日,或者在火堆旁,经常会观察到热源周围空气的不稳定波动现象。本文将讲解如何通过WebGL来实现这个特效。该效果可用于热变形、波浪、水面波光等场...

  • 浏览器控制台报JS脚本执行错误:Module is not defined

    现在JS分成了两个分支,一部分在服务器端发展如NodeJS,一部分是传统的浏览器运行环境。
    有些插件在编写JS代码时,是针对Node编写的,所以直接在浏览器中使...

  • WebGL入门教程1 - 3D绘图基础知识

    现代浏览器努力使得Web用户体验更为丰富,而WebGL正处于这样的技术生态系统的中心位置。其应用范围覆盖在线游戏、大数据可视化、计算机辅助设计、虚拟现实以及数...

  • Canvas实例教程:图像移动、大小调整和裁剪

    本文介绍如何使用JavaScript和HTML5 Canvas元素来移动、调整大小和...

  • 如何使用CSS3/SCSS实现逼真的车窗雨滴效果

    在天气预报类的Web移动应用中,常常需要实现屏幕的雨滴效果,表示阴雨天气。感觉上比较神奇,其实想通了,这个效果的实现只需要一点物理知识和CSS3的简单变换。实现一个小雨滴首先雨滴是一个个小的椭圆形元素:.raindrop

  • 更多...