1.webgl点光源的漫反射

点光源的特点:

  1. 点光源照射到物体上的每个顶点的入射光方向是各不相同的。
  2. 需要一个点光源的位置。
  3. 需要一个点光源的光颜色。

需要计算的是
我们需要计算出每个顶点的入射光线的方向
点光源向四周放射光线,所以顶点处的光线方向是由点光源坐标 - 顶点坐标而得到得矢量

入射光线的方向 = 点光源的坐标 - 顶点坐标

顶点着色器中
声明点光源的位置

'uniform vec3 u_LightPosition;\n' + // 点光源的位置

获取地址,并且赋值

const u_LightPosition = gl.getUniformLocation(gl.program, 'u_LightPosition'); // 获取点光源位置的存储地址
gl.uniform3f(u_LightPosition, 0.0, 3.0, 4.0);

声明模型矩阵

'uniform mat4 u_ModelMatrix;\n' + // 模型矩阵

获取地址,赋值模型矩阵

const modemoMatrixt = new Matrix4();
// modemoMatrixt.setTranslate(0, 0, 0); // 设置平移的坐标
modemoMatrixt.setRotate(0, 0, 1, 0) // 设置旋转的角度,旋转轴
const u_ModelMatrix = gl.getUniformLocation(gl.program, 'u_ModelMatrix');
gl.uniformMatrix4fv(u_ModelMatrix, false, modemoMatrixt.elements);

具体计算入射光的方向

'   vec4 vertexPosition = u_ModelMatrix * a_Position;\n' + // 每个顶点的坐标,经过模型矩阵变化之后的顶点坐标
'   vec3 lightDirection = normalize(u_LightPosition - vec3(vertexPosition));\n' + // 计算每个顶点的入射光向量
// u_LightPosition 点光源的位置
// vertexPosition 经过变化之后的顶点坐标
// lightDirection 点光源入射光的方向

然后我们计算法线向量 与 入射光的方向的夹角

'   float nDotl = max(dot(lightDirection, normal), 0.0);\n' + // 计算每个顶点的法向量与入射光向量的夹角余弦值

最终计算点光源的漫反射的颜色
物体基底色
光反射的颜色
夹角

'   vec3 diffuse = a_Color.rgb * u_LightColor * nDotl;\n' + // 计算点光源漫反射的光颜色

计算出环境光的颜色

'   vec3 ambient = u_AmbientLight * a_Color.rgb;\n' + // 环境光反射的颜色

赋值给varying类型的变量,使其能在片源着色器中使用

'   c_Color = vec4(diffuse + ambient, a_Color);\n' + // 环境光反射的颜色 + 点光源反射的颜色, 物体基础底色

片源着色器中

const FSHADER_SOURCE ='#ifdef GL_ES\n' +'precision mediump float;\n' +'#endif\n' +'varying vec4 c_Color;\n' +'void main(){\n' +'   gl_FragColor = c_Color;\n' +'}\n';

