当前位置: 首页 > Web前端 > JavaScript

Graphicstextures-WebGL编码简介

时间:2023-03-27 11:29:52 JavaScript

背景本文收录在《数据可视化和图形学》专栏。首先,上一篇文章中Canvas2D和WebGL的简单对比可以看出,WebGL的API比较难理解。所以我觉得后续的编码更多的是使用WebGL来实现我们的效果(嘿嘿,随便玩~)当然知识点还是由简单到复杂。..如果我引入视觉物理、光照/全局光照、抗锯齿、延迟渲染、实时渲染……也许我创建专栏的初衷就失去了;当然,如果想深入探讨,可以私下交流。上面实现了简单的二维图形。有需要的可以参考前面课文的大纲。什么是纹理?2d和3d纹理贴图之间的区别?TheTexturingPipelinecoding(WebGL中纹理的简单使用)1.什么是纹理?区别?在计算机图形学中,纹理是使用图像、函数或其他数据源来改变对象表面外观的技术。2D纹理2D纹理(2Dtexture)是一种简单的位图图像,用来为3D模型提供表面点的颜色值3D纹理3D纹理(3Dtexture),可以认为是由很多2D纹理组成的,用一张图片描绘了三个维空间数据。2.通用纹理管线TexturingPipeline渲染管线对于日常使用来说可能是个黑盒子,但是了解这个会对你的编程有很大的提升...(看不懂也没关系,本地copy。哈哈)简单换句话说,纹理是一种“建模”对象表面属性的有效技术。图像纹理中的像素通常称为纹素,与屏幕上的像素不同。请看下图---将纹理贴图应用到单个纹理的详细过程。投影函数(projectorfunction)是将空间中的三维点转换为纹理坐标,即获取表面的位置,并将其投影到参数空间中。例如,有与球面、圆柱面和平面投影相关的函数。Corresponder函数用于将参数空间坐标转换为纹理空间位置。第一步。通过对空间中的点应用投影函数,得到一组关于纹理的值,称为参数空间值。第二步。在使用这些新值访问纹理之前,可以使用一个或多个对应函数将参数空间值转换为纹理空间。第三步。使用这些纹理空间位置从纹理中获取相应的值。例如,图像纹理的数组索引可用于检索像素值。第四步。然后利用值变换函数(valuetransformfunction)对检索结果进行值变换,最后利用得到的值改变表面属性,如材质或着色法线等。normal/normalvector相关知识需要自己补充。在图形(经常看到)编码中很重要(WebGL中简单使用texturemap2d)简单的用WebGL实现一个texture(map),通过一个matrix进行animate(旋转)插入的gif有点卡...1.Shader编写添加纹理坐标和修改顶点坐标(使用矩阵/旋转)//纹理坐标传输v_texcoord=a_texcoord;}//片段着色器精度mediumpfloat;varyingvec2v_texcoord;uniformsampler2Du_texture;voidmain(){gl_FragColor=texture2D(u_texture,v_texcoord);}2.初始化上下文(renderingcontext)和着色器程序varcanvas=document.querySelector("#canvas");vargl=canvas.getContext("webgl");if(!gl){return;}3.初始设置GLSLProgramand添加新缓冲区(纹理)//设置GLSL程序varprogram=webglUtils.createProgramFromScripts(gl,["vertex-shader","fragment-shader"]);//获取需要绑定顶点坐标的地方varpositionLocation=gl.getAttribLocation(program,"a_position");vartexcoordLocation=gl.getAttribLocation(program,"a_texcoord");//获取制服varmatrixLocationcation=gl.getUniformLocation(program,"u_matrix");vartextureLocation=gl.getUniformLocation(program,"u_texture");//创建缓冲区varpositionBuffer=gl.createBuffer();gl.bindBuffer(gl.ARRAY_BUFFER,positionBuffer);变量位置=[-1,-1,-1,1,1,-1,1,-1,-1,1,1,1,];gl.bufferData(gl.ARRAY_BUFFER,newFloat32Array(positions),gl.STATIC_DRAW);//为纹理坐标创建缓冲区vartexcoordBuffer=gl.createBuffer();gl.bindBuffer(gl.ARRAY_BUFFER,texcoordBuffer);vartexcoords=[0,0,0,1,1,0,1,0,0,1,1,1,];gl.bufferData(gl.ARRAY_BUFFER,newFloat32Array(texcoords),gl.STATIC_DRAW);4.创建并加载纹理//解决图片跨域问题functionrequestCORSIfNotSameOrigin(img,url){if((newURL(url,window.location.href)).origin!==window.location.origin){img.crossOrigin="";}}//创建纹理{width:w,height:h,texture:tex}//初始化1x1px像素图像加载和更新函数loadImageAndCreateTextureInfo(url){vartex=gl.createTexture();gl.bindTexture(gl.TEXTURE_2D,tex);//用1x1蓝色像素填充纹理。gl.texImage2D(gl.TEXTURE_2D,0,gl.RGBA,1,1,0,gl.RGBA,gl.UNSIGNED_BYTE,newUint8Array([0,0,255,255]));//假设所有图像都不是2的幂gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_WRAP_S,gl.CLAMP_TO_EDGE);gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_WRAP_T,gl.CLAMP_TO_EDGE);gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_MIN_FILTER,gl.LINEAR);vartextureInfo={width:1,height:1,texture:tex,};varimg=新图像();img.addEventListener('load',function(){textureInfo.width=img.width;textureInfo.height=img.height;gl.bindTexture(gl.TEXTURE_2D,textureInfo.texture);//调用texImage2D()把已加载将图片数据写入纹理gl.texImage2D(gl.TEXTURE_2D,0,gl.RGBA,gl.RGBA,gl.UNSIGNED_BYTE,img);render()});请求CORSIfNotSameOri杜松子酒(img,网址);img.src=网址;returntextureInfo;}//加载纹理vartexInfo=loadImageAndCreateTextureInfo('https://webglfundamentals.org/webgl/resources/leaves.jpg');5.绘图相关设置纹理坐标和分配的矩阵坐标是使用着色器程序绘制的。函数渲染(时间){时间*=0.001;//时间加速旋转图像//重置画布大小webglUtils.resizeCanvasToDisplaySize(gl.canvas);//裁剪像素区域gl.viewport(0,0,gl.canvas.width,gl.canvas.height);gl.clear(gl.COLOR_BUFFER_BIT);gl.bindTexture(gl.TEXTURE_2D,texInfo.texture);//使用着色器程序gl.useProgram(program);//设置参数,让我们可以绘制任意大小的图像gl.bindBuffer(gl.ARRAY_BUFFER,positionBuffer);gl.enableVertexAttribArray(positionLocation);gl.vertexAttribPointer(positionLocation,2,gl.FLOAT,false,0,0);gl.bindBuffer(gl.ARRAY_BUFFER,texcoordBuffer);gl.enableVertexAttribArray(texcoordLocation);gl.vertexAttribPointer(texcoordLocation,2,gl.FLOAT,false,0,0);varaspect=gl.canvas.clientWidth/gl.canvas.clientHeight;可变矩阵=m4。缩放(1,方面,1);//但是尝试将aspect改为0.1看看效果--matrix=m4.zRotate(matrix,time);矩阵=m4.scale(矩阵,0.5,0.5,1);//设置矩阵gl.uniformMatrix4fv(matrixLocation,f另外,矩阵);//从第0个单元开始获取纹理gl.uniform1i(textureLocation,0);//绘制(2个三角形,6个顶点)gl.drawArrays(gl.TRIANGLES,0,6);requestAnimationFrame(render);}webgl-utils.jswebgl相关函数封装工具库m4.js矩阵相关数学函数库完整代码示例请点击git仓库查看代码示例二维渲染你可能需要了解的纹理缓存纹理压缩2D/2D纹理优化渲染优化……最后强烈希望大家学习相关的理论知识;理论在日常生活中可能很少用到,但它可以决定你能走多远(有人问怎么办,勤练),写作速度我会加快本专栏(每周1-2篇)和其他专栏(1篇)计算机图形学相关的基础知识将再次覆盖。然后后续主要写数据可视化方向。