糖尿病康复,内容丰富有趣,生活中的好帮手!
糖尿病康复 > WebGL编程指南-24 同时使用漫反射光和环境反射光 立方体平移旋转缩放变换时漫反射光

WebGL编程指南-24 同时使用漫反射光和环境反射光 立方体平移旋转缩放变换时漫反射光

时间:2022-12-23 12:40:03

相关推荐

WebGL编程指南-24 同时使用漫反射光和环境反射光 立方体平移旋转缩放变换时漫反射光

1.demo效果

此效果是上一章绘制的立方体基础上,向Y轴方向平移一个单位,然后绕Z轴旋转30度。

如上图,归纳一下物体坐标变换法向量变化的规律如下

平移变换,法向量不会改变旋转变换,大多数情况下法向量会变,如果绕某个轴旋转360度,又回到原点,法向量自然不变缩放变换, 法向量可能会变 ,如果物体在X轴、Y轴、Z轴上的缩放比例不一致,会导致物体形状的改变,自然也会改变法向量,如果在所有轴上的缩放比例一样,那法向量也不会变

2.矩阵逆转置

上面我们学习了物体变幻时法向量如何变化,那变化后的法向量如何计算呢?有强大的矩阵运算助力,实现变成一件很简单的事,只需要用原法向量乘以变换模型矩阵的逆转只矩阵即可,用公式表示如下。

<变换后的法向量> = <原法向量> x <模型矩阵的逆转置矩阵>

Matrix4对象为我们提供了获取模型矩阵的逆转置矩阵的方法,相关方法如下

3.demo代码