详细代码

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head><body><canvas id="canvas" width="400" height="400"></canvas><script src="../../三维/lib/cuon-matrix.js"></script><script>const gl = canvas.getContext('webgl');const VSHADER_SOURCE ='attribute vec4 a_Position;\n' + // 顶点坐标 ok'attribute vec4 a_Color;\n' + // 顶点颜色 ok'varying vec4 c_Color;\n' + // 传递给片源着色器的变量'uniform mat4 u_NormalMatrix;\n' + // 变化之后的顶点法向量 ok'uniform mat4 u_ViewProjMatrix;\n' + // 视图透视投影矩阵 ok'uniform mat4 u_ModelMatrix;\n' + // 模型矩阵'uniform vec3 u_LightColor;\n' + // 光线的颜色 ok 'uniform vec3 u_AmbientLight;\n' + // 环境光的颜色 ok'uniform vec3 u_LightPosition;\n' + // 点光源的位置'attribute vec4 a_Normal;\n' + // 顶点法向量 ok' void main(){\n' +'   gl_Position = u_ViewProjMatrix * a_Position;\n' + // 确定经过变化之后的顶点坐标'   vec3 normal = normalize(vec3(u_NormalMatrix * a_Normal));\n' + // 经过变化之后的法向量'   vec4 vertexPosition = u_ModelMatrix * a_Position;\n' + // 每个顶点的坐标'   vec3 lightDirection = normalize(u_LightPosition - vec3(vertexPosition));\n' + // 计算每个顶点的入射光向量'   float nDotl = max(dot(lightDirection, normal), 0.0);\n' + // 计算每个顶点的法向量与入射光向量的夹角余弦值'   vec3 diffuse = a_Color.rgb * u_LightColor * nDotl;\n' + // 计算点光源漫反射的光颜色'   vec3 ambient = u_AmbientLight * a_Color.rgb;\n' + // 环境光反射的颜色'   c_Color = vec4(diffuse + ambient, a_Color);\n' + // 环境光反射的颜色 + 点光源反射的颜色, 物体基础底色'}\n';const FSHADER_SOURCE ='#ifdef GL_ES\n' +'precision mediump float;\n' +'#endif\n' +'varying vec4 c_Color;\n' +'void main(){\n' +'   gl_FragColor = c_Color;\n' +'}\n';const createShader = (type, source) => {const shader = gl.createShader(type);gl.shaderSource(shader, source);gl.compileShader(shader);const compileState = gl.getShaderParameter(shader, gl.COMPILE_STATUS);if (!compileState) {const info = gl.getShaderInfoLog(shader);console.log(`编译报错信息为:${info}`)gl.deleteShader(shader);return null}return shader}const createProgram = (vshader, fshader) => {const vertexShader = createShader(gl.VERTEX_SHADER, vshader);const fragementShader = createShader(gl.FRAGMENT_SHADER, fshader);if (!fragementShader || !vertexShader) {console.log('初始着色器失败')return false}const program = gl.createProgram();gl.attachShader(program, vertexShader);gl.attachShader(program, fragementShader);gl.linkProgram(program);const linkState = gl.getProgramParameter(program, gl.LINK_STATUS);if (!linkState) {const err = gl.getProgramInfoLog(program);console.log(`链接报错信息为:${err}`);gl.deleteShader(vertexShader);gl.deleteShader(fragementShader);gl.deleteProgram(program);return null}return program;}const program = createProgram(VSHADER_SOURCE, FSHADER_SOURCE);gl.program = program;gl.useProgram(program);const createBuffers = () => {var vertices = new Float32Array([   // Coordinates2.0, 2.0, 2.0, -2.0, 2.0, 2.0, -2.0, -2.0, 2.0, 2.0, -2.0, 2.0, // v0-v1-v2-v3 front2.0, 2.0, 2.0, 2.0, -2.0, 2.0, 2.0, -2.0, -2.0, 2.0, 2.0, -2.0, // v0-v3-v4-v5 right2.0, 2.0, 2.0, 2.0, 2.0, -2.0, -2.0, 2.0, -2.0, -2.0, 2.0, 2.0, // v0-v5-v6-v1 up-2.0, 2.0, 2.0, -2.0, 2.0, -2.0, -2.0, -2.0, -2.0, -2.0, -2.0, 2.0, // v1-v6-v7-v2 left-2.0, -2.0, -2.0, 2.0, -2.0, -2.0, 2.0, -2.0, 2.0, -2.0, -2.0, 2.0, // v7-v4-v3-v2 down2.0, -2.0, -2.0, -2.0, -2.0, -2.0, -2.0, 2.0, -2.0, 2.0, 2.0, -2.0  // v4-v7-v6-v5 back]); // 顶点坐标// 顶点颜色var colors = new Float32Array([    // Colors1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0,     // v0-v1-v2-v3 front1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0,     // v0-v3-v4-v5 right1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0,     // v0-v5-v6-v1 up1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0,     // v1-v6-v7-v2 left1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0,     // v7-v4-v3-v2 down1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0     // v4-v7-v6-v5 back]); // 顶点颜色var normals = new Float32Array([    // Normal0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0,  // v0-v1-v2-v3 front1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0,  // v0-v3-v4-v5 right0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0,  // v0-v5-v6-v1 up-1.0, 0.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0,  // v1-v6-v7-v2 left0.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0,  // v7-v4-v3-v2 down0.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0, -1.0   // v4-v7-v6-v5 back]); // 顶点法向量initArrayBuffer('a_Position', vertices, 3, gl.FLOAT);initArrayBuffer('a_Color', colors, 3, gl.FLOAT);initArrayBuffer('a_Normal', normals, 3, gl.FLOAT);var indices = new Uint8Array([0, 1, 2, 0, 2, 3,    // front4, 5, 6, 4, 6, 7,    // right8, 9, 10, 8, 10, 11,    // up12, 13, 14, 12, 14, 15,    // left16, 17, 18, 16, 18, 19,    // down20, 21, 22, 20, 22, 23     // back]); // 顶点索引const bufferIndex = gl.createBuffer();gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, bufferIndex)gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, gl.STATIC_DRAW);return indices.length;}const initArrayBuffer = (attribute, data, num, type) => {// console.log(attribute, 'attribute')const buffer = gl.createBuffer();gl.bindBuffer(gl.ARRAY_BUFFER, buffer);gl.bufferData(gl.ARRAY_BUFFER, data, gl.STATIC_DRAW);// const a_attribute = gl.getAttribLocation(gl.program, attribute);var a_attribute = gl.getAttribLocation(gl.program, attribute);if (a_attribute < 0) {console.log('Failed to get the storage location of ' + attribute);return false;}gl.vertexAttribPointer(a_attribute, num, type, false, 0, 0);gl.enableVertexAttribArray(a_attribute);gl.bindBuffer(gl.ARRAY_BUFFER, null);}const n = createBuffers();// 设置环境光const u_AmbientLight = gl.getUniformLocation(gl.program, 'u_AmbientLight'); // 环境光的变量地址gl.uniform3f(u_AmbientLight, 0.2, 0.2, 0.2); // 设置环境光的颜色// 设置点光源的位置const u_LightPosition = gl.getUniformLocation(gl.program, 'u_LightPosition'); // 获取点光源位置的存储地址gl.uniform3f(u_LightPosition, 0.0, 3.0, 4.0);// 设置点光源的颜色const u_LightColor = gl.getUniformLocation(gl.program, 'u_LightColor'); // 获取点光源颜色变量存储地址// console.log(u_LightColor)gl.uniform3f(u_LightColor, 1.0, 1.0, 1.0);// 设置透视视图投影矩阵const u_ViewProjMatrix = gl.getUniformLocation(gl.program, 'u_ViewProjMatrix'); // 获取视图透视投影矩阵的变量存储地址// console.log(u_ViewProjMatrix)const mvpMatrixd = new Matrix4(); // 视图透视投影矩阵mvpMatrixd.setPerspective(30, canvas.width / canvas.height, 1, 100); // 设置透视投影矩阵mvpMatrixd.lookAt(6, 6, 14, 0, 0, 0, 0, 1, 0); // 设置视图矩阵const modemoMatrixt = new Matrix4();// modemoMatrixt.setTranslate(0, 0, 0); // 设置平移的坐标modemoMatrixt.setRotate(0, 0, 1, 0) // 设置旋转的角度,旋转轴// // 透视视图投影矩阵 * 模型矩阵mvpMatrixd.multiply(modemoMatrixt);console.log(mvpMatrixd.elements, 'mvpMatrix.elements')// 设置具体的值// 模型矩阵const u_ModelMatrix = gl.getUniformLocation(gl.program, 'u_ModelMatrix');gl.uniformMatrix4fv(u_ModelMatrix, false, modemoMatrixt.elements);// 设置变化之后的法向量const normalMatrix = new Matrix4(); // 变化之后的法线向量normalMatrix.setInverseOf(modemoMatrixt); // 计算模型矩阵的逆矩阵normalMatrix.transpose(); // 对矩阵进行转置运输const normalChange = gl.getUniformLocation(gl.program, 'u_NormalMatrix');gl.uniformMatrix4fv(normalChange, false, modemoMatrixt.elements); // 设置具体的值gl.uniformMatrix4fv(u_ViewProjMatrix, false, mvpMatrixd.elements);gl.clearColor(0, 0, 0, 1);gl.enable(gl.DEPTH_TEST);gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);console.log(n)gl.drawElements(gl.TRIANGLES, n, gl.UNSIGNED_BYTE, 0);</script>
</body></html>

