首页
留言
友链
关于
Search
1
思源笔记docker私有化部署及使用体验分享
2,438 阅读
2
windows11 远程提示:为安全考虑,已锁定该用户帐户,原因是登录尝试或密码更改尝试过多。
1,114 阅读
3
Pointer-Focus:一款功能强大的教学、录屏辅助软件
620 阅读
4
解决 nginxProxyManager 申请证书时的SSL失败问题
615 阅读
5
使用cspell对项目做拼写规范检查
582 阅读
Web前端
CSS
JavaScript
交互
Vue
小程序
后端
运维
项目
生活
其他
转载
软件
职场
登录
Search
标签搜索
docker
DevOps
magic-boot
Linux
酷壳
RabbitMQ
gitlab
Node
git
工具
MybatisPlus
clickhouse
Syncthing
规范
前端
产品
nginx
markdown
axios
H5
朱治龙
累计撰写
139
篇文章
累计收到
7
条评论
首页
栏目
Web前端
CSS
JavaScript
交互
Vue
小程序
后端
运维
项目
生活
其他
转载
软件
职场
页面
留言
友链
关于
搜索到
1
篇与
WebGL
的结果
2022-04-11
WebGL实战解析(一) - 学习笔记
3D基本元素2D坐标系2D坐标系由x轴和y轴构成。其中,笛卡尔坐标系是最常见的2D坐标系。笛卡尔坐标系规定y轴向上为正方向,x轴向右为正方向HTML5 Canvas 2D坐标系原点(0,0)为左上角,向右为x轴的正方向,向下为y轴的正方向3D坐标系在2D坐标系上增加了表示深度的z轴,即3D物体里屏幕的深度HTML5 WebGL 3D坐标系绘图的可是范围为[-1,+1]网格与3D图形三角形是基础图形3D图形由一个或多个三角形组成网格由一个或多个图形组成,网格也叫模型法线始终垂直于某平面的虚线。在几何中,法线是指平面上垂直于曲线在某点切线的直线。3D变换概念变换原理是对顶点的改变变换的缩放、平移和旋转矩阵逐个顶点的变换方法是复杂乏味的矩阵是复杂性解决之道网格表面纹理与材质一个网格构成了物体的形状,纹理可以定义网格表面的外观纹理可以定义网格表面的外观材质是网格表面的特性光照原理光线方向决定物体的明暗度与阴影在着色过程中,需要考虑光源类型与反射类型光源类型平行光点光源光环境光反射类型漫反射:光色由入射光色、表面漆色和入射角决定环境反射:由入射光色和表面漆色决定着色器替代传统的固定渲染管线可编程性顶点着色器顶点着色器用来描述顶点的位置、颜色的程序片元着色器片元着色器是对网格表面像素的处理程序。3D 世界与立方体立方体的构成一个正方形的立方体在WebGL程序中,实际上是绘制了12个三角形,再对它的表面进行着色,最终形成我们看到的效果。模型文件格式相机、视口和投影左下角的眼睛代表相机,相机角度的不同,观察到的场景的景象就是不同的。而它的远近(x)就决定了他到的物体的大小。图中的绿色区域代表视口,通俗的讲就是WebGL Canvas决定的,它的大小也就决定了它可视化的范围。后面红色的区域能够显示场景的最远距离到哪里。红绿块之间的可视化椎体,就决定了可视化世界的范围。最终的影像会在可视化视口中呈现出来。投影的概念就是物体投影到前方视口上最终形成的影像通过对相机角度的不同,它的椎体肯定是有变化的,它看到的投影到视口上的影像肯定也是不同的。第一个WebGL程序开发WebGL程序的基本步骤得到canvas标签得到绘制上下文对象编写着色器初始化着色器绘制代码实现<!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>第一个WebGL程序</title> <script src="./lib.js"></script> </head> <body> <canvas id="webgl" width="500" height="500"></canvas> <script> var canvasElement = document.getElementById('webgl') const context = canvasElement.getContext('webgl') // 绘制顶点着色器 const vertexShaderSource = ` attribute vec4 apos; void main() { gl_PointSize=20.0; gl_Position = apos; } ` // 绘制片元着色器 const fragShaderSource = ` void main(){ gl_FragColor = vec4(1.0,0.0,0.0,1.0); } ` const program = initShader(context, vertexShaderSource, fragShaderSource) const aposLocation = context.getAttribLocation(program, 'apos') context.clearColor(0.2, 0.3, 0.5, 1.0) context.clear(context.COLOR_BUFFER_BIT) let x = 0.0 let y = 0.0 for(var i = 0, j = 0.1; i< 10; i++){ x += y y += j context.vertexAttrib4f(aposLocation, x, y, 0.0, 1.0) context.drawArrays(context.POINTS, 0, 1) } </script> </body> </html> // lib.js /** * * @param {CanvasContext} gl Canvas Context 对象 * @param {*} vertexShaderSource 顶点着色器源码 * @param {*} fragmentShaderSource 片元着色器源码 * @returns */ const initShader = function(gl, vertexShaderSource, fragmentShaderSource) { // 创建一个空的顶点着色器对象 const vertexShader = gl.createShader(gl.VERTEX_SHADER) // 创建一个空的片元着色器对象 const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER) // 加入源代码 gl.shaderSource(vertexShader, vertexShaderSource) gl.shaderSource(fragmentShader, fragmentShaderSource) // 编译源代码 gl.compileShader(vertexShader) gl.compileShader(fragmentShader) // 创建内部调用的应用程序 var program = gl.createProgram() // 将着色器附着在应用程序上 gl.attachShader(program, vertexShader) gl.attachShader(program, fragmentShader) // 连接 gl.linkProgram(program) gl.useProgram(program) // 输出调试日志 console.log(gl.getShaderInfoLog(fragmentShader)) return program } WebGL 缓冲区对象attribute 变量的使用在顶点着色器中,声明 attribute 变量将 attribute 变量赋值给 gl_Position 变量向 attribute 变量传递数据缓冲区对象的创建与绑定缓冲区对象是绘制面所必须的技术,否则只能绘制点,它可以一次性地写入多个顶点数据,这样就可以为我们描绘出一个图形的轮廓,它可以是一块内存区域,这块内存区域通常来说很可能是显卡分配的创建步骤1、创建缓冲区的方法 var buffer = gl.createBuffer()2、根据返回值判断是否创建成功3、绑定缓冲区方法 gl.bindBuffer(gl.ARRAY_BUFFER,buffer)向缓冲区内写入数据gl.bufferData(gl.ARRAY_BUFFER, data, useMethod)data:是类型化数组useMethod:如何使用内存中的数据,可选值有:gl.STATIC_DRAW 一次性写入,多次绘制gl.STREAM_DRAW 一次性写入,调用几次,比第一次调用的要少,但都是写入一次gl.DYNAMIC_DRAW 多次写入,多次绘制类型化数组:Int8Array Unit8ArrayInt16Array Unit16ArrayInt32Array Unit32ArrayFloat32Array 最常用Float64Array缓冲区数据导入 attribute变量vertexAttribPointer(location, size, type, normalized, stride, offset)完整代码示例<!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> <script src="./lib.js"></script> </head> <body> <canvas id="webglcanvas" width="500" height="500"></canvas> <script> var ctx = document.getElementById('webglcanvas').getContext('webgl') var vertexShaderSource = ` attribute vec4 apos; void main(){ gl_Position = apos; gl_PointSize = 15.0; } ` var fragmentShaderSource = ` void main(){ gl_FragColor = vec4(1.0,0.0,0.0,1.0); } ` var buf = ctx.createBuffer() ctx.bindBuffer(ctx.ARRAY_BUFFER, buf) var program = initShader(ctx,vertexShaderSource,fragmentShaderSource) var aposLocation = ctx.getAttribLocation(program, 'apos') var data = new Float32Array([ 0.6,0.8, 0.2,0.5, -1.0,1.0, 1.0,1.0, -1.0,-1.0, 1.0,-1.0, 0.0,0.0 ]) ctx.bufferData(ctx.ARRAY_BUFFER, data, ctx.STATIC_DRAW) ctx.vertexAttribPointer(aposLocation, 2, ctx.FLOAT, false, 0, 0) ctx.enableVertexAttribArray(aposLocation) ctx.clearColor(0.0,0.0,1.0,1.0) ctx.clear(ctx.COLOR_BUFFER_BIT) // var points = [ // {x:0, y:0}, // {x:0.6, y:0.8}, // {x:0.2, y:0.5} // ] // for(var i = 0; i< points.length; i++) { // ctx.vertexAttrib4f(aposLocation, points[i].x, points[i].y, 1.0, 1.0) // ctx.drawArrays(ctx.POINTS, 0, 3) // } ctx.drawArrays(ctx.POINTS, 0, 7) </script> </body> </html> WebGL 基本图形绘制点的绘制gl.drawArrays(gl.POINTS, 0, 1)线段的绘制绘制线gl.drawArrays(gl.LINES, start, count)var vertexShaderSource = ` attribute vec4 aPos; void main() { gl_Position = aPos; gl_PointSize = 20.5; } ` var fragmentShaderSource = ` void main() { gl_FragColor = vec4(1.0,0.0,0.0,1.0); } ` var gl = document.getElementById('canvas').getContext('webgl') var program = initShader(gl,vertexShaderSource,fragmentShaderSource) var posLocation = gl.getAttribLocation(program, 'aPos') var data = new Float32Array([ 0.0,0.0,0.5,0.5, 0.3,0.6,-0.3,-0.9 ]) var buffer = gl.createBuffer() gl.bindBuffer(gl.ARRAY_BUFFER, buffer) gl.bufferData(gl.ARRAY_BUFFER, data, gl.STATIC_DRAW) gl.vertexAttribPointer(posLocation, 2, gl.FLOAT, false, 0, 0) gl.enableVertexAttribArray(posLocation) gl.clearColor(0.0, 0.0, 0.0, 1.0) gl.clear(gl.COLOR_BUFFER_BIT) gl.drawArrays(gl.LINES, 0, 4)运行效果:绘制多线段gl.drawArray(gl.LINE_STRIP, start, count)绘制Z形线var vertexShaderSource = ` attribute vec4 aPos; void main() { gl_Position = aPos; gl_PointSize = 20.5; } ` var fragmentShaderSource = ` void main() { gl_FragColor = vec4(1.0,0.0,0.0,1.0); } ` var gl = document.getElementById('canvas').getContext('webgl') var program = initShader(gl,vertexShaderSource,fragmentShaderSource) var posLocation = gl.getAttribLocation(program, 'aPos') var data = new Float32Array([ -0.5,0.5, 0.5,0.5, -0.5,-0.5, 0.5,-0.5 ]) var buffer = gl.createBuffer() gl.bindBuffer(gl.ARRAY_BUFFER, buffer) gl.bufferData(gl.ARRAY_BUFFER, data, gl.STATIC_DRAW) gl.vertexAttribPointer(posLocation, 2, gl.FLOAT, false, 0, 0) gl.enableVertexAttribArray(posLocation) gl.clearColor(0.0, 0.0, 0.0, 1.0) gl.clear(gl.COLOR_BUFFER_BIT) gl.drawArrays(gl.LINE_STRIP, 0, 4)绘制矩形框// 绘制矩形框 var vertexShaderSource = ` attribute vec4 aPos; void main() { gl_Position = aPos; gl_PointSize = 20.5; } ` var fragmentShaderSource = ` void main() { gl_FragColor = vec4(1.0,0.0,0.0,1.0); } ` var gl = document.getElementById('canvas').getContext('webgl') var program = initShader(gl,vertexShaderSource,fragmentShaderSource) var posLocation = gl.getAttribLocation(program, 'aPos') var data = new Float32Array([ -0.5,0.5, 0.5,0.5, 0.5,-0.5, -0.5,-0.5, -0.5,0.5 ]) var buffer = gl.createBuffer() gl.bindBuffer(gl.ARRAY_BUFFER, buffer) gl.bufferData(gl.ARRAY_BUFFER, data, gl.STATIC_DRAW) gl.vertexAttribPointer(posLocation, 2, gl.FLOAT, false, 0, 0) gl.enableVertexAttribArray(posLocation) gl.clearColor(0.0, 0.0, 0.0, 1.0) gl.clear(gl.COLOR_BUFFER_BIT) gl.drawArrays(gl.LINE_STRIP, 0, 5)绘制回路线段gl.drawArray(gl.LING_LOOP,start, count)可以把最后一个顶点跟第一个顶点连接在一起// 绘制回路线段 var vertexShaderSource = ` attribute vec4 aPos; void main() { gl_Position = aPos; gl_PointSize = 20.5; } ` var fragmentShaderSource = ` void main() { gl_FragColor = vec4(1.0,0.0,0.0,1.0); } ` var gl = document.getElementById('canvas').getContext('webgl') var program = initShader(gl,vertexShaderSource,fragmentShaderSource) var posLocation = gl.getAttribLocation(program, 'aPos') var data = new Float32Array([ -0.5,0.5, 0.5,0.5, 0.5,-0.5, -0.5,-0.5 ]) var buffer = gl.createBuffer() gl.bindBuffer(gl.ARRAY_BUFFER, buffer) gl.bufferData(gl.ARRAY_BUFFER, data, gl.STATIC_DRAW) gl.vertexAttribPointer(posLocation, 2, gl.FLOAT, false, 0, 0) gl.enableVertexAttribArray(posLocation) gl.clearColor(0.0, 0.0, 0.0, 1.0) gl.clear(gl.COLOR_BUFFER_BIT) gl.drawArrays(gl.LINE_LOOP, 0, 4)多边形的绘制gl.drawArray(gl.TRIANGLES, start, count)// 绘制三角形 var vertexShaderSource = ` attribute vec4 aPos; void main() { gl_Position = aPos; gl_PointSize = 20.5; } ` var fragmentShaderSource = ` void main() { gl_FragColor = vec4(1.0,0.0,0.0,1.0); } ` var gl = document.getElementById('canvas').getContext('webgl') var program = initShader(gl,vertexShaderSource,fragmentShaderSource) var posLocation = gl.getAttribLocation(program, 'aPos') var data = new Float32Array([ 0.0,0.0, -0.5,-0.5, 0.5,-0.5 ]) var buffer = gl.createBuffer() gl.bindBuffer(gl.ARRAY_BUFFER, buffer) gl.bufferData(gl.ARRAY_BUFFER, data, gl.STATIC_DRAW) gl.vertexAttribPointer(posLocation, 2, gl.FLOAT, false, 0, 0) gl.enableVertexAttribArray(posLocation) gl.clearColor(0.0, 0.0, 0.0, 1.0) gl.clear(gl.COLOR_BUFFER_BIT) gl.drawArrays(gl.TRIANGLES, 0, 3)绘制三角带gl.drawArray(gl.TRIANGLE_STRIP,start, count)// 绘制平行四边形 var vertexShaderSource = ` attribute vec4 aPos; void main() { gl_Position = aPos; gl_PointSize = 20.5; } ` var fragmentShaderSource = ` void main() { gl_FragColor = vec4(1.0,0.0,0.0,1.0); } ` var gl = document.getElementById('canvas').getContext('webgl') var program = initShader(gl,vertexShaderSource,fragmentShaderSource) var posLocation = gl.getAttribLocation(program, 'aPos') var data = new Float32Array([ -0.3,0.3, 0.5,0.3, -0.5,-0.3, 0.3, -0.3 ]) var buffer = gl.createBuffer() gl.bindBuffer(gl.ARRAY_BUFFER, buffer) gl.bufferData(gl.ARRAY_BUFFER, data, gl.STATIC_DRAW) gl.vertexAttribPointer(posLocation, 2, gl.FLOAT, false, 0, 0) gl.enableVertexAttribArray(posLocation) gl.clearColor(0.0, 0.0, 0.0, 1.0) gl.clear(gl.COLOR_BUFFER_BIT) gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4)绘制三角扇gl.drawArray(gl.TRIANGLE_FAN, start, count)// 绘制六边形 var vertexShaderSource = ` attribute vec4 aPos; void main() { gl_Position = aPos; gl_PointSize = 20.5; } ` var fragmentShaderSource = ` void main() { gl_FragColor = vec4(1.0,0.0,0.0,1.0); } ` var gl = document.getElementById('canvas').getContext('webgl') var program = initShader(gl,vertexShaderSource,fragmentShaderSource) var posLocation = gl.getAttribLocation(program, 'aPos') var data = new Float32Array([ 0.0,0.0, -0.3,0.5, -0.6,0.0, -0.3,-0.5, 0.3,-0.5, 0.6,0.0, 0.3,0.5, -0.3,0.5 ]) var buffer = gl.createBuffer() gl.bindBuffer(gl.ARRAY_BUFFER, buffer) gl.bufferData(gl.ARRAY_BUFFER, data, gl.STATIC_DRAW) gl.vertexAttribPointer(posLocation, 2, gl.FLOAT, false, 0, 0) gl.enableVertexAttribArray(posLocation) gl.clearColor(0.0, 0.0, 0.0, 1.0) gl.clear(gl.COLOR_BUFFER_BIT) gl.drawArrays(gl.TRIANGLE_FAN, 0, 8)WebGL 图形变换图形的移动原理图形的移动,实际上就是定量改变顶点的位置,在顶点着色器中,顶点修改是逐个进行的,且偏移值一致平移代码示例var main = function() { // 顶点着色器 var vertexShaderSource = ` attribute vec4 pos; uniform float a; uniform float b; void main() { gl_Position.x = pos.x + a; gl_Position.y = pos.y + b; gl_Position.z = 0.0; gl_Position.w = 1.0; } ` // 片元着色器 var fragmentShaderSource = ` void main() { gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); } ` var gl = document.getElementById('canvas').getContext('webgl') var buffer = gl.createBuffer() gl.bindBuffer(gl.ARRAY_BUFFER, buffer) var data = new Float32Array([ 0.0,0.0, -0.5,-0.5, 0.5,-0.5 ]) gl.bufferData(gl.ARRAY_BUFFER, data, gl.STATIC_DRAW) var program = initShader(gl, vertexShaderSource, fragmentShaderSource) var a = 0.0, b = 0.0 var posLocation = gl.getAttribLocation(program, 'pos') var aLocation = gl.getUniformLocation(program, 'a') var bLocation = gl.getUniformLocation(program, 'b') gl.vertexAttribPointer(posLocation, 2, gl.FLOAT, false, 0, 0) gl.enableVertexAttribArray(posLocation) var run = function() { gl.uniform1f(aLocation, a) gl.uniform1f(bLocation, b) gl.clearColor(0.0, 0.0, 1.0, 1.0) gl.clear(gl.COLOR_BUFFER_BIT) gl.drawArrays(gl.TRIANGLES, 0, 3) a += 0.05 b += 0.05 setTimeout(run, 50) } run() } main()图形的缩放顶点不变的方式缩放var main = function() { // 顶点着色器 var vertexShaderSource = ` attribute vec4 pos; uniform float zoomRadio; void main() { gl_Position.x = pos.x * zoomRadio; gl_Position.y = pos.y * zoomRadio; gl_Position.z = 0.0; gl_Position.w = 1.0; } ` // 片元着色器 var fragmentShaderSource = ` void main() { gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); } ` var gl = document.getElementById('canvas').getContext('webgl') var buffer = gl.createBuffer() gl.bindBuffer(gl.ARRAY_BUFFER, buffer) var data = new Float32Array([ 0.0,0.0, -0.5,-0.5, 0.5,-0.5 ]) gl.bufferData(gl.ARRAY_BUFFER, data, gl.STATIC_DRAW) var program = initShader(gl, vertexShaderSource, fragmentShaderSource) var zoomRatio = Math.random() var posLocation = gl.getAttribLocation(program, 'pos') var zoomLocation = gl.getUniformLocation(program, 'zoomRadio') gl.vertexAttribPointer(posLocation, 2, gl.FLOAT, false, 0, 0) gl.enableVertexAttribArray(posLocation) var run = function() { gl.uniform1f(zoomLocation, zoomRatio) gl.clearColor(0.0, 0.0, 1.0, 1.0) gl.clear(gl.COLOR_BUFFER_BIT) gl.drawArrays(gl.TRIANGLES, 0, 3) zoomRatio = Math.random() setTimeout(run, 500) } run() } main()图形的旋转var main = function() { // 顶点着色器 var vertexShaderSource = ` attribute vec4 pos; uniform float sinB; uniform float cosB; void main() { gl_Position.x = pos.x * cosB - pos.y * sinB; gl_Position.y = pos.x * sinB + pos.y * cosB; gl_Position.z = 0.0; gl_Position.w = 1.0; } ` // 片元着色器 var fragmentShaderSource = ` void main() { gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); } ` var gl = document.getElementById('canvas').getContext('webgl') var data = new Float32Array([ 0.0,0.0, -0.5,-0.5 ]) gl.bufferData(gl.ARRAY_BUFFER, data, gl.STATIC_DRAW) var program = initShader(gl, vertexShaderSource, fragmentShaderSource) bindAttribute(gl, 'pos', data, program) var sinB, sinBLocation,cosB, cosBLocation sinBLocation = gl.getUniformLocation(program, 'sinB') cosBLocation = gl.getUniformLocation(program, 'cosB') var angle = -135; setInterval(function() { angle -= 1 var t = Math.PI * angle / 180 sinB = Math.sin(t) cosB = Math.cos(t) gl.uniform1f(sinBLocation, sinB) gl.uniform1f(cosBLocation,cosB) gl.clearColor(0.0, 0.0, 1.0, 1.0) gl.clear(gl.COLOR_BUFFER_BIT) gl.drawArrays(gl.LINES, 0, 2) }, 1000) } main()
2022年04月11日
35 阅读
0 评论
0 点赞