//Chapter 08//temp 03//绘制一个立方体// => 运动中的光照效果// 加上逆转置变化法向量var VSHADER_SOURCE = `attribute vec4 a_Position;attribute vec4 a_Color;uniform mat4 u_VpMatrix; //view and range matuniform mat4 u_ModelMatrix; //model matuniform mat4 u_ReverseModelMat; //模型矩阵的逆转置attribute vec4 a_Normal; //法向量uniform vec3 u_LightColor; //平行光uniform vec3 u_LightDirection; //光照方向 //=归一化后的世界坐标uniform vec3 u_AmbientLight; // 环境光varying vec4 v_Color;void main() {gl_Position = u_VpMatrix * u_ModelMatrix * a_Position;//漫反射光颜色//法向量进行归一化vec3 normal = normalize(vec3(u_ReverseModelMat * a_Normal));//计算cos入射角 当角度大于90 说明光照在背面 赋值为0float nDotLight = max(dot(u_LightDirection, normal), 0.0);//计算反射光颜色vec3 diffuse = u_LightColor * vec3(a_Color) * nDotLight;// 环境反射光颜色vec3 ambient = u_AmbientLight * a_Color.rgb;v_Color = vec4(diffuse + ambient, a_Color.a);}`;var FSHADER_SOURCE = `precision mediump float;varying vec4 v_Color;void main() {gl_FragColor = v_Color;// gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);}`;ready(loadWEBGL);function loadWEBGL() {var canvas = document.getElementById('webgl');var webgl = canvas.getContext('webgl');if ( !initShaders(webgl, VSHADER_SOURCE, FSHADER_SOURCE) ) {console.log(new Error('failed to init shaders!'));return ;}var viewMat = new Matrix4().setLookAt(7, 2.5, 6, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);// var modelMat = new Matrix4().setIdentity();var modelMat = new Matrix4().setTranslate(0, 1, 0).rotate(30, 0, 0, 1);var projMat = new Matrix4();projMat.setPerspective(30, canvas.width/canvas.height, 1.0, 100);var vpMat = new Matrix4().setIdentity().multiply(projMat).multiply(viewMat);var u_VpMatrix = webgl.getUniformLocation(webgl.program, 'u_VpMatrix');webgl.uniformMatrix4fv(u_VpMatrix, false, vpMat.elements);var u_ModelMatrix = webgl.getUniformLocation(webgl.program, 'u_ModelMatrix');webgl.uniformMatrix4fv(u_ModelMatrix, false, modelMat.elements);//************* *///model逆转置var reverseModelMat = new Matrix4().setInverseOf(modelMat); //求逆reverseModelMat.transpose(); //转置var u_ReverseModelMat = webgl.getUniformLocation(webgl.program, 'u_ReverseModelMat');webgl.uniformMatrix4fv(u_ReverseModelMat, false, reverseModelMat.elements);//************* */// datavar vertexData = new Float32Array([1.0, 1.0, 1.0, -1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 1.0, -1.0, 1.0, //front面 v0-41.0, 1.0, 1.0, 1.0, -1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 1.0, -1.0, //right v03451.0, 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, 1.0, -1.0, -1.0, 1.0, 1.0, //up v0561-1.0, 1.0, 1.0, -1.0, -1.0, 1.0, -1.0, -1.0, -1.0, -1.0, 1.0, -1.0, //left -1.0, -1.0, 1.0, 1.0, -1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, //down1.0, -1.0, -1.0, 1.0, 1.0, -1.0, -1.0, 1.0, -1.0, -1.0, -1.0, -1.0 //back]);var colorData = new Float32Array([0.4, 0.4, 1.0, 0.4, 0.4, 1.0, 0.4, 0.4, 1.0, 0.4, 0.4, 1.0, //front0.4, 1.0, 0.4, 0.4, 1.0, 0.4, 0.4, 1.0, 0.4, 0.4, 1.0, 0.4, //right1.0, 0.4, 0.4, 1.0, 0.4, 0.4, 1.0, 0.4, 0.4, 1.0, 0.4, 0.4, //up1.0, 1.0, 0.4, 1.0, 1.0, 0.4, 1.0, 1.0, 0.4, 1.0, 1.0, 0.4, //left1.0, 0.4, 1.0, 1.0, 0.4, 1.0, 1.0, 0.4, 1.0, 1.0, 0.4, 1.0, //btm0.4, 1.0, 1.0, 0.4, 1.0, 1.0, 0.4, 1.0, 1.0, 0.4, 1.0, 1.0 //back]);var colorData_ALLWHITE = new Float32Array([1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, ]);var indicesData = new Uint8Array([0, 1, 2, 0, 2, 3,4, 5, 6, 4, 6, 7,8, 9, 10, 8, 10, 11,12, 13, 14, 12, 14, 15,16, 17, 18, 16, 18, 19,20, 21, 22, 20, 22, 23]);initArrayBuffer(webgl, vertexData, 'a_Position', 3, webgl.FLOAT);initArrayBuffer(webgl, colorData_ALLWHITE, 'a_Color', 3, webgl.FLOAT);initIndexBuffer(webgl, indicesData);var n = indicesData.length;//设置光照颜色var u_LightColor = webgl.getUniformLocation(webgl.program, 'u_LightColor');webgl.uniform3f(u_LightColor, 1.0, 1.0, 1.0);//设置光照方向var u_LightDirection = webgl.getUniformLocation(webgl.program,'u_LightDirection');var lightDirection = new Vector3([0.5, 3.0, 4.0]);lightDirection.normalize();webgl.uniform3fv(u_LightDirection, lightDirection.elements);//通过设置顶点的法向量 确定面的法向量var normalData = new Float32Array([0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0,1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0, -1.0]);initArrayBuffer(webgl, normalData, 'a_Normal', 3, webgl.FLOAT);//设置环境光var u_AmbientLight = webgl.getUniformLocation(webgl.program, 'u_AmbientLight');webgl.uniform3f(u_AmbientLight, 0.2, 0.2, 0.2);webgl.enable(webgl.DEPTH_TEST);webgl.clearColor(0.0, 0.0, 0.0, 1.0);webgl.clear(webgl.COLOR_BUFFER_BIT | webgl.DEPTH_BUFFER_BIT);// webgl.drawArrays(webgl.TRIANGLES, 0, n);webgl.drawElements(webgl.TRIANGLES, n, webgl.UNSIGNED_BYTE, 0);var tempRMatrix = new Matrix4().setInverseOf(modelMat);var tick = () => {var modelMat = animateRotate(webgl, 30);//model逆转置tempRMatrix.setInverseOf(modelMat); //求逆tempRMatrix.transpose(); //转置webgl.uniformMatrix4fv(u_ReverseModelMat, false, tempRMatrix.elements);//mvp矩阵webgl.uniformMatrix4fv(u_ModelMatrix, false, modelMat.elements);//************* */webgl.clear(webgl.COLOR_BUFFER_BIT | webgl.DEPTH_BUFFER_BIT);webgl.drawElements(webgl.TRIANGLES, n, webgl.UNSIGNED_BYTE, 0); requestAnimationFrame(tick);};// requestAnimationFrame(tick);}// 初始化顶点缓冲区// 坐标值 或者 颜色值function initArrayBuffer (webgl, data, name, num, type) {var vertexBuffer = webgl.createBuffer();webgl.bindBuffer(webgl.ARRAY_BUFFER, vertexBuffer);webgl.bufferData(webgl.ARRAY_BUFFER, data, webgl.STATIC_DRAW);var vertexLoction = webgl.getAttribLocation(webgl.program, name);webgl.vertexAttribPointer(vertexLoction, num, type, false, 0, 0);webgl.enableVertexAttribArray(vertexLoction);return true;}//=> 使用索引function initIndexBuffer (webgl, indexData) {var indicesBuffer = webgl.createBuffer();webgl.bindBuffer(webgl.ELEMENT_ARRAY_BUFFER, indicesBuffer);webgl.bufferData(webgl.ELEMENT_ARRAY_BUFFER, indexData, webgl.STATIC_DRAW);return true;}//=> 添加一个动画// return rotate 矩阵var CURRENT_ANGLE = 0;var CURRENT_MODEL_MATRIX = new Matrix4();var CURRENT_TIMESTAMP = Date.now();function animateRotate (webgl, speed) {var now = Date.now();var interval = Date.now() - CURRENT_TIMESTAMP;CURRENT_TIMESTAMP = now;CURRENT_ANGLE += (interval * speed / 1000);//累加CURRENT_MODEL_MATRIX.setRotate(CURRENT_ANGLE, 0, 0, 1);return CURRENT_MODEL_MATRIX;}

WebGL编程指南-24 同时使用漫反射光和环境反射光 立方体平移旋转缩放变换时漫反射光和环境反射光处理

如果觉得《WebGL编程指南-24 同时使用漫反射光和环境反射光 立方体平移旋转缩放变换时漫反射光》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。