效果图

webgl点光源的漫反射相关推荐

  1. 计算机图形学(七)——Phong光照模型

    计算机图形学(七)--Phong光照模型 Phong光照反射模型 点光源 环境光 漫反射 镜面反射 Phong光照反射模型 Phong反射模型认为来自一个表面的反射由下面三个线性叠加的分量组成: 反射 ...

  2. 华科_图形学笔记_09_奇妙的真实感_片元着色01_02

    计算机图形学_华中科技大学_中国大学MOOC(慕课) 9.3_光照明模型_上_Phong模型初步 首先,我们来看看光照模型发展的历史. 在1967年,Wylie等人,第一次在显示物体时加进了光照的效果 ...

  3. OpenGL 4.0 Shading Language Cookbook-中文版问世了

    OpenGL 4.0 Shading Language Cookbook-中文版问世了, http://item.taobao.com/item.htm?spm=a230r.1.14.13.K3kTO ...

  4. 西安科技大学计算机图形学课程设计,长方体体的光照效果计算机图形学课程设计...

    <长方体体的光照效果计算机图形学课程设计>由会员分享,可在线阅读,更多相关<长方体体的光照效果计算机图形学课程设计(29页珍藏版)>请在人人文库网上搜索. 1.西安科技大学计算 ...

  5. 如何在unity的前向渲染路径ForwardBase中同时使用逐顶点和逐像素光源

    前言:问题来自于<Unity Shader入门精要>中,第195页.书中给出了如何在forwardbase和forwardadd中计算逐像素光照,并没有给出如何同时进行逐顶点的光照,因此当 ...

  6. WebGL实践篇(九)—— 光照:点光源

    1.点光源的光照值 光照来源于点,太阳也算是一个点光源,光照射到物体的同一面上有明有暗(即光照值不同),将面上的每个点到光源的矢量与法向量点乘得到的值就是光照值. 顶点着色器: 主要添加了光照位置的参 ...

  7. WebGL编程指南-27 逐片元处理点光源光照效果

    1.demo效果 如上图,图二为逐片元处理点光源的效果,与之前的demo效果相比,物体表面的光照效果更佳柔和.细腻. 2.实现要点 在上一章中实现方式是逐顶点的方式,实现点光源在照射到立方体呈现出的效 ...

  8. 【视觉高级篇】20 # 如何用WebGL绘制3D物体?

    说明 [跟月影学可视化]学习笔记. 如何用 WebGL 绘制三维立方体 我们知道立方体有8个顶点,6个面,在 WebGL 中,需要用 12 个三角形来绘制它.把每个面的顶点分开,需要 24 个顶点. ...

  9. Unity 2.Space Shooter(碰撞器Collider,WebGL,刚体中属性,(定时)实例化、销毁游戏对象,触碰OnTriggerEnter/Exit,爆炸效果,音频,文字,定时调方法)

    目录 项目介绍 WebGL发布 游戏对象设置 灯光.相机 背景 移动游戏对象 Debug 制作子弹 射击动作 清理离开边界的游戏对象 制作危险物 添加爆炸,移动小行星,作为预制件 创建游戏控制器 循环 ...

  10. WebGL编程指南-23 光照原理、漫反射光计算、漫反射光照射下的立方体

    1.demo效果 如上,添加了漫反射光照射效果的立方体,最前面的面亮一些,顶上和右侧的面暗一些 2.光照原理 现实中,物体被光线照射,会有一部分光在物体表面反射,当反射光线进入你的眼睛时,你就看到了物 ...

