1.点光源的光照值

光照来源于点,太阳也算是一个点光源,光照射到物体的同一面上有明有暗(即光照值不同),将面上的每个点到光源的矢量与法向量点乘得到的值就是光照值。

顶点着色器:

主要添加了光照位置的参数,并将顶点着色器中求出来的光照向量传值给着色器进行渲染。

  <script id="vertex-shader-3D" type="x-shader/x-vertex">attribute vec4 a_position;attribute vec3 a_normal;//光源位置uniform vec3 u_lightWorldPosition;uniform mat4 u_world;uniform mat4 u_worldViewProjection;uniform mat4 u_worldInverseTranspose;varying vec3 v_normal;varying vec3 v_surfaceToLight;void main(){gl_Position = u_worldViewProjection * a_position;v_normal = mat3(u_worldInverseTranspose) * a_normal;vec3 surfaceWorldPosition = (u_world * a_position).xyz;v_surfaceToLight = u_lightWorldPosition - surfaceWorldPosition;}</script>

片段着色器(比较重要的就是点乘获取光照值进行渲染):

  <script id="fragment-shader-3D" type="x-shader/x-fragment">precision mediump float;varying vec3 v_normal;varying vec3 v_surfaceToLight;uniform vec4 u_color;void main() {vec3 normal = normalize(v_normal);vec3 surfaceToLightDirection = normalize(v_surfaceToLight);float light = dot(normal, surfaceToLightDirection);gl_FragColor = u_color;gl_FragColor.rgb *= light;} </script>

获取参数以及设定

    var MVPUniformLocation = webgl.getUniformLocation(program, "u_worldViewProjection");var worldUniformLocation = webgl.getUniformLocation(program, "u_world");var worldITUniformLocation = webgl.getUniformLocation(program, "u_worldInverseTranspose");var lightPUniformLocation = webgl.getUniformLocation(program, "u_lightWorldPosition");//投影矩阵var projectionMatrix = m4.perspective(fieldofViewInRadians, webgl.canvas.clientWidth / webgl.canvas.clientHeight, 1, 2000);var cameraPosition = [100, 150, 200];var targetPosition = [0, 35, 0];var up = [0, 1, 0];//相机矩阵var cameraMatrix = m4.lookAt(cameraPosition, targetPosition, up);//视图矩阵var viewMatrix = m4.inverse(cameraMatrix);//视图投影矩阵var viewProjectionMatrix = m4.multiply(projectionMatrix, viewMatrix);//模型矩阵var worldMatrix = m4.yRotation(fRotationRadians);var worldInverseMatrix = m4.inverse(worldMatrix);var worldInverseTransposeMatrix = m4.transpose(worldInverseMatrix);//模型视图投影矩阵var worldViewProjectionMatrix = m4.multiply(viewProjectionMatrix, worldMatrix);webgl.uniformMatrix4fv(MVPUniformLocation, false, worldViewProjectionMatrix);webgl.uniformMatrix4fv(worldITUniformLocation, false, worldInverseTransposeMatrix);webgl.uniformMatrix4fv(worldUniformLocation, false, worldMatrix);//设置光照方向,光源来源webgl.uniform3fv(lightPUniformLocation, [20, 30, 60]);

结果如下:

2.镜面反射

如果入射角和反射角恰好与眼睛和光源的夹角相同,那么光线就会反射到眼前且会特别亮,就如镜子一般。将halfVector向量与物体表面法向量点乘,+1表示方向一致,0表示垂直,-1表示方向相反;方向一致时,光就会进入人眼。

顶点着色器(加了个相机位置跟物体表面到相机的向量):

  <script id="vertex-shader-3D" type="x-shader/x-vertex">attribute vec4 a_position;attribute vec3 a_normal;//光源位置uniform vec3 u_lightWorldPosition;//相机位置uniform vec3 u_viewWorldPosition;uniform mat4 u_world;uniform mat4 u_worldViewProjection;uniform mat4 u_worldInverseTranspose;varying vec3 v_normal;varying vec3 v_surfaceToLight;varying vec3 v_surfaceToView;void main(){gl_Position = u_worldViewProjection * a_position;v_normal = mat3(u_worldInverseTranspose) * a_normal;vec3 surfaceWorldPosition = (u_world * a_position).xyz;v_surfaceToLight = u_lightWorldPosition - surfaceWorldPosition;v_surfaceToView = u_viewWorldPosition - surfaceWorldPosition;}</script>

