WebGL

从零开始手撸WebGL3D引擎2:WebGL和3D编程基础概念

佐手、 提交于 2020-01-28 04:53:38
我们在第一篇里面浏览了一下WebGL的参考卡片,也列出了一些WebGL的功能点,但是对于没有接触过3D编程的人来说,这些东西很难理解并形成一个统一的认识。所以这篇我就以WebGL为参考平台谈谈3D编程的一些基础概念。 3D坐标系变换 正常来说,人们学习新东西都会从已有的知识出发,对于3D编程,在屏幕上画出3D图形,如果有2D图形API使用的基础,就会想着从2D编程的经验出发。比如对于2D编程,都是指定一个屏幕坐标,设定一个颜色,去画一个点,你能画点就能画任何东西,很简单很直观。但是到3D这儿就不行了,因为你没法简单直接且直观的指定一个立方体的各个点在屏幕上是什么位置。为了解决这个问题,在3D编程中,需要将3D空间的点变换到屏幕空间,即我们在3D空间指定点的坐标(一组3d坐标),然后设置一个摄像机,将摄像机镜头拍到的点映射到屏幕上,这样就可以绘制出来。这个过程就需要用不同的坐标空间,以及在这些坐标空间之间变换坐标。简单说一说。 模型空间 3D模型通常由很多三角形构成,而每个三角形又是由三个顶点构成。一个3D模型有很多顶点,这个顶点的坐标定义在模型自身的坐标系中,这个坐标系就是模型空间。坐标系的原点根据模型的形状特点以及使用的方便情况而设置。比如两足动物(人)的模型,通常将坐标原点放在两脚中间。而球的模型中心一般放在球心。使用模型空间一方面建模方便,另一方面同样的模型可以复用

WebGL渲染2D图形

拥有回忆 提交于 2020-01-27 13:59:48
WebGL是通过OpenGL ES在HTML的<canvas></canvas>上渲染图形的。 ... <canvas id="main-canvas"></canvas> ... let gl = document.getElementById("main-canvas").getContext("webgl"); if (!gl) { alert("无法使用WebGL!"); } else { console.log(gl); } 这样,就获取到了在canvas上渲染webgl的上下文。 接下来,在canvas上一切的渲染操作,最终都是要依靠这个gl变量来控制的。 不过在此之前,需要作一下前期准备。 着色器准备 首先要准备一下着色器的源码,着色器(shader)是由GLSL(OpenGL Shadering Language,一种类C++语言)编写的计算机程序。着色器是成对出现的,分别是顶点着色器: <script type="notjs" id="vertex-shader-2d"> attribute vec4 a_position; void main() { gl_Position = a_position; } </script> 和片段着色器: <script type="notjs" id="fragment-shader-2d"> precision

从0开发3D引擎(九):实现最小的3D程序-“绘制三角形”

冷暖自知 提交于 2020-01-26 20:01:03
目录 上一篇博文 运行测试截图 需求分析 目标 特性 头脑风暴 确定需求 总体设计 具体实现 新建Engine3D项目 实现上下文 实现_init 实现“获得WebGL上下文” 实现“初始化所有Shader” 实现“初始化场景” 实现“设置清空颜色缓冲时的颜色值” 返回用于主循环的数据 实现_loop 实现“主循环” 实现“clearCanvas” 实现“_render” 最终的分层和领域模型 总结 本文完整代码地址 大家好,本文开始编程,实现最小的3D程序。 我们首先进行需求分析,确定功能点; 然后进行总体设计,划分模块,并且对模块进行顶层设计,给出类型签名和实现的伪代码; 最后进行具体实现,实现各个模块。 注:在Reason中,一个Reason文件(如Main.re)就是一个模块(Module)。 上一篇博文 从0开发3D引擎(八):准备“搭建引擎雏形” 运行测试截图 测试场景包括三个三角形: 需求分析 首先,我们分析最小3D程序的目标和特性; 接着,根据特性,我们进行头脑风暴,识别出功能关键点和扩展点; 最后,根据功能关键点和扩展点,我们确定最小3D程序的功能点。 目标 可从最小3D程序中提炼出通用的、最简化的引擎雏形 特性 为了达成目标,最小3D程序应该具备以下的特性: 简单 最小3D程序应该很简单,便于我们分析和提炼。 具有3D程序的通用特性

WebGL: using framebuffers for picking multiple objects

非 Y 不嫁゛ 提交于 2020-01-25 11:53:27
问题 I am trying to implement picking in WebGL. I have a lot of objects (around 500), and I'd like each one to be allowed to be picked. In order to do that, I did a loop which assigns a unique colour to each object (cf. picking principle): for (var i = 0, len = objects.length; i < len; i++) { framecolors[count++] = i % 256 / 256; //Red framecolors[count++] = Math.floor(i/256) / 256; //Green framecolors[count++] = Math.floor(i/(256*256)) / 256; //Blue } framecolors was then used in a classical

WebGL Matrix4(4*4矩阵库)

