原文地址:WebGL多模型光照综合实例

WebGL是一个非常的接近硬件底层的光栅化API, 从非常类似C/C++风格的API调用方式就可以看出来, 习惯了高级语言的我们会觉得很不友好,觉得特别繁琐. 这个也是很多人觉得WebGL难的原因之一. 如果我们要使用WebGL做一些项目,毫无疑问要么使用Three.js之类的3D库, 要么需要对原生的API进行封装. 这段时间查看了一些WebGL工具库的源代码, 参考封装出了一个简单的工具库,这样往后用WebGL做小项目就方便多了.

经过前面章节的学习, WebGL的知识点掌握的差不多了, 终于到了做特效和Demo的阶段了,来看一下这节实现的特效:WebGL多物体多光源场景

内容大纲

实现图形绕坐标原点旋转, 同时给所有的物体增加环境光, 漫反射, 高光. 其中旋转功能使用矩阵复合变换实现; 光照部分比较复杂,实现了多个光源照射.

  1. 着色器
  2. 模型变换

着色器

顶点着色器

代码很简单,逐顶点传入坐标,法向量矩阵,模型矩阵,mvp矩阵.

attribute vec4 a_position;
attribute vec4 a_normal;
uniform mat4 u_modelMatrix;
uniform mat4 u_normalMatrix;
uniform mat4 u_mvpMatrix;
varying vec3 v_normal;
varying vec3 v_position; void main() {
gl_Position = u_mvpMatrix * a_position;
v_normal=vec3(u_normalMatrix * a_normal);
v_position= vec3(u_modelMatrix * a_position);
}

片元着色器

分别在左前方和右后方添加了平行光源和点光源, 平行光源的高光使用的是宾氏模型, 它的高光过渡效果比较平滑; 点光源的高光使用的是冯氏模型, 它的高光部分比较明亮, 反射的效果比较好.

最后将两个光源照射产生的漫反射,高光亮度相加,就得到它们的综合光照效果了.

precision mediump float;
uniform vec3 u_lightColor;
uniform vec3 u_lightPosition;
uniform vec3 u_lightPosition2;
uniform vec3 u_ambientColor;
uniform vec3 u_viewPosition;
uniform vec4 u_color;
varying vec3 v_normal;
varying vec3 v_position; void main() {
// 法向量归一化
vec3 normal = normalize(v_normal);
// 计算环境光反射颜色
vec3 ambient = u_ambientColor * u_color.rgb; // 第一个光源:平行光
vec3 lightDirection = normalize(u_lightPosition);
// 计算法向量和光线的点积
float cosTheta = max(dot(lightDirection, normal), 0.0);
// 计算漫反射光的颜色
vec3 diffuse = u_lightColor * u_color.rgb * cosTheta;
// 宾氏模型高光
float shininess =100.0;
vec3 specularColor =vec3(1.0,1.0,1.0);
vec3 viewDirection = normalize(u_viewPosition-v_position);
vec3 halfwayDir = normalize(lightDirection + viewDirection);
float specularWeighting = pow(max(dot(normal, halfwayDir), 0.0), shininess);
vec3 specular = specularColor.rgb * specularWeighting * step(cosTheta,0.0); // 第二个光源:点光源
vec3 lightDirection2 = normalize(u_lightPosition2 - v_position.xyz);
// 计算法向量和光线的点积
float cosTheta2 = max(dot(lightDirection2, normal), 0.0);
// 计算漫反射光的颜色
vec3 diffuse2 = u_lightColor * u_color.rgb * cosTheta2;
// 冯氏模型高光
float shininess2 =30.0;
vec3 specularColor2 =vec3(1.0,1.0,1.0);
vec3 reflectionDirection = reflect(-lightDirection2, normal);
float specularWeighting2 = pow(max(dot(reflectionDirection, viewDirection), 0.0), shininess2);
vec3 specular2 = specularColor2.rgb * specularWeighting2 * step(cosTheta,0.0);
// 两个光源亮度相加
gl_FragColor = vec4(diffuse+diffuse2+ambient+specular+specular2,u_color.a);
}

模型变换

js代码部分使用工具库封装了原生WebGL的很多细节, 现在写起代码来要愉快得多了, 感觉和写canvas差不了太多

最新文章

  1. [NHibernate]利用LINQPad查看NHibernate生成SQL语句
  2. [转]云计算研究必备——精典Google论文
  3. 实战mysql分区(PARTITION)
  4. windows下node.js+sublime中安装coffeescript
  5. window.onscroll
  6. chrome下如何显示打开网页的IP地址
  7. 表单提交checkbox的值
  8. IKAnalyzer 分词
  9. webpack2.x基础属性讲解(一)
  10. Oracle数据库(一)概述、基础与简单操作
  11. C语言程序设计第一次作业(2017.10.10完成)
  12. [Redis]处理定时任务的2种思路
  13. JS windows对象的top属性
  14. 【算法】LeetCode算法题-Remove Duplicates from Sorted Array
  15. appium 启动了2个端口,但是只有一台机器在跑的 问题解决 (还没试,记录在此)
  16. 【转】iPhone易被窃听应用三分钟即可获取所有信息
  17. etcd ui
  18. vue.js常用指令
  19. python的一些科学计算的包
  20. 测试开发面试的Linux面试题总结之二:常用命令

热门文章

  1. 中国十大B2C电商站点开发语言调查
  2. freemarker将文件读写到HTML中
  3. 漂亮CSS样式用户留言表单
  4. JAVA入门[7]-Mybatis generator(MBG)自动生成mybatis代码
  5. 【SqlServer】【问题收集】阻止保存要求重新创建表的更改
  6. 「mysql优化专题」什么是慢查询?如何通过慢查询日志优化?(10)
  7. 《Java并发编程实战》/童云兰译【PDF】下载
  8. 【java】Date与String之间的转换及Calendar类:java.text.SimpleDateFormat、public Date parse(String source) throws ParseException和public final String format(Date date)
  9. LINUX:alias命令详解
  10. 服务器端语言go之开篇分享