精华内容
下载资源
问答
  • 解压密码:RJ4587 今天要给大家分享一个非常炫酷的HTML5 3D樱花飘落动画,基于WebGL技术。每一片樱花落叶都是在canvas上绘制而成,而且樱花叶片也会随着不同的角度发出不同的色泽光芒,总体呈现出3D立体的视觉效果...
  • webGL3D机房模型

    2018-10-17 16:19:29
    一个基于webGL3D机房demo,实现了烟雾、巡检、漏水、机柜容量等功能
  • webGL教程,十分全面包括了Threejs的使用,部署等操作。基于浏览器的动效,一般用于最新的谷歌浏览器适用性更强。
  • HTML5+WebGL 3D雪花飘落动画特效,比较逼真的一款下雪网页背景动画效果。
  • 档案管理系统是通过建立统一的标准以规范整个文件管理,包括规范各业务系统的文件管理的完整的档案资源信息共享服务平台,主要实现档案流水化采集功能。为企事业单位的档案现代化管理,提供完整的解决方案,档案管理...
  • WebGL 3D重做器 在打字稿中实现的webgl 3d渲染器。 利用Webpack进行部署构建。 开发人员使用情况 克隆或下载仓库 npm安装 npm run dev 部署方式 npm运行构建 未来的核心更新 添加边界框图元以动态设置所有导入模型的...
  • 我们在第一篇里面浏览了一下WebGL的参考卡片,也列出了一些WebGL的功能点,但是对于没有接触过3D编程的人来说,这些东西很难理解并形成一个统一的认识。所以这篇我就以WebGL为参考平台谈谈3D编程的一些基础概念。 3D...

    我们在第一篇里面浏览了一下WebGL的参考卡片,也列出了一些WebGL的功能点,但是对于没有接触过3D编程的人来说,这些东西很难理解并形成一个统一的认识。所以这篇我就以WebGL为参考平台谈谈3D编程的一些基础概念。

    3D坐标系变换

    正常来说,人们学习新东西都会从已有的知识出发,对于3D编程,在屏幕上画出3D图形,如果有2D图形API使用的基础,就会想着从2D编程的经验出发。比如对于2D编程,都是指定一个屏幕坐标,设定一个颜色,去画一个点,你能画点就能画任何东西,很简单很直观。但是到3D这儿就不行了,因为你没法简单直接且直观的指定一个立方体的各个点在屏幕上是什么位置。为了解决这个问题,在3D编程中,需要将3D空间的点变换到屏幕空间,即我们在3D空间指定点的坐标(一组3d坐标),然后设置一个摄像机,将摄像机镜头拍到的点映射到屏幕上,这样就可以绘制出来。这个过程就需要用不同的坐标空间,以及在这些坐标空间之间变换坐标。简单说一说。

    • 模型空间
      3D模型通常由很多三角形构成,而每个三角形又是由三个顶点构成。一个3D模型有很多顶点,这个顶点的坐标定义在模型自身的坐标系中,这个坐标系就是模型空间。坐标系的原点根据模型的形状特点以及使用的方便情况而设置。比如两足动物(人)的模型,通常将坐标原点放在两脚中间。而球的模型中心一般放在球心。使用模型空间一方面建模方便,另一方面同样的模型可以复用,例如世界场景中放置很多人。
    • 世界空间
      3D世界里面的物体是有层级关系的,比如人坐在车里,车在路上。每个物体的本地坐标就是其在父坐标系中的坐标,移动这个本地坐标就等于在其父坐标系中移动他的位置,而不需要修改其顶点的模型坐标。例如人坐在车上换了位置,换位置前后只是修改了其在车上的本地坐标,而人的模型上的所有顶点的坐标并没有改变,还是相对于人模型的中心点。父坐标系之上可能还有父坐标系,这样父坐标系空间的移动会带着其内部的子坐标系一起移动,而最终有一个最外层的坐标系是不会动的,这就是世界坐标系。因为我们要渲染世界中的模型,而每个模型在世界坐标系中有自己的位置,甚至有自己的父坐标系。为了渲染怎个世界,需要把模型坐标变换到世界坐标,这样所有的物体的所有顶点都在同一个坐标系中描述,WebGL就能把他们都渲染出来了。
    • 视图空间
      对于3D世界来说,我们会通过一个摄像机从某个角度去观察他,摄像机镜头内的物体才会绘制。摄像机一般也是放在世界中的,有他的本地坐标(但是由于摄像机不是一个实体模型,所以没有顶点,也就没有模型坐标)。另外摄像机还会有不同的朝向。通过摄像机去看物体,其实就是在摄像机的坐标系里面定义物体的位置,而我们知道物体的位置是定义在世界坐标系中的,所以需要把物体的顶点进一步变换到摄像机的视图空间。视图空间虽然和模型空间,世界空间一样只是一个坐标空间,理论上没有边界的概念,但是为了渲染效率以及为了能够实现投影,会用六个面将摄像机能够绘制的物体包围起来,这样只需要渲染这六个面中的物体。这六个面分别是前后,上下,左右视截面,构成的形状叫视景体。
    • 裁剪空间和NDC
      上面说了视景体的概念,在视景体外面的点是不绘制的,需要裁剪掉。但是视景体有各种不同的参数,虽然都是六个面,但是六个面的位置,大小,甚至视景体本身的形状都不同,这样裁剪起来很麻烦,于是出现了裁剪空间。裁剪空间其实不是3D空间,而是一个齐次坐标系。但是齐次坐标可以转化到一个3d空间,方法是对于齐次坐标(x,y,z,w)的x,y,z分量分别除以w分量,得到的新的x,y,z组成一个3d空间。这个除法在这儿叫做透视除法,而得到的3d空间叫做归一化坐标空间(NDC),为啥叫归一化呢?因为视景体内部的点对应到这个空间中点的x,y,z坐标的范围都是在-1和1之间。这个NDC其实和裁剪空间是一体两面的,他们其实是同一个空间,只是用齐次坐标表示时是裁剪空间。由于NDC的这个性质,对于裁剪空间,所有满足在视景体内部的点的范围就是x,y,z都在-w和w之间。这样裁剪的时候只要用x,y,z去和w比较就可以了,非常容易。
    • 屏幕空间
      通过裁剪空间的裁剪而过关的点,进行透视除法而得到NDC空间的3D点之后,其实x,y值就已经可以对应到屏幕上了,只是屏幕坐标一般是按像素描述的,所以经过一个线性映射后得到屏幕坐标的x,y。而z值也经过一个转换后存入深度缓冲。

    WebGL是什么

    现在来看看WebGL做了什么,上面科普了很多关于坐标系的知识,但是却和WebGL没有一毛钱关系。。WebGL实际上只是一个光栅化引擎。那什么是光栅化,先看一下OpenGLES 3.0的流水线(没找到WebGL的图):
    OpenGL ES 3.0 Graphics Pipeline
    WebGL对模型顶点的处理从Vertex shader开始,shader就是运行在显卡上的小程序,同一时间会有很多的这样的小程序在并行运行。vertex shader是处理顶点的,三角形的三个顶点都处理好之后,只是得到了三角形的边界。而绘制三角形的内部,就需要把三角形分解成一个个的像素片段,这个过程就是光栅化Rasterization。光栅化产生的片段Fragment通过Fragment shader的处理,被设置上颜色,再经过逐片段操作最终被写入FrameBuffer中。其实WebGL所做的事情可以总结为把三角形的顶点通过vertex shader计算出坐标,然后分解三角形成片段,对片段执行fragment shader设置颜色,最后显示到屏幕上。所以WebGL做的事情真的就是光栅化而已。而其他的事情都在shader里面,这个需要开发人员自己去实现。而我们上面说了半天坐标系到底和WebGL有什么关系呢?还是有关系的,那就是WebGL要求Vertex shader计算出来的顶点坐标位于裁剪空间中。这样WebGL会进行图元集成(Primitive Assembly):
    图元集成
    所谓图元就是三角形,线和点。图元集成首先做裁剪(clip),因此vertex shader的输出需要是一个裁剪空间中的坐标。不管你的shader怎么写的,反正WebGL就当你输出的是一个裁剪空间的(x,y,z,w)齐次坐标,然后用x,y,z和-w,w比较。不满足条件的顶点被抛弃。但是裁剪不仅仅是抛弃顶点,还得满足图元的要求,你一个三角形的一个点被抛弃了,剩下两个点怎么办,就需要WebGL去补充额外的点让剩下的两个点构成两个三角形。之后就是透视触发以及view port变换上面说了。

    使用WebGL需要的一些操作

    结合流水线总结一下,为了使用WebGL这个强大的光栅化引擎,我们需要哪些操作。

    • 首先需要提供给WebGL顶点数据(包括顶点索引:定义了顶点是如何组成三角形的),这个一般放在Vertex Buffer中。WebGL并不关心你提供的顶点在什么坐标空间中定义,但是遵从3D编程的一般规律,一般我们提供的是模型空间的坐标。顶点数据被上传到显存中的vertex buffer中。
    • 我们可能还需要提供一些贴图,把他们上传到显存中供shader使用。
    • 我们需要设置一些全局的渲染状态,有一种说法是OpenGL是一个状态机。包括当前使用哪个vetex buffer都是一个状态。
    • 然后我们需要编写一组Shader,即顶点着色器和片段着色器。把他们编译出来之后link成一个program一起使用。顶点shader必须输出裁减空间中的坐标,并且可以输出一些顶点相关的参数。而片段shader是最终计算出颜色的地方,片段shader被执行很多次所以效率很重要。
    • 我们设置了所有的数据,贴图,shader,状态之后,通过调用draw call启动一次绘制。然后就等着WebGL搞定所有的事情。一次draw call一般被称为一个pass,某些渲染效果需要多个pass。而一些高级效果需要把中间结果保存在某个buffer中再进一步处理。虽然实际事情很复杂,但是WebGL本身并不复杂。复杂的是图形学的算法和各种优化。

    下一步

    写科普太累了,所以后面不会写很多。好在虽然细节还不到位,但基本的概念都有了,足够开始介绍代码了。

    展开全文
  • 基于HTML5 WebGL 3D仓储系统Demo,使用范围还很广!ht.js评论留言邮箱地址,看到留言会发送至邮箱
  • WebGL开启了网页3D渲染的新时代,它允许在canvas中直接渲染3D的内容,而不借助任何插件,看到此处是不是感觉特别惊讶啊,WebGL有一个很好的中文教程,就是下面使用参考中的第一个链接,所以这里不再班门弄斧,后面的...
  • Omega3D-Javascript WebGL 3D库# 什么 ? Javascript WebGL 3D渲染库。 当前稳定版本: 0.0.1.5 Alpha 特征 点和定向照明。 阴影贴图。 可自定义的RenderPass。 RenderChains,用于渲染控件。 FrameBuffer...
  • 主要介绍了基于 HTML5 的 WebGL 3D 版俄罗斯方块的示例代码的相关资料,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
  • 突袭HTML5之WebGL3D概述

    2021-01-31 07:01:39
    WebGL开启了网页3D渲染的新时代,它允许在canvas中直接渲染3D的内容,而不借助任何插件。WebGL同canvas 2D的API一样,都是通过脚本操纵对象,所以步骤也是基本相似:准备工作上下文,准备数据,在canvas中绘制对象并...
  • WebGL 3D雪花飘落动画特效是一款适合用作网页背景特效下载。
  • 基于WebGL3D字体

    2019-07-10 08:46:53
    基于WebGL3D字体,用于实现Web端3D字体的演示效果,含所有代码
  • WebGL 3D重做器 在打字稿中实现的webgl 3d渲染器。 利用Webpack进行部署构建。 开发人员使用情况 克隆或下载仓库 npm install npm运行开发 部署方式 npm运行构建 未来的核心更新 添加边界框图元以动态设置所有导入...
  • grrd的骰子 grrd的Dice是HTML5 3D Dice ... 3D WebGL图形是通过three.js实现的。 grrd's Dice是免费的,没有广告,没有应用内购买。 版权所有(c)2015 Gerard Tyedmers, 根据MPL许可获得许可 单击此处播放: :
  • 玩具WebGL 3D引擎(具有基本的2D支持) :warning: 正在建设中 :construction_worker: :construction: 到处乱混 这些示例当前可从。 去看看他们! 如果您希望在本地运行项目: $ npm install # start webpack's ...
  • 超图三维地球开发代码,vscode直接运行,感兴趣下载
  • 前面我们看到了使用原生的WebGL API开发是多么的累,正因为如此,大量的WebGL框架被开发出来。使用这些框架,你可以快速创建需要的3D场景。这些框架不同程度的封装了创建3D场景的各种要素,例如场景,相机、模型、...

    前面我们看到了使用原生的WebGL API开发是多么的累,正因为如此,大量的WebGL框架被开发出来。使用这些框架,你可以快速创建需要的3D场景。这些框架不同程度的封装了创建3D场景的各种要素,例如场景,相机、模型、光照、材质等等;使用这些封装起来的对象,就可以很简单的创建需要的3D场景,这样你就只需要把更多精力放在逻辑方面就可以了。

    目前并没有哪一个具有能压倒其他框架的优势,选择什么样的框,还是看个人喜好吧,不过选择框架的时候,个人觉得还是多看看框架最后的更新时间,选择稳定更新的框架能让你始终能使用上最新的特性,使你的程序稳定性更好。

    下面的例子就使用了Three.js框架进行开发。

    Three.js是一个比较全面的开源框架,它良好的封装的3D场景的各种要素。你可以用它来很容易的去创建摄像机,模型,光照,材质等等。你还可以选择不同的渲染器,Three.js提供了多种渲染方式,你可以选择使用canvas来渲染,也可以使用WebGL或者SVG来进行渲染。

    此外,Three.js可以加载很多格式的3D文件,你的模型文件可以来自Blender,Maya,Chinema4D,3DMax等等。而且内置了比较基础的东西:(球体)Spheres, (飞机)Planes, (立方体) Cubes, (圆柱体)Cylinders。Three.js创建这些物体会非常的容易。

    好了,不废话了,直接看代码:

    复制代码代码如下:

    threeJSDemo

    body

    {

    margin:0px;

    background-color:#B0B0B0;

    overload:hidden;

    }

    var camera,scene,renderer;

    var mesh;

    init();

    animate();

    function init(){

    scene = new THREE.Scene();

    camera = new THREE.PerspectiveCamera(70,window.innerWidth / window.innerHeight,1,1000);

    camera.position.z = 400;

    scene.add(camera);

    geometry = new THREE.CubeGeometry(200,200,200);

    material = new THREE.MeshBasicMaterial( { color: 0xff0000, wireframe: true } );

    mesh = new THREE.Mesh(geometry,material);

    scene.add(mesh);

    renderer = new THREE.WebGLRenderer();

    renderer.setSize(window.innerWidth,window.innerHeight);

    document.body.appendChild(renderer.domElement);

    }

    function animate() {

    requestAnimationFrame( animate );

    mesh.rotation.x += 0.05;

    mesh.rotation.y += 0.05;

    renderer.render( scene, camera );

    }

    这个是全部的代码,相对于前面使用WebGL的API的代码,这个简直就是太简单了。

    代码很直观,就那么几步:

    1. 创建场景scene。

    2. 创建摄像机camera。

    3. 创建/加载模型geometry。

    4. 加载材质material。

    5. 渲染模型对象mesh(是由geometry和material组成)。

    6. 启用动画。

    这是每个框架都提供的功能,使用不同的框架除了函数的名称可能不同以外,这些步骤基本都是一样的。下面的参考中列出了很多的框架学习文档,大家可以选几种学习一下。

    针对模型数据,我还想说一点,因为JSON短小精悍,所以比较适合网络传输。未来它可能成为最适合WebGL的模型数据格式,所以很多的框架都开始支持JSON格式的模型数据。

    展开全文
  • 如上文所说,我希望这个基于WebGL的框架是一个独立的库,可以像一个普通的js库那样被引用,但是开发的时候又需要根据需求拆分成很多js文件,那么就涉及到一个打包问题。且这一次我想使用ES6的模块系统和ES6的语法,...

    如上文所说,我希望这个基于WebGL的框架是一个独立的库,可以像一个普通的js库那样被引用,但是开发的时候又需要根据需求拆分成很多js文件,那么就涉及到一个打包问题。且这一次我想使用ES6的模块系统和ES6的语法,那么rollup.js都可以做到,好吧就他吧。
    既然使用js,我们就用npm初始化了一个模块:mini3d.js,需要说明的是,目前暂时没有将mini3d.js注册到npm,也许以后会,所以现在的用法就是从源码build出mini3d.js文件,然后使用。由于我在Web前端开发上的经验很有限,所以可能显得不专业,但是没事,这个可以慢慢完善。
    好了,先看一下目录结构。

    mini3d.js目录结构

    mini3d.js ms1
    作为一个npm模块,mini3d.js有package.json配置文件以及本地的node_modules目录。mini3d.js框架的代码放到src目录中,测试例子的代码放到examples目录中。rollup.js打包出来的框架代码和测试例子代码以及相关的资源放到build目录中。

    package.json 设置

    {
      "name": "mini3d",
      "version": "0.1.0",
      "description": "A tiny webGL library",
      "main": "mini3d.js",
      "scripts": {
        "build": "rollup -c",
        "watch": "rollup -c -w",
        "dev": "npm-run-all --parallel start watch",
        "start": "serve build"
      },
      "repository": {
        "type": "git",
        "url": "git+https://github.com/happyfire/mini3d.js.git"
      },
      "keywords": [
        "webGL"
      ],
      "author": "happyfire",
      "license": "ISC",
      "bugs": {
        "url": "https://github.com/happyfire/mini3d.js/issues"
      },
      "homepage": "https://github.com/happyfire/mini3d.js#readme",
      "devDependencies": {
        "@babel/core": "^7.6.2",
        "@babel/preset-env": "^7.6.2",
        "core-js": "^3.2.1",
        "npm-run-all": "^4.1.5",
        "rollup": "^1.21.4",
        "rollup-plugin-babel": "^4.3.3",
        "rollup-plugin-commonjs": "^10.1.0",
        "rollup-plugin-node-resolve": "^5.2.0",
        "rollup-plugin-terser": "^5.1.2",
        "serve": "^11.2.0"
      },
      "dependencies": {}
    }
    
    

    目前所有的库都是本地依赖,即通过npm install安装到项目的node_modules中。主要依赖的库有rollup以及rollup的一些插件。插件的作用具体参考rollup.js官网。另外使用了一个serve,用于启动一个http服务进行测试。项目的构建使用了npm脚本,即:

    "scripts": {
        "build": "rollup -c",
        "watch": "rollup -c -w",
        "dev": "npm-run-all --parallel start watch",
        "start": "serve build"
      },
    
    • npm run build会执行rollup -c,即根据rollup配置文件rollup.config.js中的设置执行rollup。
    • npm run watch会执行rollup -c -w,同样是根据配置文件执行rollup,并且加入了对代码变动的检测,一旦发现代码改变就会执行构建。
    • npm run start会执行serve build,即在build目录上启动一个http服务,方便测试
    • npm run dev使用npm-run-all同时执行start和watch,即启动http服务,且对源代码进行检测,自动构建。
      以上设置参考了rollup.js官方的例子项目 rollup-starter-app

    rollup配置文件rollup.config.js

    import resolve from 'rollup-plugin-node-resolve';
    import commonjs from 'rollup-plugin-commonjs';
    import babel from 'rollup-plugin-babel';
    //import { terser } from 'rollup-plugin-terser';
    
    // npm run build -> production is true
    // npm run dev -> production is false
    const production = !process.env.ROLLUP_WATCH;
    
    export default [ {
        input: 'src/mini3d.js',
        output: {        
            format: 'iife',
            name: 'mini3d',
            file: 'build/mini3d.js',
            sourcemap: true
        },
        plugins:[
            resolve(),  // tells Rollup how to find date-fns in node_modules
            commonjs(), // converts date-fns to ES modules
            // babel({
            //     exclude:'node_modules/**'
            // }),
            
            //production && terser() // minify, but only in production
        ]
    },{
        input: 'examples/src/main.js',
        output: {
            file: 'build/examples/bundle.js',
            format: 'iife',
            name: 'main',
            sourcemap: true
        },
        plugins:[
            resolve(),  // tells Rollup how to find date-fns in node_modules
            commonjs(), // converts date-fns to ES modules
            babel({
                exclude:'node_modules/**'
            }),
            
            //production && terser() // minify, but only in production
        ]
    }]
    

    注意我注释掉了一些,因为开发时有些功能暂时不用,另外有个别问题我还没解决好,下面会说。
    export default后面跟着的是一个数组,所以可以放多个配置。我这为了方便,把example的配置和mini3d.js的配置都放这儿了。
    第一个配置是构建mini3d.js,input指定的入口文件:src/mini3d.js,output指定了输出文件即配置。file为build/mini3d.js即最终框架会被打包到这个位置的mini3d.js,注意这个和src/mini3d.js是不同的。format为’iife’意思是将模块打包成iife的格式,且模块名为mini3d。
    plugins配置是按顺序使用多个插件去进行处理,resolve然后是commonjs,目前我就用了这两个,结果是产生了build/mini3d.js这个单个文件。即ES6的模块被转换成了iife格式。然后babel被我注释掉了,所以产生的文件里面的会保留ES6的语法(如果用了的话,实际确实用了)。当然如果打开babel也是可以的,但是为了查看最终产生的框架代码我就先去掉了。另外就是有个问题没解决,WebGL会用到typed array,例如Float32Array,这个虽然是ES6的东西,但是很多支持WebGL的浏览器在支持ES6之前就支持这个了,换句话说如果不支持这个也不能支持WebGL。然而使用Bable,具体的是使用了corejs后,会把typed array换成pollyfill,这个我还不知道怎么处理,在我理解中,typed array应该保留,所以我暂时把babel去掉了,但是如果打开babel最后也能运行。然后最后是terser,且在production环境才会使用,这个就是把生成的代码变短变紧凑,为了看最后代码的内容,也先去掉了。
    export default数组的第二个配置是example的打包,入口是examples/src/main.js,输出为build/examples/bundle.js。配置和mini3d.js一样,只是我打开了babel,因为example的代码里面不会出现typed array(细节被mini3d.js封装了)。

    rollup-plugin-babel的设置

    bable配置文件为 .babelrc,可以放到每个源码目录下面独立设置。这个先不说了,我自己也没完全搞清楚,先留着。目前的配置能跑,由于版本的原因,按照网上的很多教程会有错误。本来说使用WebGL就行看中了环境好搭建,但是作为前端外行来说还是很麻烦的,好在重点是研究WebGL,这种环境相关的东西可以慢慢处理,或者如果真有Web前端专业人士关注我的这个小项目,希望能伸出援手,多谢!

    测试项目结构

    测试项目的源码在examples/src中,目前仅有一个main.js,由于使用了rollup.js,所以可以使用ES6模块去划分代码,但是入口必须是main.js。mini3d.js框架和example的代码都会被打包到build目录中,如果运行npm run build就会同时打包这两个,目前这样是为了方便,毕竟代码不多。实际最好是分开的。其中examples的代码会被打包到build/examples/bundle.js,这个目录中还有一个写好的index.html。而mini3d.js框架代码直接打包到build根目录中。http服务目前是起在build根目录下的,这样测试项目所在的url为:http://localhost:5000/examples/

    index.html和webGL程序入口

    总算写完环境搭建了,看一看入口的index.html吧。由于WebGL是依托在canvas上的(下一节会讲),所以在body下面创建了一个canvas,且id为"webgl"。然后两个script标签分别指向打包出来的mini3d.js框架和测试项目代码bundle.js。由于mini3d.js是一个IIFE,被载入时即执行,执行产生的结果赋值给了一个叫mini3d的对象。所以我们在onLoad里面可以使用mini3d.init('webgl')初始化整个框架,传入的webgl是canvas的id。之后执行main()方法,这个main()方法测试代码examples/src/main.js中通过ES6的export default导出的函数,然后被rollup.js处理成bundle.js这个IIFE模块载入执行后导出的main函数。(mini3d.js导出的是一个叫mini3d的对象,而bundle.js导出的是一个叫main的函数)。执行main()函数启动实例代码

    下一步

    下面会从WebGL的一些基本概念开始(当然是非常总结性的,可能会忽略很多细节),介绍mini3d.js的第一个里程碑ms1_rotate_cube的实现细节。说实话细节是魔鬼,就这么一个简单的东西,搞了很久,为了基础扎实,所有的矩阵都是自己推导的,好吧先看一下截图,确实很不吸引人
    在这里插入图片描述

    展开全文
  • 提供快速、简约的用户界面,以从数据库中搜索和加载透明或不透明的 3D 器官模型。 尽管 BodyParts3D 中的所有器官名称均可搜索,但只有与神经科学相关的器官 3D 模型可用。 控制台日志显示加载的器官 ID。 这可...
  • Examine the issues involved in building WebGL based 3D applications for mobile browsers ☆ 出版信息:☆ [作者信息] Tony Parisi [出版机构] 奥莱理 [出版日期] 2014年03月06日 [图书页数] 404页 [图书...
  • Polygonjs是基于节点的3D Webgl引擎。 。 安装: npm install @polygonjs/polygonjs或yarn add @polygonjs/polygonjs 。 或从CDN使用: ...
  • 使用three.js的WebGL 3D模型查看器 规格 OBJ加载器,用于加载与GIF一样古老且广泛支持的几何格式。 MTL加载器用于加载非常简单的材料。 轨道控件可平稳地使相机围绕模型旋转。 最近邻滤波和纯白色环境光可显示...
  • VTS浏览器JS是功能强大JavaScript 3D地图渲染引擎,占地面积很小(约163 kB的gzip压缩JS代码)。 它几乎提供了您想要的基于Web的3D映射的所有功能。 VTS浏览器JS是独立可用部分:这是用于3D地理空间应用程序开发的...
  • 引言 : 学习webgl已经接近2年时间了,对常见的开源3D引擎也比较熟悉了,但是目前为止three.js、babyLon、clayGL、cesium对webgl2新特性的支持也不是特别多。从今天开始,准备着手构建自己的3D引擎,一是希望能有...

    引言 :
    学习webgl已经接近2年时间了,对常见的开源3D引擎也比较熟悉了,但是目前为止three.js、babyLon、clayGL、cesium对webgl2新特性的支持也不是特别多。从今天开始,准备着手构建自己的3D引擎,一是希望能有自我提升,二是希望能做一个更快速、更炫酷、更容易扩展的引擎,并且希望能对webgl2的新特性有更多的支持。(目前引擎设计主要参考three.js和clayGL、少部分可能会参考babylon、如果后续做地球部分应该会参考cesium,由于对playCanvas使用不多,后续在引擎设计的时候也会着重去看playCanvas的源码并将好的思想融入进来。总而言之,在设计引擎的过程中自己多思考,然后多看这些开源引擎的思路,取其精华)

    1. 首先介绍下几个开源引擎:

    Three.js
    https://github.com/mrdoob/three.js
    最火的web3D引擎,功能最丰富而且最便于使用,笔者对其的研究比较深入,上层的一些设计可能会对其参考较多

    ClayGL
    https://github.com/pissang/claygl
    ClayGL是一个用于构建可扩展Web3D应用程序的WebGL图形库,目前主要应用到echarts中,笔者对其比较熟悉,后续对它的一些分析可能会比较多

    Babylon.js
    https://github.com/BabylonJS/Babylon.js
    一个完整的JavaScript框架,用于构建HTML5,WebGL,WebVR和Web Audio的3D游戏和体验,该引擎主要使用typescript,性能强大,对webgl2支持较多

    Cesium.js
    https://github.com/CesiumGS/cesium
    一个3D地球引擎,主要是解决地球上的一些计算和大尺度问题,后续做地球可以参考

    PlayCanvas
    https://github.com/playcanvas/engine
    PlayCanvas是一个开源游戏引擎。目前对其使用不多。它是ECS架构,架构比较清晰,渲染列表的标脏处理的不错。

    2.搭建工具和语言:

    要着手做自己的引擎,首先要构建一套打包工具,我这里使用webpack+gulp+eslint进行构建。由于对typescript不太熟悉,目前还是主要使用es6的语法(后续会逐步适应typescript)。用构建工具构建项目的过程比较简单,这里就不一一记录了。

    3.架构和渲染设计:

    该如何设计一个架构:我们先看一下three做了什么?
    其实只干了两件事
    Graph Tree 场景树管理
    Render 渲染

    如何构建场景树:我们看看three的设计思路:

    Render渲染
    首先反思一下Three.js,three在渲染上有什么改进空间?
    答:对Three比较熟悉的人应该知道,Three的最大痛点就是Renderer的设计包含了太多东西:
    更新场景中所有物体的矩阵
    生成渲染列表(分类,收集, 视锥裁剪,排序…)
    更新灯光信息
    执行渲染

    Three在renderer中做了太多的事情,这确实不是太合适,主要是为了让用户更加容易使用吧,但是这个设计确实也带来了很多扩展和性能上的问题。
    这样设计使其在实现VAO、UniformBlock、MRT这些关键技术的时候带来了极大的困难,现在也没有实现这几个非常关键的技术,这其实才是最大的痛点。
    而一个引擎是否强大的核心是有没有强大的延迟渲染系统,显然Three不具备,我们看看为什么?

    后期和延迟渲染经常会遇到的场景:
    一般在后处理的时候我们希望替换某些物体的材质为材质1,替换另一些物体的材质为材质2,也就是常用的scheme策略
    graph LR
    场景–>物体
    物体–>材质1
    物体–>材质2

    如果要用Three.js要如何实现那?
    scene.traverse(object => {
    // change material1
    });

    renderer.render(scene, camera, target);

    scene.traverse(object => {
    // change material2
    });

    renderer.render(scene, camera, target);

    // …

    实际上:
    1.遍历场景替换材质1(遍历浪费)
    2.更新场景中所有物体的矩阵
    3.生成渲染列表(分类,收集, 视锥裁剪,排序…)
    4.执行渲染
    5.遍历场景替换材质2(遍历浪费)
    6.更新场景中所有物体的矩阵(浪费)
    7.生成渲染列表(分类,收集, 视锥裁剪,排序…)(浪费)
    8.执行渲染
    9…
    (参考shawn0326的文章https://juejin.im/post/5e5dbe23e51d4526f363b123)

    所以我们在实现Render的时候,希望render能只专注于渲染,而且为了后处理,我们希望render在渲染之前用户可以自定义自己的材质,默认使用MRT
    scene.updateMatrix();//将更新矩阵移出renderer,可以手动更新

    const renderList = renderer.getRenderList(scene, camera);//获取渲染列表,将渲染列表的获取分离出来

    const light = renderer.getLight();//灯光信息单独处理,生成uniformBlock
    renderer.renderBackground(scene);//单独渲染背景
    // 渲染渲染列表
    renderer.renderRenderList(renderList, camera, light, {
    getMaterial: item => {
    // 这里可以通过item.object动态判断使用哪种材质
    return material1;
    }
    });
    //当然我们也提供一个直接的render函数,便于用户使用,该render直接调用上述几个接口组装在一起
    renderer.render(scene, camera);

    实际上:
    1.更新场景树
    2.生成渲染列表(分类,收集, 视锥裁剪,排序…)
    3.更新并计算灯光和阴影
    4.渲染背景
    5.使用材质1渲染
    目前这样设计思路非常明确,用户可以更加灵活的使用renderer,并以更加优化的方式实现自己的延迟渲染策略。后续还应该思考如何内置一个更加方便的延迟渲染策略以及MRT。
    当然渲染这块在实现的时候我会使用VAO和uniformBlock,后续在实现渲染之后再详细说明思路和好的设计方式。

    4.矩阵运算设计

    矩阵运算的设计:这部分是我们要关注的重点,仔细看了下three的设计,矩阵运算这部分的设计是直接使用数组进行计算的,这种设计不是太理想。为什么那?因为后续很难将矩阵运算移植到webAssembly,而且还有很多的js对象和数组的创建,内存开销也不小。
    因此我设计的引擎需要摒弃这种思路,希望后续能更好更快的切换到webAssembly。目前矩阵运算主要借助gl-matrix库(https://github.com/toji/gl-matrix),这个库比较简单轻量而且是直接使用并得到内存数组。接口调用完成可以直接上传uniform,非常方便快捷。
    想要让引擎更加快速简单,我还是希望使用dirty机制来触发引擎的更新,特别是矩阵运算的时候。如果你做了position、rotation包括灯光的修改,我希望能有个好的机制直接触发引擎的更新,这样就不用每帧去更新和计算这些参数,能给引擎带来更好的性能。

    5.上游工具

    第一步先支持gltf以及一些gltf的扩展吧。目前大部分工具都可以导出到gltf。后续希望能实现更加强大的粒子系统和编辑器。

    展开全文
  • 我这样做的唯一目的是学习和实践three.js年前,那里有更好,更完整的解决方案( ),甚至没有尝试使用这个。 由于我当时没有任何经验,因此代码质量和所有内容可能真的很糟糕。 绘制函数和.csv文件。...
  • 代码为3D地图,使用Vue+Three+shader,流光飞线,下钻,热力,区域范围等,相机控制,进场动画等,高性能3D炫酷效果
  • 预计itee解决方案可用于运行WebGL 3d内容。 这是一台轻巧而快速的3d服务器,随时可以使用。 如何安装 从npm: npm install itee 如何使用 您只需要输入: npm start 就这样 ! 如何贡献 即将推出... BSD-3条款...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 19,264
精华内容 7,705
关键字:

webgl3d