片段着色器(主要是halfVector和specular):

  <script id="fragment-shader-3D" type="x-shader/x-fragment">precision mediump float;varying vec3 v_normal;varying vec3 v_surfaceToLight;varying vec3 v_surfaceToView;uniform vec4 u_color;void main() {vec3 normal = normalize(v_normal);vec3 surfaceToLightDirection = normalize(v_surfaceToLight);vec3 surfaceToViewDirection = normalize(v_surfaceToView);vec3 halfVector = normalize(surfaceToLightDirection + surfaceToViewDirection);float light = dot(normal, surfaceToLightDirection);float specular = dot(normal,halfVector);gl_FragColor = u_color;gl_FragColor.rgb *= light;//加上高光gl_FragColor.rgb += specular;} </script>

参数设置:

    var viewPUniformLocation = webgl.getUniformLocation(program, "u_viewWorldPosition");webgl.uniform3fv(viewPUniformLocation, cameraPosition);

结果如下:

太亮啦!那我们调整一下吧

3. 镜面光的优化

将高光从线性变换变成指数变换,即 y = pow(x,a),a越大,图中阴影面积就越小,越接近指数变换,a越小阴影面积就越接近整个矩形,这样光照就变强了。

只用修改片段着色器:

light的点乘结果有可能为赋值,这里只取正值做高光的计算,如果为负的话,高光设为0

  <script id="fragment-shader-3D" type="x-shader/x-fragment">precision mediump float;varying vec3 v_normal;varying vec3 v_surfaceToLight;varying vec3 v_surfaceToView;uniform vec4 u_color;uniform float u_shininess;void main() {vec3 normal = normalize(v_normal);vec3 surfaceToLightDirection = normalize(v_surfaceToLight);vec3 surfaceToViewDirection = normalize(v_surfaceToView);vec3 halfVector = normalize(surfaceToLightDirection + surfaceToViewDirection);float light = dot(normal, surfaceToLightDirection);//float specular = dot(normal,halfVector);float specular = 0.0;if(light>0.0){specular = pow(dot(normal,halfVector),u_shininess);}gl_FragColor = u_color;gl_FragColor.rgb *= light;gl_FragColor.rgb += specular;} </script>

设置参数:

    var shininessUniformLocation = webgl.getUniformLocation(program, "u_shininess");var shininess = 150;webgl.uniform1f(shininessUniformLocation, shininess);

结果如下:

看 仿佛一个小灯。

4. 光源颜色的修改

片段着色器(加了光源颜色和高光颜色):

  <script id="fragment-shader-3D" type="x-shader/x-fragment">precision mediump float;varying vec3 v_normal;varying vec3 v_surfaceToLight;varying vec3 v_surfaceToView;uniform vec4 u_color;uniform float u_shininess;uniform vec3 u_lightColor;uniform vec3 u_specularColor;void main() {vec3 normal = normalize(v_normal);vec3 surfaceToLightDirection = normalize(v_surfaceToLight);vec3 surfaceToViewDirection = normalize(v_surfaceToView);vec3 halfVector = normalize(surfaceToLightDirection + surfaceToViewDirection);float light = dot(normal, surfaceToLightDirection);//float specular = dot(normal,halfVector);float specular = 0.0;if(light>0.0){specular = pow(dot(normal,halfVector),u_shininess);}gl_FragColor = u_color;gl_FragColor.rgb *= light * u_lightColor;gl_FragColor.rgb += specular * u_specularColor;} </script>

参数设置:

    var lightColorUnifromLoation = webgl.getUniformLocation(program, "u_lightColor");var specularColorUniformLocation = webgl.getUniformLocation(program, "u_specularColor");webgl.uniform3fv(lightColorUnifromLoation, m4.normalize([1, 0.6, 0.6]));webgl.uniform3fv(specularColorUniformLocation, m4.normalize([1, 0.2, 0.2]));

结果如下:

将~暖光来了。

WebGL实践篇(九)—— 光照:点光源相关推荐

  1. unity 烘焙参数 设置_Unity通用渲染管线(URP)系列(九)——点光源和聚光灯

    200+篇教程总入口,欢迎收藏: 放牛的星星:[教程汇总+持续更新]Unity从入门到入坟--收藏这一篇就够了​zhuanlan.zhihu.com 本文重点内容: 1.支持更多类型的灯光 2.包含实 ...

  2. WebGL 实践篇(三)—— 二维图形的平移、旋转、缩放

    一 平移 (1)平移直接体现在代码当中 在二维当中,平移相当于就是改变x,y的位置. function setRectangle(gl, x, y, width, height) {var x1 = ...

  3. webgl——给场景添加光

    文章目录 前言 光照理论介绍 光照效果 光源类型 反射光颜色 向场景中添加光 向场景中添加环境光和点光源 逐片元光照--更加逼真 总结 前言 在之前的学习中已经将三维物体添加到了场景中,但是并没有在场 ...

  4. WebGL展示3D房屋内景

     由于生活和工作上的原因,从年前开始一直到处奔波,没有太多的时间去关注和学习WebGL图形学相关的技术, 不过陆陆续续都有学习使用blender进行3D建模, 而这篇文章涉及到的房屋内景3D建模就是我 ...

  5. threejs添加立方体_前端图形学(三十)——从源码去看threejs中的光照模型

    欢迎来到[畅哥聊技术]前端图形学相关技术文章,更多精彩内容持续更新中,敬请关注. 上章节回顾 熟悉了threejs中内置的几何图形的渲染原理就是通过顶点渲染 传入自定义顶点渲染自定义的几何图形 本章目 ...

  6. 【教程汇总+持续更新】Unity游戏开发从入门到入坟

    新的一年,本该在年前整理的年终总结被拖到了年后开工.去年大量时间投入在Catlike教程的翻译上,截止目前位置,教程的进度已经完全追平原作者. 去年还有一部分是断断续续的更新SLG实战教程,但遗憾的是 ...

  7. API理解清晰(转载)

    1.API的概念:         AIP全称(Aplication Programming Interface),一般来说就是 软件组件之间信息交互的桥梁. 2.举个例子: 假如你有一个银行,客户想 ...

  8. API是什么?有哪些常见的API?

    转自 https://blog.csdn.net/cumtdeyurenjie/article/details/80211896#t2 和https://blog.csdn.net/weixin_38 ...

  9. 什么是API,API的概念

    1.API的概念:         AIP全称(Aplication Programming Interface),一般来说就是 软件组件之间信息交互的桥梁. 2.举个例子: 假如你有一个银行,客户想 ...

最新文章

  1. c语言程序解决生活中的问题作文,生活中烦恼的事五年级满分作文
  2. xml配置linux启动脚本,linux中利用Shell脚本实现自动安装部署weblogic服务
  3. MySQL工作中的实际用_数据库在工作中的应用,以及什么是MySQL?
  4. 146. LRU Cache
  5. MyBatis 缓存详解-一级缓存的不足
  6. [蓝桥杯][2013年第四届真题]核桃的数量-枚举(水题)
  7. [crypto][ipsec] 简述ESP协议的sequence number机制
  8. nbu WIN平台下面(mtx/robtest/tar/nt_ttu)手动测试driver是否正常
  9. New ipad与ipad2有何不同
  10. (tip_修订0618)bmp 32位转24位
  11. 迄今为止2020年AI的奋斗与成功
  12. Windows中ActiveX控件注册的方法
  13. 一、Fiddler抓包工具 — Fiddler介绍与安装
  14. Linux中文件颜色代表类型
  15. 繁体字转换 java_java代码实现简体繁体转换
  16. 赛码输入输出java_(赛码编程)博弈问题
  17. 梦想经不起等待 -- 美文转载
  18. 情感天地——《不能牵手就握手吧》
  19. 2019年04月01日_拔剑-浆糊的传说_新浪博客
  20. ARMV8体系结构简介:预备知识

热门文章

  1. sqlmap之tamper脚本
  2. [含lw+源码等]javaweb银行柜员业务绩效考核系统
  3. 全球与中国太阳能测试仪市场现状及未来发展趋势
  4. Qt中用户界面的User Interface Compiler(uic)机制的相关说明
  5. Linux ssh无密登陆
  6. 这项镜头贴膜技术背后,藏着让VR变轻巧的秘密
  7. rust future async/await
  8. 【NeurIPS100】谷歌、Facebook、斯坦福等十篇机器学习最新论文解读
  9. 【原创】VBA学习笔记(306)VBA中关于 exit 的用法
  10. Five nines