最新文章

  1. python3基本知识_Python3 - 基础知识、基本了解
  2. 讲给普通人听的分布式数据存储
  3. 大量的 TIME_WAIT 状态 TCP 连接,对业务有什么影响?
  4. LeetCode Populating Next Right Pointers in Each Node II(dfs)
  5. 【原创】 关于全局静态变量初始化
  6. RedHat AS4 配置Yum
  7. MybatisPlus学习(四)条件构造器Wrapper方法详解
  8. 火车票售票系统mysql_2021年元旦火车票今日开售!具体开售时间是几点?
  9. spring data mongodb CURD
  10. python 英文字典-python如何制作英文字典
  11. Jeesite--- Datagrid 行高亮+单元格高亮
  12. [Vue]动态加载组件的四种方式
  13. 计算机桌面死机的原因是,电脑屏幕死机了怎么办
  14. licecap图片区域问题
  15. 俄罗斯FAC认证介绍
  16. 利用Gson对json进行flatten(扁平化)处理
  17. ArcGIS之创建企业级地理数据库(Oracle)
  18. 8款炫酷的HTML5特效源码
  19. c语言俄罗斯方块随机,C语言实现俄罗斯方块
  20. android 实现挂电话和接电话

热门文章

  1. godaddy无法修改域名服务器,godaddy的DNS A记录不能修改原因
  2. 仿微信雷达寻好友动画
  3. 阻止原生输入中文拼音途中会触发input方法的问题
  4. 《学会提问》之一——学会提出好问题
  5. canvas教程15-变形
  6. 关于等价鞅、反等价鞅、剀利公式、赌徒输光定理
  7. erp5 主要业务模块介绍
  8. linux让别人电脑蓝屏,愚人节必备,教你制作整人神器,用代码实现计算机蓝屏...
  9. 椭圆拟合fitEllipse()函数
  10. 机器人语音---走进优必选