為{幸葍}努か 提交于 2020-01-25 09:33:18
Matrix4是由<<WebGL编程指南>>作者写的提供WebGL的4*4矩阵操作的方法库,简化我们编写的代码。源代码共享地址,点击链接: Matrix4源代码 。 下面罗列了Matrix4库的所有方法: 1.setIdentity() 将Matrix4实例初始化为单位阵 2.setTranslate(x, y, z) 将Matrix4实例设置为平移变换矩阵,在x轴上平移的距离为x,在y轴上平移的距离为y,在z轴上平移的距离为z 3.setRotate(angle, x, y, z) 将Matrix4实例设置为旋转变换矩阵,旋转角度为angle,旋转轴为(x, y, z)。旋转轴(x,y,z)无需归一化 4.setScale(x, y, z) 将Matrix4实例设置为缩放变换矩阵,在三个轴上的缩放因子分别为x、y、z 5.translate(x, y, z) 将Matrix4实例生意一个平移变换矩阵(该平移矩阵在x轴上的平移距离为x,在y轴上的平移距离为y,在z轴上的平移距离为z),所得到的结果存储在Matrix4中 6.rotate(angle, x, y, z) 将Matrix4实例乘以一个旋转变换矩阵(该旋转矩阵旋转的角度为angle,旋转轴为(x、y、z)。旋转轴(x、y、z)无须归一化),所得的记过还存储在Matrix4中 7.scale(x, y, z)

Is there a way to cache slow WebGL shader compilation if the shader never changes?

隐身守侯 提交于 2020-01-25 00:19:19
问题 I have a WebGL shader which compiles perceptually immediately (Chrome on Windows 7) when I have this: void main(void) { if (antialias_level == 1) gl_FragColor = NewtonIteration((gl_FragCoord.xy + offset) / zoom); else if (antialias_level == 2) gl_FragColor = (NewtonIteration((gl_FragCoord.xy + offset + vec2(-0.25, -0.25)) / zoom) + NewtonIteration((gl_FragCoord.xy + offset + vec2(0.25, 0.25)) / zoom)) * 0.5; } But it takes a very long time (~10 sec) to compile this: void main(void) { if

Is there a way to cache slow WebGL shader compilation if the shader never changes?

你离开我真会死。 提交于 2020-01-25 00:19:06
问题 I have a WebGL shader which compiles perceptually immediately (Chrome on Windows 7) when I have this: void main(void) { if (antialias_level == 1) gl_FragColor = NewtonIteration((gl_FragCoord.xy + offset) / zoom); else if (antialias_level == 2) gl_FragColor = (NewtonIteration((gl_FragCoord.xy + offset + vec2(-0.25, -0.25)) / zoom) + NewtonIteration((gl_FragCoord.xy + offset + vec2(0.25, 0.25)) / zoom)) * 0.5; } But it takes a very long time (~10 sec) to compile this: void main(void) { if

WebGL 颜色与纹理

最后都变了- 提交于 2020-01-24 09:50:14
1.纹理坐标 纹理坐标是纹理图像上的坐标,通过纹理坐标可以在纹理图像上获取纹理颜色。WebGL系统中的纹理坐标系统是二维的,如图所示。为了将纹理坐标和广泛使用的x、y坐标区分开来,WebGL使用s和t命名纹理坐标(st坐标系统)。 纹理图像的四个角坐标为左下角(0.0,0.0),右下角(1.0,0.0),右上角(1.0, 1.0)和左上角(0.0, 1.0)。纹理坐标很通用,因为坐标值与图像自身的尺寸无关,不管是128*128还是128*256的图像,右上角的纹理坐标始终是(1.0, 1.0)。 2.纹理映射步骤 1.准备好映射到几何图形上的纹理图像。 2.为几何图形配置纹理映射方式。 3.加载纹理图像,对其进行写配置,以在WebGL中使用它。 4.在片元着色器中将相应的纹理从纹理中抽取出来,并将纹素的颜色赋给片元。 3.gl.createTexture() 创建纹理对象以存储纹理图像。 4.gl.deleteTexture() 使用textur删除纹理对象。如果删除一个已经被删除的纹理对象,不会报错也不会产生任何影响。 5.gl.pixelStorei(pname, param) 使用pname和param指定的方式处理加载得到的图像。参数 pname:可以是以下二者之一。gl.UNPACK_FLIP_Y_WEBGL,对图像进行Y轴反转。默认值为false;gl.UNPACK

Performance drops when trying to reset whole scene with Three.js

只愿长相守 提交于 2020-01-24 08:22:08
问题 In my current project Im using Threejs for buildin a level with meshes. All the graphical stuff with camera, scene, projector, renderer and so on is done in one object. For test purposes I want to reset the whole scene with different parameters, for example different level sizes. Because I want measure time of an algorithm I want a "full" reset. So my current approach is deleting the div-box containing the scene/canvas and deleting the whole object which has the threejs code. After this I

Performance drops when trying to reset whole scene with Three.js

对着背影说爱祢 提交于 2020-01-24 08:20:22
问题 In my current project Im using Threejs for buildin a level with meshes. All the graphical stuff with camera, scene, projector, renderer and so on is done in one object. For test purposes I want to reset the whole scene with different parameters, for example different level sizes. Because I want measure time of an algorithm I want a "full" reset. So my current approach is deleting the div-box containing the scene/canvas and deleting the whole object which has the threejs code. After this I