关于webgl:GLB文件格式简介与GLB文件格式转换

什么是GLB文件?GLB文件(.GLB)代表“GL传输格局二进制文件”,是用于共享3D数据的标准化文件格式。确切地说,它能够蕴含无关三维模型、场景、模型、光源、材质、节点档次和动画的信息。当您关上GLB文件格式时,您能够实现残缺的三维场景可视化,并与之交互。这就是为什么它也被称为3D资产世界的JPEG。 GLB文件的用处是什么?GLB文件格式是一种绝对较新的格局,于2015年引入,作为示意GLTF文件的二进制格局(.GLTF),而不是JSON格局。因为其轻量级个性,这种格局通常用于挪动和网络应用程序,以及图形游戏、视频游戏、VR和AR应用程序,GLB文件也很容易通过电子邮件或其余文件共享平台共享。总的来说,GLB文件格式为3D内容交付和显示提供了一个通用而高效的解决方案。 GLB和GLTF文件之间有什么区别?GLB和GLTF之间存在显著差别,GLB格局是GLTF文件的一个版本,不同之处在于,GLB格局是二进制文件格式,而GLTF格局是基于JSON(JavaScript对象表示法)的。GLB将三维场景的所有元素(包含材质、节点档次和摄影机)定位在一个压缩文件中。相比之下,GLTF文件须要内部解决文件格式,例如纹理、着色器和动画数据等其余格局。这些内部元素存储在GLTF文件中,但每个元素都应用惟一的格局编码语言(JPEG用于纹理,GLSL用于着色器,BIN用于动画数据)。因而,GLB被辨认为一个独立的文件,蕴含单个网络中3D场景的所有组件,而GLTF被视为一个非独立文件,须要纹理、着色器和动画数据等元素的内部解决文件。此外,GLB格局的大小比GLTF格局小33%,这使其成为一种更高效的抉择,因为它须要更少的解决能力。 如何关上GLB文件?能够在所有次要的三维建模程序中关上和转换GLB文件。关上GLB文件最简略的办法是首先在计算机上找到文档。而后只需右键单击残缺的文件名并抉择关上。如果您有Windows设施,但没有3D建模软件,依然能够在 Microsoft 3D Viewer 或者Microsoft Paint 3D 中收费关上GLB并进行即时交互。如果你想在Mac上关上GLB文件,能够间接在线关上。什么收费程序关上GLB文件?有几个收费程序能够关上GLB文件,并能够轻松查看3D模型并与之交互。其中一个程序是微软的3D查看器,它预装在Windows 10上,三维查看器容许用户对模型进行旋转、缩放和平移,并提供各种照明和着色选项。另一个收费选项是Blender,这是一款弱小的开源3D建模软件,反对GLB文件,并提供了编辑和操作3D模型的宽泛性能。此外,许多基于web的3D查看器,如3D模型在线转换,也反对GLB文件,容许用户间接在web应用程序中查看和转换3D模型,而无需装置任何软件。 如何创立GLB文件?创立GLB文件是一个简略的过程,能够间接从风行的三维建模程序(如Blender、Autodesk 3DS Max或SketchUp)中实现。在设计软件中,将模型、光源、材质、节点层次结构、动画等的所有内部文件合并为一个我的项目文件,而后将其导出为GLB文件。一些旧版本的3D建模程序可能须要额定的软件,来导出GLB文件。 GLB文件格式的构造是什么?GLB文件格式被结构为对数据进行编码的单个二进制文件。这个独自的GLB文件大小和格局由两局部组成:一个JSON数据局部,包含现有GLTF文件的原始信息数据及其设置,另一个二进制缓冲区,反对其余文件,如动画。JSON数据局部蕴含无关3D模型的元数据,例如节点层次结构、纹理和动画。二进制缓冲区蕴含理论的三维几何体数据,例如模型顶点的地位、法线和UV。这两个局部联合在一起,能够在互联网上高效、高效地传输3D模型。 如何转换GLB文件?能够将GLB文件转换为特定格局。您能够应用网络上的在线资源,将GLB转换为FBX、将GLB转换为OBJ、将GLB转换为STL、将GLB转换为GLTF,如3D模型在线转换,该网站能够在实现GLB文件与其余格局之间的转换。 应用GLB文件的长处和毛病是什么?应用GLB文件格式的次要益处是其紧凑的尺寸,使其更适宜挪动和网络应用程序、视频游戏和AR/VR应用程序。与其余文件格式(如OBJ文件)不同,GLB扩大蕴含单个独立文件中的齐全基于物理的渲染(PBR)着色器、纹理和动画信息。这容许在关上此类文件时立刻查看和交互。须要留神的是,尽管GLB文件的压缩个性提供了劣势,但它可能蕴含的细节和复杂性与其余文件类型和格局(如GLTF文件)不同。 GLB文件如何更改PBR着色器的游戏基于物理的渲染(PBR)是一种用于在三维建模中取得更真切和精确后果的渲染技术。通过模仿光如何与事实世界中的材质交互,PBR着色器能够产生加强的渲染成果,使对象看起来更真切。为了实现这一点,PBR着色器在很大水平上依赖于纹理,例如漫反射、粗糙度和金属贴图。GLB文件非常适合此操作,因为它们在一个独立文件中蕴含残缺的PBR着色器以及所有必要的纹理。在GLB文件中拜访这些原始纹理很容易,能够在3D建模和渲染中实现更精简、更高效的工作流程。 你能打印GLB文件吗?尽管能够以GLTF/GLB文件格式打印3D模型,但通常倡议将文件转换为更规范的3D打印格局,例如STL文件格式。STL 3D文件格式还将模型组织为3D三角形和网格的列表,并且能够通过二进制版本的3D打印软件轻松读取,从而简化打印过程。相同,应用GLB文件扩展名进行3D打印可能会导致额定的解决工夫和复杂性,从而升高其效率。

August 31, 2023 · 1 min · jiezi

关于webgl:WebGLThreejs-入门与实战系统学习-Web3D-技术

download:WebGL+Three.js 入门与实战,零碎学习 Web3D 技术React 18 和 Next.js 13:前端开发的新时代 引言 前端开发是一个一直变动和进化的畛域,每年都有新的工具和技术呈现,为开发人员提供了更多的抉择和可能性。在 2023 年,两个最受关注和期待的前端开发工具是 React 18 和 Next.js 13,它们都是在原有的根底上进行了重大的更新和改良,为开发人员带来了许多新性能和劣势。本文将介绍 React 18 和 Next.js 13 的次要个性和长处,以及它们如何协同工作,为前端开发带来新的体验和成果。 React 18 React 是一个用于构建用户界面的 JavaScript 库,它是目前最风行和最宽泛应用的前端框架之一。React 18 是 React 的最新版本,它在放弃 React 的核心理念和劣势的同时,引入了一些新的概念和性能,如: Streaming SSR:这是一种新的服务端渲染(SSR)形式,它能够让 React 在服务端生成 HTML 的同时,将 HTML 流式地发送给客户端,而不是期待整个页面渲染实现后再发送。这样能够进步页面的加载速度和性能,以及晋升用户体验。React Server Components:这是一种新的组件类型,它能够让 React 在服务端运行一些组件逻辑,并且将后果发送给客户端。这样能够缩小客户端的代码量和累赘,以及进步数据获取和安全性。Automatic Batching:这是一种新的更新机制,它能够让 React 主动将多个状态更新合并为一个批次,并且在适合的机会执行。这样能够防止不必要的重渲染和性能损耗,以及晋升应用程序的稳定性。Concurrent Mode:这是一种新的渲染模式,它能够让 React 在后盾预渲染一些组件,并且在用户交互时疾速切换到最新的状态。这样能够进步页面的响应速度和平滑度,以及晋升用户体验。Suspense:这是一种新的数据获取形式,它能够让 React 在渲染组件时暂停,并且期待数据筹备好后再持续。这样能够防止显示空白或加载中的状态,并且提供更好的过渡成果。Next.js 13 Next.js 是一个基于 React 的框架,它能够让开发人员轻松地构建动态网站、服务端渲染网站、混合网站等各种类型的 Web 应用程序。Next.js 13 是 Next.js 的最新版本,它在继承 Next.js 的优良个性和生态系统的同时,引入了一些新的性能和改良,如: Edge and Node.js Runtimes:这是一种新的运行时环境,它能够让 Next.js 在边缘服务器或者 Node.js 服务器上运行,并且提供对立的 API 和体验。这样能够进步应用程序的部署灵活性和可扩展性,以及进步性能和安全性。Middleware:这是一种新的申请解决形式,它能够让开发人员在边缘服务器或者 Node.js 服务器上编写一些中间件函数,并且在每个申请达到应用程序之前执行。这样能够实现一些自定义的逻辑和性能,如身份验证、重定向、缓存等。Image Optimization:这是一种新的图片优化形式,它能够让 Next.js 在边缘服务器或者 Node.js 服务器上对图片进行压缩、裁剪、格局转换等操作,并且依据不同的设施和网络条件提供最合适的图片。这样能够缩小图片的大小和加载工夫,以及进步用户体验。Script Optimization:这是一种新的脚本优化形式,它能够让 Next.js 在构建时对 JavaScript 代码进行剖析和优化,并且依据不同的页面和组件提供最合适的脚本。这样能够缩小脚本的数量和大小,以及进步性能和可维护性。Built-in CSS and Sass Support:这是一种新的款式反对形式,它能够让开发人员间接在 Next.js 中应用 CSS 或者 Sass 文件,并且主动解决导入、作用域、压缩等问题。这样能够简化款式的编写和治理,以及进步兼容性和效率。React 18 和 Next.js 13 的协同 ...

August 19, 2023 · 1 min · jiezi

关于webgl:网易Threejs可视化企业实战WEBGL课2023全面升级版

download:网易Three.js可视化企业实战WEBGL课-2023全面升级版Vue 3整体意识和路由配置Vue.js是一个风行的JavaScript框架,用于创立动静Web应用程序。在Vue 3中,组合式API和新的个性使得开发更加灵便和高效。 本文将介绍Vue 3的整体意识以及如何应用Vue Router进行路由配置。 Vue 3整体意识组合式APIVue 3引入了一种新的API,称为组合式API,它容许咱们以性能为核心地组织代码。通过组合式API,能够更容易地复用逻辑和状态,并从基于选项的API过渡到更具表现力和可维护性的代码。 以下是一个通过应用组合式API创立Vue组件的示例: javascriptimport { reactive, computed } from 'vue' export default { setup() { const state = reactive({ count: 0,})const increment = () => { state.count++}const doubleCount = computed(() => state.count * 2)return { state, increment, doubleCount,}},}在这个示例中,咱们应用了reactive函数来创立响应式的state对象,并应用computed函数来计算doubleCount属性。而后,咱们将state、increment和doubleCount作为返回值裸露给Vue组件。 Teleport组件Vue 3引入了Teleport组件,它容许咱们将内容传输到DOM构造中的其余地位,而无需创立嵌套组件。 以下是一个应用Teleport组件的示例: html<teleport to="#modal"> <div>Modal content here</div></teleport> <div id="modal" />在这个示例中,咱们将modal内容传输到id为“modal”的DOM元素中。这使得咱们能够将模态框内容搁置在任何地位,而不用间接蕴含在模态框组件中。 Vue Router路由配置Vue Router是Vue.js官网提供的路由管理器,用于在应用程序中实现客户端路由。Vue Router提供了多种路由配置选项,包含动静路由和嵌套路由等。 以下是一个根本的Vue Router配置示例: javascriptimport { createRouter, createWebHistory } from 'vue-router' const routes = [ { ...

May 31, 2023 · 1 min · jiezi

关于webgl:WebGLThreejs-入门与实战系统学习-Web3D-技术

download:WebGL+Three.js 入门与实战,零碎学习 Web3D 技术产品思维:让你的产品更加用户导向 在当今竞争强烈的市场中,要想打造一款胜利的产品并不容易。而要想真正做好产品,就须要有一种被称为“产品思维”的理念。那么什么是产品思维呢?它又有哪些特点和劣势呢? 简略来说,产品思维就是一种以用户需要为导向来开发和设计产品的思维形式。与传统的技术或工程思维不同,产品思维将用户体验放在首位,并且提倡通过数据分析和用户反馈来继续改良产品。这样能够让企业更加聚焦用户需要,进步产品的满意度和市场份额。 那么产品思维又有哪些特点呢?首先,它强调用户体验。在传统的产品开发过程中,往往由技术人员主导,而对用户体验的关注则绝对较少。而产品思维则将用户体验作为外围,一直优化产品的界面、性能和操作流程等方面,从而实现更好的用户体验。 其次,产品思维具备敏锐的市场洞察力。基于对用户需要的深刻理解,产品思维可能更好地把握市场变化趋势,及时调整产品的策略和方向。这样能够让企业始终保持在市场的前沿,抢占竞争劣势。 最初,产品思维强调数据驱动。通过对用户行为、应用习惯等数据进行剖析,产品思维可能及时理解用户需要和反馈,并以此作为产品改良的根据。这样能够让企业更加聚焦于用户需要,一直进步产品的满意度和市场份额。 总之,产品思维是一种十分重要的理念,它可能让企业更加聚焦于用户需要,强化市场洞察力,并通过数据分析继续改良产品。因而,如果您心愿打造一款胜利的产品,那么就请务必遵循产品思维,将用户体验放在首位,一直迭代优化,为用户提供更好的产品体验。

May 3, 2023 · 1 min · jiezi

关于webgl:尝试-WebGPU-过程中掉的一些坑

TODO 两个试验我的项目 https://github.com/Triadica/lagopus.tshttps://github.com/Triadica/solubleuniform buffer 的编码规定. 数据会依照大小对齐, 然而编码的时候 https://www.w3.org/TR/WGSL/#address-space-layout-constraints 能够试试本人加上 padding 来 buffer https://stackoverflow.com/questions/74186801/is-there-any-way-to-enforce-a-16-byte-alignment-for-a-uniform-buffer-in-glsl 依照文档说的, 不止对 uniform buffer 是这样, 我还没解决过. 没有 FBO 怎么办. https://www.cnblogs.com/onsummer/p/the-missing-fbo-and-rbo-in... 整体思路能够参考 blur 的做法, 至多能跑通的, https://webgpu.github.io/webgpu-samples/samples/imageBlur#../... TODO

April 10, 2023 · 1 min · jiezi

关于webgl:OpenGL和WebGL的关系与区别

什么是WebGLWebGL™是一个跨平台的,免版税的凋谢Web规范,用于基于OpenGL ES的低级3D图形API,通过HTML5 Canvas元素向ECMAScript公开。相熟OpenGL ES 2.0的开发人员将应用GLSL将WebGL辨认为基于Shader的API,其结构在语义上与底层OpenGL es API的结构类似。它十分靠近OpenGL ES标准,对开发人员对内存治理语言(如JavaScript)的冀望做出了一些退让。WebGL 1.0 公开了 OpenGL ES 2.0 功能集;WebGL 2.0 公开了 OpenGL ES 3.0 API。 WebGL将无插件3D带到了Web上,并在浏览器中实现。 WebGL和OpenGL的区别两者都是市场上的热门抉择,接下来看看两者之间有什么区别: WebGL缩写为Web Graphics Library。它次要用于渲染二维图形和交互式三维图形。它是能够与HTML5一起应用的Javascript API。它反对跨平台,并且仅提供英语版本。WebGL程序由一个用JavaScript编写的控制代码组成。 OpenGL被称为Open Graphics Library。它被称为跨语言和平台应用程序编程接口,用于渲染二维和三维矢量图形。OpenGL提供了许多性能,如扩大。 WebGL专为渲染 2D 和 3D 图形而设计。OpenGL是一个跨语言和平台的API,用于渲染2D和3D矢量图形。WebGL次要用于在浏览器中运行Web应用程序。OpenGL次要用于桌面应用程序。WebGL是用JavaScript语言编写的。OpenGL是用C语言编写的。WebGL相对而言,它具备较少的性能。OpenGL具备许多性能,能够使应用程序或图形更具交互性。WebGL基于OpenGL ES,不足惯例OpenGL所具备的许多性能,例如WebGL仅反对顶点和片段着色器。OpenGL 具备 WebGL 中没有的性能,如几何着色器、细分着色器和计算着色器。在WebGL中,能够借助2D纹理来伪造3D纹理。在OpenGL中,能够利用几何体和着色器。WebGL基于OpenGL ES 2.这不是一般的OpenGL。OpenGL ES是OpenGL的子集。OpenGL ES的性能较少,对用户来说非常简单。OpenGL有很多性能,很难应用。总结OpenGL与WebGL都是渲染二维和三维图形的图形库。WebGL被用于HTML画布元素,这意味着它能够与HTML语言合并。WebGL很容易学习,因为它在javascript和Html中简略易用。 OpenGL的确须要良好的常识能力应用和开发应用程序。 OpenGL与WebGL都有长处和毛病。图形库的抉择能够依据应用程序的要求、可扩展性进行。 扩大Sovit3D 是一个物联网可视化PaaS开发平台,基于JavaScript语言的3D图形引擎,为Web可视化提供了丰盛的展示模式和视觉效果,帮忙软件开发公司、解决方案提供商轻松搭建3D可视化界面。平台聚焦工业数字孪生的生产管控、智慧城市的监控运维等可视化应用领域,产品的模块组态化模式能够满足全因素智慧场景的构建。广泛应用于电力能源、水利、物联网、工业互联网、智慧城市、智慧医疗、智慧农业、IT运维等各行业多畛域。 Sovit3D 平台采纳B/S架构,基于WebGL绘图技术标准,提供基于Web浏览器的3D可视化行业组件,反对HTML5/SVG等最新技术,可不便的在浏览器上进行浏览和调试。为开发人员制作合乎用户应用习惯的大屏可视化利用,包含2D图表剖析、3D修建实景、3D工业设施模型等相干内容,轻松拖拽即可实现,管制实时数据及动画展现、历史回放、报警、命令下发等性能。

February 22, 2023 · 1 min · jiezi

关于webgl:基于Web的6个完美3D图形WebGL库

古代前端、游戏和Web开发正是WebGL能够转化为数字杰作的货色。应用GPU绘制在浏览器屏幕上生成的矢量元素,WebGL创立交互式Web图形,从而取得用户体验。视觉元素的品质和复杂性使该工具在HTML或CSS等其余办法中怀才不遇。 WebGL根底WebGL不是一个图形套件。相同,它利用代码绘制几何对象,利用客户端的 GPU 引擎在 HTML 画布上栅格化图形对象。 在 3D 场景中,每个点都是由其 x,y,z 坐标标识的顶点。而后将顶点连接起来造成一组三角形形态,称为基元。利用光源来创立暗影和深度的外观。而后将基元栅格化以将 3D 矢量图形创立为 2D 像素的投影,从而诱使大脑在 2D 计算机屏幕上看到 3D 对象。 WebGL代码中有两种类型的函数: 顶点着色器片段着色器它们用于通知计算机如何在屏幕上绘制像素。尽管主程序代码是用JavaScript编写的,但着色器应用GL Shader语言,它与C / C++十分类似。 顶点着色器计算顶点的坐标,片段着色器负责计算像素色彩。着色过程须要计算机执行大量计算能力流畅地渲染图像。CPU 解决的工作负载通常太大。出于这个起因,WebGL利用GPU来更无效地调配计算。 从实质上讲,WebGL API就是自定义着色器状态,以管制在客户端屏幕上绘制的内容。侥幸的是,无需手动创立程序即可增加 3D 图形。能够应用 Three.j、Unity WebGL构建选项等资源来疾速设计 3D 体验,也能够用用像Sovit3D可视化编辑器来疾速设计,无需太多的 WebGL 基础知识。 WebGL其余库Web开发人员能够应用各种各样的WebGL框架和库来构建Web产品。利用事后编写的元素能够大大提高 Web 开发的速度。 当初让咱们疾速概述一下一些用于应用 WebGL 开发应用程序的风行附加库。 Unity WebGL 如果你正在寻找WebGL开发的资源,这可能是你会遇到的第一个库。在网页中创立内容时,Unity WebGL容许Web开发人员间接与浏览器的JavaScript引擎交互。这样,网页上的所有元素都能够互相通信。 Unity WebGL提供了不同的办法来做到这一点:从Unity脚本调用Javascript或C函数,甚至从浏览器的JavaScript向Unity脚本发送一些数据。目前,大多数支流桌面浏览器都反对Unity WebGL内容。然而,它尚不提供对挪动设施的反对。 Three.js Three.js 是一个专门为 WebGL 筹备的 JavaScript 元素库。该库具备大量成果、对象、摄像机、场景、材质、着色器和其余实用程序。这些手册仍在编写中,但网络上的宏大开发人员社区运行论坛和探讨。Babylon.jsGithub上的另一个开源库,Babylon.js通常被形容为在浏览器中显示3D图形的引擎。它的原始语言是Typescript,但它的代码由所有反对WebGL和HTML5的浏览器本地解释。 Babylon.js 具备宽泛的利用,包含游戏、立功数据可视化、时尚、医疗保健教育和军事训练。PlayCanvasPlayCanvas 专门用于游戏,是一个由专有的基于云的开发平台反对的 3D 引擎,容许 Web 开发团队从多台计算机实时编辑 Web 我的项目。这些性能包含 3D 动画、刚体物理模仿和声音设计。该引擎于 2014 年开源,在 Github 上也有一个收费的存储库。 ...

February 16, 2023 · 1 min · jiezi

关于webgl:WebGL简明教程之2使用缓冲区绘制三角形

纯色三角形咱们首先借助缓冲区绘制一个三角形: 残缺的代码如下: <canvas width=200 height=200 style="outline:1px solid gray;"> 十分道歉,您的浏览器不反对canvas!</canvas><!-- 顶点着色器 --><script type='x-shader/x-vertex' id='vs'> attribute vec4 a_position; void main(){ gl_Position=a_position; }</script><!-- 片段着色器 --><script type='x-shader/x-fragment' id='fs'> precision mediump float; uniform vec4 u_color; void main(){ gl_FragColor=u_color; }</script><script> var gl = document.getElementsByTagName('canvas')[0].getContext('webgl'); var loadShader = function (type, source) { var shader = gl.createShader(type); gl.shaderSource(shader, source); gl.compileShader(shader); return shader; }; var vertexShader = loadShader(gl.VERTEX_SHADER, document.getElementById('vs').innerHTML), fragmentShader = loadShader(gl.FRAGMENT_SHADER, document.getElementById('fs').innerHTML); var glProgram = gl.createProgram(); gl.attachShader(glProgram, vertexShader); gl.attachShader(glProgram, fragmentShader); gl.linkProgram(glProgram); gl.useProgram(glProgram); // 设置三角形的色彩(红色) var u_color = gl.getUniformLocation(glProgram, 'u_color'); gl.uniform4f(u_color, 1, 0, 0, 1); // 创立缓冲区 var buffer = gl.createBuffer(); // 把缓冲区对象绑定到指标 gl.bindBuffer(gl.ARRAY_BUFFER, buffer); // 筹备好点的数据 var data = new Float32Array([ -0.7, -0.7, 0, 0.7, -0.7, 1, 0, 0.7, 0 ]); // 写入数据到缓冲区 gl.bufferData(gl.ARRAY_BUFFER, data, gl.STATIC_DRAW); // 获取变量地位 var a_position = gl.getAttribLocation(glProgram, "a_position"); // 把缓冲区对象调配给指标变量 gl.vertexAttribPointer(a_position, 3, gl.FLOAT, false, data.BYTES_PER_ELEMENT * 3, 0); // 连贯指标对象和缓冲区对象 gl.enableVertexAttribArray(a_position); // 绘制一个三角形 gl.drawArrays(gl.TRIANGLES, 0, 3);</script>接着,咱们未来解读下面这段代码。 ...

January 14, 2023 · 2 min · jiezi

关于webgl:WebGL简明教程之1绘制一个点

咱们在画布的核心绘制一个正方形,你能够先看看最终的成果: 代码上面是残缺的代码,咱们后续将对外面的内容进行解说阐明: <canvas width=200 height=200 style="outline:1px solid gray;"> 十分道歉,您的浏览器不反对canvas!</canvas><!-- 顶点着色器 --><script type='x-shader/x-vertex' id='vs'> void main(){ gl_Position=vec4(0.0,0.0,0.0,1.0); gl_PointSize=100.0; }</script><!-- 片段着色器 --><script type='x-shader/x-fragment' id='fs'> void main(){ gl_FragColor=vec4(1.0,0.0,0.0,1.0); }</script><script> // 先获取gl var gl = document.getElementsByTagName('canvas')[0].getContext('webgl'); // 定义一个把着色器字符串加载成着色器对象的函数 var loadShader = function (type, source) { // 创立着色器对象 var shader = gl.createShader(type); // 绑定资源 gl.shaderSource(shader, source); // 编译着色器 gl.compileShader(shader); return shader; }; // 别离加载顶点着色器对象和片段着色器对象 var vertexShader = loadShader(gl.VERTEX_SHADER, document.getElementById('vs').innerHTML), fragmentShader = loadShader(gl.FRAGMENT_SHADER, document.getElementById('fs').innerHTML); // 创立一个着色器程序 var glProgram = gl.createProgram(); // 把后面创立的两个着色器对象增加到着色器程序中 gl.attachShader(glProgram, vertexShader); gl.attachShader(glProgram, fragmentShader); // 把着色器程序链接成一个残缺的程序 gl.linkProgram(glProgram); // 应用这个残缺的程序 gl.useProgram(glProgram); // 绘制一个点 gl.drawArrays(gl.POINTS, 0, 1);</script>绘制流程 ...

January 14, 2023 · 1 min · jiezi

关于webgl:Web3D从0开始学习ThreejsBlender实现甜甜圈掉落效果-大帅老猿threejs特训

前言最近大帅邀请胖达老师带来了元宇宙实战特训,具体解说了如何应用Blender进行3D建模、增加动画以及如何在Threejs中展现、管制3D模型,让我特地感叹,原来一些看似简单的3D我的项目能够如此简略的实现。 Web3D 简介Web3D的次要展现形式:浏览器间接渲染:电脑浏览器、挪动端浏览器(包含微信浏览器) 微信小程序;服务端渲染(服务端运行,成果好,经营老本高);将3D画面像素推流到前端浏览器/小程序展现;3D近几年风行的相干概念:数字孪生:三维实景模型 + 多系统监控/告警数据,实现近程监管(监控、治理);VR:把人装进虚拟环境AR:把虚构装进事实浏览器运行3D的计划ActiveX插件: IE、Chrome老版本、Firefox老版本,已过期; Flash: 时代王者,官网已进行保护; WebGL: 浏览器原生反对(IE11根本反对,其它浏览器根本都反对) WebGPU: 性能高,目前还未失去操作系统和浏览器的广泛支持; 可实现公布WebGL到浏览器运行的计划(从重到轻):Unity引擎: wasm webgl 空包:20m+ (不反对ie11低版本chrome及Firefox及国产化) CocosCreator: webgl 空包:6m+ (不反对ie11及低版本chrome及firefox) threejs: webgl 库大小:1m- (开源,IE11均反对) babylonjs: webgl 库大小:4m+ (微软开源,中文材料绝对较少) 明天咱们就来理解Three.js提到 Three.js,不得不先提 OpenGL 和 WebGL,OpenGL 是一个跨平台的3D/2D的绘图规范(标准),WebGL(Web Graphics Library)是一种3D绘图协定。 WebGL容许把JavaScript和OpenGL 联合在一起使用,但应用WebGL原生的API来写3D程序十分的简单,同时须要绝对较多的数学知识,对于开发者来说学习老本十分高。 Three.js是基于webGL的封装的一个易于应用且轻量级的3D库,Three.js对WebGL提供的接口进行了十分好的封装,简化了很多细节,大大降低了学习老本,极大地提高了性能,性能也十分弱小。 (1)Three.js官网 (2)Three.js 的 github 地址 起步阶段先从简略开始,间接援用 Three.js,学会最根本的 Three.js 的应用办法<!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></head><body> <script src="js/three.min.js"></script> <script> // 创立场景 const scene = new THREE.Scene(); // 创立相机,PerspectiveCamera(透视相机),参数(视线角度,长宽比,进截面,远截面) const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000); // 渲染器 const renderer = new THREE.WebGLRenderer(); // 设置渲染器的宽高 renderer.setSize( window.innerWidth, window.innerHeight ); // 将renderer(渲染器)的dom元素(renderer.domElement)增加到咱们的HTML文档中 document.body.appendChild( renderer.domElement ); // demo--立方体 const geometry = new THREE.BoxGeometry( 1, 1, 1 ); // BoxGeometry 立方体对象 const material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } ); // MeshBasicMaterial 其中的一种材质,设置色彩绿色 const cube = new THREE.Mesh( geometry, material ); // 创建一个网格对象 scene.add( cube ); // 将网格对象增加到场景中 camera.position.z = 5; // function animate() { requestAnimationFrame( animate ); // 创立了一个使渲染器可能在每次屏幕刷新时对场景进行绘制的循 cube.rotation.x += 0.01; // 使正方体能动起来 cube.rotation.y += 0.01; // 使正方体能动起来 renderer.render( scene, camera ); } animate(); </script></body></html>应用 npm 来开发并测试(1)获取我的项目代码(2)装置依赖 ...

January 13, 2023 · 2 min · jiezi

关于webgl:加载OBJ和MTL文件

HTML形式<!-- * @Author: yangyuguang * @Date: 2022-12-04 17:22:11 * @LastEditors: yangyuguang * @LastEditTime: 2023-01-11 11:19:31 * @FilePath: /排行榜初始代码/test2.html--><!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>加载OBJ和MTL文件</title> <style> html, body{ width: 100%; height: 100%; overflow: hidden; } *{ margin:0; padding:0; } </style> <!-- 引入three.js三维引擎 --> <script src="http://www.yanhuangxueyuan.com/versions/threejsR92/build/three.js"></script> <script src="http://www.yanhuangxueyuan.com/threejs/examples/js/controls/OrbitControls.js"></script> <script src="http://www.yanhuangxueyuan.com/threejs/examples/js/loaders/OBJLoader.js"></script> <script src="http://www.yanhuangxueyuan.com/threejs/examples/js/loaders/MTLLoader.js"></script></head><body> <script> var scene = new THREE.Scene(), camera, renderer = new THREE.WebGLRenderer(); /* OBJ和材质文件mtl加载 */ var OBJLoader = new THREE.OBJLoader(); //obj加载器 var MTLLoader = new THREE.MTLLoader();//材质文件加载器 MTLLoader.load('./static/material.mtl',function(meterials){ console.log(meterials); OBJLoader.setMaterials(meterials); OBJLoader.load('./static/model.obj',function(obj){ /* 返回的组对象插入场景中 */ scene.add(obj) obj.children[0].scale.set(5,5,5)//网络模型播放 }) }) createLight() createCamera() createRenderer() /* 通过requestAnimationFrame()操作三维场景 */ var controls = new THREE.OrbitControls(camera,renderer.domElement); //创立控件对象 // 创立一个时钟对象Clock var clock = new THREE.Clock() function render(){ renderer.render(scene,camera);//执行渲染操作 requestAnimationFrame(render) //申请再次执行渲染函数render } render() // 正投影相机设置 function createCamera(){ var width = window.innerWidth; //窗口设置 var height = window.innerHeight;//窗口高度 var k = width/height;//窗口宽高比 var s = 150;//三维场景显示范畴管制系数,系数越大,显示的范畴越大 // 创立相机对象 camera = new THREE.OrthographicCamera(-s*k,s*k,s,-s,1,1000) camera.position.set(200,300,200) //设置相机地位 camera.lookAt(scene.position);//设置相机方向(指向的场景对象) } // 透视相机 function createPerspectiveCamera(){ var width = window.innerWidth;//窗口宽度 var height = window.innerHeight//窗口高度 /* 透视投影相机对象 */ camera= new THREE.PerspectiveCamera(60,width/height,1,1000) camera.position.set(200,300,200)//设置相机地位 camera.lookAt(scene.position)//设置相机方向(指向的场景对象) } /* 创立渲染器对象 */ function createRenderer(){ renderer.setSize(window.innerWidth,window.innerHeight)//设置渲染区域尺寸 renderer.setClearColor(0xb9d3ff,1)//设置背景色彩 document.body.appendChild(renderer.domElement)//body元素中插入canvas对象 } /* 创立光源 */ function createLight(){ // 点光源 var point = new THREE.PointLight(0xffffff) point.position.set(400,200,300)//点光源地位 scene.add(point);//点光源增加到场景中 // 环境光 var ambient = new THREE.AmbientLight(0x444444) scene.add(ambient) } </script></body></html>在vue中应用第一种办法应用three-obj-mtl-loader插件 ...

January 13, 2023 · 2 min · jiezi

关于webgl:汽车行业场景化营销新方向基于-WebGL-的网上虚拟车展

车展作为车市的风向标,代表着汽车倒退的趋势,也是厂商展现本人、推广本人的舞台。WebGL 作为一种新兴的技术,为 Web 端提供了交互式三维动画新体验,汽车之家的网上车展就是两者联合之后的一种新的产品状态。 到目前为止,汽车之家车展总共经验了五年的风雨倒退,历经三大阶段,它们别离是全景实拍车展、步进式全景实拍车展和纯 3D 虚构车展。 全景实拍车展:线下车展现场实拍全景图,以此为次要素材构建而成的线上车展。 步进式全景实拍车展:应用业余设施实地拍摄线下车展全景图,同时采集空间信息,实现全景场景的平滑切换,就像镜头在行走,这也是步进式这个名称在之家的由来。 纯 3D 虚构车展:在 Web 端实现了展馆和汽车模型的加载展现,真正实现了第一人称逛展看车,源于事实而又超过事实,保障性能的同时尽可能的出现高质量视觉效。 每一次的车展迭代更新都对业务有的极大的推动,而这背地都是 WebGL 技术一直成熟和生态的一直残缺所造就的。 一、WebGL 介绍1.1 WebGL 引擎现状WebGL 是近些年呈现的一种 3D 绘图协定,这种绘图技术通过减少 OpenGL ES 2.0 的一个 JavaScript 绑定,为 HTML5 Canvas 提供硬件 3D 减速渲染,这样 Web 开发人员就能够借助零碎显卡来在浏览器里运行 3D 利用。随着挪动互联网的崛起和倒退,Web 业务也随之拓展,有时须要在网页/ H5 /小程序中渲染 3D 模型,WebGL 就有了用武之地。 WebGL 引擎应用 JavaScript 语言编程,学习成本低,容易入门,公布部署不便灵便且无需装置下载,但国内没有比拟成熟的 WebGL 开发者生态,可应用的插件很少;因为是基于 Web 浏览器生态,能够十分不便的以外链形式对外进行社区裂变流传,同时引擎能力满足简略的 3D 需要,常见的 WebGL 引擎有 three.js、BabylonJS 和 PlayCanvas 等,它们都是最近几年才呈现,积攒绝对于传统的空幻(UE)或者 Unity 引擎要少很多。 1.2 WebGL 的长处跨平台:WebGL 是 H5 规范之一,具备对立的、规范的、跨平台的 OpenGL 接口实现,通过 JavaScript 脚本实现了 Web 端的 3D 利用制作,无需任何浏览器插件反对,是浏览器级别的一次开发多处利用; ...

November 24, 2022 · 2 min · jiezi

关于webgl:如何实现水面波动一种代码实现两种效果shader-奇技淫巧

在最初咱们将一起实现如下图水面稳定的成果,不过浏览完本文,也将理解到这一思路的其余用法本篇默认读者本曾经能读懂根本的glsl语言,语法不再做过多解释,如果有不了解能够翻看之前的文章有具体解说用shader制作马赛克这是上帝的杰作:10行代码搞定“热成像”几款2077格调的shader 如何扭曲图片如何扭曲图片?办法多种多样,但偏移是其中比拟罕用也极其便宜的形式。比方能够让小骑士左侧身材偏移20%: void main() { if(st.x>0.5 ){ st.y+=0.2; } vec4 color = texture2D (u_image0, st); gl_FragColor = vec4(color.rgb, 1.0);}st是一张(0.0)->(1,1)的二维立体,让其中右侧区域的像素点都读取其上方0.2地位处的像素信息,就实现了平移掉过,这种线性的平移咱们在几款2077格调的shader一文中曾经领教,但用它模仿扭曲是有点尴尬胖虎了。所以咱们给他来点非线形的偏移: #define PI 3.14//圆周率#define E 2.71828//自然对数的底.....float Distribution(float x){ float a = 1.0/(4.0*PI*PI); float b = pow(E,-(x-0.5)*(x-0.5)/0.04); return a*b;}void main() { st.y = mod(st.y+ 10.0*Distribution(st.x),1.0); // mod保障画面间断 vec4 color = texture2D (u_image0, st); gl_FragColor = vec4(color.rgb, 1.0);}这里咱们在x=0.5处增加了一个正太散布的偏移:由正太散布的性质能够晓得,越靠近x=0.5偏移量越大,越靠近1和0偏移越小。在一些须要实现非平面镜的场景中,这个shader能够联合鱼眼及其他扭曲一起实现一些鬼魅的成果。 意外的涂鸦成果如果叠加一个正太方程就能实现扭曲,那么叠加一个稳定方程能够实现怎么的成果?这里简略选取一个正弦波: void main() { vec2 offset = vec2(0.0); offset.x = sin(st.x * 14.0) * .2; offset.y = sin(st.y * 14.0) * .2; vec4 color = texture2D(u_image0, uv+offset); gl_FragColor = vec4(color.rgb, 1.0);}这里设置一个偏移量offset,因为须要在画面中呈现间断的波峰和波谷,须要将函数的频率进步,同时咱们不想让offset取值偏移到屏幕之外,所以管制了振幅,该选什么呢?就暂定0.2吧,而后:克苏鲁来临了。这是因为此时振幅还是过大,频率快能够在画面中呈现多层次扭曲,振幅小意味着每次的稳定是轻微的。能够做以下调整: ...

November 4, 2022 · 1 min · jiezi

关于webgl:开课吧高薪webGL工程师2022最新完结无密

download:开课吧-高薪webGL工程师2022最新完结无密WebGL是什么?WebGL百度百科给出的解释是WebGL是一个3D绘图协定,而维基百科给出的解释是一个JavaScript API。因为WebGL技术旨在帮忙咱们在不应用插件的状况下,在任何兼容的web浏览器中开发交互式2D和3D web成果,因而咱们能够将其了解为帮忙咱们开发3D网页的绘图技术。当然,最底层是JavaScript API。WebGL倒退历史WebGL的倒退能够追溯到2006年。WebGL源于Mozilla员工Vladimir Forge Sivic的一个Canvas 3D试验我的项目,Canvas 3D的原型于2006年首次展现。这项技术于2007年底在FireFox和Opera浏览器中实现。2009年初,Khronos团体联盟成立了WebGL。最后的工作成员包含苹果、谷歌、Mozilla、Opera等等。2011年3月,WebGL 1.0公布。WebGL 2的开发始于2013年,最终于2017年1月实现。火狐51、Chrome 56、Opera 43中首次反对WebGL 2。总帐中的基本概念WebGL运行在电脑的GPU上,所以须要应用能在GPU上运行的代码。这样的代码须要提供成对的办法,其中一个叫做顶点着色器,另一个叫做切片着色器,应用GLSL语言。连贯顶点着色器和切片着色器的办法称为着色程序。 顶点着色器着色器的作用是计算顶点的地位,即提供顶点在裁剪空间中的坐标值。 请参考webglfundamentals一文理解该模块的内容。 片段着色器切片着色器的性能是计算图形元素的色彩值。咱们能够粗略地将切片着色器了解为网页中的像素。数据采集模式后面咱们提到了顶点着色器和片段着色器的概念,顶点着色器和片段着色器都须要相应的数据能力运行。接下来,让咱们看看着色器获取数据的四种形式: 和属性缓冲。缓冲区是发送到GPU的二进制数据序列。通常,缓冲数据包含地位、方向、纹理坐标、顶点色彩值等。当然,你能够依据本人的须要存储任何你想要的数据。属性用于解释如何从缓冲区获取所需的数据,并将其提供给顶点着色器。全局变量全局变量在着色器运行之前调配,在运行过程中全局无效。全局变量在一个绘制过程中将雷同的值传递给着色器。静脉纹理是一个数据序列,在着色程序运行时能够随便读取其中的数据。一般来说,咱们次要以纹理模式存储图像数据,然而除了色彩数据之外,您还能够依据本人的爱好存储其余数据。可变变量变量是顶点着色器将值传递给片段着色器的一种形式。 总结WebGL只关怀两件事:裁剪空间的坐标值和色彩值。要应用WebGL,只须要给它提供这两样货色。所以咱们通过提供两个着色器来做这两件事,一个顶点着色器提供裁剪空间坐标值,另一个切片着色器提供色彩值。WebGL的工作原理理解了WebGL的一些基本概念后,咱们能够看看WebGL在GPU上做了什么。之前咱们曾经理解到,WebGL在GPU上的工作次要分为两局部,即顶点着色器所做的工作(将顶点转换为裁剪空间坐标)和片段着色器所做的工作(依据顶点着色器的计算结果绘制像素)。如果咱们须要画一个三角形,此时在GPU上做的工作就是先调用顶点着色器三次,计算三角形的三个顶点在裁剪空间坐标系中的对应地位,并通过变量gl_Position保留在GPU中,而后调用切片着色器计算每个顶点的色彩值,并通过变量gl_FragColor将对应的色彩值保留在GPU中。实现所有这些工作后,咱们失去了绘制三角形所需的像素,最终失去了栅格化的三角形。原生WebGL API绘制三角形咱们之前曾经学习了WebGL的历史、基本概念和工作原理,接下来是咱们实际真谛的时候了,那么咱们就来看看如何通过WebGL在一个网页中绘制一个简略的三角形。咱们晓得WebGL作为一种3D绘图技术,自身就是依附HTML5中的canvas元素而存在的,所以在正式开始绘图之前,咱们须要做一系列的筹备工作: 首先咱们须要创立一个canvas元素作为画三角形所需的画布,并实现浏览器对canvas元素兼容性的测试。函数webglInit () {const canvasEl = document . createelement(' canvas ');//画布元素创立canvasel . width = document . body . client width;//设置画布画布的宽度canvasel . height = document . body . client height;//设置画布canvas高度document . body . append(canvasEl);//将创立的canvas画布增加到页面的body元素下。//接下来须要判断浏览器对WebGL的兼容性。如果浏览器不反对WebGL,那么咱们就不须要持续了。如果(!canvasEl.getContext("webgl") &&!canvasel . get context(" experimental-web GL "){alert("您的浏览器不反对web GL ");返回;}//如果浏览器反对Webgl,那么咱们将获取Webgl的context对象,并将其复制到变量GL中。const context =(canvasel . get context(" web GL "))?canvasEl.getContext("webgl "):get context(" experimental-web GL ");/*设置viewport context.viewport (x,y,width,height);x:用于设置视口左下角的程度坐标。默认值:0y:用于设置视口左下角的垂直坐标。默认值:0宽度:用于设置视口的宽度。默认值:画布宽度高度:用于设置视口的高度。默认值:画布的高度当您第一次创立WebGL上下文时,视口大小与画布大小相匹配。然而,如果再次更改canvas的大小,须要通知WebGL context设置一个新的viewport,所以此处能够省略这行代码,作为第一次创立它。*/context.viewport(0,0,context.canvas.width,context . canvas . height);返回上下文;}复制代码 ...

September 13, 2022 · 1 min · jiezi

关于webgl:开课吧-高薪webGL工程师2022最新含源码ppt

download:开课吧 高薪webGL工程师2022最新含源码ppt编程猿自学it java python go c基于springboot的国际化解决方案1底漆1.1国际化概述作为一名服务器端开发人员,这里我想从本人的角度简略概述一下国际化(国际化也叫i18n,因为I和N之间有18个字母)是做什么的: 在理论的国际化我的项目中,责任是让服务器依据客户指定的语言,返回相应语言的内容。 1.2 spring/spring boot我的项目中国际化游戏性概述在spring/springboot的世界中,国内游戏基于以下界面:org . spring framework . context . message source .该接口次要定义了以下三种办法:公共接口音讯源{//如果国际化配置文件中找不到var1对应的音讯,能够给它一个默认值var3。@NullableString getMessage(String var1,@Nullable Object[] var2,@Nullable String var3,Locale var 4);//如果在国际化配置文件中找不到var1对应的音讯,抛出异样String getMessage(String var1,@Nullable Object[] var2,Locale var3)抛出NoSuchMessageException//这个办法临时没有做太多的钻研,所以本文也不会波及。string getMessage(MessageSourceResolvable var 1,Locale var2)抛出NoSuchMessageException}复制代码该接口的三个重要实现类如下: ResourceBundleMessageSourceReloadableResourceBundleMessageSource动态音讯源 2如何播放ResourceBundleMessage源(默认)首先咱们来看看springboot我的项目中国际化最根本的玩法: (1)构建springboot我的项目(至多增加web依赖)。Messages.properties(默认配置) 用户名=溜溜球复制代码 messages_en_US .属性 user.name=yoyo-ENuser.name1=nrscuser.name2=nrsc{0}-{1}复制代码 音讯_zh_CN.properties 用户名1=张耳User.name2=张耳{0}-{1}复制代码(3)创立一个控制器测试类@RestController公共类i18d专制控制器{@主动连线公有MessageSource messageSource @GetMapping("/hello ")公共字符串hello() {String defaultM = messageSource。getMessage("user.name ",null,locale context holder . getlocale());字符串message1 =音讯源。getMessage("user.name1 ",null,locale context holder . getlocale());字符串message2 = messageSource。getMessage("user.name2 ",new String[]{"WW "," MM"},locale context holder . getlocale());字符串message3 = messageSource。getMessage("user.nameXX ",null," defaultName ",locale context holder . getlocale()); ...

September 12, 2022 · 3 min · jiezi

关于webgl:开课吧高薪webGL工程师2022最新完结无密

download:开课吧高薪webGL工程师2022最新完结无密文章参考 自学it666 https://www.zxit666.com/形容你在玩一个蕴含多个角色的游戏,每个角色都有两个次要属性:攻打和进攻。给你一个2D整数数组属性,其中properties[i] = [attacki,defensei]代表游戏中第I个角色的属性。如果一个角色的攻打和进攻等级都比这个角色的攻打和进攻等级高很多,那么这个角色就被认为是弱的。更正式地说,如果存在另一个字符j,其中attackj > attacki和defensej > defensei,则称字符I是弱的。返回弱字符的数量。示例1:输出:属性= [[5,5],[6,3],[3,6]]输入:0阐明:没有一个角色比另一个角色有更强的攻击力和防御力。 复制代码示例2:输出:属性= [[2,2],[3,3]]输入:1阐明:第一个角色很弱,因为第二个角色有更强的攻击力和防御力。复制代码留神:2属性[i]。长度== 2一个复制代码剖析依据题目,咱们正在玩一个有多个角色的游戏,每个角色有两个次要属性:攻打和进攻。给定一个二维整数数组属性,其中properties [i] = [attack,defense]代表第I个字符的属性。如果另一个角色的攻打和防具等级严格高于该角色的攻打和防具等级,则该角色被称为弱角色。更艰深地说,如果有另一个字符索引J,其中attackj > attacki,defence j > defence i,则索引为I的字符称为弱字符。返回弱角色的数量。其实这个问题是对于排序的,AC一次遍历就能够实现。咱们晓得问题须要弱字符的个数,所以咱们只须要数一数。我要判断的维度有两个维度:攻击力和防御力,所以能够依照物理学中“控制变量法”的思路,先判断一个维度,再判断另一个维度。要达到这个“严格大于”的要求,首先要排序。咱们依照攻击力降序和防御力升序排序,这样在确定弱角色攻击力满足“严格小于”时,就能够通过判断弱角色防御力“严格小于”来找到弱角色。而后咱们遍历属性。如果以后角色的攻击力小于之前穿梭过的角色,就不能判断是弱角色。因为防御力是不确定的,所以为了不便,咱们要用一个变量max_defense来记录被遍历角色的最大防御力,所以如果以后角色的防御力严格小于max_defense,就阐明肯定是真角色,后果能够加一。理论须要判断攻击力雷同但防御力严格小于前一个角色的状况。然而咱们的写法能够省去这个判断步骤,因为咱们是按防御力升序排序的,这样如果以后防御力严格小于之前的最大防御力,那么攻击力肯定是不相等的,因为攻击力相等时防御力是按升序排序的。依照下面的办法,一次遍历后失去的后果就是最终后果,能够返回。工夫复杂度是O(logN+N),N是属性的长度,因为属性要先排序再遍历,空间复杂度是O(1),因为没有开拓新的空间。解释类别解决方案(对象):def numberOfWeakCharacters(本身,属性):""":类型属性:List[List[int]]:rtype: int"""properties . sort(key = lambda x:(-x[0],x[1]))后果=最大进攻= 0对于_,属性中的进攻:如果进攻<最大进攻:后果+= 1否则:max_defense =进攻回送后果复制代码运行后果运行工夫:2301 ms,比游戏中弱角色数量的Python在线提交快84.75%。内存应用:69.6 MB,不到Python在线提交的游戏中弱角色数量的42.37%。复制代码

September 10, 2022 · 1 min · jiezi

关于webgl:干货为什么说开源基金会的选择很关键上

数字经济时代,人口和流量红利逐步隐没,须要咱们开拓新的生态模式,这所有都源于技术的推动。开源是一种凋谢、共享、协同的翻新合作模式。它不仅是凋谢源代码的软件技术开发,还包含更宽泛的凋谢技术畛域及协同翻新的理念与机制。开源正在以“自在”的流传模式,成为寰球信息技术倒退的弱小推动力。开源根底软件当初曾经成为咱们国家的倒退策略。 而开源的倒退离不开开源基金会,如Apache基金会、Linux基金会、以及中国的凋谢原子开源基金会,都曾经成为开源生态中十分要害的局部。目前寰球100多个开源我的项目基金会绝大部分注册在美国,这些开源基金会中,曾经孵化了800多个顶级我的项目。中国在2020年成立的凋谢原子开源基金会,随着百度、华为、腾讯、阿⾥等企业的项⽬捐献,基⾦会以后已有OpenHarmony 、OpenEuler等开源项⽬。目前Gitee的用户数量600万,但只有Github的十分之一,中国开源基础设施和产业⽣态也在逐渐倒退。97%的开发者和99%的企业都在应用开源软件,从整个软件产业的供应链上看,开源曾经成为将来信息技术的主战场了。 那么,意识理解基金会的运行规定以及如何抉择退出适合的基金会,是企业开源生态倒退十分要害一环,对此咱们整体做了梳理,会分两期内容分享给大家~ 开源基金会简介开源基金会(Open Source Foundation) 是专门为反对开源软件我的项目而创立的非营利性组织,开源基金会遵循公开、通明、凋谢等理念,为开源软件的孵化提供技术、经营、法律等全方位反对和服务,为开源社区建设和经营提供领导,是开源软件成长倒退的孵化器和加速器。 开源基金会目前已成为开源生态最重要的组织者,作为非营利组织,基金会的运行次要依赖志愿者,孵化的软件我的项目次要依附来自不同地区、不同组织的开发者协同单干。基金会遵循凋谢共享机制,激励企业、开发者、志愿者等独特参加开源,在齐全中立的合作平台做出奉献,从而实现开源生态发展壮大。材料来源于网络 开源基金会的运行模式目前国内上已有几十家权威开源基金会在寰球的开源生态中施展着重要作用,如1985年建设的自由软件基金会、1999年创立的Apache基金会、2007年成立的 Linux基金会等。他们致力于技术创新倒退、为行业利用提供解决方案,大力推广开源文化,既有综合性基金会,也有专一于某个畛域的,同时还有基于单个开源我的项目成立的基金会。从运作模式上次要分为三大类: 01 独特决策模式基金会由整个社区独特决策,回绝“独裁”,如果出现分歧就以投票形式做出决策。Apache基金会是最典型的案例。他们提倡“扁平化”运作,激励社区成员发表意见,我的项目决策由社区所有成员探讨决定。当须要协调时,我的项目会以一种懈怠的共识形式做出决策:几票赞成票,没有反对票就能够开始了,这确实是一个衰弱社区的十分重要的标记。但在波及我的项目策略倒退或法律立场时,必须以投票形式决策,此时仅我的项目提交者和项目管理委员会成员具备投票权。基金会不会强制执行流程,灵活性是他们认为可继续开源成功之路不可或缺的一部分。材料来源于网络 02 “善良的独裁者”(BDL)模式该模式主张我的项目决策者对我的项目整个生命周期放弃相对管制,负责确定我的项目方向,如果出现分歧时来做出最终决策。Linux基金会采纳该模式,我的项目负责人称为“善良的独裁者”(BDL),具备最终决策权,负责制订战略方针、率领我的项目倒退。当社区呈现质疑我的项目提交者的决定时,我的项目负责人可通过查看电子邮件存档来复审其决定,来反对或颠覆决定。这种模式不须要正式抵触解决程序,由我的项目负责人来最终决策。这里假如社区可能是无序的,当存在相互竞争的议程或观点时,可能导致重要问题得不到解决。BDL 模式防止了这些问题,因为善良的独裁者领有最终决定权,能够通过单边决策来解决抵触。材料来源于网络 03 公司主导模式公司主导的我的项目由软件公司管制和赞助,通常是为了减速开发并确保与客户需要保持一致。在这样的设置中,公司对开发的控制权比基金会在社区主导的致力中的控制权更大,但治理依然植根于社区。 只管每个基金会都有不同的价值观和模式,也有着不尽相同的倒退路线。然而他们独特的主旨是统一的,就是为开源提供法律、经营、市场、技术等全方位反对,为社区建设和经营提供领导。 为什么要退出开源基金会在国内开源基金会中,中国成员较2021年同期数量增长26%,达到125家;在云原生计算基金会中,超过20%的我的项目来自中国;在Apache软件基金会中,源自中国的沉闷开源我的项目共24个,其中有14个我的项目成为了顶级我的项目,2021年仅有5个进入Apache软件基金会孵化器的新我的项目全副来自中国;在Linux基金会中,现有中国会员139家……同时 ,2020年中国首个开源基金会“凋谢原子开源基金会”成立,基金会的成立是一次翻新实际,也是中国开源社区倒退的重要里程碑。因而,抉择退出适合且优良的开源基金会显得尤为重要,对于开源我的项目的倒退起着重要的推动作用。材料来源于网络 01 法律和知识产权反对开源基金会能够提供法律和知识产权反对。基金会能够提供一个软件知识产权治理的法律框架,在这个框架中,商业公司能够和自在/开源软件我的项目的贡献者谐和地在一起工作。以Apache基金会为例,其通过制订软件版本公布等规定,明确软件版本由基金会下设的项目管理委员会公布,以此躲避我的项目贡献者的法律危险,为开发人员提供法律爱护。同时,Apache基金会的法律顾问无偿帮忙开源软件社区解决无关许可证兼容和知识产权方面的政策问题。 02 我的项目孵化和营销推广基金会专门设立孵化器负责新我的项目顺利创立。以Apache基金会为例,其孵化器职责包含:筛选无关创立新我的项目或子项目的意向书;帮忙创立我的项目及其所需的基础设施;监督和领导孵化我的项目社区;评估孵化我的项目的成熟度,将其晋升为正式我的项目/子项目,或者在失败时进行孵化。 基金会能够应用通过验证的营销形式吸引开发人员社区和企业,从概念到执行,推广开源我的项目品牌。如Linux基金会借助大型会议、研讨会、沙龙、新媒体等路径推广、宣传旗下开源我的项目,吸引开发者和用户退出。 03 提供业余技术领导基金会设立技术领导与协调组织,帮忙开源我的项目把关技术方向和品质。如,Apache基金会的项目管理委员会(PMC)、CNCF的技术监督委员会(TOC)等。Linux 基金会会指定一位技术顾问委员会负责导师,通过电子邮件领导和帮忙开发人员。 04 基础设施反对基金会提供了一套根底服务,来满足开源我的项目在不同阶段的需要。基金会对于软件治理有一套本人的实际,这对于开发者、用户以及软件的发行,都是十分重要的。Apache基金会为旗下开源我的项目提供包含邮件列表、网站、Gitbox代码托管服务、问题跟踪器以及一系列构建和部署工具等基础设施服务。Linux基金会提供的基础设施服务包含:源代码治理、代码审查、问题追踪、通信基础设施等。 开源我的项目想要取得更快更久远的倒退,就须要较为正式的治理和法律框架。开源基金会提供了一种简略、协同的机制,通过这种机制,企业、集体等组织能够为开源软件做出奉献,基金会通过提供一个齐全中立的合作空间,让所有人参加开发我的项目,同时升高法律危险,为开发人员和开源我的项目提供了一个平安的避风港。**下期咱们对一些优良的开源基金会进行介绍,欢送大家继续关注~** Orillusion致力于打造全世界第一款齐全开源基于WebGPU规范的一种轻量级渲染引擎,指标是在浏览器中实现桌面级的渲染成果,反对超大简单场景的3D出现。易上手,易分享,易迭代,易合作、成本低,跨平台是咱们的外围劣势,咱们将为3D场景暴发时代提供引擎根底工具。 将来咱们将会继续把最干货最前沿的WebGPU技术分享给每一位社区成员,也欢送大家为Orillusion开源社区做出本人的奉献。咱们始终深信,开源社区的技术留痕是每一位技术人员最高尚的谋求!因而,咱们尊重,咱们认可,咱们更期待,退出Orillusion,让咱们共同进步! ——Link uncharted, 链接将来世界

August 25, 2022 · 1 min · jiezi

关于webgl:webglthreejs生成房间楼层

楔子在很多数字孪生我的项目中,都会波及到楼层的建模。楼层的建模因为构造繁多,如果都是建模师进行手动建模,工作量会比拟大。而楼层自身的构造,能够形象成能够通过门路结构的对象(这和之前的文章提及的的管路以及路线相似),这不便咱们通过代码的形式来生成房间楼层。 墙体几何对象PathCubeGeometry楼层个别分成墙体和地板两个局部,首先来看下墙体对象。 以threejs为根底,扩大一个几何对象PathCubeGeometry。 该对象通过一个Path3D门路来结构一个墙的几何体,该几何体能够分成start,end,top,bottom,outside,inside等几个外表分组,这样就不便给内外表和外外表,以及顶面等设置不同的材质贴图的成果。 次要代码如下: this.vert = vert; this.rawUV = rawUV; this.pathU = pathU; this.indices = [] this.vertices = []; this.uvs = [], this.normals = []; this.generateSideWall(vert,inner,outer,innerTop, outerTop, true,closed); this.generateSideWall(vert,inner,outer,innerTop, outerTop, false,closed); this.generateTopBottom(vert,inner,outer,innerTop,outerTop,true,closed); this.generateTopBottom(vert,inner,outer,innerTop,outerTop,false,closed); if(!closed) { this.generateAZSide(vert,inner,outer,innerTop,outerTop,true); this.generateAZSide(vert,inner,outer,innerTop,outerTop,false); }通过PathCubeGeometry,咱们能够不便的构建墙体,比方如下示例代码: const materials = [m1, m2, m3, m3, m3, m3];const points = json.outerWall.path;const p0 = points[0];const path = new Path3D();const scale = 20;path.moveTo(p0.x * scale, p0.y * scale, p0.z * scale);for (let i = 1; i < points.length; i++) {let p = points[i]; path.lineTo(p.x * scale, p.y * scale, p.z * scale);}path.closePath();cosnt patCube = new PathCubeGeometry(path, 10, 50, 32, 500);const mesh = new dt.Mesh(patCube, materials);首先通过Path3D结构一个门路(门路来源于传入的一系列点points),而后通过门路结构一个结合体对象PathCubeGeometry,最初生成实体,成果如下图所示: ...

August 20, 2022 · 2 min · jiezi

关于webgl:干货语义网Web30Web3元宇宙这些概念还傻傻分不清楚下

上一期内容,咱们理解到海内外Web3.0或者说元宇宙的倒退方向不尽相同,其次要起因是两者所处的经济周期和经济构造不同造成的。 海内因为海内的Web3.0倒退都是和金融挂钩,根本都是要发行Token,而后再建设本人的生态。Token在海内是能够间接跟法币进行兑换的,这样就会在短时间内吸引大量的创业者和资本的投入。这种状况的劣势就是从分布式的底层协定到下层利用都会疾速呈现大量的新我的项目,其中肯定不乏一些好我的项目,比方力争取代HTTP的IPFS协定等;但同时带来的问题,就是这种通过Token疾速积攒大量资本的守业模式,对开创团队的“定力”要求更高,毕竟通过发行Token,曾经帮忙创业者换来了十分雄厚的资金,那真正再去投入全情搞研发的初衷和能源就须要更动摇的信念来反对。有点儿像SPAC上市,制度的发明者和初衷肯定是好的,能够帮忙科技企业借助资本疾速推出产品,实现市场验证。然而,稍有不慎,很可能又调演变成已经的“ICO庞氏”。 https://blog.liquid.com/coin-... 咱们置信将来肯定有Web3.0的Facebook和微信,但大概率不是有了Web3.0,就能做成Web3.0的Facebook和微信。其实Facebook和微信能胜利不是有了区块链,而是因为它们自身就是好的利用。利用自身比底层技术是不是区块链更重要。最早提出元宇宙概念的Roblox,没有区块链的加持,然而切中了青少年用户群体,同样获得了胜利。当然,将来底层技术可能都调演变成分布式的网络架构,开发的利用自然而然就是分布式的,也就不会有人再强调本人是基于区块链的某某利用了,拼的必然还是利用自身。 https://moralis.io/decentrali... 国内中国的Web3.0显著比海内要“激进”很多。当下中国没有齐全分布式的底层公链,而是次要在倒退联盟链,包含阿里的蚂蚁链,腾讯的至信链,还有政府主导的长安链等。 联盟链绝对于公链最大的区别就是,它并不是齐全的去中心化,而是半中心化,由一些绝对大的节点(不同的组织)独特参加治理。因为联盟链不须要全副参加节点进行信息确认,所以它的劣势非常明显,比方交易速度快,交易成本低,数据隐衷不会默认公开,可控性强等。因为联盟链不是真正的分布式架构,还是有绝对的中心化概念的,在寰球的Web3.0大背景下天然也存在很多的争议。 https://www.foley.com/en/insi... 咱们认为“不可能三角”带来的问题,目前还是没有方法彻底解决的,更多的是衡量和折中。比方最出名的比特币网络,如果用它来进行商品交易,所有的节点来确认可能须要几个小时的工夫,那这种利用场景显然是没有方法被满足的。而且自然界中如同也的确没有齐全的分布式构造,因为齐全的分布式带来的很可能就是效率的低下。 以后的互联网存在三个比较严重的问题:虚伪信息、隐衷泄露、利用孤岛。人们都寄希望于Web3.0能够真正解决上述问题,而且从技术角度剖析,确实是可行的。通过区块链和智能合约能够很好的实现数据确实权和流程自动化,无效解决虚伪信息问题;通过Token能够让用户本身真正领有本人的数字资产,无效爱护个人隐私;而最初的利用孤岛,指的是各种国内外的超级APP利用。本来凋谢的互联网逐步被一些科技巨头的几款利用所垄断,而Web3.0的分布式特点也是寻求冲破的外围所在。在这种状况下,中国依据本身的倒退状况,确定了属于咱们本人的Web3.0倒退路线。主推联盟链,通过Token和智能合约,解决很多咱们当下互联网构造所面临的问题,比方用户的隐衷,商业合同推动,供应链溯源,图片和视频数字资产确实权,大宗交易的合规等等。 总结,这两种模式并没有优劣好坏之分,都是基于不同的倒退阶段天然演进的。 引擎不管从技术角度,还是商业角度,甚至是人类常识状态演进的角度,元宇宙必然到来。然而,至多须要5-10年的倒退,才有可能实现。在这个漫长的过程中,引擎处于一个十分重要的环节。它是虚拟世界和真实世界的桥梁,是数字内容的外围生产力工具,通过引擎能够更加简略高效的发明虚构的数字世界。在之前的内容里,咱们介绍过很多对于渲染的概念,比方离线渲染,实时渲染,云渲染,混合渲染。这是因为渲染是引擎中很重要的一部分。因为将来的元宇宙肯定是能够实时交互的,所以渲染能力次要还是依附实时渲染和混合渲染相干的技术来撑持。除了渲染,引擎中还蕴含很多其余的技术能力,比方资源、物理、动画、声音、粒子、天气、地形,还有更底层的平台适配和更下层的工具链等等。其实这些能力最早能齐全体现的就是游戏引擎,比方Unity和Unreal。随着元宇宙概念的呈现,传统的游戏引擎也在缓缓的去游戏化,把很多游戏技术利用到其余的行业当中,缓缓的从游戏引擎变成了互动引擎或者说是交互式内容创作引擎。 https://www.gamearter.com/blo... 咱们认为元宇宙肯定不是一个或者几个独立的超级APP来构建的,而应该像World Wide Web (3W)凋谢网络一样,通过对立的规范,保障咱们随时随地接入元宇宙,并且在任何设施上都能够取得雷同的体验,这也是咱们特地关注Web生态的起因。人们通过浏览器,接入一个凋谢的世界,能够实现不同利用的自在切换,并且无效突破商店“抽成”的围墙。 https://thenextweb.com/news/w... 咱们在之前的文章中提过,从技术路线的角度来看,以后的引擎分为Native客户端引擎和Web浏览器引擎。他们的比照剖析,咱们已经也有过具体的介绍:Web or Native 谁才是元宇宙的将来(上)?Web or Native 哪个才是元宇宙的将来(下)? 简略说,Native引擎能够更容易施展出硬件的极致性能,实现高质量的3A级数字内容;而Web引擎,能够更低成本的疾速实现内容创作,同时借助浏览器的跨平台人造劣势,实现内容的疾速散发裂变。家喻户晓,Web生态中的3D内容以后依附的是WebGL规范,而且曾经造成了丰盛的Web3D内容生态。然而随着最新规范WebGPU的推出,才是真正能使得浏览器迫近Native原生图形API成果的最终解决办法。将来构建元宇宙简单空间,内容开发和创作是十分外围的一环,也是引擎的次要工作。 像Metamask这样的钱包利用曾经在浏览器中实现了用户的身份确认问题,而元宇宙场景中的3D内容创作怎么在浏览器中疾速高质量的实现,便是要解决的下一个问题。在WebGPU规范行将公布之时,Orillusion正在致力抓住机遇,力争做一款国人本人的跨时代的Web3D引擎。 Orillusion致力于打造全世界第一款齐全开源基于WebGPU规范的一种轻量级渲染引擎,指标是在浏览器中实现桌面级的渲染成果,反对超大简单场景的3D出现。易上手,易分享,易迭代,易合作、成本低,跨平台是咱们的外围劣势,咱们将为3D场景暴发时代提供引擎根底工具。 将来咱们将会继续把最干货最前沿的WebGPU技术分享给每一位社区成员,也欢送大家为Orillusion开源社区做出本人的奉献。咱们始终深信,开源社区的技术留痕是每一位技术人员最高尚的谋求!因而,咱们尊重,咱们认可,咱们更期待,退出Orillusion,让咱们共同进步! ——Link uncharted, 链接将来世界

August 17, 2022 · 1 min · jiezi

关于webgl:WebGPU-导入1-入门常见问题与个人分享

1. 常见问题① WebGL、ThreeJS 会淘汰吗?WebGL 是不是过期了?WebGPU 性能是不是比 WebGL 强?ThreeJS 会淘汰吗?ThreeJS、BabylonJS 两个利用级 3D 库始终在设计 WebGPU 为底层的新渲染器,后者尤为踊跃。 什么是利用级?这两个库都屏蔽了 WebGL 的底层调用细节,大多数时候,你编写的代码更专一于“场景”中的“三维物体”的地位,加载“模型文件”,高级点的会写丑陋的“材质”。这些带引号的概念,在 WebGL 底层接口都是没有的,是实时渲染技术的一些概念在 JavaScript 中的实现。 如果你是利用级别的开发者,不关怀这些库如何封装底层图形 API,那当初大可不必入场,等正式公布再理解也不迟,毕竟这两个受众这么广的库,为了放弃稳定性,在下层封装上不会短时间内进行激进改变。 WebGL 会淘汰吗?WebGL 是不是过期了?短时间内不会,至多 10 年内。不信你看看 Java8?(开个玩笑) WebGL 1.0 公布至今已有 10 年,齐全落实 WebGL 2.0 的实现也才一年(截至发文),有很多作品、程序仍旧在用基于 WebGL 技术族运行着,发光发热。借用马克思主义哲学的一个原理,是说“旧事物在它的作用没有齐全施展进去之前是绝不会自行沦亡的,旧事物当中除了消极因素,仍然存在积极因素”。 WebGL 的“全局状态”机制继承自 OpenGL,有大量的材料可供查问,大量的案例仍存于互联网中。 WebGPU 的性能是不是比 WebGL 强?有一部分人被 WebGPU 吸引过去的起因是“跨平台 + 性能”这对组合。 诚然,WebGL 比照 Canvas2D 绘图技术的性能,是间接碾压的,在这十年中给 Web 前端带来了高性能的可能,然而长时间的实际下来,有的人发现了“WebGL 程序有时候,并不是那么快,甚至卡的要死”,他们 兴许不会深究底层起因,间接寄希望于一个他们认为的新的王:WebGPU,这其实是一种很不唯心主义的、十分唯心主观的认识。 WebGPU 从设计上来看,的确有不少特色是优于 WebGL 的,列举如下: PromiseAPI / async + await 的异步语法退出:对网络数据加载、解码等同步耗时操作有了更好的反对,肯定水平上防止了回调天堂问题面向对象的 API 设计:绝对于 WebGL API 的过程式调用,选项式图形 API 的应用更迷信不再应用全局状态机制:应用指令缓冲节约了 CPU 到 GPU 之间的信息传递老本,要晓得 WebGL 切换某个状态(例如纹理、着色器程序),就是在切换全局状态对象,这个在宏观上是比拟耗时的,而 60 帧速率的每一帧只有 16.67 毫秒左右,能在宏观节约每一点每一滴的工夫,累计起来就不少了原生反对计算管线、计算着色器:WebGL 磨磨蹭蹭实现的 GPU 并行计算性能间接提供进去,并与渲染管线位置对等然而这些仅仅是在底层的对话根底上比 WebGL 强,这些底层解决的问题,不肯定是有的敌人的“性能问题”。譬如,在应用层、代码逻辑层可能会有这些起因导致了“性能问题”: ...

August 1, 2022 · 2 min · jiezi

关于webgl:WebGL之快速入门

这里,咱们将向大家演示WebGL的一些奢侈阐明和根本应用,即便你后续应用第三方3D渲染引擎进行绘制,这里的基本概念仍旧是十分无益的,或者说是必要的。 在演示和阐明的时候,咱们抉择基于image3D.js来作为依赖库,但因为其奢侈的语法简直和原生WebGL是统一的,因而咱们认为这不是一个蹩脚的抉择(如果间接应用原生,代码会变得过于冗余,不好阐明)。 在后续的阐明中,你都无需查阅别的文档,当然,如果你想晓得的更具体,也能够间接拜访image3D.js 文档进行查阅。 绘制流程个别最通用的绘制流程大抵如下: 筹备好着色器→数据写入缓冲区并实现调配→调用绘制办法进行绘制 不晓得你是否能够了解下面每个步骤是在干什么,咱们上面将通过一个逐步丰盛的例子来进行解释。 你能够提前看看咱们最终要绘制的成果: 这是二元函数 : y=x2+ z2的图像。 你能够点击此处进行查看运行成果。 着色器绘制的第一步,就是筹备好两个着色器:顶点着色器和片段着色器。前者用于形容绘制的图形的点的地位,后者用于形容每个点的色彩。 可能这样说你会无奈了解,其实简略的说就是:咱们在绘图的时候,会一次性的把数据都传递给GPU,传递给GPU的数据须要一些"整顿"后再应用,而着色器就是驻留在GPU上的这段"整顿程序"。 咱们传递的数据是什么?不就是点的地位和点的色彩吗。所以,着色器就分为了顶点着色器和片段着色器(有时候也叫片元着色器),前者解决点,后者解决色彩。 所以,让咱们先看看这里的顶点着色器的具体代码: attribute vec4 a_position;attribute vec4 a_color;varying vec4 v_color;void main(){ gl_Position = a_position; v_color = a_color;}内置变量gl_Position就是绘图最终接管的点的数据,而咱们定义的变量a_position好比一个管道,咱们后续能够给这个变量赋值,也就间接的给gl_Position赋值了(也就是点的地位)。 那v_color是什么?你能够了解,绘图的时候,是以点为主的,每个点的色彩,须要借助点的地位来设置,而v_color就是地位到色彩的桥梁。还是间接看看片段着色器: precision mediump float;varying vec4 v_color;void main(){ gl_FragColor=v_color;}同样的存在一个内置变量,这里叫gl_FragColor, 其接管了来自顶点着色器的v_color。 我不晓得你是否了解了下面的行为,不过你可能也感觉到了,点的地位和色彩如何解决曾经筹备好了,后续咱们只须要借助a_position和a_color就能够设置数据了。 3D对象在传递数据前,咱们先就基于这两个着色器创立3D对象,这一步非常简单,间接看代码: var image3d = new image3D(document.getElementsByTagName('canvas')[0], { "vertex-shader": vsCode, "fragment-shader": fsCode, depth: true});后续的所有操作,包含传递绘制和绘制等,间接调用这个对象上的接口就能够了。 特地阐明:vsCode和fsCode就是下面两个着色器的代码,是字符串。 传递数据终于,能够给GPU传递数据了,所以,咱们先来筹备好数据: var points = [];/** 具体的写法你能够间接看最终的代码,获取的思路大略就是: 三个点拼接成一个三角形, 每个点由6个数据组成,前3个示意点的地位,后3个示意点的色彩, 而一个个三角形拼接成最终的图形。*/// 因而,点的个数就是var num = points.length / 6;这些三角形如何确定的?对xoz面,范畴是-1 ~ 1,切割成一个个正方形,而后斜切一下就能够了: ...

July 24, 2022 · 3 min · jiezi

关于webgl:干货语义网Web30Web3元宇宙这些概念还傻傻分不清楚上

随着元宇宙概念的爆火,也同样呈现了很多新的科技词汇。有些词汇的确容易造成人们的误会,甚至曾经造成了习惯性的混用,然而咱们有必要绝对谨严地对一些词汇的前因后果做一些梳理。在某些状况下,会帮忙大家做一些更精确的判断和了解。 元宇宙这个概念很大,目前也没有定论,先把这个概念放到前面探讨。首先,咱们聊聊语义网、Web3.0和Web3。 语义网语义网,是W3C组织对于WWW万维网的扩大。这个概念,在1999年就被万维网的创始人Berners-Lee提出: I have a dream for the Web [in which computers] become capable of analyzing all the data on the Web – the content, links, and transactions between people and computers. A "Semantic Web", which makes this possible, has yet to emerge, but when it does, the day-to-day mechanisms of trade, bureaucracy and our daily lives will be handled by machines talking to machines. The "intelligent agents" people have touted for ages will finally materialize. ...

July 11, 2022 · 1 min · jiezi

关于webgl:开源生态超实用开源License基础知识扫盲帖下

上一期咱们介绍了对于开源License的一些基本知识。尽管开源License的总体数量很多,然而罕用的License还是很无限的。明天咱们就更间接地理解下罕用License具体的含意和区别。通过这篇文章,首先大家能够对罕用License有一个根本的意识,同时能够让咱们更加“平安”的援用其余的开源我的项目,最初如果咱们本人须要主导开发开源我的项目,也能够更有针对性的抉择适宜本人的开源License。 ·MIT·MIT,源自麻省理工学院(Massachusetts Institute of Technology, MIT),又称X11协定。这是目前最为宽松,限度起码的开源协定。应用MIT License作为开源我的项目的作者,惟一诉求就是保留版权,而不在有其余任何限度。 在应用MIT License的开源我的项目时,只须要记住一点:批改后的代码或者发行包,无论是以源代码模式还是二进制模式,必须要蕴含原作者的许可信息。 *代表开源我的项目:React, Vue, Angular, JQuery, Node.js, Three.js, Lua, .Net Core, Ruby on Rails等 实用商业软件* 材料来源于网络 ·BSD·BSD,伯克利软件发行版(Berkeley Software Distribution)。也是相当宽松的开源协定,能够自在地应用,批改源代码,也能够将批改后的代码抉择持续开源或者闭源。然而咱们要晓得的是BSD自身并不是一个协定,它是由五个协定组成:0-Clause、1-Clause、2-Clause、 3-Clause, and 4-Clause。后面的数字代表限度条款的数目,比方4-Clause就是BSD四条款版。第一个版本的BSD指的就是4-Clause,目前4-Clause和1-Clause都曾经不怎么再应用了。而0-Clause也倒退成为了公共畛域协定(Public Domain License),连作者信息都不要求保留。目前最风行的BSD指的是BSD 3-Clause License(BSD-3-Clause),也叫做BSD 3-Clause New/Revised License。所以咱们这里次要介绍下BSD-3-Clause在产生派生我的项目时,须要留神的状况: 如果是开源我的项目派生,源代码中必须蕴含原我的项目中的BSD协定。 如果是闭源我的项目派生,比方二进制类库或者商业软件,在软件的文档和版权申明中要蕴含原我的项目中的BSD协定。 不管开源或闭源我的项目派生,不能够用BSD我的项目作者、机构或我的项目产品的名称做市场推广。 与此同时,BSD 2-Clause License(BSD-2-Clause)也比拟罕用,它也被称为BSD 2-Clause Simplified/FreeBSD License。咱们须要晓得的是BSD-2-Clause和BSD-3-Clause的最大区别就是,它疏忽了下面的第三条“不许炒作打广告”的条款限度。 *代表开源我的项目:Dart, Django, FreeBSD, Flask, Go, Nginx等 实用商业软件* 材料来源于网络 ·Apache-2.0·Apache-2.0,是一个由Apache软件基金会公布的自由软件许可证(Apache License Vesion 2.0),最新版本为 “Version 2”。它和BSD相似,也是比拟宽松的开源协定,容许用户批改和再公布。然而,公布派生我的项目时须要留神: 如果批改了源代码,须要在被批改的文件中加以阐明。 派生我的项目中,须要带有原我的项目代码中的Apache-2.0协定,同时还包含商标,专利申明以及其余原作者规定须要蕴含的阐明。 派生我的项目中,如果蕴含Notice文件,则在Notice文件中也须要带有Apache-2.0协定。 *代表开源我的项目:Android, Apache HTTP Server, Hadoop, Spark, Babylon.js, LLVM, Log4j等 ...

June 20, 2022 · 1 min · jiezi

关于webgl:开源生态打造活力开源社区共建开源新生态

“在开源还只是一个小众群体的业余爱好时,简直做任何事件,都是自在的。然而,在软件吞噬世界、开源吞噬软件的明天,开源技术,曾经成为整个世界的基础设施之一。 ——《2021年中国开源年度报告》” 先通知大家一个好消息,咱们马上就要开源啦,期待一下哦~ 在开源前,小鸥会用一点点工夫跟大家聊聊对于开源、对于社区的事儿。咱们刚刚开始长大,期待与大家共建一个有价值、有生机、有温度的开源社区! 开源和闭源开源(Open Source)即凋谢源代码,是源代码凋谢共享的开发模式,具备自在凋谢、共建共享的特点。它是一种依靠互联网平台,通过大量群体智慧独特参加合作,一直积攒,实现继续翻新的形式。 “Open Source”的概念出自Debian的社长Bruce Perens起草的“自由软件指导方针”。对确立“Open Source”概念有决定意义的是在1998 年4月7日由18位自由软件静止首领召开的“自由软件高层会议”,通过了流传开源的必要性。 那开源和闭源次要的区别都有哪些呢?看下图 开源的意义GitHub 2021 年度报告数据显示:寰球已有超过 7300 万开发者用户,其中 56.8% 来自北美之外的地区。我国开发者占 10%,有 755 万,位居寰球第二。我国开发者数量及开源贡献度增长已成为寰球最快。GitHub 预测到 2030 年我国开发者将成为寰球最大的开源群体。Raymond在《大教堂与集市》中用大教堂和集市这两个具体形象,来代表两种不同的软件开发模式: 大教堂模式:自上而下,有一群精英进行顶层设计,依照打算去实现工作。 集市模式:自下而上,没有一个相对主导外围,靠的是一般个体们的自组织,一起去实现简单的工作。Raymond观点是:随着互联网的倒退,越来越多的大教堂会隐没,那么剩下的都是大集市。 所以,咱们必须认同一个趋势:“开源软件作为一种「非垄断性」和「非排他性」的常识存在,曾经是软件世界的重要基础设施,也是数字世界不可或缺的将来。” 数字经济时代,人口和流量红利逐步隐没,这都须要咱们开拓新的生态模式,而这所有都源于技术的推动。开源是一种凋谢、共享、协同的翻新合作模式,它不仅是凋谢源代码的软件技术开发,还包含更宽泛的凋谢技术畛域及协同翻新的理念与机制。无论是在寰球还是国内,开源正在推动着信息技术的翻新倒退。这种冲破物理边界、高效麻利的沟通和协同形式必将会为数字经济的倒退带来新生机。同时,开源的高度凋谢和自在,也会让人类智慧失去更好的共享和倒退,升高学习、复用和改良老本,突破技术封闭。开源,最终将造福整个软件业和整个社会。 为什么要开源01 WebGPU,下一代Web3D技术Orillusion致力于打造一款齐全开源基于WebGPU规范的轻量级渲染引擎,指标是在浏览器中实现桌面级的渲染成果,反对超大简单场景的3D出现。易上手、易分享、易迭代、易合作、成本低,跨平台是咱们的外围劣势,咱们将为3D场景暴发时代提供引擎根底工具。 Web环境中始终没有呈现能够实现和桌面级渲染能力相媲美的革命性技术,然而这一现状随着WebGPU规范的提出,行将失去扭转,这是十分让人振奋的改革,咱们将迎来网页图形的全新时代! 通过开源能够帮忙社区更好地理解这项技术,同时也能够通过社区的影响力对这项技术进行推广,邀请更多的开发者参加进来。社区的踊跃疾速反馈也能帮咱们吸取更多的需要场景输出,帮忙技术迭代更新,技术才更有生命力。咱们冀望在将来的数字经济时代可能施展更大更踊跃的作用。 02 开发者生态,构建高价值社区咱们始终深信,软件再优良,如果没有构建起良好的生态,没有开发者和合作伙伴的共建,是很难走得更好更远的。一个开源产品,社区的文化氛围和协同创造力,才是区别于别人最大的不同。 开源生态的建设根植于社区,有了衰弱社区生态的哺养,开源技术能力取得继续成长。志趣相投的开发者们源于被动发明价值的外在能源,在社区共享、共创、共赢,将会激发出有限的创造力,这就是开源最大的魅力! Orillusion在创建之初就动摇地拥抱开源,凋谢容纳、共创共赢是咱们的根本理念。咱们秉承全球化与本土化相结合,既要放弃全球化视角,吸引来自寰球各地优良的开发者退出进来,又要在咱们原有的文化背景下打造合乎外乡特色的开发者生态,推动我国开发者力量长期倒退。 咱们深知,开源生态的建设并非欲速不达,这将是一个长期过程,须要咱们有急躁、有信念、好高鹜远、凋谢心态。 抉择开源,源于咱们深信,“独行快,众行远”! 共建社区是这样的“社区的实质是归属感,没有归属感就没有社区。——Jono Bacon” 01 每一位社区参与者才是宝藏对于开源社区而言,最重要的宝藏不是代码,而是代码背地的每一位参与者和创造者,及大家在共创协同过程中建设起来的链接。社区的建设与成长,社区的文化与气氛,源于社区体系中的每一个人,源于集体会集成的凝聚力。因而,从咱们开源第一天起,每一位参与者是咱们要珍视和爱护的宝藏。 咱们也会始终放弃这样的敬畏之心,邀请更多行业内优良的开发者进来,建设起独特合作的开源社区。 02 放眼寰球的国际化社区咱们心愿通过开源的形式将Orillusion 做成一个平凡的产品,不仅局限在国内,更要着眼寰球! Github 2021 Octoverse报告数据,寰球的开发者有7300万+,2021年新增1600万+。我国2021年在Github的新增开发者103万,总数达到755万+。我国开发者在开源世界的影响力正在一直晋升,曾经从晚期开源的受益者,逐步转变成开源的贡献者。 https://octoverse.github.com/...寰球 97% 的软件开发者和 99% 的企业在应用开源软件,《财产》100 强里就有 84% 的企业应用 GitHub。从整个软件产业的供应链上看,开源曾经成为将来信息技术的主战场。因而,随着工信部信息技术倒退司公布的《“十四五”软件和信息技术服务业倒退布局》,中国开源根底软件当初曾经成为咱们国家的倒退策略。“欠缺开源知识产权和法律体系”相继被写入《“十四五”布局和二〇三五年近景指标大纲》、《“十四五”国家知识产权爱护和使用布局》等国家政策文件。国内的代码托管平台Gitee,2021年托管的代码仓库超过了 2000 万,⽤户总量超过 800 万。在这样一个国内和国内的背景下,中国的技术开发者须要致力,也须要工夫。在这个过程中,Orillusion会邀请全世界优良开发者宽泛参加,以真正凋谢的心态单干和推动开源生态,为我国的开源倒退添砖加瓦。 03 高价值且共赢的社区文化为开发者提供清晰欠缺的文档,升高大家的学习老本和门槛,尽力做到让每个人都是可参加的,能够从提交代码、社区文档、网站建设等方面循序渐进地参加。 WebGPU小白课程曾经上线七期,失去了大家的统一好评,后续咱们将继续输入各种类型优质的体系课程,帮忙大家高效学习。同时,咱们将定期邀请行业内的大咖举办线上、线下交流活动,为大家发明分享学习的机会。同时,咱们将会和各大高校进行单干,疏导更多大学生参加开源社区的建设中。 丰盛和稀缺有着实质不同,稀缺是意味着要击败其余所有对手你才能够胜利的一个游戏规则,但丰盛是将每个人的想法汇聚在一起来减少机会,达到共赢的游戏规则。所以,咱们所建设的社区是共创、共享、共赢的合作模式。 咱们的使命在开源世界,社区的概念不是物理定义的结构,也不是某个社交软件独自的状态,它是通过大家独特参加发明、分享观点和趣味来定义的。来自不同背景、不同观点的人都能够参加,思维、教训和意见的多样性,都使得衰弱的社区衰弱倒退。 基于WebGPU新技术,基于开源新生态,Web3D场景新需要,咱们深信在这个全新的我的项目和社区中,每一位参与者能够感触到共创和翻新的力量,并在这个过程中与别人建设长久高价值的协同关系。激发激情、挖掘劣势、找到气味相投的伙伴、突破天花板,取得成长,实现自我价值~ ...

May 26, 2022 · 1 min · jiezi

关于webgl:在-WebGPU-的片元着色器中访问帧缓冲坐标

在片元着色器中拜访帧缓冲坐标 1. 技术阐明应用最新 Edge/Chrome Canary 浏览器应用 VSCode 插件 LiveServer 的 HTTP 服务器对本机提供 5500 端口的页面服务,即 http://localhost:5500/index.html应用 es-module 格调的 JavaScript 实现2. 三角形例子先上成果,前面再解析片元着色器: HTMLhtml 局部就简略一些 <canvas id="c" width="600" height="600" style="border: 1px solid darkseagreen;"></canvas><script type="module" src="./main.js"></script>不出意外的话,你能够看到一个带暗绿色边框的 canvas,长宽均为 600 像素。 JavaScriptJavaScript 代码也比较简单,省略大部分动静代码和有无判断代码: const canvas = document.getElementById('c')const shaderText = `/* 着色器代码,前面会给 */`const init = async () => { const adapter = await navigation.gpu.requestAdapter() const device = await adapter.requestDevice() const context = canvas.getContext('webgpu') const presentationFormat = context.getPreferredFormat(adapter) context.configure({ device, format: presentationFormat, size: [ 600, 600 ], // canvas 的画图尺寸 }) const pipeline = device.createRenderPipeline({ vertex: { module: device.createShaderModule({ code: shaderText }), entryPoint: 'vertexMain' }, fragment: { module: device.createShaderModule({ code: shaderText }), entryPoint: 'fragmentMain', targets: [{ format: presentationFormat }], }, primitive: { topology: 'triangle-list' }, }) const render = () => { /* 每帧创立编码器并“录制”编码过程,最终提交给设施 */ const commandEncoder = device.createCommandEncoder() const textureView = context.getCurrentTexture().createView() const renderPassDescriptor = { colorAttachments: [ { view: textureView, clearValue: { r: 0.0, g: 0.0, b: 0.0, a: 1.0 }, loadOp: 'clear', storeOp: 'store', }, ], } const passEncoder = commandEncoder.beginRenderPass(renderPassDescriptor) passEncoder.setPipeline(pipeline) passEncoder.draw(3, 1, 0, 0) passEncoder.end() device.queue.submit([commandEncoder.finish()]) requestAnimationFrame(render) } requestAnimationFrame(render)} // async function initinit()我保留了残缺的 rAF 帧动画构造。 ...

April 27, 2022 · 2 min · jiezi

关于webgl:WebGL-及其在-WebRTC-中的应用

一、前言1、什么是 WebGL ?WebGL 的全称是 Web Graphics Library,是一种 3D 绘图协定。 WebGL 容许把 JavaScript 和 OpenGL ES 2.0 联合在一起,通过减少 OpenGL ES 2.0 的一个JavaScript 绑定,WebGL 能够为 HTML5 Canvas 提供硬件 3D 减速渲染。Web 开发人员就能够借助零碎显卡来在浏览器里更流畅地展现 3D 场景和模型,还能创立简单的导航和数据视觉化。 2、OpenGL 与 GLSL在理解 WebGL 之前,咱们需理解下什么是 OpenGL 与 GLSL。 OpenGL(英语:Open Graphics Library,译名为凋谢图形库或者“开放式图形库”)是用于渲染 2D、3D 矢量图形的跨语言、跨平台的应用程序编程接口(API), GLSL 则是用来在 OpenGL 中着色编程的语言。 从上文中能够看到 WebGL 实际上是 JavaScript 操作一些 OpenGL 接口,也就意味着,可能会编写一部分 GLSL ES 2.0 的代码,没错你猜对了,WebGL 只是绑定了一层,外部的一些核心内容,例如着色器、材质、灯光等都是须要借助 GLSL ES 语法来操作的。 基于 WebGL 周边也衍生了泛滥的第三方库,比方开发利用类的 Three.js,开发游戏类的 Egert.js 等,都大大的升高了学习 WebGL 的老本,然而本着有问题解决问题,没问题制作问题再解决问题的程序猿态度,还是感觉应该略微理解一下 WebGL 的一些基本概念,以便能更好的去了解不同框架带来的便捷以及劣势! ...

March 25, 2022 · 3 min · jiezi

关于webgl:WebGPU-计算管线计算着色器通用计算入门案例2D-物理模拟

原文译名:WebGPU - 专一于解决外围(GPU Cores),而不是绘图画布(Canvas)原文公布于 2022年3月8日,传送门 https://surma.dev/things/webgpu 这篇货色十分长,不计代码字符也有1w字,能比拟好了解 WebGPU 的计算管线中的各个概念,并应用一个简略的 2D 物理模拟程序来了解它,本篇重点是在计算管线和计算着色器,绘图局部应用 Canvas2D 来实现。 WebGPU 是行将推出的 WebAPI,你能够用它拜访图形处理器(GPU),它是一种底层接口。 原作者对图形编程没有多少教训,他是通过钻研 OpenGL 构建游戏引擎的教程来学习 WebGL 的,还在 ShaderToy 上学习 Inigo Quilez 的例子来钻研着色器。因而,他能在 PROXX 中创立背景动画之类的成果,然而他示意对 WebGL 并不太称心。别急,下文马上会解释。 当作者开始留神 WebGPU 后,大多数人通知他 WebGPU 这货色比 WebGL 多很多条条框框。他没思考这些,曾经预感了最坏的状况,他尽可能找了一些教程和标准文档来看,尽管彼时并不是很多,因为他找的时候 WebGPU 还在晚期制订阶段。不过,他深刻之后发现 WebGPU 并没有比 WebGL 多所谓的“条条框框”,反而是像见到了一位老朋友一样相熟。 所以,这篇文章就是来分享学到的货色的。 作者明确指出,他 不会 在这里介绍如何应用 WebGPU 绘制图形,而是要介绍 WebGPU 如何调用 GPU 进行它自身最原始的计算(译者注:也就是通用计算)。 他感觉曾经有很多材料介绍如何用 WebGPU 进行绘图了,例如 austin 的例子,或者他思考之后也写一些绘图方面的文章。 他在这里会探讨得比拟深刻,心愿读者能正确、无效地应用 WebGPU,然而他不保障你读完就能成为 GPU 性能专家。 絮絮叨叨完结后,筹备发车。 1. WebGLWebGL 是 2011 年公布的,迄今为止,它是惟一能在 Web 拜访 GPU 的底层 API,实际上它是 OpenGL ES 2.0 的繁难封装版以便能在 Web 中应用。WebGL 和 OpenGL 都是科纳斯组标准化的,这个工作组是图形界的 W3C,能够这么了解。 ...

March 21, 2022 · 8 min · jiezi

关于webgl:webGL-vertexAttribPointer-函数理解

MDN官网定义通知显卡从以后绑定的缓冲区(bindBuffer()指定的缓冲区)中读取顶点数据。 语法void gl.vertexAttribPointer(index, size, type, normalized, stride, offset);参数index 指定要批改的顶点属性的索引size 指定每个顶点属性的组成数量,必须是1,2,3或4。type 指定数组中每个元素的数据类型normalized 当转换为浮点数时是否应该将整数数值归一化到特定的范畴stride 一个GLsizei,以字节为单位指定间断顶点属性开始之间的偏移量(即数组中一行长度)。不能大于255。如果stride为0,则假设该属性是严密打包的,即不交织属性,每个属性在一个独自的块中,下一个顶点的属性紧跟以后顶点之后。offset GLintptr (en-US)指定顶点属性数组中第一局部的字节偏移量。必须是类型的字节长度的倍数了解为什么应用vertexAttribPointer如果须要批改顶点地位和色彩, 那么须要创立两个缓冲区。而应用vertexAttribPointer 能够存多种数据,不同数据间通过偏移来辨别,这样就能够只须要一个缓冲区数据了。 参数了解index 通过gl.getAttribLocation(gl.program, "a_Position")办法能够返回a_Position属性的索引,这就是index须要的数据size 你须要一次取几个数据。 例如: const verties = new Float32Array([ 0.0, 0.5, -0.4, 0.19607843137254902, 0.8431372549019608, 0.8745098039215686, -0.5, -0.5, -0.4, 0.4, 1.0, 0.4, 0.5, -0.5, -0.4, 1.0, 0.4, 0.4, 0.5, 0.4, -0.2, 1.0, 0.4, 0.4, -0.5, 0.4, -0.2, 1.0, 1.0, 0.4, 0.0, -0.6, -0.2, 1.0, 1.0, 0.4, 0.0, 0.5, 0.0, 0.4, 0.4, 1.0, -0.5, -0.5, 0.0, 0.4, 0.4, 1.0, 0.5, -0.5, 0.0, 1.0, 0.4, 0.4, ]);如果参数设置为3, 那就是说一次拿3个数据。 ...

March 7, 2022 · 1 min · jiezi

关于webgl:WebGL-与-WebGPU比对5-渲染计算的过程

前两篇文章介绍了 WebGL 和 WebGPU 是如何筹备顶点和数字型 Uniform 数据的(纹理留到下一篇),当渲染所需的原材料筹备实现后,就要进入逻辑组装的过程。 WebGL 在这方面通过指定“WebGLProgram”,最终触发“drawArrays”或“drawElements”来启动渲染/计算。全局状态为特色的 WebGL 显然做多步骤渲染来说会麻烦一些,WebGPU 改善了渲染计算过程的接口设计,容许开发者组装更简单的渲染、计算流程。 以所有的“draw”函数调用为分界线,调用后,就认为 CPU 端的工作曾经实现,开始移交筹备好的渲染、计算原材料(数据与着色器程序)至 GPU,进而运行起渲染管线,直至输入到帧缓冲/Canvas,我称 draw 这个行为是“一个通道”。 WebGPU 的呈现,除了渲染的性能,还呈现了通用计算性能,draw 也有了兄弟概念:dispatch(调度),下文会比照介绍。1. WebGL1.1. 应用 WebGLProgram 示意一个计算过程WebGL 的整个渲染管线(尽管没有管线 API)中,能染指编程的就两处:顶点着色阶段 和片元着色阶段,别离应用顶点着色器和片元着色器实现渲染过程的定制。 很多书或入门教程都会说,顶点着色器和片元着色器是成对呈现的,而能治理这两个着色器的下层容器对象,就叫做程序对象(接口 WebGLProgram)。 const vertexShader = gl.createShader(gl.VERTEX_SHADER) // WebGLShadergl.shaderSource(vertexShader, vertexShaderSource)gl.compileShader(vertexShader)const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER) // WebGLShadergl.shaderSource(fragmentShader, fragmentShaderSource)gl.compileShader(fragmentShader)const program = gl.createProgram() // WebGLProgramgl.attachShader(program, vertexShader)gl.attachShader(program, fragmentShader)gl.linkProgram(program)其实,真正的渲染管线是有很多步骤的,顶点着色和片元着色只是比拟有代表性: 顶点着色器大多数时候负责取色、图形变换片元着色大多数时候负责计算并输入屏幕空间的片元色彩既然 WebGL 只能定制这两个阶段,又因为这俩 WebGLShader 是被程序对象(WebGLProgram)治理的,所以,一个程序对象所代表的那个“管线”,通常用于执行一个通道的计算。 在简单的 Web 三维开发中,一个通道还不足以将想要的一帧画面渲染实现,这个时候要切换着色器程序,再进行 drawArrays/drawElements,绘制下一个通道,这样组合多个通道的绘制后果,就能在一个 requestAnimationFrame 中实现想要的渲染。 1.2. WebGL 没有通道 API上文提及,在一帧的渲染过程中,有可能须要多个通道共同完成渲染。最初一次 gl.drawXXX 的调用会应用一个绘制到指标帧缓冲的 WebGLProgram,这么说可能很形象,无妨思考这样一帧的渲染过程: 渲染法线、漫反射信息到 FBO1 中;渲染光照信息到 FBO2 中;应用 FBO1 和 FBO2,把最初后果渲染到 Canvas 上。每一步都须要本人的 WebGLProgram,而且每一步都要全局切换各种 Buffer、Texture、Uniform 的绑定,这样就须要一个封装对象来实现这些状态的切换,惋惜的是 WebGL 并没有这种对象,大多数时候是第三方库应用相似的类实现的。 ...

February 28, 2022 · 2 min · jiezi

关于webgl:WebGL-与-WebGPU比对4-Uniform

家喻户晓,在 GPU 跑可编程管线的时候,着色器是并行运行的,每个着色器入口函数都会在 GPU 中并行执行。每个着色器对一大片对立格局的数据进行冲锋,体现 GPU 多外围的劣势,能够小核同时解决数据;不过,有的数据对每个着色器都是一样的,这种数据的类型是“uniform”,也叫做对立值。 这篇文章列举了原生 WebGL 1/2 中的 uniform 材料,以及 WebGPU 中的 uniform 材料,有一些例子供参考,以用来比对它们之间的差别。 1. WebGL 1.0 Uniform1.1. 用 WebGLUniformLocation 寻址在 WebGL 1.0 中,通常是在 JavaScript 端保留 WebGLUniformLocation 以向着色器程序传递 uniform 值的。 应用 gl.getUniformLocation() 办法获取这个 location,有如下几种形式 全名:gl.getUniformLocation(program, 'u_someUniformVar')重量:通常是向量的一部分,譬如 gl.getUniformLocation(program, 'u_someVec3[0]') 是获取第 0 个元素(元素类型是 vec3)的 location构造体成员:gl.getUniformLocation(program, 'u_someStruct.someMember')下面三种状况与之对应的着色器代码: // 全名uniform float u_someUniformVar;// 重量uniform vec3 u_someVec3[3]; // 留神,这里是 3 个 vec3// 构造体成员struct SomeStruct { bool someMember;};uniform SomeStruct u_someStruct; 传值分三类,标量/向量、矩阵、采样纹理,见下文。 1.2. 矩阵赋值用 uniformMatrix[234]fv对于矩阵,应用 gl.uniformMatrix[234]fv() 办法即可传递,其中,f 代表 float,v 代表 vector,即传入参数要是一个向量(即数组); ...

February 19, 2022 · 5 min · jiezi

关于webgl:WebGL-与-WebGPU比对3-顶点缓冲

1. 获取高频操作对象1.1 WebGL 获取上下文对象WebGL 获取的是 WebGLRenderingContext/WebGLRenderingContext2 对象,必须依赖于有适合宽度和高度的 HTMLCanvasElement,通常命名为 gl,gl 变量有十分多办法,容许批改 WebGL 的全局状态 const gl = document.getElementById("id")?.getContext("webgl")// ...1.2 WebGPU 获取设施对象而 WebGPU 则不依赖具体的 Canvas,它操作的是物理图形卡设施,并应用 ES6/7 的异步语法获取,获取的是 GPUAdapter 和 GPUDevice,然而与 WebGLRenderingContext 起着相似“收回大多数命令”的大管家式角色的,更多是 GPUDevice 对象 const entryFn = async () => { if (!navigator.gpu) { return } // 测试版 Chrome 有可能返回 null const adapter = await navigator.gpu.requestAdapter() if (!adapter) { return } const device = await adapter.requestDevice() // ...}entryFn()WebGPU 的入口是 navigator.gpu 对象,这个对象在 WebWorker 中也有,所以对 CPU 端的多线程有良好的反对。应用此对象异步申请适配器后,再应用适配器申请具象化的设施对象即可。 ...

February 14, 2022 · 2 min · jiezi

关于webgl:WebGL-与-WebGPU比对2-初始化篇

1. 获取高频操作对象1.1 WebGL 获取上下文对象WebGL 获取的是 WebGLRenderingContext/WebGLRenderingContext2 对象,必须依赖于有适合宽度和高度的 HTMLCanvasElement,通常命名为 gl,gl 变量有十分多办法,容许批改 WebGL 的全局状态 const gl = document.getElementById("id")?.getContext("webgl")// ...1.2 WebGPU 获取设施对象而 WebGPU 则不依赖具体的 Canvas,它操作的是物理图形卡设施,并应用 ES6/7 的异步语法获取,获取的是 GPUAdapter 和 GPUDevice,然而与 WebGLRenderingContext 起着相似“收回大多数命令”的大管家式角色的,更多是 GPUDevice 对象 const entryFn = async () => { if (!navigator.gpu) { return } // 测试版 Chrome 有可能返回 null const adapter = await navigator.gpu.requestAdapter() if (!adapter) { return } const device = await adapter.requestDevice() // ...}entryFn()WebGPU 的入口是 navigator.gpu 对象,这个对象在 WebWorker 中也有,所以对 CPU 端的多线程有良好的反对。应用此对象异步申请适配器后,再应用适配器申请具象化的设施对象即可。 ...

February 14, 2022 · 2 min · jiezi

关于webgl:WebGPU-中消失的-FBO-和-RBO

OpenGL 体系给图形开发留下了不少的技术积攒,其中就有不少的“Buffer”,耳熟能详的就有顶点缓冲对象(VertexbufferObject,VBO),帧缓冲对象(FramebufferObject,FBO)等。 切换到以三大古代图形开发技术体系为根底的 WebGPU 之后,这些经典的缓冲对象就在 API 中“隐没了”。其实,它们的职能被更迷信地扩散到新的 API 去了。 本篇讲一讲 FBO 与 RBO,这两个通常用于离屏渲染逻辑中,以及到了 WebGPU 后为什么没有这两个 API 了(用什么作为了代替)。 1 WebGL 中的 FBO 与 RBOWebGL 其实更多的角色是一个绘图 API,所以在 gl.drawArrays 函数收回时,必须确定将数据资源画到哪里去。 WebGL 容许 drawArrays 到两个中央中的任意一个:canvas 或 FramebufferObject. 很多材料都有介绍,canvas 有一个默认的帧缓冲,若不显式指定本人创立的帧缓冲对象(或者指定为 null)那就默认绘制到 canvas 的帧缓冲上。 换句话说,只有应用 gl.bindFramebuffer() 函数指定一个本人创立的帧缓冲对象,那么就不会绘制到 canvas 上。 本篇探讨的是 HTMLCanvasElement,不波及 OffscreenCanvas1.1 帧缓冲对象(FramebufferObject)FBO 创立起来简略,它大多数时候就是一个负责点名的头儿,出汗水的都是小弟,也即它下辖的两类附件: 色彩附件(在 WebGL1 中有 1 个,在 WebGL 2 能够有16个)深度模板附件(能够只用深度,也能够只用模板,也能够两个一起应用)对于 MRT 技术(MultiRenderTarget),也就是容许输入到多个色彩附件的技术,WebGL 1.0 应用 gl.getExtension('WEBGL_draw_buffers') 获取扩大来应用;而 WebGL 2.0 原生就反对,所以色彩附件的数量上有所区别。而这两大类附件则通过如下 API 进行设置: // 设置 texture 为 0 号色彩附件gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, color0Texture, 0)// 设置 rbo 为 0 号色彩附件gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, color0Rbo)// 设置 texture 为 仅深度附件gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.TEXTURE_2D, depthTexture, 0)// 设置 rbo 为 深度模板附件(须要 WebGL2 或 WEBGL_depth_texture)gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_STENCIL_ATTACHMENT, gl.RENDERBUFFER, depthStencilRbo)实际上,在须要进行 MRT 时,gl.COLOR_ATTACHMENT0、gl.COLOR_ATTACHMENT1 ... 这些属性只是一个数字,能够通过计算属性进行色彩附件的地位索引,也能够间接应用明确的数字代替: ...

February 14, 2022 · 4 min · jiezi

关于webgl:Web-or-Native-哪个才是元宇宙的未来下

上一篇文章咱们介绍了 Web 和 Native 的倒退历程,对Web端的跨平台个性以及生态的倒退和遍及水平广的劣势进行了剖析,还没有看到的敌人们能够点击上面链接回顾一下哦 Web or Native 谁才是元宇宙的将来(上)? 置信看完这篇文章,你曾经有了一些想法,明天咱们持续来聊一聊对于Web和Native的技术栈抉择,看看你是否也批准小鸥的认识呢~ Web劣势3: 超级APP生态的嵌入任何公司具备了超级APP之后,必然都会思考打造利用外部的生态,将尽量多的场景和能力在本人的利用生态中对立解决。比方咱们日常都会应用的微信、支付宝、淘宝等等。 思考到应答场景和需要的多变性,支付宝、淘宝、微信都是混合框架,在保留弱小的Native能力和性能的同时,又充分利用JS/Web的灵便的前端生态能力,保障开发效率的同时,又能满足疾速迭代热更新。春节邻近期间,支付宝或者淘宝中都会有很多3D的特效呈现,像红包、五福等等。 对于Unity这种Native引擎来说,尽管实现这些3D特效都非常简单,然而因为它齐全是在Native框架下的产品,在交融上存在泛滥技术难点,很难和前端的技术进行无缝的对接。所以,面对这种超级APP的人造流量汇聚地,Unity也无奈接入。而最终咱们看到的各种3D特效,都是由挪动优先、Web优先的Oasis引擎团队打造实现的! Oasis 引擎 Github 链接https://github.com/oasis-engineWeb劣势4: 易流传、易分享、易合作,人造的SaaS服务模式因为在Web环境下,通过一个链接就能够把内容分享到不同的平台,不同的人群,这种模式能够达到极致的内容流传成果。最有代表性的就是咱们的微信,通过朋友圈,微信群,公众号等等,都可能引起内容分享的病毒式裂变成果。 已经,咱们分享的内容更多的是以图片,文字,视频,音频的模式。随着元宇宙时代的到来,更多样的3D内容也可能会随着一个链接引发内容流传的爆点,这给了内容制作畛域更广大的设想空间。WebGPU规范是实现此场景的关键技术点。 更值得一提的是,基于浏览器通用反对的WebSocket/WebRTC协定,配合如OT等分布式算法能够轻松实现分布式协同,达到多人同步实现一项工作的高效单干模式,这些都是Web得天独厚的劣势体现。比方Google Doc,石墨文档,飞书文档等,也都是借助于浏览器环境实现了合作性能。依附Web协同个性最胜利的企业应该是估值超百亿美金的Figma,它的胜利同时也引爆了「设计合作」这样一个超过千亿市场规模的SaaS赛道。 说到SaaS服务,是简直所有的互联网公司都谋求的变现模式。这也正是Web另外一个微小的劣势体现,因为简直所有的SaaS都是以Web浏览器作为媒介来提供服务的。 最近十分火爆的「Gather Town」元宇宙办公服务提供商,全套的技术框架都是基于Web环境实现的,这大大降低了用户应用的门槛,也为他们的流传带来了的微小的促进作用(他们的客户端也是基于Electron打包,一套代码间接散发成为各个平台的APP进行装置)。 Web劣势5: 热加载不管喜不喜欢“元宇宙”这个词汇,它都无奈阻挡的向咱们缓缓走来。咱们了解的“元宇宙”,是一个有限可能的场景。为了实现这种有限的可能性,就要求元宇宙产品必须具备两个特点: 性能的疾速更新及有限扩大:将来,咱们的产品有了新的feature,一旦通过测试,就应该立即服务于咱们的用户;资源的疾速更新及有限扩大:不论是UGC还是PGC,用户在应用产品进行内容创作时,一旦有了新的变动,其余所有的用户应该在第一工夫无提早的状况下进行体验。Native原生的应用程序是很难实现这些特点的,因为每一次应用程序的公布更新等,都须要从新的编译,甚至还须要利用商店的审核。如果一个技术团队,面对需要变动微小的场景进行产品研发,任何前端需要的变动都要造成一次APP的从新编译公布,那效率会十分低下。这也是为什么像Flutter,React Native,Weex这种框架会越来越火,因为它们都有着和Web一样的热加载个性。 热加载的原理是利用脚本语言的可解释个性,咱们通过间接刷新的模式,或者网络通信,把新的脚本内容直接插入或者笼罩原来须要被解释的代码局部,这样再由实时的解释形语言编译器进行实时运行,就能够达到即时更新的热加载成果。 而Native的利用,都是要进行预编译,简略了解就是最终APP都会变成0101这种货色,那新扭转的内容就没有方法在未编译的状况下,被间接执行了。 咱们利用Web的人造热加载个性,再配合产品设计的模块化架构以及代码治理的Monorepo机制,就能够轻松的实现产品性能的疾速更新及有限扩大和资源的疾速更新及有限扩大。总而言之,Web可能更加适宜“元宇宙”这种高速变动且具备有限可能性的场景。 小鸥的思考Web技术栈和Native技术栈并不是一种纯竞争的关系。Native能带来更加极致的性能体验,这是毋庸置疑的事实。不论是Unity,还是Unreal,甚至是依附靠近原生图形API性能的Bgfx架构来开发各种游戏和利用,都体现了Native弱小的劣势。 Bgfx 引擎Github链接https://github.com/bkaradzic/bgfx咱们常常打一个比如,即便手机的拍照能力再强,真正的“老法师”也仍然会保持用600去打鸟。即便美图秀秀能够一键生成简直完满的自拍照,PS的专业级忠诚用户仍然会死守不放。 因而,抉择Web或Native,也不再是一个哲学问题,而是一个场景问题。 如果咱们的场景须要谋求极致的性能,那就用Native的技术栈去开发,比方Unity和Unreal。他们在游戏场景里简直垄断的位置,足以证实这一点。R Star引擎下的《荒野大镖客》更是成为了行业内的天花板级存在。 如果场景更多的是趋向于便捷,简略,易分享等等特色,抉择Web很可能是一个更佳的计划。最重要的是,当初有了WebGPU这样一个跨时代的全新规范,将最大限度的磨平Web和Native对于3D场景出现上的差距。 已经的WebGL时代,在3D场景中,Web开发者是很难真正发力的。实现一个优良的3D场景利用是一个极其苦楚的过程。因为WebGL的性能切实太差了,很多Native能够轻松实现的渲染成果,WebGL都实现不了。但在这种极其艰巨的状况下,Web上也呈现了泛滥优良的利用案例! 事实世界中应用WebGL的25+个利用https://zhuanlan.zhihu.com/p/369632693因而,抉择Web和Native,可能也不再是一个场景问题,而是一个面对元宇宙暴发时代的将来判断问题。 将来的世界,会有大量的3D内容制作需要,因为3D内容是元宇宙搭建的根底。这也就意味着,咱们面对的不是一个存量市场,而是一个增量市场,甚至是一个未知的充斥有限可能的市场。泛滥的Web开发者,都会成为将来3D场景搭建的潜在生产力。Web的技术栈会因为WebGPU规范的到来,呈现前所未有的晋升和扭转。这对于Web前端开发者,是一件太幸福的事件! 面对将来,当更多的年轻人,更多的新人进入到相应行业中,他们要思考:什么是最适宜的, 什么是最简略的,或者哪种抉择将来的需要更多,本人更可能成长。Web生态就很有可能暴发出前所未有的劣势:易上手,易分享,易迭代,成本低,跨平台,这些特点未然满足了绝大部分的场景。 因而,咱们对于WebGPU加持下的Web生态充斥了期待! 如何退出Orillusion WebGPU社区?第一步:长按下图,扫码增加管理员微信 第二步:填写论坛注册申请表 第三步:查看邮箱,点击注册申请链接 第四步:注册胜利,欢送留言发帖 欢送更多的小伙伴能够退出咱们的Orillusion社区,陪咱们一起见证WebGPU的倒退。咱们会尽本人最大的致力把最干货最前沿的WebGPU技术分享给每一位社区成员,也诚心的心愿大家为Orillusion开源社区做出本人的奉献。咱们始终深信,开源社区的技术留痕是每一位技术人员最高尚的谋求。因而,咱们尊重,咱们认可,咱们更期待,退出Orillusion,让咱们共同进步! ——Link uncharted, 链接将来世界

January 26, 2022 · 1 min · jiezi

关于webgl:WebGPU-的几个最佳实践

来自 2022 WebGL & WebGPU Meetup 的 幻灯片 1 在能用的中央都用 label 属性WebGPU 中的每个对象都有 label 属性,不论你是创立它的时候通过传递 descriptor 的 label 属性也好,亦或者是创立实现后间接拜访其 label 属性也好。这个属性相似于一个 id,它能让对象更便于调试和察看,写它简直不须要什么老本考量,然而调试的时候会十分、十分爽。 const projectionMatrixBuffer = gpuDevice.createBuffer({ label: 'Projection Matrix Buffer', size: 12 * Float32Array.BYTES_PER_ELEMENT, // 成心设的 12,实际上矩阵应该要 16 usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST,})const projectionMatrixArray = new Float32Array(16)gpuDevice.queue.writeBuffer(projectionMatrixBuffer, 0, projectionMatrixArray)下面代码成心写错的矩阵所用 GPUBuffer 的大小,在谬误校验的时候就会带上 label 信息了: // 控制台输入Write range (bufferOffset: 0, size: 64) does not fit in [Buffer "Projection Matrix Buffer"] size (48).2 应用调试组指令缓冲(CommandBuffer)容许你增删调试组,调试组其实就是一组字符串,它批示的是哪局部代码在执行。谬误校验的时候,报错音讯会显示调用堆栈: ...

January 26, 2022 · 3 min · jiezi

关于webgl:WebGL-与-WebGPU-比对1-前奏

这篇讲讲历史,不太适宜直奔主题的敌人们。 1 为什么是 WebGPU 而不是 WebGL 3.0你若往 Web 图形技术的底层去深究,肯定能追溯到上个世纪 90 年代提出的 OpenGL 技术,也肯定能看到,WebGL 就是基于 OpenGL ES 做进去的这些信息。OpenGL 在那个显卡羸弱的年代施展了它应有的价值。 显卡驱动咱们都晓得当初的显卡都要装置显卡驱动程序,通过显卡驱动程序裸露的 API,咱们就能够操作 GPU 实现图形处理器的操作。 问题就是,显卡驱动和一般编程界的汇编一样,底层,不好写,于是各大厂就做了封装 —— 码界的基操。 图形 API 的简略年表OpenGL 就是干这个的,负责下层接口封装并与上层显卡驱动打交道,然而,家喻户晓,它的设计格调曾经跟不上古代 GPU 的个性了。 Microsoft 为此做进去最新的图形API 是 Direct3D 12,Apple 为此做进去最新的图形API 是 Metal,有一个驰名的组织则做进去 Vulkan,这个组织名叫 Khronos。D3D12 当初在发光发热的中央是 Windows 和 PlayStation,Metal 则是 Mac 和 iPhone,Vulkan 你可能在安卓手机评测上见得多。这三个图形 API 被称作三大古代图形API,与古代显卡(无论是PC还是挪动设施)的分割很亲密。 WebGL 能运行在各个浏览器的起因噢,忘了一提,OpenGL 在 2006 年把丢给了 Khronos 管,当初各个操作系统根本都没怎么装这个很老的图形驱动了。 那问题来了,基于 OpenGL ES 的 WebGL 为什么能跑在各个操作系统的浏览器? 因为 WebGL 再往下曾经能够不是 OpenGL ES 了,在 Windows 上当初是通过 D3D 转译到显卡驱动的,在 macOS 则是 Metal,只不过工夫越靠近当初,这种非亲儿子式的实现就越发艰难。 ...

January 15, 2022 · 3 min · jiezi

关于webgl:北京-数据分析公司-招聘渲染方向研发工程师-薪资开放

工作内容/要求:参加研发2D根底渲染引擎(为满足图可视化方向) 参考 netv,sigma图相干算法。(这个作为抉择)前端/后端日常开发也会参加。不过少... 最多算是对接。。数学要好一点点, 渲染协定Webgl / OpenGL理论开发教训。 (加分)。工作劣势:属于研发团队。领导nice(直属leader当然是我啦) 我关注就是后果。(也就是输入内容我认可。那么下班天天摸鱼都可轻易你。)我可能带给你的( 工作上 技术晋升,工作其余软能力晋升。 当然有一天你想去大厂,也能够推你一把。生存上嘛 我可能帮忙的肯定乐意效劳)公司可能带给你的,钱(对,还能够申请奖金) 环境 将来(前景的很大的。IPO的日子也不会远) 一个不一样的经验。公司介绍:规模400+,大数据分析类型公司。 薪资问题:看面试后果定。 有动向的请分割我的微信。wywin2021over - -

January 14, 2022 · 1 min · jiezi

关于webgl:如何基于模型数据绘制一个3D机器人

最终的成果如左边所示(你能够应用鼠标、手指或者键盘来管制这个机器人的旋转): 本我的项目基于image3D实现。 在正式开始之前,咱们须要筹备好模型数据,你能够去这里下载:model.json 如果想疾速体验最终成果,能够点击此处查看。 着色器首先,你须要筹备好两个着色器。 顶点着色器<script type='x-shader/x-vertex' id='vs'> attribute vec3 a_position; // 顶点坐标 uniform mat4 u_matrix; // 变换矩阵 uniform vec3 u_LPosition; // 光的地位 attribute vec3 a_normal; varying vec3 v_LDirection; varying vec3 v_normal; void main(){ // 坐标新增齐次坐标,为了和矩阵对齐 gl_Position=u_matrix * vec4(a_position,1); // 点光源方向计算:点光源方向 = 点光源坐标 - 顶点坐标 // 顶点的地位应该应用计算过的 v_LDirection=u_LPosition-gl_Position.xyz; v_normal=a_normal; }</script>片段着色器<script type='x-shader/x-fragment' id='fs'> precision mediump float; uniform vec4 u_LColor; // 光色彩 uniform vec4 u_color; // 顶点色彩 varying vec3 v_LDirection; // 光线方向 varying vec3 v_normal; // 法线方向 void main(){ // 先对方向进行序列化,使得向量长度为1 vec3 LDirection=normalize(v_LDirection); vec3 normal=normalize(v_normal); // 计算序列化后的光方向和法线方向的点乘 float dotValue=max(dot(LDirection,normal),0.2); gl_FragColor=u_color*u_LColor*dotValue;}</script>画布也就是一个canvas: ...

January 5, 2022 · 1 min · jiezi

关于webgl:Cesium-实现建筑夜景贴图

在线预览 Demo 源码 在新版本的 Cesium(1.87.0),反对了 CustomShader,能够为 Cesium3DTileset 编写自定义的 GLSL 代码。在此之前,要批改 3D Tileset 的款式,只能通过 style 属性,能做的最多也就是依据高度使不同修建展现不同色彩这种水平。 CustomShader 的根底用法能够查看官网文档,这里不再赘述,次要是介绍如何利用 CustomShader 实现修建贴图。 楼顶着色首先,楼顶不会和周围贴一样的图,先对立解决成深色。 并没有间接的属性表明以后点位于哪块墙上,但浏览文档能够发现,Cesium 提供了 normalMC 属性,也就是这个点所在立体的单位法向量。而楼顶个别是于高空平行的,将其法向量与高空的法向量比拟,如果夹角较小,就能够把它看作楼顶。 FragmentShader 代码如下(normalMC 在片段着色器不可用,须要在顶点着色器中通过 varying 传递过去,这里省略了过程): void fragmentMain(FragmentInput fsInput, inout czm_modelMaterial material) { if (dot(vec3(0.0, 0.0, 1.0), v_normalMC) > 0.95) { material.diffuse = vec3(0.079, 0.107, 0.111); }}对两个向量做 dot(点积),能够失去这两个向量夹角的余弦值,再做反余弦,即可失去夹角,但反余弦操作比较慢,并且这里不须要准确的夹角值,所以对余弦值的大小做判断就行了 楼顶着色残缺代码 周围贴图解决完楼顶,再解决四个侧面。贴图的要害是确定一个二维坐标,而后间接调用 texture2D 办法获取图片上对应色彩。从视觉上看,Shader 中的 Z 坐标必定是对应图片的纵坐标,问题在于 Shader 中的 X,Y 坐标如何对应到图片的横坐标 其实这里不能应用繁多的 X,Y 坐标,这样做会有很多修建的某个侧面是繁多的色彩,达不到贴图的成果。我最初还是利用了法向量属性,计算他们与 vec3(1.0, 0.0, 0.0) & vec3(0.0, 1.0, 0.0) 的夹角,如果与 vec3(1.0, 0.0, 0.0) 的夹角较小,就应用它的 Y 坐标,反之亦然。 ...

November 22, 2021 · 2 min · jiezi

关于webgl:如何给普通图片加上水波纹shader-奇技淫巧

3D场景实现水波纹,咱们往往会应用网格去模仿实在的水流动,无论是简略的三角函数或是gerstner wave。而后通过实在物理渲染(base physcal render)来实现其中的折射与反射。这些实现能够参考《GPU GEMS》第一版。 原谅我,古早年代的书就这成果但对于2D场景这样的模仿就显得开销过大,2D场景往往会应用一些“投机取巧”的形式,例如应用沃罗诺伊纹理(voronoi)来模仿焦散成果。而本文就来聊聊如何投机出一个2D的水波纹成果,最终成果如下: 最终代码:precision mediump float;/* 变量申明*/varying vec2 uv;uniform sampler2D u_image0;uniform float u_time;uniform float u_offset;uniform float u_radio;#define MAX_RADIUS 1#define DOUBLE_HASH 0#define HASHSCALE1 .1031#define HASHSCALE3 vec3 (.1031, .1030, .0973)/* 工具函数*/float hash12 (vec2 p) { vec3 p3 = fract (vec3 (p.xyx) * HASHSCALE1); p3 += dot (p3, p3.yzx + 19.19); return fract ((p3.x + p3.y) * p3.z);}vec2 hash22 (vec2 p) { vec3 p3 = fract (vec3 (p.xyx) * HASHSCALE3); p3 += dot (p3, p3.yzx + 19.19); return fract ((p3.xx + p3.yz) * p3.zy);}void main () { vec2 frag = uv; frag.x *= u_radio; frag = frag * u_offset * 1.5; vec2 p0 = floor (frag); vec2 circles = vec2 (0.); for (int j = -MAX_RADIUS; j <= MAX_RADIUS; ++j) { for (int i = -MAX_RADIUS; i <= MAX_RADIUS; ++i) { vec2 pi = p0 + vec2 (i, j); vec2 hsh = pi; vec2 p = pi + hash22(hsh) ; // hash12 增加随机 float t = fract (0.3 * u_time + hash12(hsh)); vec2 v = p - frag; // 半径: float d = length (v) - (float (MAX_RADIUS) + 1. )*t ; float h = 1e-3; float d1 = d - h; float d2 = d + h; float p1 = sin (31. * d1) * smoothstep (-0.6, -0.3, d1) * smoothstep (0., -0.3, d1); float p2 = sin (31. * d2) * smoothstep (-0.6, -0.3, d2) * smoothstep (0., -0.3, d2); circles += 0.5 * normalize (v) * ((p2 - p1) / (2. * h) * (1. - t) * (1. - t)); } } // 两轮循环增加了weight个波(取均匀) float weight = float ((MAX_RADIUS * 2 + 1) * (MAX_RADIUS * 2 + 1)); circles /= weight; float intensity = mix (0.01, 0.05, smoothstep (0.1, 0.6, abs (fract (0.05 * u_time + .5) * 2. - 1.))); vec3 n = vec3 (circles, sin ( dot (circles, circles))); vec3 colorRipple = texture2D (u_image0, uv + intensity * n.xy).rgb; float colorGloss = 5. * pow (clamp (dot (n, normalize (vec3 (1., 0.7, 0.5))), 0., 1.), 6.); vec3 color = colorRipple + vec3(colorGloss); gl_FragColor = vec4 (color, 1.0);}折射和反射2D模仿水波纹,次要就是要实现水波的折射与反射。它们别离由反射项vec3(colorGloss)和折射项colorRipple管制其中反射项由colorGloss管制 ...

October 28, 2021 · 4 min · jiezi

关于webgl:WebGL浅入浅出

豆皮粉儿们,又见面了,明天这一期,由“Kakashi”,给咱们带来webgl的学习,webgl一种很强的数据可视化的图形库,同时数据可视化也是前端倒退的一个重要方向之一,值得入坑和学习。 本文作者:Kakashi前言:本篇文章预计浏览耗时【15min】将较为全面根底的带你学习 如何应用WebGL(并重) && 相干原理(简略)。通过本次学习 你将能够从0到1搭建本人的webgl繁难渲染库一 、背景:1.1 为什么要用WebGL?先热身一下吧,看个问题: 如果你有一堆作业没有做完,能够抉择帮手替你实现,你会抉择? A. 1个老传授 B. 9个小学生 选A的同学,你真的忍心让老传授帮忙写语文填空?选B的同学,你真的释怀让小学生帮你解线性代数?所以咱们要看看“作业”内容到底是什么,有多少作业量。如果题目是 1+2 ,9个小学生 = 人海战术收费劳动力,没有技术含量,纯正体力活,效率会很高。如果题目是线性代数 ,老传授 >> 99 个小学生。回到咱们的主题,相似的,因为设计指标的不同,CPU和GPU也是大不相同的。它们别离针对了两种不同的利用场景:CPU须要很强的通用性来解决各种不同的数据类型,同时又要逻辑判断又会引入大量的分支跳转和中断的解决。这些都使得CPU的内部结构异样简单。GPU面对的则是类型高度对立的、互相无依赖的大规模数据和不须要被打断的污浊的计算环境。 (图片来自nVidia CUDA文档。其中绿色的是计算单元,橙红色的是存储单元,橙黄色的是管制单元。)GPU在概念上实用于高度并行计算,因为GPU能够通过计算暗藏内存拜访提早,而不是通过大数据缓存和流控制来防止内存拜访提早。简而言之,CPU 基于低延时的设计,GPU是基于大的吞吐量设计。 1.2 什么是WebGL?WebGL是一种3D绘图规范,这种绘图技术标准容许把JavaScript和OpenGL ES 2.0联合在一起,通过减少OpenGL ES 2.0的一个JavaScript绑定,WebGL能够为HTML5 Canvas提供硬件3D减速渲染(局部计算GPU),这样Web开发人员就能够借助零碎显卡来在浏览器里更流畅地展现3D场景和模型了,还能创立简单的导航和数据视觉化。显然,WebGL技术标准免去了开发网页专用渲染插件的麻烦,可被用于创立具备简单3D构造的网站页面,甚至能够用来设计3D网页游戏等等。 总结一下,WebGL的实质 —— JavaScript操作OpenGL接口。 当然,WebGL只是绑定了一层,外部的一些核心内容,如着色器,材质,灯光等都是须要借助GLSL ES语法来操作的。1.2.1 WebGL / OpenGL / ES X.0之间的关系? OpenGL(Open Graphics Library)一种图形应用程序编程接口标准(Application Programming Interface,API)。它是一种能够对图形硬件设施个性进行拜访的软件库,OpenGL被设计为一个现代化的、硬件无关的接口,因而咱们能够在不思考计算机操作系统或窗口零碎的前提下,在多种不同的图形硬件零碎上,齐全通过软件的形式实现OpenGL的接口。OpenGL ES(embedded system) OpenGL ES是OpenGL的一个非凡版本,次要针对嵌入式设施应用,专用于嵌入式计算机、智能手机、家用游戏机等设施。OpenGL ES 2003-2004年被首次提出来,其中两次重要降级别离在2007年(OpenGL ES 2.0)和2012年(OpenGL ES 3.0),WebGL就是基于OpenGL ES 2.0的。二、如何应用WebGL2.1 入门示例,不再是hello world! let gl = (document.getElementById( 'canvas' ) as HTMLCanvasElement).getContext('webgl') as WebGLRenderingContextBase; // 指定一个笼罩(清空)canvas的rgba色彩,实质是setColor,它把背景色存到了webgl system中的glCOLOR_BUFFER_BIT,得手动render一下 gl.clearColor(0.0, 0.0, 0.5, 1.0); // 革除canvas,会革除全副,再应用背景色 填充 gl.clear(gl.COLOR_BUFFER_BIT); }运行后果&流程示意: ...

September 13, 2021 · 2 min · jiezi

关于webgl:如何玩转-WebGL-并行计算

简介: 现在在 Web 端应用 WebGL 进行高性能计算已有不少实际,例如在端智能畛域中的 tensorflow.js,再比方可视化畛域中的 Stardust.js。 作者 | 沧东起源 | 阿里技术公众号 现在在 Web 端应用 WebGL 进行高性能计算已有不少实际,例如在端智能畛域中的 tensorflow.js,再比方可视化畛域中的 Stardust.js。在本文中,咱们将介绍以下内容: 应用 GPU 进行通用计算(GPGPU)的历史以后在 Web 端应用图形 API 实现 GPGPU 的技术原理,以及前端开发者可能遇到的难点相干业界实际,包含布局计算、动画插值等局限性与将来瞻望一 什么是 GPGPU因为硬件构造不同,GPU 与 CPU 善于执行不同类型的计算工作。CPU 通过简单的 Cache 设计实现低提早,蕴含简单的管制逻辑(分支预测),ALU 只占一小部分。而 GPU 为高吞吐量而生,蕴含大量 ALU。因而在单指令流多数据流(SIMD)场景下,GPU 的运算速度远超 CPU,并且这种差距还在一直拉大。 而一些古代 GPU 上甚至有专门负责张量计算、光线追踪的硬件(Tensor/RT Core),例如 Nvidia 的图灵架构。这使得在解决这些计算复杂度极高的工作时能取得更大的性能晋升。 这里就须要引出一个概念,用 GPU 进行除渲染外的通用计算:General-Purpose computation on Graphics Processing Units,即 GPGPU。 自 2002 年提出以来,在实时加解密、图片压缩、随机数生成等计算畛域都能看到它的身影,GPU Gems/Pro 上也有专门的章节介绍。经由 Nvidia 提出的 CUDA(Compute Unified Device Architecture) 这一对立计算架构,开发者能够应用 C、Java、Python 等语言编写本人的并行计算工作代码。 ...

August 19, 2021 · 3 min · jiezi

关于webgl:WebGL10-常用API及参数

WebGL Specifications (khronos.org) 类型以及对象定义这部分内容次要定义一部分类型和数据结构。 // 由 WebGLContextAttributes 援用enum WebGLPowerPreference { "default", "low-power", "high-performance" };// 获取上下文时反对的参数// getContext('webgl', <WebGLContextAttributes>)dictionary WebGLContextAttributes { boolean alpha = true; boolean depth = true; boolean stencil = false; boolean antialias = true; boolean premultipliedAlpha = true; boolean preserveDrawingBuffer = false; WebGLPowerPreference powerPreference = "default"; boolean failIfMajorPerformanceCaveat = false;};interface WebGLObject {};interface WebGLBuffer : WebGLObject {};interface WebGLFramebuffer : WebGLObject {};interface WebGLProgram : WebGLObject {};interface WebGLRenderbuffer : WebGLObject {};interface WebGLShader : WebGLObject {};interface WebGLTexture : WebGLObject {};interface WebGLUniformLocation {};interface WebGLActiveInfo { readonly attribute GLint size; readonly attribute GLenum type; readonly attribute DOMString name;};interface WebGLShaderPrecisionFormat { readonly attribute GLint rangeMin; readonly attribute GLint rangeMax; readonly attribute GLint precision;};WebGLRenderingContext 对象属性数据readonly attribute (HTMLCanvasElement or OffscreenCanvas) canvas;// 能够在 Web Work 上应用 canvas api// 须要调用 canvas.transferControlToOffscreen() 将渲染权转移给后盾线程readonly attribute OffscreenCanvas canvas;readonly attribute GLsizei drawingBufferWidth;readonly attribute GLsizei drawingBufferHeight;Example:gl.uniform1f(u_Width, gl.drawingBufferWidth);gl.uniform1f(u_Height, gl.drawingBufferHeight);缓冲区相干办法// 缓冲区类型const GLenum DEPTH_BUFFER_BIT = 0x00000100;const GLenum STENCIL_BUFFER_BIT = 0x00000400;const GLenum COLOR_BUFFER_BIT = 0x00004000;// 清理指定缓存内容, 能够通过或运算符一次清理多个缓冲区void clear(GLbitfield mask);//色彩缓冲区(COLOR_BUFFER_BIT) | 深度缓冲区(DEPTH_BUFFER_BIT) | 模板缓冲区(STENCIL_BUFFER_BIT)// 将指定缓冲区设置为指定的值(参数范畴都是 0.0 - 1.0)void clearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); //默认 0.0, 0.0, 0.0, 0.0void clearDepth(GLclampf depth); //默认 1.0void clearStencil(GLint s); //默认 0Example:gl.clearColor(0.0, 0.0, 0.0, 1.0);ctx.clearDepth(1); //resetctx.clearStencil(-1);gl.enable(gl.DEPTH_TEST);gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); //执行的意思绘制相干办法// 绘制的类型const GLenum POINTS = 0x0000;const GLenum LINES = 0x0001;const GLenum LINE_LOOP = 0x0002;const GLenum LINE_STRIP = 0x0003;const GLenum TRIANGLES = 0x0004;const GLenum TRIANGLE_STRIP = 0x0005;const GLenum TRIANGLE_FAN = 0x0006;void drawArrays(GLenum mode, //依照mode参数指定的形式绘制图形,下面 GLint first, //指定从哪个定点开始绘制 GLsizei count); //指定绘制须要用到多少个顶点 void drawElements(GLenum mode, //依照mode参数指定的形式绘制图形,下面 GLsizei count, //指定绘制须要用到多少个顶点 GLenum type, //指定索引值数据类型。包含:UNSIGNED_BYTE、UNSIGNED_SHORT、UNSIGNED_INT 留神这三个 GLintptr offset); //指定索引数组中绘制的偏移地位,以字节为单位drawArraysInstancedANGLE(gl.TRIANGLES, 0, 6, instanceCount)Example:gl.drawArrays(gl.TRIANGLES, 0, n); //n 个别是 数组/3gl.drawElements(gl.TRIANGLES, n, gl.UNSIGNED_BYTE, 0); //n 个别是indices.lengthext = gl.getExtension("ANGLE_instanced_arrays");ext.vertexAttribDivisorANGLE(aOffsetLocation, 1);ext.vertexAttribDivisorANGLE(aColorLocation, 1);ext.drawArraysInstancedANGLE(gl.TRIANGLES, 0, 6, instanceCount);缓存对象// 创立缓冲区对象WebGLBuffer? createBuffer();// 容许应用buffer示意的缓冲区对象并将其绑定到target示意的指标上// 下文中的target参数值const GLenum ARRAY_BUFFER = 0x8892;const GLenum ELEMENT_ARRAY_BUFFER = 0x8893;// const GLenum ARRAY_BUFFER_BINDING = 0x8894; // const GLenum ELEMENT_ARRAY_BUFFER_BINDING = 0x8895;void bindBuffer(GLenum target, //下面 WebGLBuffer? buffer); //createBuffer // 开拓存储空间,向绑定在target上的缓冲区对象写入数据data// 下文中的usage参数值const GLenum STREAM_DRAW = 0x88E0;//STATIC_DRAW 只会向缓冲区写入一次数据 须要绘制很屡次const GLenum STATIC_DRAW = 0x88E4;//TREAM_DRAW 只会向缓冲区写入一次数据 须要绘制若干次const GLenum DYNAMIC_DRAW = 0x88E8;//DYNAMIC_DRAW 会向缓冲区对象中屡次写入数据 并绘制很屡次void bufferData(GLenum target, //下面 target BufferSource? data, //data 类型化数组 比方:Float32Array GLenum usage); //下面 usage// 获取由 name 参数指定的 attribute 变量存储地址GLint getAttribLocation(WebGLProgram program, //program 指定蕴含顶点或者片元着色器的程序对象 DOMString name); //name 获取其存储的 attribute 变量名称,最大长度256字节// 将数据传给由index参数指定的attribute变量void vertexAttrib1f(GLuint index, GLfloat x);void vertexAttrib2f(GLuint index, GLfloat x, GLfloat y);void vertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z);void vertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);// 接管参数为 Float32Array 数组void vertexAttrib1fv(GLuint index, Float32List values);void vertexAttrib2fv(GLuint index, Float32List values);void vertexAttrib3fv(GLuint index, Float32List values);void vertexAttrib4fv(GLuint index, Float32List values);// 数据类型// vertexAttribPointer 中参数type的取值const GLenum BYTE = 0x1400;const GLenum UNSIGNED_BYTE = 0x1401;const GLenum SHORT = 0x1402;const GLenum UNSIGNED_SHORT = 0x1403;const GLenum INT = 0x1404;const GLenum UNSIGNED_INT = 0x1405;const GLenum FLOAT = 0x1406; //罕用// 将绑定到ARRAY_BUFFER的缓冲区对象调配给index指定的attribute变量void vertexAttribPointer(GLuint index, //指向attribute变量 GLint size, //指定缓冲区中每个顶点重量的个数 xyz的话就3 rgba的话就4 GLenum type, //数据格式 见下面的枚举 GLboolean normalized, //是否将浮点型数据归一化到[0, 1]或者[-1, 1]区间 false GLsizei stride, //指定相邻两个顶点之间的字节数 FSIZE*5 GLintptr offset);//指定缓冲区对象中的偏移量 单位字节 能够利用这个偏移量赋值多个attribute // 开启index对应的attribute对象// 开启后不能通过 vertexAttrib[1234]f 传值void enableVertexAttribArray(GLuint index);//指向attribute变量// 敞开index对应的attribute对象void disableVertexAttribArray(GLuint index);//指向attribute变量// 删除参数buffer示意的缓冲区对象// @param buffer 缓冲区对象 由createBuffer创立void deleteBuffer(WebGLBuffer? buffer);Example: var verticesColors = new Float32Array([ 0.0, 0.5, 1.0, 0.0, 0.0, -0.5, -0.5, 0.0, 1.0, 0.0, 0.5, -0.5, 0.0, 0.0, 1.0, ]); var n = 3; var vertexColorBuffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, vertexColorBuffer); //bind的是createbuffer gl.bufferData(gl.ARRAY_BUFFER, verticesColors, gl.STATIC_DRAW); //data是数组 data是float32array var FSIZE = verticesColors.BYTES_PER_ELEMENT; var a_Position = gl.getAttribLocation(gl.program, 'a_Position');//用字符来获取缓冲区 gl.enableVertexAttribArray(a_Position); //启动吗? gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, FSIZE * 5, 0);//数据指向缓冲区 2是读取数 FSIZE * 5是总数 FSIZE * 2是偏移数 var a_Color = gl.getAttribLocation(gl.program, 'a_Color'); gl.enableVertexAttribArray(a_Color); // Enable the assignment of the buffer object gl.vertexAttribPointer(a_Color, 3, gl.FLOAT, false, FSIZE * 5, FSIZE * 2); //3 是读取数 FSIZE * 5是总数 FSIZE * 2是偏移数 drawcall();var verticesColors = new Float32Array([ // Vertex coordinates and color 1.0,1.0,1.0,1.0,1.0,1.0, // v0 White -1.0,1.0,1.0,1.0,0.0,1.0, // v1 Magenta -1.0,-1.0,1.0,1.0,0.0,0.0, // v2 Red 1.0,-1.0,1.0,1.0,1.0,0.0, // v3 Yellow 1.0,-1.0,-1.0,0.0,1.0,0.0, // v4 Green 1.0,1.0,-1.0,0.0,1.0,1.0, // v5 Cyan -1.0,1.0,-1.0,0.0,0.0,1.0, // v6 Blue -1.0,-1.0,-1.0,0.0,0.0,0.0 // v7 Black]);// Indices of the verticesvar indices = new Uint8Array([0,1,2,0,2,3, // front 0,3,4,0,4,5, // right 0,5,6,0,6,1, // up 1,6,7,1,7,2, // left 7,4,3,7,3,2, // down 4,7,6,4,6,5 // back]);var vertexColorBuffer = gl.createBuffer();gl.bindBuffer(gl.ARRAY_BUFFER, vertexColorBuffer);gl.bufferData(gl.ARRAY_BUFFER, verticesColors, gl.STATIC_DRAW);var FSIZE = verticesColors.BYTES_PER_ELEMENT;var a_Position = gl.getAttribLocation(gl.program, "a_Position");gl.vertexAttribPointer(a_Position, 3, gl.FLOAT, false, FSIZE * 6, 0);gl.enableVertexAttribArray(a_Position);var a_Color = gl.getAttribLocation(gl.program, "a_Color");gl.vertexAttribPointer(a_Color,3,gl.FLOAT,false,FSIZE * 6,FSIZE * 3);gl.enableVertexAttribArray(a_Color);//index的话 必须通过这个apivar indexBuffer = gl.createBuffer(); //index gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer); //bind buffergl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, gl.STATIC_DRAW); // bufferdatagl.drawElements(gl.TRIANGLES, n, gl.UNSIGNED_BYTE, 0); //这里的n是index.count var a_Position = gl.getAttribLocation(gl.program, 'a_Position'); gl.vertexAttrib3f(a_Position, 0.0, 0.0, 0.0); //感觉很少用 这个是不必指向的 gl.clearColor(0.0, 0.0, 0.0, 1.0); gl.clear(gl.COLOR_BUFFER_BIT); gl.drawArrays(gl.POINTS, 0, 1);var vertex = [ 5, -30, 0, 50, -30, 0, 50, 30, 0, 5, 30, 0];vertexBuffer2 = gl.createBuffer();vao2 = ext.createVertexArrayOES();ext.bindVertexArrayOES(vao2);gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer2);gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertex), gl.STATIC_DRAW);var index = [ 0, 1, 2, 0, 2, 3];indexBuffer2 = gl.createBuffer();gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer2);gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(index), gl.STATIC_DRAW);gl.vertexAttribPointer(aVertexPosition, 3, gl.FLOAT, false, 0, 0);gl.enableVertexAttribArray(aVertexPosition);ext.bindVertexArrayOES(null);gl.clear(gl.COLOR_BUFFER_BIT);ext.bindVertexArrayOES(vao1);draw();ext.bindVertexArrayOES(vao2);draw();ext.deleteVertexArrayOES(vao);着色器 uniform 相干// 获取指定名称的 uniform 变量存储地位WebGLUniformLocation? getUniformLocation(WebGLProgram program, DOMString name);//指定想要获取其存储地位的uniform变量名称 最大长度256字节// 将数据传给location指定的uniform变量void uniform1f(WebGLUniformLocation? location, GLfloat x);void uniform2f(WebGLUniformLocation? location, GLfloat x, GLfloat y);void uniform3f(WebGLUniformLocation? location, GLfloat x, GLfloat y, GLfloat z);void uniform4f(WebGLUniformLocation? location, GLfloat x, GLfloat y, GLfloat z, GLfloat w);void uniform1i(WebGLUniformLocation? location, GLint x);void uniform2i(WebGLUniformLocation? location, GLint x, GLint y);void uniform3i(WebGLUniformLocation? location, GLint x, GLint y, GLint z);void uniform4i(WebGLUniformLocation? location, GLint x, GLint y, GLint z, GLint w);void uniform1fv(WebGLUniformLocation? location, Float32List v);void uniform2fv(WebGLUniformLocation? location, Float32List v);void uniform3fv(WebGLUniformLocation? location, Float32List v);void uniform4fv(WebGLUniformLocation? location, Float32List v);void uniform1iv(WebGLUniformLocation? location, Int32List v);void uniform2iv(WebGLUniformLocation? location, Int32List v);void uniform3iv(WebGLUniformLocation? location, Int32List v);void uniform4iv(WebGLUniformLocation? location, Int32List v);// @param 是否对矩阵进行转置 默认 false 在webgl中必须是falsevoid uniformMatrix2fv(WebGLUniformLocation? location, GLboolean transpose, Float32List value);void uniformMatrix3fv(WebGLUniformLocation? location, GLboolean transpose, Float32List value);void uniformMatrix4fv(WebGLUniformLocation? location, GLboolean transpose, Float32List value);Example: var xformMatrix = new Float32Array([ cosB, sinB, 0.0, 0.0, -sinB, cosB, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ]); var u_xformMatrix = gl.getUniformLocation(gl.program, 'u_xformMatrix'); gl.uniformMatrix4fv(u_xformMatrix, false, xformMatrix); drawcall();着色器 texture 相干// 将图像RGB色彩值每一个重量乘以A 默认falseconst GLenum UNPACK_PREMULTIPLY_ALPHA_WEBGL = 0x9241; // 创立纹理对象以存储纹理图像WebGLTexture? createTexture();// pixelStorei 中参数pname取值const GLenum UNPACK_FLIP_Y_WEBGL = 0x9240; // 对图像进行Y轴反转,默认false// 应用 pname 和 param 指定的形式加载失去的图像void pixelStorei(GLenum pname, //下面 GLint param); //非0为true、0为false 必须是整数 个别是1 // activeTexture 办法应用的枚举常量const GLenum TEXTURE0 = 0x84C0;const GLenum TEXTURE1 = 0x84C1; //gl.TEXTURE1 =gl.TEXTURE0+1const GLenum TEXTURE31 = 0x84DF;void activeTexture(GLenum texture); //下面//target 参数const GLenum TEXTURE_2D = 0x0DE1; //立体纹理const GLenum TEXTURE_CUBE_MAP = 0x8513; //立方体纹理// 开启 texture 指定的纹理对象,并将其绑定到 target 上。 // 如果曾经通过 gl.activeTexture 激活了某个纹理单元,则纹理对象也会绑定到这个纹理单元上void bindTexture(GLenum target, //下面 WebGLTexture? texture); //createTexture // pname 参数const GLenum TEXTURE_MAG_FILTER = 0x2800;const GLenum TEXTURE_MIN_FILTER = 0x2801;const GLenum TEXTURE_WRAP_S = 0x2802;const GLenum TEXTURE_WRAP_T = 0x2803;//param 参数const GLenum NEAREST = 0x2600;const GLenum LINEAR = 0x2601;const GLenum NEAREST_MIPMAP_NEAREST = 0x2700;const GLenum LINEAR_MIPMAP_NEAREST = 0x2701;const GLenum NEAREST_MIPMAP_LINEAR = 0x2702;const GLenum LINEAR_MIPMAP_LINEAR = 0x2703;const GLenum REPEAT = 0x2901; // 平铺式的反复纹理const GLenum CLAMP_TO_EDGE = 0x812F; // 镜像对称式的反复纹理const GLenum MIRRORED_REPEAT = 0x8370; // 应用纹理图像的边缘值// 配置纹理,将param值赋给绑定到指标的纹理对象的pname参数上void texParameterf(GLenum target,//下面 GLenum pname, //下面 GLfloat param); //下面void texParameteri(GLenum target, GLenum pname, GLint param);// texImage2D 的 internalformat 参数const GLenum ALPHA = 0x1906; //只读取Alpha通道。const GLenum RGB = 0x1907; //读取RGB三个通道const GLenum RGBA = 0x1908; //读取RGBA四个通道。const GLenum LUMINANCE = 0x1909; //把每个通道视为亮度,alpha取1.0。const GLenum LUMINANCE_ALPHA = 0x190A; //每个通道视为 亮度/alpha。// texImage2D 的 type 参数const GLenum UNSIGNED_BYTE; //RGBA每个通道应用8位。const GLenum UNSIGNED_SHORT_4_4_4_4 = 0x8033; // RGBA RGBA每个通道应用4位。const GLenum UNSIGNED_SHORT_5_5_5_1 = 0x8034; // RGBA 红色5位、绿色5位、 蓝色5位、alpha用1位。const GLenum UNSIGNED_SHORT_5_6_5 = 0x8363; // RGB 红色5位、绿色6位,蓝色5位。// 将 source 指定的图像调配给绑定到指标上的纹理对象void texImage2D(GLenum target, //下面 GLint level, //传入0 (该参数是为金字塔纹理筹备的) GLint internalformat, //图像的外部格局 见上枚举 GLenum format, //format 纹理数据的格局 必须应用与 internalformat 雷同的值 GLenum type, //纹理数据的类型 TexImageSource source); //source 蕴含纹理图像的Image对象 // 为 WebGLTexture 对象生成一组mip纹理映射。void generateMipmap(GLenum target);//下面// 应用texture删除纹理对象void deleteTexture(WebGLTexture? texture); //createTextureExample:var u_Sampler = gl.getUniformLocation(gl.program, 'u_Sampler');//var a_Position = gl.getAttribLocation(gl.program, 'a_Position');//用字符来getvar image = new Image();image.onload = function(){ loadTexture(gl, n, texture, u_Sampler, image); };image.src = '../resources/sky.jpg';function loadTexture(gl, n, texture, u_Sampler, image) { var texture = gl.createTexture(); //创立 var vertexColorBuffer = gl.createBuffer(); gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, 1); // 倒置 gl.activeTexture(gl.TEXTURE0); //gl.enableVertexAttribArray(a_Position); //容许 gl.bindTexture(gl.TEXTURE_2D, texture); // gl.bindBuffer(gl.ARRAY_BUFFER, vertexColorBuffer); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); //设置参数 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.MIRRORED_REPEAT); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE, image);//数据指向缓冲区 gl.bufferData(gl.ARRAY_BUFFER, verticesColors, gl.STATIC_DRAW); //data是数组 data是float32array gl.generateMipmap(gl.TEXTURE_2D); gl.uniform1i(u_Sampler, 0);//讲数据指向usampler gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, FSIZE * 5, 0);//数据指向缓冲区 gl.clear(gl.COLOR_BUFFER_BIT); // Clear <canvas> gl.drawArrays(gl.TRIANGLE_STRIP, 0, n); // Draw the rectangle}帧缓冲区// 创立渲染缓冲区对象WebGLRenderbuffer? createRenderbuffer();//target 必须是 gl.RENDERBUFFERconst GLenum RENDERBUFFER = 0x8D41;//renderbuffer// 将 renderbuffer 指定的渲染缓冲区对象绑定在target指标上 createRenderbuffer// 如果 renderbuffer 为 null 则将曾经绑定在target指标上的渲染缓冲区对象解除绑定void bindRenderbuffer(GLenum target, //下面 WebGLRenderbuffer? renderbuffer); //下面 //internalformat 示意渲染缓冲区将代替色彩缓冲区 const GLenum RGBA4 = 0x8056;const GLenum RGB5_A1 = 0x8057;const GLenum RGB565 = 0x8D62;const GLenum DEPTH_COMPONENT16 = 0x81A5; // 示意渲染缓冲区将代替深度缓冲区const GLenum STENCIL_INDEX8 = 0x8D48; // 示意渲染缓冲区将代替模板缓冲区// 创立并初始化渲染缓冲区的数据区void renderbufferStorage(GLenum target, //下面 GLenum internalformat, //下面 GLsizei width, //指定渲染缓冲区的宽度和高度 单位像素 GLsizei height); // 删除渲染缓冲区对象void deleteRenderbuffer(WebGLRenderbuffer? renderbuffer);//createRenderbuffer// 创立帧缓冲区对象WebGLFramebuffer? createFramebuffer();// 绑定帧缓冲区// targetconst GLenum FRAMEBUFFER = 0x8D40;void bindFramebuffer(GLenum target, //下面 WebGLFramebuffer? framebuffer); //createFramebuffer// attachment 设置纹理为 attachment 附件const GLenum COLOR_ATTACHMENT0 = 0x8CE0; //色彩附件const GLenum DEPTH_ATTACHMENT = 0x8D00; //深度附件const GLenum STENCIL_ATTACHMENT = 0x8D20; //模板附件const GLenum DEPTH_STENCIL_ATTACHMENT = 0x821A;// textargetconst GLenum TEXTURE_2D = 0x0DE1; //立体纹理const GLenum TEXTURE_CUBE_MAP = 0x8513; //立方体纹理// level 0void framebufferTexture2D(GLenum target, //下面 GLenum attachment, //下面 GLenum textarget, //下面 WebGLTexture? texture, //下面 GLint level); //下面 // 设置渲染缓冲区对象为 attachment 附件// renderbuffertarget gl.RENDERBUFFERvoid framebufferRenderbuffer(GLenum target, //下面 GLenum attachment, //下面 GLenum renderbuffertarget, //下面 WebGLRenderbuffer? renderbuffer); //createFramebuffer// 删除帧缓冲区对象void deleteFramebuffer(WebGLFramebuffer? framebuffer);// 查看帧缓冲区GLenum checkFramebufferStatus(GLenum target); //下面Example: var texture = gl.createTexture(); // 纹理创立 gl.bindTexture(gl.TEXTURE_2D, texture); // Bind the object to target gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, OFFSCREEN_WIDTH, OFFSCREEN_HEIGHT, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);//最初是null gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); var depthBuffer = gl.createRenderbuffer(); // 创立渲染缓冲区 gl.bindRenderbuffer(gl.RENDERBUFFER, depthBuffer); // Bind the object to target gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, OFFSCREEN_WIDTH, OFFSCREEN_HEIGHT); var framebuffer = gl.createFramebuffer(); //帧缓冲区 framebuffer.texture = texture; // Store the texture object gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer); gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0); //帧缓冲区 贴图 必须要这个 gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, depthBuffer); //帧缓冲区 渲染缓冲区 var e = gl.checkFramebufferStatus(gl.FRAMEBUFFER); //判断是否正确配置COLOR_ATTACHMENT0 = RGBA/UNSIGNED_BYTE textureCOLOR_ATTACHMENT0 = RGBA/UNSIGNED_BYTE texture + DEPTH_ATTACHMENT = DEPTH_COMPONENT16 renderbufferCOLOR_ATTACHMENT0 = RGBA/UNSIGNED_BYTE texture + DEPTH_STENCIL_ATTACHMENT = DEPTH_STENCIL renderbuffer贴图相干// 指定一个为压缩格局的2D纹理图片。void compressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, [AllowShared] ArrayBufferView data);// 指定一个为压缩格局的2D纹理子图片。如果你的3D场景同时应用的纹理较多或者其余因素导致内存耗费较大,同时须要长时间运行,那么你能够思考应用压缩纹理void compressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, [AllowShared] ArrayBufferView data);// 复制2D纹理图片。void copyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);//gl.copyTexImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 0, 0, 512, 512, 0);// 复制2D纹理子图片。void copyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);// gl.copyTexSubImage2D(gl.TEXTURE_2D, 0, 0,0, 0, 0, 16, 16);// 更新以后 WebGLTexture 的子矩形。void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, [AllowShared] ArrayBufferView? pixels);void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLenum format, GLenum type, TexImageSource source); // May throw DOMExceptionExample:gl.bindTexture(gl.TEXTURE_2D, this.screen);gl.copyTexImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 0, 0, this.width, this.height, 0);启用性能// enable disable 的 cap 参数const GLenum CULL_FACE = 0x0B44;// 混合const GLenum BLEND = 0x0BE2;const GLenum DITHER = 0x0BD0;const GLenum STENCIL_TEST = 0x0B90;// 暗藏面打消const GLenum DEPTH_TEST = 0x0B71;const GLenum SCISSOR_TEST = 0x0C11;// 多边形位移 (解决深度抵触问题)const GLenum POLYGON_OFFSET_FILL = 0x8037;const GLenum SAMPLE_ALPHA_TO_COVERAGE = 0x809E;const GLenum SAMPLE_COVERAGE = 0x80A0;// 启用性能void enable(GLenum cap);// 敞开性能void disable(GLenum cap);// 解决深度抵触// 指定加到每个顶点绘制后Z值上的偏移量,偏移量依照公式 m * factor + r * units 计算,其中m代表顶点所在外表// 绝对于观察者的实现角度,而r示意硬件可能辨别两个Z值之差的最小值void polygonOffset(GLfloat factor, GLfloat units);// 尽管下面的办法能够应用,然而在渲染器中用起来还是很麻烦的。// 解决深度抵触有更好的形式,就是放大远近裁剪面的间隔Example:gl.enable(gl.POLYGON_OFFSET_FILL);gl.drawArrays(gl.TRIANGLES, 0, n/2); // The green trianglegl.polygonOffset(1.0, 1.0); // Set the polygon offsetgl.drawArrays(gl.TRIANGLES, n/2, n/2); // The yellow triangle着色器相干// type 参数const GLenum FRAGMENT_SHADER = 0x8B30;const GLenum VERTEX_SHADER = 0x8B31;WebGLShader? createShader(GLenum type); //下面// 将 source 指定的字符串模式的代码传入shader指定的着色器 ..如果之前曾经向shader传入了代码 旧的代码就会被替换掉void shaderSource(WebGLShader shader, //createShader DOMString source); //字符串 // 编译 shader 指定的着色器中的源代码void compileShader(WebGLShader shader); //createShader// pname 参数const GLenum SHADER_TYPE = 0x8B4F;const GLenum DELETE_STATUS = 0x8B80;const GLenum COMPILE_STATUS = 0x8B81;any getShaderParameter(WebGLShader shader, //createShader GLenum pname); //下面 // 如果 getShaderParameter(shader, COMPILE_STATUS) 返回false // 则能够通过 此函数获取 指定shader 的信息日志DOMString? getShaderInfoLog(WebGLShader shader); //createShader// 删除 shader 指定的着色器对象void deleteShader(WebGLShader? shader); //createShaderExample: var shader = gl.createShader(type); gl.shaderSource(shader, source); gl.compileShader(shader); var compiled = gl.getShaderParameter(shader, gl.COMPILE_STATUS);着色器程序相干// pname 参数// 着色器相干 章节已定义const GLenum DELETE_STATUS; const GLenum LINK_STATUS = 0x8B82;const GLenum VALIDATE_STATUS = 0x8B83;const GLenum ATTACHED_SHADERS = 0x8B85;const GLenum ACTIVE_UNIFORMS = 0x8B86;const GLenum ACTIVE_ATTRIBUTES = 0x8B89;// 创立着色器程序对象WebGLProgram? createProgram();// 将 shader 指定的着色器对象调配给 program 指定的程序对象void attachShader(WebGLProgram program, //createProgram WebGLShader shader); //createShader// 勾销 shader 指定的着色器对 program 对象的调配void detachShader(WebGLProgram program, //createProgram WebGLShader shader); //createShader// 连贯 program 指定的程序对象中的着色器void linkProgram(WebGLProgram program); //createProgram// 获取 program 指定的程序对象中 pname 指定的参数信息any getProgramParameter(WebGLProgram program, //createProgram GLenum pname); //下面 // 如果通过 getProgramParameter(LINK_STATUS) 取得返回值 为 false// 能够通过 此函数获取 program 指定的程序对象的信息日志DOMString? getProgramInfoLog(WebGLProgram program); //createProgram// 验证 WebGLProgram void validateProgram(WebGLProgram program); //createProgram// 告知 WEBGL 零碎绘制时应用的 program 对象void useProgram(WebGLProgram? program); //createProgram// 删除着色器程序对象void deleteProgram(WebGLProgram? program); //createProgramExample:gl.useProgram(program)const program = gl.createProgram();gl.attacheShader(program, vertexShader);gl.attacheShader(program, fragmentShader);gl.linkProgram(program);if(!gl.getProgramParameter(program, gl.LINK_STATUS)){ var info = gl.getProgramInfoLog(program); throw new Error('Could not compile WebGL program. \n\n ' + info);}gl.useProgram(SHADER_PROGRAM);扩大通过扩大基本上能使 WebGL1 领有 WebGL2 的能力。获取扩大以及扩大反对信息 ...

May 19, 2021 · 16 min · jiezi

关于webgl:ecahrtgl实现中国版块仿三维地图

首先申明 mapName:'china',maptype:1而后调用办法,传参1和2有不同的成果 getPeo (status) { function NumDescSort(a, b) { return b.value - a.value; } function NumAsceSort(a, b) { return a.value - b.value; } this.$nextTick(() => { this.myChart = echarts.init(document.getElementById("mapPeople")); echarts.registerMap("china", china); var geoCoordMap = {}; var alirl = []; var conData = []; var matchCount = 0 var maxVal = 0 var convertData // var distance = 0 if (status == 1) { geoCoordMap = { 昭通:[103.715, 27.3436], 毕节市:[105.2812, 27.3036], 红河哈尼族彝族自治州: [103.715, 27.3436], 嘉兴市:[120.7524, 30.7518], 金华市: [119.6424, 29.0982], 昆明市: [102.8246, 24.8898], 凉山彝族自治州: [102.265, 27.887], 六盘水市: [104.819, 26.5972], 泸州市: [105.448, 28.8876], 攀枝花市: [101.7168, 26.5862], 普洱市: [103.715, 27.3436], 曲靖市: [103.7922, 25.4888], 西双版纳傣族自治州: [103.715, 27.3436], 宜宾市: [104.6212, 28.7698], 玉溪市: [102.5394, 24.3522], 自贡市: [104.7652, 29.3634], 北京: [116.4004, 39.9028], 成都市: [104.0618, 30.661], 东莞市: [113.7468, 23.0218], 广州市: [113.2592, 23.131], 贵阳市: [106.6268, 26.6514], 杭州市: [120.2039, 30.2503], 乐山市: [103.7626, 29.5646], 宁波市: [121.6242, 29.8648], 厦门市: [118.0826, 24.4816], 上海: [121.4686, 31.232], 深圳市: [114.054, 22.5462], 苏州市: [120.5778, 31.2996], 台州市: [121.4126, 28.6618], 温州市: [120.6718, 27.9994], 重庆: [106.545, 29.5658], }; alirl = [ [ [105.2812, 27.3036], [103.715, 27.3436], ], [ [103.715, 27.3436], [103.715, 27.3436], ], [ [120.7524, 30.7518], [103.715, 27.3436], ], [ [119.6424, 29.0982], [103.715, 27.3436], ], [ [102.8246, 24.8898], [103.715, 27.3436], ], [ [102.265, 27.887], [103.715, 27.3436], ], [ [104.819, 26.5972], [103.715, 27.3436], ], [ [105.448, 28.8876], [103.715, 27.3436], ], [ [101.7168, 26.5862], [103.715, 27.3436], ], [ [103.715, 27.3436], [103.715, 27.3436], ], [ [103.7922, 25.4888], [103.715, 27.3436], ], [ [103.715, 27.3436], [103.715, 27.3436], ], [ [104.6212, 28.7698], [103.715, 27.3436], ], [ [102.5394, 24.3522], [103.715, 27.3436], ], [ [104.7652, 29.3634], [103.715, 27.3436], ], [ [103.715, 27.3436], [116.4004, 39.9028], ], [ [103.715, 27.3436], [105.2812, 27.3036], ], [ [103.715, 27.3436], [104.0618, 30.661], ], [ [103.715, 27.3436], [113.7468, 23.0218], ], [ [103.715, 27.3436], [113.2592, 23.131], ], [ [103.715, 27.3436], [106.6268, 26.6514], ], [ [103.715, 27.3436], [120.2039, 30.2503], ], [ [103.715, 27.3436], [120.7524, 30.7518], ], [ [103.715, 27.3436], [119.6424, 29.0982], ], [ [103.715, 27.3436], [102.8246, 24.8898], ], [ [103.715, 27.3436], [103.7626, 29.5646], ], [ [103.715, 27.3436], [102.265, 27.887], ], [ [103.715, 27.3436], [105.448, 28.8876], ], [ [103.715, 27.3436], [121.6242, 29.8648], ], [ [103.715, 27.3436], [103.7922, 25.4888], ], [ [103.715, 27.3436], [118.0826, 24.4816], ], [ [103.715, 27.3436], [121.4686, 31.232], ], [ [103.715, 27.3436], [114.054, 22.5462], ], [ [103.715, 27.3436], [120.5778, 31.2996], ], [ [103.715, 27.3436], [121.4126, 28.6618], ], [ [103.715, 27.3436], [120.6718, 27.9994], ], [ [103.715, 27.3436], [104.6212, 28.7698], ], [ [103.715, 27.3436], [102.5394, 24.3522], ], [ [103.715, 27.3436], [106.545, 29.5658], ], ]; conData = [ { name: "毕节市", value: 535395 }, { name: "红河哈尼族彝族自治州", value: 3458 }, { name: "嘉兴市", value: 118863 }, { name: "金华市", value: 11673 }, { name: "昆明市", value: 680763 }, { name: "凉山彝族自治州", value: 800617 }, { name: "六盘水市", value: 311 }, { name: "泸州市", value: 97157 }, { name: "攀枝花市", value: 997 }, { name: "普洱市", value: 40 }, { name: "曲靖市", value: 241885 }, { name: "西双版纳傣族自治州", value: 754 }, { name: "宜宾市", value: 832551 }, { name: "玉溪市", value: 13917 }, { name: "自贡市", value: 1959 }, { name: "北京", value: 58749 }, { name: "毕节市", value: 608996 }, { name: "成都市", value: 87722 }, { name: "东莞市", value: 770 }, { name: "广州市", value: 67 }, { name: "贵阳市", value: 22192 }, { name: "杭州市", value: 6387 }, { name: "嘉兴市", value: 135817 }, { name: "金华市", value: 185891 }, { name: "昆明市", value: 808905 }, { name: "乐山市", value: 1151 }, { name: "凉山彝族自治州", value: 814000 }, { name: "泸州市", value: 95801 }, { name: "宁波市", value: 70101 }, { name: "曲靖市", value: 217802 }, { name: "厦门市", value: 25 }, { name: "上海", value: 13156 }, { name: "深圳市", value: 1811 }, { name: "苏州市", value: 2218 }, { name: "台州市", value: 30632 }, { name: "温州市", value: 42829 }, { name: "宜宾市", value: 810975 }, { name: "玉溪市", value: 5185 }, { name: "重庆", value: 97341 }, ]; matchCount = 20; maxVal = 832551; convertData = function (data) { var res = []; for (var i = 0; i < data.length; i++) { var geoCoord = geoCoordMap[data[i].name]; if (geoCoord) { res.push({ name: data[i].name, value: geoCoord.concat(data[i].value), }); } } return res; }; var option = { backgroundColor: "transparent", tooltip: { show: true, trigger: "item" }, visualMap: [ { show:false, type: "continuous", seriesIndex: 0, calculable: true, max: maxVal, inRange: { color: ["#87aa66", "#eba438", "#d94d4c"], }, }, ], geo3D: { map: "china", roam: true, regionHeight: 1, itemStyle: { color: "#0066aa", opacity: 1, borderWidth: 0.4, borderColor: "#000", }, aspectScale: 0.8, label: { show: true, textStyle: { color: "#fff", //地图初始化区域字体色彩 fontSize: 14, opacity: 1, backgroundColor: "rgba(0,23,11,0)", }, }, emphasis: { //当鼠标放上去 地区区域是否显示名称 label: { show: true, textStyle: { color: "#fff", fontSize: 20, backgroundColor: "rgba(0,23,11,0)", }, }, }, light: { //光照暗影 main: { color: "#fff", //光照色彩 intensity: 1.2, //光照强度 //shadowQuality: 'high', //暗影亮度 shadow: false, //是否显示暗影 alpha: 55, beta: 10, }, ambient: { intensity: 0.3, }, }, viewControl: { projection: "perspective", autoRotate: false, // 主动旋转 distance: 99, // 视距 }, }, series: [ //柱状图 { name: "", type: "bar3D", coordinateSystem: "geo3D", barSize: 1, //柱子粗细 shading: "lambert", opacity: 1, bevelSize: 0.3, minHeight: 0.5, label: { show: false, formatter: "{b}", }, data: convertData(conData), }, //画线 { type: "lines3D", coordinateSystem: "geo3D", effect: { show: true, trailWidth: 2, trailOpacity: 0.6, trailLength: 0.5, constantSpeed: 8, }, blendMode: "lighter", lineStyle: { width: 0.2, opacity: 0.05, }, data: alirl, }, ], }; this.myChart.setOption(option); } else { debugger if (this.mapName == "china") { echarts.registerMap("china", china); } else { pass } matchCount = 20; debugger if (this.maptype == 1) { geoCoordMap = { 昭通: [103.715, 27.3436], 北京: [116.4004, 39.9028], 上海: [121.4686, 31.232], 重庆: [106.545, 29.5658], 成都: [104.0618, 30.661], 深圳: [114.054, 22.5462], 东莞: [113.7468, 23.0218], 广州: [113.2592, 23.131], 宜宾: [104.6212, 28.7698], 杭州: [120.2039, 30.2503], 枣庄: [117.3252, 34.814], 中山: [113.3866, 22.5198], 苏州: [120.5778, 31.2996], 天津: [117.1966, 39.085], 贵阳: [106.6268, 26.6514], 邯郸: [114.4844, 36.6086], 佛山: [113.116, 23.0234], 无锡: [120.306878, 31.492395], 武汉: [114.2984, 30.5954], 毕节: [105.2812, 27.3036], 南京: [118.7912, 32.0606], 西安: [108.934, 34.3354], 济南: [117.1134, 36.6526], 六盘水: [104.819, 26.5972], 郑州: [113.6188, 34.7468], 泸州: [105.448, 28.8876], 青岛: [120.3766, 36.0656], 淄博: [118.0522, 36.8052], 邢台: [114.4972, 37.0658], 聊城: [115.9784, 36.4564], 长沙: [112.9324, 28.2296], 宁波: [121.6242, 29.8648], 温州: [120.6718, 27.9994], 南宁: [108.362, 22.8198], 内江: [105.0546, 29.5828], 厦门: [118.0826, 24.4816], 常州: [119.9688, 31.8126], 泰安: [117.1164, 36.1936], 合肥: [117.2232, 31.8242], 石家庄: [114.509, 38.0408], 金华: [119.6424, 29.0982], 惠州: [114.411, 23.1136], 嘉兴: [120.7524, 30.7518], 吉林: [126.5422, 43.8366], 沧州: [116.8324, 38.304], 广安: [106.6366, 30.472], 乐山: [103.7626, 29.5646], 兰州: [103.8314, 36.0606], 自贡: [104.7652, 29.3634], 南通: [120.8878, 31.9824], 福州: [119.2896, 26.0762], 大连: [121.599, 38.9146], 泉州: [118.6658, 24.8776], 遵义: [106.9224, 27.7296], 沈阳: [123.459625, 41.672542], 向阳: [120.4466, 41.572], 珠海: [113.5712, 22.275], 潍坊: [119.1562, 36.7052], 济宁: [116.583, 35.4142], 攀枝花: [101.7168, 26.5862], 雅安: [102.995, 29.9888], 台州: [121.4126, 28.6618], 廊坊: [116.6988, 39.5192], 南昌: [115.8586, 28.6842], 临沂: [118.3418, 35.0518], 哈尔滨: [126.5268, 45.8022], 徐州: [117.2792, 34.2052], 盐城: [120.1378, 33.3674], 玉林: [110.1598, 22.6394], 扬州: [119.4062, 32.3954], 安顺: [105.9348, 26.249], 保定: [115.4586, 38.8846], 江门: [113.0754, 22.5808], 资阳: [104.6262, 30.1316], 延安: [109.4848, 36.5856], 健康: [109.0214, 32.6874], 太原: [112.5434, 37.8696], 衡水: [115.6916, 37.7342], 烟台: [121.4256, 37.4648], 乌鲁木齐: [87.6142, 43.8238], 绍兴: [120.5756, 30.0068], 德州: [116.304, 37.4444], 昌都: [97.1774, 31.136], 肇庆: [112.4598, 23.051], 绵阳: [104.7404, 31.4682], 长春: [125.3156, 43.8164], 西宁: [101.775, 36.6174], 河源: [114.6964, 23.7482], 洛阳: [112.4438, 34.6234], 渭南: [109.506, 34.503], 商洛: [109.9336, 33.8708], 丽水: [119.9084, 28.4504], 宜昌: [111.2776, 30.704], 宝鸡: [107.2332, 34.3634], 桂林: [110.1748, 25.2418], 遂宁: [105.5748, 30.5092], 汕头: [116.6768, 23.3566], 湛江: [110.3518, 21.273], 眉山: [103.8328, 30.0464], 景德镇: [117.1802, 29.2794], 吉安: [114.9806, 27.1246], 唐山: [118.1724, 39.6292], 湖州: [120.0996, 30.8672], 咸阳: [108.7062, 34.33], 汉中: [107.017, 33.068], 达州: [107.468, 31.212], 铜川: [108.9288, 34.9], 银川: [106.2268, 38.4856], 淮安: [119.0084, 33.6118], 莆田: [118.9954, 25.449], 铜仁: [109.1844, 27.7348], 镇江: [119.4504, 32.2032], 柳州: [109.4114, 24.3324], 德阳: [104.3878, 31.1354], 漳州: [117.6456, 24.5178], 海口: [110.194947, 20.046268], 三亚: [109.508, 18.2566], 日喀则: [88.881, 29.2778], 日照: [119.545, 35.394], 新乡: [113.9206, 35.3032], 广元: [105.8176, 32.4396], 山南: [91.7736, 29.2406], 岳阳: [113.1182, 29.3686], 榆林: [109.7354, 38.2864], 大庆: [125.0974, 46.5866], 泰州: [119.9168, 32.4572], 上饶: [117.962, 28.4478], 天水: [105.7196, 34.5806], 威海: [122.1146, 37.5124], 南阳: [112.5306, 32.995], 酒泉: [98.511, 39.7434], 安阳: [114.3804, 36.0974], 怀化: [109.9658, 27.5558], 韶关: [113.5914, 24.8138], 清远: [113.0442, 23.6876], 九江: [115.995, 29.7072], 菏泽: [115.4738, 35.2398], 河池: [108.0558, 24.6982], 东营: [118.654, 37.4224], 巴中: [106.744, 31.872], 芜湖: [118.4276, 31.3548], 亳州: [115.777, 33.8664], 邵阳: [111.4624, 27.241], 连云港: [119.2136, 34.5976], 秦皇岛: [119.594, 39.934], 淮南: [117.0172, 32.5822], 茂名: [110.9194, 21.6654], 宿迁: [118.266, 33.9646], 株洲: [113.1236, 27.8336], 大同: [113.2874, 40.0924], 白银: [104.1348, 36.5482], 承德: [117.9362, 40.976], 赣州: [114.9228, 25.838], 北海: [109.1096, 21.4628], 龙岩: [117.0274, 25.1028], 黄山: [118.3272, 29.7154], 潮州: [116.6166, 23.6596], 蚌埠: [117.3828, 32.9192], 马鞍山: [118.4724, 31.6166], 运城: [110.9898, 35.0264], 六安: [116.5084, 31.7398], 张家口: [114.8788, 40.8148], 新余: [114.9038, 27.8268], 商丘: [115.652, 34.4158], 衡阳: [112.5636, 26.9006], 安庆: [117.045, 30.518], 湘潭: [112.93, 27.8358], 郴州: [113.0326, 25.7954], 信阳: [114.0778, 32.1378], 鹰潭: [117.0482, 28.25], 阳江: [111.9776, 21.8602], 林芝: [94.3614, 29.652], 来宾: [109.2326, 23.735], 呼和浩特: [111.7352, 40.841], 包头: [109.8244, 40.6564], 荆州: [112.2336, 30.3364], 张家界: [110.475, 29.1196], 拉萨: [91.1718, 29.6546], 南平: [118.0968, 27.3688], 贵港: [109.5914, 23.116], 十堰: [110.7834, 32.6528], 揭阳: [116.367, 23.5522], 营口: [122.2266, 40.668], 宜春: [114.3834, 27.7946], 呼伦贝尔: [119.7578, 49.2122], 崇左: [107.366, 22.3766], 阜阳: [115.8094, 32.9012], 晋中: [112.7344, 37.6804], 衢州: [118.8678, 28.9428], 益阳: [112.3472, 28.583], 吕梁: [111.1356, 37.5172], 防城港: [108.3464, 21.6182], 丹东: [124.381, 40.1254], 通化: [125.9418, 41.7394], 萍乡: [113.8436, 27.635], 许昌: [113.842, 34.0352], 随州: [113.3762, 31.6918], 钦州: [108.6194, 21.9702], 晋城: [112.8348, 35.5026], 抚顺: [123.9578, 41.8794], 平顶山: [113.1854, 33.7702], 黄冈: [114.8738, 30.435], 百色: [106.6106, 23.8994], 铜陵: [117.806, 30.9508], 开封: [114.3038, 34.7984], 汕尾: [115.3668, 22.7906], 周口: [114.6902, 33.6282], 忻州: [112.7326, 38.4084], 四平: [124.3516, 43.1598], 焦作: [113.24, 35.222], 常德: [111.6948, 29.031], 永州: [111.606, 26.4252], 云浮: [112.039, 22.9176], 阳泉: [113.5772, 37.863], 襄阳: [112.129, 32.01], 娄底: [112.0126, 27.728], 三明: [117.6298, 26.2656], 锦州: [121.1256, 41.091], 滨州: [118.0164, 37.379], 宁德: [119.543, 26.6682], 临汾: [111.5148, 36.0818], 宣城: [118.7512, 30.9472], 通辽: [122.265, 43.6188], 阜新: [121.6524, 42.019], 驻马店: [114.0308, 32.9774], 贺州: [111.559559, 24.409395], 佳木斯: [130.3608, 46.8088], 齐齐哈尔: [123.9206, 47.3626], 荆门: [112.198, 31.036], 朔州: [112.4204, 39.3152], 乌海: [106.7898, 39.6542], 舟山: [122.103, 30.0176], 滁州: [118.3116, 32.3068], 梅州: [116.1178, 24.296], 克拉玛依: [84.866, 45.5916], 赤峰: [118.8922, 42.2518], 长治: [113.1088, 36.1938], 鞍山: [122.989, 41.1082], 濮阳: [115.0132, 35.7662], 辽源: [125.1374, 42.885], 定西: [104.6232, 35.5904], 牡丹江: [129.6298, 44.5572], 陇南: [104.9206, 33.394], 辽阳: [123.164, 41.2668], 黄石: [115.0312, 30.2018], 鄂尔多斯: [109.770944, 39.620142], 葫芦岛: [120.8384, 40.7186], 梧州: [111.2934, 23.481], 盘锦: [122.0662, 41.1248], 咸宁: [114.3162, 29.8438], 孝感: [113.9468, 30.9218], 鸡西: [130.9572, 45.2898], 伊春: [128.8348, 47.7238], 宿州: [116.9838, 33.6374], 松原: [124.8124, 45.1436], 绥化: [126.9748, 46.6348], 中卫: [105.1848, 37.5152], 淮北: [116.8046, 33.9578], 池州: [117.4788, 30.6612], 鹤壁: [114.286, 35.742], 七台河: [130.9292, 45.7842], 阿拉尔: [81.278327, 40.547623], 抚州: [116.3508, 27.9506], 平凉: [106.6972, 35.5298], 漯河: [114.012, 33.5826], 白山: [126.4204, 41.9408], 鄂州: [114.8896, 30.3934], 仙桃: [113.448444, 30.364899], 吐鲁番: [89.1844, 42.947], 黑河: [127.4938, 50.2446], 双鸭山: [131.1514, 46.6392], 凉山彝族自治州: [102.265, 27.887], 张掖: [100.46, 38.9334], 石嘴山: [106.376, 39.0168], 铁岭: [123.836, 42.2928], 白城: [122.8348, 45.6178], 本溪: [123.7606, 41.293], 庆阳: [107.6336, 35.739], 哈密: [93.5154, 42.8284], 嘉峪关: [98.2892, 39.774], 三门峡: [111.1962, 34.7746], 吴忠: [106.192, 37.9942], 乌兰察布: [113.121, 40.993], 武威: [102.6332, 37.9248], 金昌: [102.1874, 38.501], 天门: [113.160107, 30.665725], 潜江: [112.893716, 30.404192], 固原: [106.2746, 36.0072], 济源: [112.599893, 35.067444], 鹤岗: [130.3138, 47.3726], 海东: [102.4054, 36.4776], 巴彦淖尔: [107.419, 40.749], 石河子: [86.077816, 44.30313], 阿拉善盟: [105.6924, 38.8462], 儋州: [109.5754, 19.5238], 三沙: [112.334, 16.8322], 锡林郭勒盟: [116.0522, 43.9466], 兴安盟: [122.056, 46.079], 阿克苏地区: [80.262, 41.1688], 五家渠: [87.540332, 44.168152], 南充: [106.1072, 30.845], 图木舒克: [79.06902, 39.859708], 延边朝鲜族自治州: [129.498, 42.892], 黔南布依族苗族自治州: [107.5174, 26.255], 黔西南布依族苗族自治州: [104.8948, 25.088], 阿坝藏族羌族自治州: [102.2204, 31.9026], 甘孜藏族自治州: [101.9566, 30.0504], 黔东南苗族侗族自治州: [107.9772, 26.5856], 喀什地区: [75.9926, 39.467], 阿勒泰地区: [88.1364, 47.8536], 湘西土家族苗族自治州: [109.7336, 28.316], 大兴安岭地区: [124.219245, 52.451053], 和田地区: [79.9216, 37.11], 恩施土家族苗族自治州: [109.475, 30.2702], 阿里地区: [80.096, 32.503], 塔城地区: [82.9752, 46.7506], 那曲地区: [92.057, 31.4776], 甘南藏族自治州: [102.9076, 34.9804], 果洛藏族自治州: [100.2404, 34.4758], 昆玉: [79.288916, 37.209579], 昌吉回族自治州: [87.3054, 44.0184], 临夏回族自治州: [103.2092, 35.5928], 海北藏族自治州: [100.8986, 36.959], 海南藏族自治州: [100.6188, 36.2754], 玉树藏族自治州: [97.0074, 33.0064], 铁门关: [85.673337, 41.867431], 海西蒙古族藏族自治州: [97.3628, 37.3658], 博尔塔拉蒙古自治州: [82.067, 44.8926], 巴音郭楞蒙古自治州: [86.144, 41.7558], 克孜勒苏柯尔克孜自治州: [76.171, 39.7088], 伊犁哈萨克自治州: [81.334, 43.914], 神农架林区: [110.67091, 31.748498], 黄南藏族自治州: [102.0128, 35.5152], }; alirl = [ [ [116.4004, 39.9028], [103.715, 27.3436], ], [ [121.4686, 31.232], [103.715, 27.3436], ], [ [106.545, 29.5658], [103.715, 27.3436], ], [ [104.0618, 30.661], [103.715, 27.3436], ], [ [114.054, 22.5462], [103.715, 27.3436], ], [ [113.7468, 23.0218], [103.715, 27.3436], ], [ [113.2592, 23.131], [103.715, 27.3436], ], [ [104.6212, 28.7698], [103.715, 27.3436], ], [ [120.2039, 30.2503], [103.715, 27.3436], ], [ [117.3252, 34.814], [103.715, 27.3436], ], [ [113.3866, 22.5198], [103.715, 27.3436], ], [ [120.5778, 31.2996], [103.715, 27.3436], ], [ [117.1966, 39.085], [103.715, 27.3436], ], [ [106.6268, 26.6514], [103.715, 27.3436], ], [ [114.4844, 36.6086], [103.715, 27.3436], ], [ [113.116, 23.0234], [103.715, 27.3436], ], [ [120.306878, 31.492395], [103.715, 27.3436], ], [ [114.2984, 30.5954], [103.715, 27.3436], ], [ [105.2812, 27.3036], [103.715, 27.3436], ], [ [118.7912, 32.0606], [103.715, 27.3436], ], [ [103.715, 27.3436], [108.934, 34.3354], ], [ [117.1134, 36.6526], [103.715, 27.3436], ], [ [104.819, 26.5972], [103.715, 27.3436], ], [ [113.6188, 34.7468], [103.715, 27.3436], ], [ [105.448, 28.8876], [103.715, 27.3436], ], [ [120.3766, 36.0656], [103.715, 27.3436], ], [ [118.0522, 36.8052], [103.715, 27.3436], ], [ [114.4972, 37.0658], [103.715, 27.3436], ], [ [115.9784, 36.4564], [103.715, 27.3436], ], [ [112.9324, 28.2296], [103.715, 27.3436], ], [ [121.6242, 29.8648], [103.715, 27.3436], ], [ [120.6718, 27.9994], [103.715, 27.3436], ], [ [108.362, 22.8198], [103.715, 27.3436], ], [ [105.0546, 29.5828], [103.715, 27.3436], ], [ [118.0826, 24.4816], [103.715, 27.3436], ], [ [119.9688, 31.8126], [103.715, 27.3436], ], [ [117.1164, 36.1936], [103.715, 27.3436], ], [ [117.2232, 31.8242], [103.715, 27.3436], ], [ [114.509, 38.0408], [103.715, 27.3436], ], [ [119.6424, 29.0982], [103.715, 27.3436], ], [ [114.411, 23.1136], [103.715, 27.3436], ], [ [120.7524, 30.7518], [103.715, 27.3436], ], [ [126.5422, 43.8366], [103.715, 27.3436], ], [ [116.8324, 38.304], [103.715, 27.3436], ], [ [106.6366, 30.472], [103.715, 27.3436], ], [ [103.7626, 29.5646], [103.715, 27.3436], ], [ [103.715, 27.3436], [103.8314, 36.0606], ], [ [104.7652, 29.3634], [103.715, 27.3436], ], [ [120.8878, 31.9824], [103.715, 27.3436], ], [ [119.2896, 26.0762], [103.715, 27.3436], ], [ [121.599, 38.9146], [103.715, 27.3436], ], [ [118.6658, 24.8776], [103.715, 27.3436], ], [ [106.9224, 27.7296], [103.715, 27.3436], ], [ [123.459625, 41.672542], [103.715, 27.3436], ], [ [120.4466, 41.572], [103.715, 27.3436], ], [ [113.5712, 22.275], [103.715, 27.3436], ], [ [119.1562, 36.7052], [103.715, 27.3436], ], [ [116.583, 35.4142], [103.715, 27.3436], ], [ [101.7168, 26.5862], [103.715, 27.3436], ], [ [102.995, 29.9888], [103.715, 27.3436], ], [ [121.4126, 28.6618], [103.715, 27.3436], ], [ [116.6988, 39.5192], [103.715, 27.3436], ], [ [115.8586, 28.6842], [103.715, 27.3436], ], [ [118.3418, 35.0518], [103.715, 27.3436], ], [ [126.5268, 45.8022], [103.715, 27.3436], ], [ [117.2792, 34.2052], [103.715, 27.3436], ], [ [120.1378, 33.3674], [103.715, 27.3436], ], [ [110.1598, 22.6394], [103.715, 27.3436], ], [ [119.4062, 32.3954], [103.715, 27.3436], ], [ [105.9348, 26.249], [103.715, 27.3436], ], [ [115.4586, 38.8846], [103.715, 27.3436], ], [ [113.0754, 22.5808], [103.715, 27.3436], ], [ [104.6262, 30.1316], [103.715, 27.3436], ], [ [103.715, 27.3436], [109.4848, 36.5856], ], [ [103.715, 27.3436], [109.0214, 32.6874], ], [ [112.5434, 37.8696], [103.715, 27.3436], ], [ [115.6916, 37.7342], [103.715, 27.3436], ], [ [121.4256, 37.4648], [103.715, 27.3436], ], [ [103.715, 27.3436], [87.6142, 43.8238], ], [ [120.5756, 30.0068], [103.715, 27.3436], ], [ [116.304, 37.4444], [103.715, 27.3436], ], [ [103.715, 27.3436], [97.1774, 31.136], ], [ [112.4598, 23.051], [103.715, 27.3436], ], [ [104.7404, 31.4682], [103.715, 27.3436], ], [ [125.3156, 43.8164], [103.715, 27.3436], ], [ [103.715, 27.3436], [101.775, 36.6174], ], [ [114.6964, 23.7482], [103.715, 27.3436], ], [ [112.4438, 34.6234], [103.715, 27.3436], ], [ [103.715, 27.3436], [109.506, 34.503], ], [ [103.715, 27.3436], [109.9336, 33.8708], ], [ [119.9084, 28.4504], [103.715, 27.3436], ], [ [111.2776, 30.704], [103.715, 27.3436], ], [ [103.715, 27.3436], [107.2332, 34.3634], ], [ [110.1748, 25.2418], [103.715, 27.3436], ], [ [105.5748, 30.5092], [103.715, 27.3436], ], [ [116.6768, 23.3566], [103.715, 27.3436], ], [ [110.3518, 21.273], [103.715, 27.3436], ], [ [103.8328, 30.0464], [103.715, 27.3436], ], [ [117.1802, 29.2794], [103.715, 27.3436], ], [ [114.9806, 27.1246], [103.715, 27.3436], ], [ [118.1724, 39.6292], [103.715, 27.3436], ], [ [120.0996, 30.8672], [103.715, 27.3436], ], [ [103.715, 27.3436], [108.7062, 34.33], ], [ [103.715, 27.3436], [107.017, 33.068], ], [ [107.468, 31.212], [103.715, 27.3436], ], [ [103.715, 27.3436], [108.9288, 34.9], ], [ [103.715, 27.3436], [106.2268, 38.4856], ], [ [119.0084, 33.6118], [103.715, 27.3436], ], [ [118.9954, 25.449], [103.715, 27.3436], ], [ [109.1844, 27.7348], [103.715, 27.3436], ], [ [119.4504, 32.2032], [103.715, 27.3436], ], [ [109.4114, 24.3324], [103.715, 27.3436], ], [ [104.3878, 31.1354], [103.715, 27.3436], ], [ [117.6456, 24.5178], [103.715, 27.3436], ], [ [110.194947, 20.046268], [103.715, 27.3436], ], [ [109.508, 18.2566], [103.715, 27.3436], ], [ [103.715, 27.3436], [88.881, 29.2778], ], [ [119.545, 35.394], [103.715, 27.3436], ], [ [113.9206, 35.3032], [103.715, 27.3436], ], [ [105.8176, 32.4396], [103.715, 27.3436], ], [ [103.715, 27.3436], [91.7736, 29.2406], ], [ [113.1182, 29.3686], [103.715, 27.3436], ], [ [103.715, 27.3436], [109.7354, 38.2864], ], [ [125.0974, 46.5866], [103.715, 27.3436], ], [ [119.9168, 32.4572], [103.715, 27.3436], ], [ [117.962, 28.4478], [103.715, 27.3436], ], [ [103.715, 27.3436], [105.7196, 34.5806], ], [ [122.1146, 37.5124], [103.715, 27.3436], ], [ [112.5306, 32.995], [103.715, 27.3436], ], [ [103.715, 27.3436], [98.511, 39.7434], ], [ [114.3804, 36.0974], [103.715, 27.3436], ], [ [109.9658, 27.5558], [103.715, 27.3436], ], [ [113.5914, 24.8138], [103.715, 27.3436], ], [ [113.0442, 23.6876], [103.715, 27.3436], ], [ [115.995, 29.7072], [103.715, 27.3436], ], [ [115.4738, 35.2398], [103.715, 27.3436], ], [ [108.0558, 24.6982], [103.715, 27.3436], ], [ [118.654, 37.4224], [103.715, 27.3436], ], [ [106.744, 31.872], [103.715, 27.3436], ], [ [118.4276, 31.3548], [103.715, 27.3436], ], [ [115.777, 33.8664], [103.715, 27.3436], ], [ [111.4624, 27.241], [103.715, 27.3436], ], [ [119.2136, 34.5976], [103.715, 27.3436], ], [ [119.594, 39.934], [103.715, 27.3436], ], [ [117.0172, 32.5822], [103.715, 27.3436], ], [ [110.9194, 21.6654], [103.715, 27.3436], ], [ [118.266, 33.9646], [103.715, 27.3436], ], [ [113.1236, 27.8336], [103.715, 27.3436], ], [ [113.2874, 40.0924], [103.715, 27.3436], ], [ [103.715, 27.3436], [104.1348, 36.5482], ], [ [117.9362, 40.976], [103.715, 27.3436], ], [ [114.9228, 25.838], [103.715, 27.3436], ], [ [109.1096, 21.4628], [103.715, 27.3436], ], [ [117.0274, 25.1028], [103.715, 27.3436], ], [ [118.3272, 29.7154], [103.715, 27.3436], ], [ [116.6166, 23.6596], [103.715, 27.3436], ], [ [117.3828, 32.9192], [103.715, 27.3436], ], [ [118.4724, 31.6166], [103.715, 27.3436], ], [ [110.9898, 35.0264], [103.715, 27.3436], ], [ [116.5084, 31.7398], [103.715, 27.3436], ], [ [114.8788, 40.8148], [103.715, 27.3436], ], [ [114.9038, 27.8268], [103.715, 27.3436], ], [ [115.652, 34.4158], [103.715, 27.3436], ], [ [112.5636, 26.9006], [103.715, 27.3436], ], [ [117.045, 30.518], [103.715, 27.3436], ], [ [112.93, 27.8358], [103.715, 27.3436], ], [ [113.0326, 25.7954], [103.715, 27.3436], ], [ [114.0778, 32.1378], [103.715, 27.3436], ], [ [117.0482, 28.25], [103.715, 27.3436], ], [ [111.9776, 21.8602], [103.715, 27.3436], ], [ [103.715, 27.3436], [94.3614, 29.652], ], [ [109.2326, 23.735], [103.715, 27.3436], ], [ [111.7352, 40.841], [103.715, 27.3436], ], [ [109.8244, 40.6564], [103.715, 27.3436], ], [ [117.66, 36.2036], [103.715, 27.3436], ], [ [112.2336, 30.3364], [103.715, 27.3436], ], [ [110.475, 29.1196], [103.715, 27.3436], ], [ [103.715, 27.3436], [91.1718, 29.6546], ], [ [118.0968, 27.3688], [103.715, 27.3436], ], [ [109.5914, 23.116], [103.715, 27.3436], ], [ [110.7834, 32.6528], [103.715, 27.3436], ], [ [116.367, 23.5522], [103.715, 27.3436], ], [ [122.2266, 40.668], [103.715, 27.3436], ], [ [114.3834, 27.7946], [103.715, 27.3436], ], [ [119.7578, 49.2122], [103.715, 27.3436], ], [ [107.366, 22.3766], [103.715, 27.3436], ], [ [115.8094, 32.9012], [103.715, 27.3436], ], [ [112.7344, 37.6804], [103.715, 27.3436], ], [ [118.8678, 28.9428], [103.715, 27.3436], ], [ [112.3472, 28.583], [103.715, 27.3436], ], [ [111.1356, 37.5172], [103.715, 27.3436], ], [ [108.3464, 21.6182], [103.715, 27.3436], ], [ [124.381, 40.1254], [103.715, 27.3436], ], [ [125.9418, 41.7394], [103.715, 27.3436], ], [ [113.8436, 27.635], [103.715, 27.3436], ], [ [113.842, 34.0352], [103.715, 27.3436], ], [ [113.3762, 31.6918], [103.715, 27.3436], ], [ [108.6194, 21.9702], [103.715, 27.3436], ], [ [112.8348, 35.5026], [103.715, 27.3436], ], [ [123.9578, 41.8794], [103.715, 27.3436], ], [ [113.1854, 33.7702], [103.715, 27.3436], ], [ [114.8738, 30.435], [103.715, 27.3436], ], [ [106.6106, 23.8994], [103.715, 27.3436], ], [ [117.806, 30.9508], [103.715, 27.3436], ], [ [114.3038, 34.7984], [103.715, 27.3436], ], [ [115.3668, 22.7906], [103.715, 27.3436], ], [ [114.6902, 33.6282], [103.715, 27.3436], ], [ [112.7326, 38.4084], [103.715, 27.3436], ], [ [124.3516, 43.1598], [103.715, 27.3436], ], [ [113.24, 35.222], [103.715, 27.3436], ], [ [111.6948, 29.031], [103.715, 27.3436], ], [ [111.606, 26.4252], [103.715, 27.3436], ], [ [112.039, 22.9176], [103.715, 27.3436], ], [ [113.5772, 37.863], [103.715, 27.3436], ], [ [112.129, 32.01], [103.715, 27.3436], ], [ [112.0126, 27.728], [103.715, 27.3436], ], [ [117.6298, 26.2656], [103.715, 27.3436], ], [ [121.1256, 41.091], [103.715, 27.3436], ], [ [118.0164, 37.379], [103.715, 27.3436], ], [ [119.543, 26.6682], [103.715, 27.3436], ], [ [111.5148, 36.0818], [103.715, 27.3436], ], [ [118.7512, 30.9472], [103.715, 27.3436], ], [ [122.265, 43.6188], [103.715, 27.3436], ], [ [121.6524, 42.019], [103.715, 27.3436], ], [ [114.0308, 32.9774], [103.715, 27.3436], ], [ [111.559559, 24.409395], [103.715, 27.3436], ], [ [130.3608, 46.8088], [103.715, 27.3436], ], [ [123.9206, 47.3626], [103.715, 27.3436], ], [ [112.198, 31.036], [103.715, 27.3436], ], [ [112.4204, 39.3152], [103.715, 27.3436], ], [ [106.7898, 39.6542], [103.715, 27.3436], ], [ [122.103, 30.0176], [103.715, 27.3436], ], [ [118.3116, 32.3068], [103.715, 27.3436], ], [ [116.1178, 24.296], [103.715, 27.3436], ], [ [103.715, 27.3436], [84.866, 45.5916], ], [ [118.8922, 42.2518], [103.715, 27.3436], ], [ [113.1088, 36.1938], [103.715, 27.3436], ], [ [122.989, 41.1082], [103.715, 27.3436], ], [ [115.0132, 35.7662], [103.715, 27.3436], ], [ [125.1374, 42.885], [103.715, 27.3436], ], [ [103.715, 27.3436], [104.6232, 35.5904], ], [ [129.6298, 44.5572], [103.715, 27.3436], ], [ [103.715, 27.3436], [104.9206, 33.394], ], [ [123.164, 41.2668], [103.715, 27.3436], ], [ [115.0312, 30.2018], [103.715, 27.3436], ], [ [109.770944, 39.620142], [103.715, 27.3436], ], [ [120.8384, 40.7186], [103.715, 27.3436], ], [ [111.2934, 23.481], [103.715, 27.3436], ], [ [122.0662, 41.1248], [103.715, 27.3436], ], [ [114.3162, 29.8438], [103.715, 27.3436], ], [ [113.9468, 30.9218], [103.715, 27.3436], ], [ [130.9572, 45.2898], [103.715, 27.3436], ], [ [128.8348, 47.7238], [103.715, 27.3436], ], [ [116.9838, 33.6374], [103.715, 27.3436], ], [ [124.8124, 45.1436], [103.715, 27.3436], ], [ [126.9748, 46.6348], [103.715, 27.3436], ], [ [103.715, 27.3436], [105.1848, 37.5152], ], [ [116.8046, 33.9578], [103.715, 27.3436], ], [ [117.4788, 30.6612], [103.715, 27.3436], ], [ [114.286, 35.742], [103.715, 27.3436], ], [ [130.9292, 45.7842], [103.715, 27.3436], ], [ [103.715, 27.3436], [81.278327, 40.547623], ], [ [116.3508, 27.9506], [103.715, 27.3436], ], [ [103.715, 27.3436], [106.6972, 35.5298], ], [ [114.012, 33.5826], [103.715, 27.3436], ], [ [126.4204, 41.9408], [103.715, 27.3436], ], [ [114.8896, 30.3934], [103.715, 27.3436], ], [ [113.448444, 30.364899], [103.715, 27.3436], ], [ [103.715, 27.3436], [89.1844, 42.947], ], [ [127.4938, 50.2446], [103.715, 27.3436], ], [ [131.1514, 46.6392], [103.715, 27.3436], ], [ [102.265, 27.887], [103.715, 27.3436], ], [ [103.715, 27.3436], [100.46, 38.9334], ], [ [103.715, 27.3436], [106.376, 39.0168], ], [ [123.836, 42.2928], [103.715, 27.3436], ], [ [122.8348, 45.6178], [103.715, 27.3436], ], [ [123.7606, 41.293], [103.715, 27.3436], ], [ [103.715, 27.3436], [107.6336, 35.739], ], [ [103.715, 27.3436], [93.5154, 42.8284], ], [ [103.715, 27.3436], [98.2892, 39.774], ], [ [111.1962, 34.7746], [103.715, 27.3436], ], [ [103.715, 27.3436], [106.192, 37.9942], ], [ [113.121, 40.993], [103.715, 27.3436], ], [ [103.715, 27.3436], [102.6332, 37.9248], ], [ [103.715, 27.3436], [102.1874, 38.501], ], [ [113.160107, 30.665725], [103.715, 27.3436], ], [ [112.893716, 30.404192], [103.715, 27.3436], ], [ [103.715, 27.3436], [106.2746, 36.0072], ], [ [112.599893, 35.067444], [103.715, 27.3436], ], [ [130.3138, 47.3726], [103.715, 27.3436], ], [ [103.715, 27.3436], [102.4054, 36.4776], ], [ [107.419, 40.749], [103.715, 27.3436], ], [ [103.715, 27.3436], [86.077816, 44.30313], ], [ [105.6924, 38.8462], [103.715, 27.3436], ], [ [109.5754, 19.5238], [103.715, 27.3436], ], [ [112.334, 16.8322], [103.715, 27.3436], ], [ [116.0522, 43.9466], [103.715, 27.3436], ], [ [122.056, 46.079], [103.715, 27.3436], ], [ [103.715, 27.3436], [80.262, 41.1688], ], [ [103.715, 27.3436], [87.540332, 44.168152], ], [ [106.1072, 30.845], [103.715, 27.3436], ], [ [103.715, 27.3436], [79.06902, 39.859708], ], [ [129.498, 42.892], [103.715, 27.3436], ], [ [107.5174, 26.255], [103.715, 27.3436], ], [ [104.8948, 25.088], [103.715, 27.3436], ], [ [102.2204, 31.9026], [103.715, 27.3436], ], [ [101.9566, 30.0504], [103.715, 27.3436], ], [ [107.9772, 26.5856], [103.715, 27.3436], ], [ [103.715, 27.3436], [75.9926, 39.467], ], [ [103.715, 27.3436], [88.1364, 47.8536], ], [ [109.7336, 28.316], [103.715, 27.3436], ], [ [124.219245, 52.451053], [103.715, 27.3436], ], [ [103.715, 27.3436], [79.9216, 37.11], ], [ [109.475, 30.2702], [103.715, 27.3436], ], [ [103.715, 27.3436], [80.096, 32.503], ], [ [103.715, 27.3436], [82.9752, 46.7506], ], [ [103.715, 27.3436], [92.057, 31.4776], ], [ [103.715, 27.3436], [102.9076, 34.9804], ], [ [103.715, 27.3436], [100.2404, 34.4758], ], [ [103.715, 27.3436], [79.288916, 37.209579], ], [ [103.715, 27.3436], [87.3054, 44.0184], ], [ [103.715, 27.3436], [103.2092, 35.5928], ], [ [103.715, 27.3436], [100.8986, 36.959], ], [ [103.715, 27.3436], [100.6188, 36.2754], ], [ [103.715, 27.3436], [97.0074, 33.0064], ], [ [103.715, 27.3436], [85.673337, 41.867431], ], [ [103.715, 27.3436], [97.3628, 37.3658], ], [ [103.715, 27.3436], [82.067, 44.8926], ], [ [103.715, 27.3436], [86.144, 41.7558], ], [ [103.715, 27.3436], [76.171, 39.7088], ], [ [103.715, 27.3436], [81.334, 43.914], ], [ [110.67091, 31.748498], [103.715, 27.3436], ], [ [103.715, 27.3436], [102.0128, 35.5152], ], ]; conData = [ { name: "北京", value: 6710 }, { name: "上海", value: 6410 }, { name: "重庆", value: 5170 }, { name: "成都", value: 4690 }, { name: "深圳", value: 3780 }, { name: "东莞", value: 3490 }, { name: "广州", value: 3260 }, { name: "宜宾", value: 3000 }, { name: "杭州", value: 2340 }, { name: "枣庄", value: 2200 }, { name: "中山", value: 2100 }, { name: "苏州", value: 2060 }, { name: "天津", value: 2000 }, { name: "贵阳", value: 1910 }, { name: "邯郸", value: 1680 }, { name: "佛山", value: 1510 }, { name: "无锡", value: 1460 }, { name: "武汉", value: 1420 }, { name: "毕节", value: 1360 }, { name: "南京", value: 1350 }, { name: "西安", value: 1350 }, { name: "济南", value: 1270 }, { name: "六盘水", value: 1220 }, { name: "郑州", value: 1170 }, { name: "泸州", value: 1140 }, { name: "青岛", value: 1020 }, { name: "淄博", value: 999 }, { name: "邢台", value: 957 }, { name: "聊城", value: 956 }, { name: "长沙", value: 956 }, { name: "宁波", value: 927 }, { name: "温州", value: 861 }, { name: "南宁", value: 794 }, { name: "内江", value: 785 }, { name: "厦门", value: 782 }, { name: "常州", value: 760 }, { name: "泰安", value: 724 }, { name: "合肥", value: 704 }, { name: "石家庄", value: 699 }, { name: "金华", value: 679 }, { name: "惠州", value: 601 }, { name: "嘉兴", value: 594 }, { name: "吉林", value: 583 }, { name: "沧州", value: 580 }, { name: "广安", value: 578 }, { name: "乐山", value: 575 }, { name: "兰州", value: 561 }, { name: "自贡", value: 559 }, { name: "南通", value: 546 }, { name: "福州", value: 542 }, { name: "大连", value: 534 }, { name: "泉州", value: 531 }, { name: "遵义", value: 524 }, { name: "沈阳", value: 517 }, { name: "向阳", value: 517 }, { name: "珠海", value: 503 }, { name: "潍坊", value: 487 }, { name: "济宁", value: 484 }, { name: "攀枝花", value: 484 }, { name: "雅安", value: 474 }, { name: "台州", value: 468 }, { name: "廊坊", value: 466 }, { name: "南昌", value: 463 }, { name: "临沂", value: 460 }, { name: "哈尔滨", value: 432 }, { name: "徐州", value: 425 }, { name: "盐城", value: 413 }, { name: "玉林", value: 413 }, { name: "扬州", value: 410 }, { name: "安顺", value: 407 }, { name: "保定", value: 389 }, { name: "江门", value: 386 }, { name: "资阳", value: 385 }, { name: "延安", value: 379 }, { name: "健康", value: 379 }, { name: "太原", value: 371 }, { name: "衡水", value: 369 }, { name: "烟台", value: 357 }, { name: "乌鲁木齐", value: 356 }, { name: "绍兴", value: 351 }, { name: "德州", value: 347 }, { name: "昌都", value: 334 }, { name: "肇庆", value: 333 }, { name: "绵阳", value: 329 }, { name: "长春", value: 328 }, { name: "西宁", value: 318 }, { name: "河源", value: 316 }, { name: "洛阳", value: 307 }, { name: "渭南", value: 307 }, { name: "商洛", value: 304 }, { name: "丽水", value: 303 }, { name: "宜昌", value: 293 }, { name: "宝鸡", value: 287 }, { name: "桂林", value: 286 }, { name: "遂宁", value: 284 }, { name: "汕头", value: 280 }, { name: "湛江", value: 279 }, { name: "眉山", value: 278 }, { name: "景德镇", value: 277 }, { name: "吉安", value: 276 }, { name: "唐山", value: 273 }, { name: "湖州", value: 273 }, { name: "咸阳", value: 269 }, { name: "汉中", value: 269 }, { name: "达州", value: 268 }, { name: "铜川", value: 265 }, { name: "银川", value: 260 }, { name: "淮安", value: 256 }, { name: "莆田", value: 256 }, { name: "铜仁", value: 255 }, { name: "镇江", value: 253 }, { name: "柳州", value: 251 }, { name: "德阳", value: 251 }, { name: "漳州", value: 250 }, { name: "海口", value: 245 }, { name: "三亚", value: 244 }, { name: "日喀则", value: 241 }, { name: "日照", value: 238 }, { name: "新乡", value: 236 }, { name: "广元", value: 235 }, { name: "山南", value: 234 }, { name: "岳阳", value: 233 }, { name: "榆林", value: 232 }, { name: "大庆", value: 221 }, { name: "泰州", value: 220 }, { name: "上饶", value: 218 }, { name: "天水", value: 216 }, { name: "威海", value: 215 }, { name: "南阳", value: 215 }, { name: "酒泉", value: 214 }, { name: "安阳", value: 213 }, { name: "怀化", value: 213 }, { name: "韶关", value: 213 }, { name: "清远", value: 209 }, { name: "九江", value: 208 }, { name: "菏泽", value: 206 }, { name: "河池", value: 206 }, { name: "东营", value: 198 }, { name: "巴中", value: 197 }, { name: "芜湖", value: 194 }, { name: "亳州", value: 191 }, { name: "邵阳", value: 189 }, { name: "连云港", value: 188 }, { name: "秦皇岛", value: 187 }, { name: "淮南", value: 187 }, { name: "茂名", value: 187 }, { name: "宿迁", value: 185 }, { name: "株洲", value: 185 }, { name: "大同", value: 180 }, { name: "白银", value: 180 }, { name: "承德", value: 178 }, { name: "赣州", value: 177 }, { name: "北海", value: 177 }, { name: "龙岩", value: 176 }, { name: "黄山", value: 173 }, { name: "潮州", value: 173 }, { name: "蚌埠", value: 169 }, { name: "马鞍山", value: 166 }, { name: "运城", value: 164 }, { name: "六安", value: 164 }, { name: "张家口", value: 163 }, { name: "新余", value: 163 }, { name: "商丘", value: 162 }, { name: "衡阳", value: 162 }, { name: "安庆", value: 161 }, { name: "湘潭", value: 161 }, { name: "郴州", value: 161 }, { name: "信阳", value: 160 }, { name: "鹰潭", value: 159 }, { name: "阳江", value: 159 }, { name: "林芝", value: 159 }, { name: "来宾", value: 157 }, { name: "呼和浩特", value: 156 }, { name: "包头", value: 154 }, { name: "济南", value: 154 }, { name: "荆州", value: 152 }, { name: "张家界", value: 152 }, { name: "拉萨", value: 152 }, { name: "南平", value: 151 }, { name: "贵港", value: 149 }, { name: "十堰", value: 147 }, { name: "揭阳", value: 147 }, { name: "营口", value: 146 }, { name: "宜春", value: 145 }, { name: "呼伦贝尔", value: 144 }, { name: "崇左", value: 144 }, { name: "阜阳", value: 143 }, { name: "晋中", value: 142 }, { name: "衢州", value: 140 }, { name: "益阳", value: 140 }, { name: "吕梁", value: 139 }, { name: "防城港", value: 138 }, { name: "丹东", value: 136 }, { name: "通化", value: 136 }, { name: "萍乡", value: 136 }, { name: "许昌", value: 136 }, { name: "随州", value: 136 }, { name: "钦州", value: 135 }, { name: "晋城", value: 133 }, { name: "抚顺", value: 133 }, { name: "平顶山", value: 133 }, { name: "黄冈", value: 133 }, { name: "百色", value: 133 }, { name: "铜陵", value: 132 }, { name: "开封", value: 132 }, { name: "汕尾", value: 132 }, { name: "周口", value: 131 }, { name: "忻州", value: 130 }, { name: "四平", value: 129 }, { name: "焦作", value: 129 }, { name: "常德", value: 129 }, { name: "永州", value: 129 }, { name: "云浮", value: 127 }, { name: "阳泉", value: 125 }, { name: "襄阳", value: 125 }, { name: "娄底", value: 125 }, { name: "三明", value: 124 }, { name: "锦州", value: 123 }, { name: "滨州", value: 122 }, { name: "宁德", value: 121 }, { name: "临汾", value: 119 }, { name: "宣城", value: 118 }, { name: "通辽", value: 117 }, { name: "阜新", value: 114 }, { name: "驻马店", value: 112 }, { name: "贺州", value: 112 }, { name: "佳木斯", value: 110 }, { name: "齐齐哈尔", value: 109 }, { name: "荆门", value: 105 }, { name: "朔州", value: 100 }, { name: "乌海", value: 100 }, { name: "舟山", value: 99 }, { name: "滁州", value: 99 }, { name: "梅州", value: 98 }, { name: "克拉玛依", value: 97 }, { name: "赤峰", value: 95 }, { name: "长治", value: 94 }, { name: "鞍山", value: 94 }, { name: "濮阳", value: 94 }, { name: "辽源", value: 92 }, { name: "定西", value: 92 }, { name: "牡丹江", value: 91 }, { name: "陇南", value: 91 }, { name: "辽阳", value: 90 }, { name: "黄石", value: 89 }, { name: "鄂尔多斯", value: 88 }, { name: "葫芦岛", value: 88 }, { name: "梧州", value: 88 }, { name: "盘锦", value: 87 }, { name: "咸宁", value: 87 }, { name: "孝感", value: 86 }, { name: "鸡西", value: 85 }, { name: "伊春", value: 85 }, { name: "宿州", value: 85 }, { name: "松原", value: 84 }, { name: "绥化", value: 84 }, { name: "中卫", value: 83 }, { name: "淮北", value: 81 }, { name: "池州", value: 79 }, { name: "鹤壁", value: 79 }, { name: "七台河", value: 78 }, { name: "阿拉尔", value: 77 }, { name: "抚州", value: 76 }, { name: "平凉", value: 76 }, { name: "漯河", value: 73 }, { name: "白山", value: 72 }, { name: "鄂州", value: 71 }, { name: "仙桃", value: 71 }, { name: "吐鲁番", value: 71 }, { name: "黑河", value: 70 }, { name: "双鸭山", value: 69 }, { name: "凉山彝族自治州", value: 69 }, { name: "张掖", value: 69 }, { name: "石嘴山", value: 68 }, { name: "铁岭", value: 66 }, { name: "白城", value: 66 }, { name: "本溪", value: 65 }, { name: "庆阳", value: 65 }, { name: "哈密", value: 65 }, { name: "嘉峪关", value: 63 }, { name: "三门峡", value: 62 }, { name: "吴忠", value: 61 }, { name: "乌兰察布", value: 59 }, { name: "武威", value: 59 }, { name: "金昌", value: 58 }, { name: "天门", value: 57 }, { name: "潜江", value: 55 }, { name: "固原", value: 54 }, { name: "济源", value: 52 }, { name: "鹤岗", value: 50 }, { name: "海东", value: 49 }, { name: "巴彦淖尔", value: 42 }, { name: "石河子", value: 33 }, { name: "阿拉善盟", value: 30 }, { name: "儋州", value: 30 }, { name: "三沙", value: 29 }, { name: "锡林郭勒盟", value: 27 }, { name: "兴安盟", value: 24 }, { name: "阿克苏地区", value: 22 }, { name: "五家渠", value: 21 }, { name: "南充", value: 20 }, { name: "图木舒克", value: 19 }, { name: "延边朝鲜族自治州", value: 13 }, { name: "黔南布依族苗族自治州", value: 13 }, { name: "黔西南布依族苗族自治州", value: 11 }, { name: "阿坝藏族羌族自治州", value: 10 }, { name: "甘孜藏族自治州", value: 10 }, { name: "黔东南苗族侗族自治州", value: 10 }, { name: "喀什地区", value: 10 }, { name: "阿勒泰地区", value: 9 }, { name: "湘西土家族苗族自治州", value: 8 }, { name: "大兴安岭地区", value: 7 }, { name: "和田地区", value: 7 }, { name: "恩施土家族苗族自治州", value: 6 }, { name: "阿里地区", value: 6 }, { name: "塔城地区", value: 6 }, { name: "那曲地区", value: 5 }, { name: "甘南藏族自治州", value: 5 }, { name: "果洛藏族自治州", value: 5 }, { name: "昆玉", value: 5 }, { name: "昌吉回族自治州", value: 4 }, { name: "临夏回族自治州", value: 3 }, { name: "海北藏族自治州", value: 3 }, { name: "海南藏族自治州", value: 3 }, { name: "玉树藏族自治州", value: 3 }, { name: "铁门关", value: 3 }, { name: "海西蒙古族藏族自治州", value: 2 }, { name: "博尔塔拉蒙古自治州", value: 2 }, { name: "巴音郭楞蒙古自治州", value: 2 }, { name: "克孜勒苏柯尔克孜自治州", value: 2 }, { name: "伊犁哈萨克自治州", value: 2 }, { name: "神农架林区", value: 1 }, { name: "海南省省直辖", value: 1 }, { name: "黄南藏族自治州", value: 1 }, ]; } else { geoCoordMap = { 昆明: [102.8246, 24.8898], 曲靖: [103.7922, 25.4888], 玉溪: [102.5394, 24.3522], 保山: [99.1584, 25.1158], 丽江: [100.2326, 26.8734], 普洱: [100.969, 22.784], 临沧: [100.0902, 23.8816], 楚雄彝族自治州: [101.527, 25.0472], 红河哈尼族彝族自治州: [103.401, 23.368], 文山壮族苗族自治州: [104.25, 23.3726], 西双版纳傣族自治州: [100.7984, 22.0154], 大理白族自治州: [100.2218, 25.5858], 德宏傣族景颇族自治州: [98.593, 24.4408], 怒江傈僳族自治州: [98.8458, 25.854], 迪庆藏族自治州: [99.7034, 27.8138], }; alirl = [ [ [102.8246, 24.8898], [103.715, 27.3436], ], [ [103.7922, 25.4888], [103.715, 27.3436], ], [ [102.5394, 24.3522], [103.715, 27.3436], ], [ [99.1584, 25.1158], [103.715, 27.3436], ], [ [103.715, 27.3436], [100.2326, 26.8734], ], [ [103.715, 27.3436], [100.969, 22.784], ], [ [103.715, 27.3436], [100.0902, 23.8816], ], [ [103.715, 27.3436], [101.527, 25.0472], ], [ [103.715, 27.3436], [103.401, 23.368], ], [ [103.715, 27.3436], [104.25, 23.3726], ], [ [103.715, 27.3436], [100.7984, 22.0154], ], [ [103.715, 27.3436], [100.2218, 25.5858], ], [ [103.715, 27.3436], [98.593, 24.4408], ], [ [103.715, 27.3436], [98.8458, 25.854], ], [ [103.715, 27.3436], [99.7034, 27.8138], ], ]; conData = [ { name: "昆明", value: 25400 }, { name: "曲靖", value: 6980 }, { name: "玉溪", value: 4710 }, { name: "保山", value: 4260 }, { name: "丽江", value: 4820 }, { name: "普洱", value: 3370 }, { name: "临沧", value: 3220 }, { name: "楚雄彝族自治州", value: 1510 }, { name: "红河哈尼族彝族自治州", value: 1510 }, { name: "文山壮族苗族自治州", value: 1650 }, { name: "西双版纳傣族自治州", value: 1250 }, { name: "大理白族自治州", value: 1440 }, { name: "德宏傣族景颇族自治州", value: 1400 }, { name: "怒江傈僳族自治州", value: 1480 }, { name: "迪庆藏族自治州", value: 1310 }, ]; // distance = 120; matchCount = 10; } conData.forEach((item) => { if (maxVal <= item.value) { maxVal = item.value; } }); convertData = function (data) { var res = []; for (var i = 0; i < data.length; i++) { var geoCoord = geoCoordMap[data[i].name]; if (geoCoord) { res.push({ name: data[i].name, value: geoCoord.concat(data[i].value), }); } } return res; }; var yMax = 1000; var dataShadow = []; // var resultdata0 = []; var titledata = []; var bartop10 = []; conData.sort(NumDescSort); for (var i = 0; i < matchCount; i++) { var top10 = { name: conData[i].name, value: conData[i].value, }; bartop10.push(top10); dataShadow.push(yMax); } bartop10.sort(NumAsceSort); for (var n = 0; n < bartop10.length; n++) { titledata.push(bartop10[n].name); } var option2 = { backgroundColor: "transparent", tooltip: { show: true, trigger: "item", }, visualMap: [ { show:false, type: "continuous", seriesIndex: 0, calculable: true, max: 7000, inRange: { color: ["#87aa66", "#eba438", "#d94d4c"], }, }, ], geo3D: { map: this.mapName, roam: true, regionHeight: 1, itemStyle: { color: "#0066aa", opacity: 1, borderWidth: 0.4, borderColor: "#000", }, label: { show: true, textStyle: { color: "#fff", //地图初始化区域字体色彩 fontSize: 14, opacity: 1, backgroundColor: "rgba(0,23,11,0)", }, }, emphasis: { //当鼠标放上去 地区区域是否显示名称 label: { show: true, textStyle: { color: "#fff", fontSize: 20, backgroundColor: "rgba(0,23,11,0)", }, }, }, //shading: 'lambert', light: { //光照暗影 main: { color: "#fff", //光照色彩 intensity: 1.2, //光照强度 //shadowQuality: 'high', //暗影亮度 shadow: false, //是否显示暗影 alpha: 55, beta: 10, }, ambient: { intensity: 0.3, }, }, viewControl: { projection: "perspective", // alpha: 0,//视角的方向。 // beta: 10,//左右旋转的角度。 // center: [0, 1, 0],// 视角 // targetCoord: [116.826801, 0], autoRotate: false, // 主动旋转 autoRotateAfterStill: 10, //鼠标静止操作后复原主动旋转的工夫距离 distance: 99, // 视距 rotateSensitivity: 1, //1能够旋转,0不能旋转 }, }, series: [ //柱状图 { name: "", type: "bar3D", coordinateSystem: "geo3D", barSize: 1, //柱子粗细 shading: "lambert", opacity: 1, minHeight: 0.5, bevelSize: 0.3, label: { show: false, formatter: "{b}", }, data: convertData(conData), }, //画线 { type: "lines3D", coordinateSystem: "geo3D", effect: { show: true, trailWidth: 2, trailOpacity: 0.6, trailLength: 0.5, constantSpeed: 8, }, blendMode: "lighter", lineStyle: { width: 0.2, opacity: 0.05, }, data: alirl, }, ], }; this.myChart.setOption(option2); } }) },

April 2, 2021 · 31 min · jiezi

关于webgl:图程之路

开了个新坑,打算学习做图程,以下是本人学习门路,心愿能有所帮忙。 线性代数:先补充基础知识,重温一下以前学的内容,会有新的了解。 https://www.bilibili.com/vide... (英文中字)https://www.bilibili.com/vide... (汉语配音)webgl:学图程必定绕不开底层API工具,当然openGL、D3D都能够,只不过本人是前端,看js的代码难受一点,底层设计都是一样的。 https://webglfundamentals.org... 这个居然有中文翻译了,前几年看英文版的是真的没保持下来,谢谢大佬们的翻译https://codepen.io/greggman/p... 能够在这里试试手,跟着下面的教程一起做https://webglfundamentals.org... 官网的这篇文章倡议提前看下,是说‘编程的矩阵’和‘数学的矩阵’的区别,不然间接从线性代数那边过去会有困扰对底层的一些补充:下面的教学挺优良的,都是联合代码例子来的,不过有几个原理没说明确。 https://blog.csdn.net/linuxhe... 比方齐次坐标、透视投影的变换。这篇文章就说的很好,在学到相机这部分内容的时候能够看下。

February 10, 2021 · 1 min · jiezi

关于webgl:几款2077风格的shader其一sh风ader格化

随同着赛博朋克2077的火爆(各种意义上的),这种电子故障类的shader仿佛成为了一种时尚,因为你真不知道这是bug还是无意为之。明天咱们就来了了几款故障类shader的原理及实现吧!本期将介绍2种shader(色彩偏移与扫描偏移)下期咱们再说两种(抖动和摇摆),正当应用这四种shader你可能实现上面短片中的成果: 色彩偏移 最终成果 咱们都晓得,图片是由RGB三个通道的色彩叠加起来而成的。R+G失去黄,R+B失去洋红,G+B是青。 色彩偏移的原理就是把其中一个通道偏移一个间隔在叠加起来。比方挪动绿色通道: void main () { // Color drift float drift = sin ( u_time) * u_colorDrift * .04; // Offset vec2 offset = vec2(drift,.0); vec4 color1 = texture2D (u_image0, uv); vec4 color2 = texture2D (u_image0, uv + offset); gl_FragColor = vec4 (color1.r, color2.g, color1.b, 1.0);}其中u_time是以后工夫,保障继续抖动,u_colorDrift是横向偏移的间隔: 是不是you点抖音的感觉?那么为什么同种呈现的色彩是洋红和绿??那是因为咱们挪动了绿通道,而洋红就是剩下的蓝通道和红通道叠加的后果。这里咱们能够试验一下,如果挪动红通道。失去的抖动色彩就会是红色和青色: gl_FragColor =vec4(color2.r, color1.g, color1.b,1.0); 扫描射线这种成果会在产生逐条的偏移,相似小时候电视机调台时那种感觉(裸露年龄了) 这里咱们须要一个随机函数对不同y进行不同的偏移(图中能够看出,对y方向雷同的点偏移是统一的)。这里咱们须要一个hash函数: float hash21 (float x, float y) { return fract (sin (dot (vec2 (x, y), vec2 (12.9898, 78.233))) * 43758.5453);}核心思想是通过fract(sin(x)*a)当a是一个很大的数时结构出出一种随机: ...

January 28, 2021 · 2 min · jiezi

关于webgl:WebGL实现简单滤镜

1. WebGL介绍WebGL(全写Web Graphics Library)是一种3D绘图协定,这种绘图技术标准容许把JavaScript和OpenGL ES 2.0联合在一起,通过减少OpenGL ES 2.0的一个JavaScript绑定。 2. WebGL、OpenGL、OpenGL ES 三者的关系 3. WebGL 根底介绍const webgl = document.getElementById("webGl-layer").getContext("webgl");4. 基本原理首先应用webgl 纹理绘制图片这里如果参照 https://webglfundamentals.org... 绘制过程中应用片段做着色器对其 rgb 值进行批改5. 具体实现 <!DOCTYPE html><html lang="ch"><head> <meta charset="UTF-8"> <title>VertexBuffer</title></head><body><canvas id="webGl-layer" width="532" height="300"></canvas><div> <label for="r1">饱和度:</label><input type="range" id="r1" value="0"/></div><div> <label for="r2">R:</label><input type="range" id="r2" value="0"/></div><div> <label for="r3">G:</label><input type="range" id="r3" value="0"/></div><div> <label for="r4">B:</label><input type="range" id="r4" value="0"/></div><script> const webgl = document.getElementById("webGl-layer").getContext("webgl"); const range1 = document.getElementById("r1"), range2 = document.getElementById("r2"), range3 = document.getElementById("r3"), range4 = document.getElementById("r4"); webgl.viewport(0, 0, 532, 300); const vertexShader2D = ` precision mediump float; attribute vec4 position; attribute vec4 inputTextureCoordinate; varying vec2 textureCoordinate; void main() { gl_Position = position; textureCoordinate = vec2((position.x+1.0)/2.0, 1.0-(position.y+1.0)/2.0); } `; const fragmentShader2D = ` precision mediump float; varying vec2 textureCoordinate; uniform sampler2D inputImageTexture; uniform float size; uniform float saturation; uniform float r; uniform float g; uniform float b; uniform float a; void main() { vec4 texture = texture2D(inputImageTexture, textureCoordinate); texture.r += r; // 图片整体 r 值 texture.g += g; // 图片整体 g 值 texture.b += b; // 图片整体 b 值 // texture.a = 0.5; // 图片整体 a 值 //内暗影 // float dist = distance(textureCoordinate, vec2(0.5, 0.5)); // texture.rgb *= smoothstep(0.8, size * 0.799, dist * (1.0 + size)); //饱和度 float average = (texture.r + texture.g + texture.b) / 3.0; if (saturation > 0.0) { texture.rgb += (average - texture.rgb) * (1.0 - 1.0 / (1.001 - saturation)); } else { texture.rgb += (average - texture.rgb) * (-saturation); } gl_FragColor = texture; } `; function createShader(gl, type, source) { const shader = gl.createShader(type); gl.shaderSource(shader, source); gl.compileShader(shader); if (gl.getShaderParameter(shader, gl.COMPILE_STATUS)) { return shader; } console.log(gl.getShaderInfoLog(shader)); gl.deleteShader(shader); } function createProgram(gl, vertexShader, fragmentShader) { const program = gl.createProgram(); gl.attachShader(program, vertexShader); gl.attachShader(program, fragmentShader); gl.linkProgram(program); if (gl.getProgramParameter(program, gl.LINK_STATUS)) { webgl.useProgram(program); return program; } console.error(gl.getProgramInfoLog(program)); gl.deleteProgram(program); } function createTextureByImageObject(gl, imgObject) { gl.activeTexture(gl.TEXTURE0); const textureObject = gl.createTexture(); gl.bindTexture(gl.TEXTURE_2D, textureObject); gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, imgObject); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); 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) return textureObject; } const vertices = [ 1.0, 1.0, 1.0, -1.0, -1.0, 1.0, -1.0, -1.0 ]; const vertexShader = createShader(webgl, webgl.VERTEX_SHADER, vertexShader2D), fragmentShader = createShader(webgl, webgl.FRAGMENT_SHADER, fragmentShader2D), program = createProgram(webgl, vertexShader, fragmentShader), buffer = webgl.createBuffer(); webgl.bindBuffer(webgl.ARRAY_BUFFER, buffer); webgl.bufferData(webgl.ARRAY_BUFFER, new Float32Array(vertices), webgl.STATIC_DRAW); let v4PositionIndex = webgl.getAttribLocation(program, "position"); webgl.enableVertexAttribArray(v4PositionIndex); webgl.vertexAttribPointer(v4PositionIndex, 2, webgl.FLOAT, false, 0, 0); let img = new Image(); img.crossOrigin = "anonymous"; img.src = "http://static.atvideo.cc/2021/01/04/09/47/1609724837(1).jpg"; img.onload = function () { document.body.append(img); createTextureByImageObject(webgl, img); let saturationUniform = webgl.getUniformLocation(program, "saturation"); let rUniform = webgl.getUniformLocation(program, "r"); let gUniform = webgl.getUniformLocation(program, "g"); let bUniform = webgl.getUniformLocation(program, "b"); // let sizeUniform = webgl.getUniformLocation(program, "size"); // webgl.uniform1f(sizeUniform, 2.0); const uniform = webgl.getUniformLocation(program, "inputImageTexture"); webgl.uniform1i(uniform, 0); webgl.drawArrays(webgl.TRIANGLE_STRIP, 0, 4); range1.addEventListener("change", function () { const val = Number(range1.value) / 100; webgl.uniform1f(saturationUniform, val); webgl.drawArrays(webgl.TRIANGLE_STRIP, 0, 4); }); range2.addEventListener("change", function () { const val = Number(range2.value) / 100; webgl.uniform1f(rUniform, val); webgl.drawArrays(webgl.TRIANGLE_STRIP, 0, 4); }); range3.addEventListener("change", function () { const val = Number(range3.value) / 100; webgl.uniform1f(gUniform, val); webgl.drawArrays(webgl.TRIANGLE_STRIP, 0, 4); }); range4.addEventListener("change", function () { const val = Number(range4.value) / 100; webgl.uniform1f(bUniform, val); webgl.drawArrays(webgl.TRIANGLE_STRIP, 0, 4); }); }</script></body></html>

January 4, 2021 · 3 min · jiezi

关于webgl:webgl智慧楼宇发光效果算法系列之高斯模糊

webgl智慧楼宇发光成果算法系列之高斯含糊如果应用过PS之类的图像处理软件,置信对于含糊滤镜不会生疏,图像处理软件提供了泛滥的含糊算法。高斯含糊是其中的一种。 在咱们的智慧楼宇的我的项目中,要求对楼宇实现楼宇发光的成果。 比方如下图所示的简略楼宇成果: 楼宇发光成果须要用的算法之一就是高斯含糊。 高斯含糊简介高斯含糊算法是计算机图形学畛域中一种应用宽泛的技术, 是一种图像空间成果,用于对图像进行含糊解决,创立原始图像的柔和含糊版本。应用高斯含糊的成果,联合一些其余的算法,还能够产生发光,光晕,景深,热雾和含糊玻璃成果。 高斯含糊的原理阐明图像含糊的原理,简略而言,就是针对图像的每一个像素,其色彩取其周边像素的平均值。不同的含糊算法,对周边的定义不一样,均匀的算法也不一样。 比方之前写#过的一篇文章,webgl实现径向含糊,就是含糊算法中的一种。 均值含糊在了解高斯含糊之前,咱们先了解比拟容易的均值含糊。所谓均值含糊其原理就是取像素点四周(上下左右)像素的平均值(其中也会包含本身)。如下图所示: 能够看出,对于某个像素点,当搜寻半径为1的时候,影响其色彩值的像素是9个像素(包含本人和周边的8个像素)。假如每个像素对于核心像素的影响都是一样的,那么每个像素的影响度就是1/9。如下图所示: 下面这个3*3的影响度的数字矩阵,通常称之为卷积核。 那么最终中心点的值的求和如下图所示:最终的值是: (8 * 1 + 1 * 2 / (8 + 1) ) = 10/9当计算像素的色彩时候,对于像素的RGB每一个通道都进行的上述均匀计算即可。 下面的计算过程就是一种卷积滤镜。所谓卷积滤镜,艰深来说,就是一种组合一组数值的算法。 如果搜寻半径变成2,则会变成25个像素的均匀,搜寻半径越大,就会越含糊。像素个数与搜寻半径的关系如下: (1 + r * 2)的平方 // r = 1,后果为9,r=2,后果为25,r=3 后果为49.通常 NxN会被称之卷积核的大小。比方3x3,5x5。 在均值含糊的计算中,参加的每个像素,对核心像素的奉献值都是一样的,这是均值含糊的特点。也就是,每个像素的权重都是一样的。 正态分布如果应用简略均匀,显然不是很正当,因为图像都是间断的,越凑近的点关系越亲密,越远离的点关系越疏远。因而,加权均匀更正当,间隔越近的点权重越大,间隔越远的点权重越小。 正态分布整好满足上述的的散布需要,如下图所示: 能够看出,正态分布是一种钟形曲线,越靠近核心,取值越大,越远离核心,取值越小。 在计算平均值的时候,咱们只须要将"中心点"作为原点,其余点依照其在正态曲线上的地位,调配权重,就能够失去一个加权平均值。 高斯函数高斯函数是形容正态分布的数学公式。公式如下: 其中,是x的均值,能够了解为正态分布的核心地位,是x的方差。因为计算平均值的时候,中心点就是原点,所以等于0。 如果是二维,则有: 能够看出二维高斯函数中,x和y绝对是独立的。也就是说: G(x,y) = G(x) + G(y)这个个性的益处是,能够把二维的高斯函数,拆解成两个独立的一维高斯函数。能够提高效率。实际上,高斯含糊使用的一维高斯函数,而不是应用二维。 高斯含糊高斯含糊的原理和后面介绍的均值含糊的原理基本上一样,只是均值含糊在计算平均值的时候,周边像素的权重都是一样的。而高斯含糊下,周边像素的权重值却应用高斯函数进行计算,这也是高斯含糊的之所以被称为高斯含糊的起因。 比方当取值为则含糊半径为1的权重矩阵如下: 这9个点的权重总和等于0.4787147,如果只计算这9个点的加权均匀,还必须让它们的权重之和等于1,因而下面9个值还要别离除以0.4787147,失去最终的权重矩阵。 渲染流程理解了高斯含糊的基本原理之后,来看看高斯含糊在webgl中根本渲染流程: 首先,依照失常流程把场景或者图像渲染到一个纹理对象下面,须要应用FrameBuffer性能。对纹理对象进行施加高斯含糊算法,失去最终的高斯含糊的纹理对象。下面第二部,施加高斯含糊算法,个别又会分成两步: 先施加垂直方向的高斯含糊算法;在垂直含糊的根底上进行程度方向的高斯含糊算法。当然,也能够先程度后垂直,后果是一样的。   分两步高斯含糊算法和一步进行两个方向的高斯含糊算法的后果根本是统一的,然而却能够进步算法的效率。 有人可能说,多含糊了一步,为啥还进步了效率。 这么来说吧,如果是3x3大小的高斯含糊:分两步要获取的像素数量是 3 + 3 = 6; 而一步却是3 x 3 = 9。 如果是5x5大小的高斯含糊:分两步要获取的像素数量是 5+5=10; 而一步却是5 x 5=25 。显然能够算法执行效率。 ...

December 30, 2020 · 3 min · jiezi

关于webgl:webgl智慧楼宇发光系列之线性采样下高斯模糊

[toc] webgl智慧楼宇发光系列之线性采样下高斯含糊后面一篇文章 <webgl智慧楼宇发光成果算法系列之高斯含糊>,   咱们晓得了 高斯含糊的实质原理,就是对每个像素,依照正态分布的权重去获取周边像素的值进行均匀,是一种卷积操作。 同时咱们能够指定周边像素的数量,比方能够是3X3,或者5X5,通用的表白就是N X N, 数字N通常称之为含糊半径,这在之前的文章的代码中有体现(uRadius): uniform float uRadius;float gaussianPdf(in float x, in float sigma) { return 0.39894 * exp( -0.5 * x * x/( sigma * sigma))/sigma;}void main() { for( int i = 1; i < MAX_KERNEL_RADIUS; i ++ ) { float x = float(i); if(x > radius){ break; } ... } vec4 result = vec4(1.0) - exp(-diffuseSum/weightSum * uExposure); gl_FragColor = result;}`效率问题通常,咱们心愿含糊的成果越强烈,含糊半径就会要求越大。所谓的半径就是下面的数字N。咱们晓得,要实现一个NxN大小的高斯含糊,在纹理的每个像素点,都须要去获取周边N个像素点。因为1024_1024大小的纹理,要实现33 33 大小的高斯含糊,须要拜访大略1024 1024 _ 33 * 33≈11.4亿个纹理像素,能力利用整个图像的含糊成果。 ...

December 29, 2020 · 1 min · jiezi

关于webgl:从C4D建模到Threejs实现闹钟产品360度展示效果stlobjmtl

演示地址:https://capricorncd.github.io/blog/dist/three/index.html#/ClockObj 源码:https://github.com/capricorncd/blog/tree/master/demos/three C4D文件:clock(R21.207).c4d https://github.com/capricorncd/blog/tree/master/c4d 流程C4D建模导出.obj文件js实现(Three.js),此例开发环境应用的Webpack+React一、C4D建模这里B站有视频教程,这里就不赘述。 在线视频教程:https://www.bilibili.com/video/BV177411P7d1?p=3 建模时留神须要留神的中央: 建模:不能应用面(Disc)建模,在浏览器中不会显示,需改用圆柱体(Cylinder)。贴图:需给每个几何体贴图,不能应用分组贴图。在Three.js中分组贴图不能与单个几何体绑定,顾浏览器中不会显示贴图。二、导出.obj文件C4D中实现建模和贴图后,就能够导出.obj文件。 # 工具栏file -> Export -> Wavefront OBJ(*.obj)其余导出选项默认即可。导出obj文件的同时,会导出一个同名贴图.mtl文件。 三、js实现# "three": "^0.120.1"npm i -S three# oryarn add threesrc/components/ClockObj/core.js import { AmbientLight, DirectionalLight, PerspectiveCamera, Scene, WebGLRenderer} from 'three'import { OBJLoader } from 'three/examples/jsm/loaders/OBJLoader'import { MTLLoader } from 'three/examples/jsm/loaders/MTLLoader'import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'let scene, renderer/** * 加载贴图和模型对象文件 * load resource * @returns {Promise<unknown>} */ function loadResource() { return new Promise((resolve, reject) => { const objLoader = new OBJLoader() const mtlLoader = new MTLLoader() // 加载贴图文件 mtlLoader.load('static/clock.mtl', mtl => { // 加载对象前,先设置贴图数据 objLoader.setMaterials(mtl) // 加载对象文件 objLoader.load('static/clock.obj', res => { resolve(res) }, undefined, reject) }, undefined, reject) })}/** * 初始化 */function _init(el, obj) { // 获取容器尺寸, // 如果时window对象,请应用window.innerWidth, window.innerHeight const width = el.offsetWidth const height = el.offsetHeight // 创立场景 scene = new Scene() // 将加载实现的模型对象,增加到场景中 scene.add(obj) // 创立环境光 const ambientLight = new AmbientLight(0x666666) ambientLight.position.set(100, -100, -200) scene.add(ambientLight) // 创立平行光 const light = new DirectionalLight(0xcccccc, 1) light.position.set(2000, 1000, 1000) scene.add(light) // 创立摄像机 const camera = new PerspectiveCamera(45, width / height, 1, 80000) camera.position.set(-150, -50, 300) // 创立renderer renderer = new WebGLRenderer({ // 打消锯齿 antialias: true }) // 设置渲染区域尺寸 renderer.setSize(width, height) // 设置背景色彩 renderer.setClearColor(COLORS.black, 1) // 将场景Canvas DOM元素,增加至父元素中 el.appendChild(renderer.domElement) // 创立场景鼠标管制实例, // 能够对页面上的模型对象进行旋转/缩放等操作 const orbitControls = new OrbitControls(camera, el) orbitControls.addEventListener('change', render) // 执行渲染,指定场景和相机作为参数 function render() { renderer.render(scene, camera) } render()}/** * 导出初始化办法 */export function init(el) { loadResource().then(res => { _init(el, res) }).catch(console.error)}/** * destroy */export function destroy() { if (!scene || !renderer) return scene.remove() renderer.dispose() scene = null renderer = null}src/components/ClockObj/index.jsx ...

October 13, 2020 · 2 min · jiezi

关于webgl:webgl实现径向模糊

径向含糊简介径向含糊,是一种从核心向外呈幅射状,逐步含糊的成果。 因而径向含糊常常会产生一些核心的发散成果,在PS中同样也有径向含糊的滤镜成果。 径向含糊通常也称为变焦含糊。径向含糊(Radial Blur)能够给画面带来很好的速度感,是各类游戏中后处理的常客,也罕用于Sun Shaft等后处理特效中作为光线投射(体积光)的模仿。 在游戏中,经常应用径向含糊来模仿一些静止的动感成果。如鬼泣4中的场景切换特效,和一些技能打击特效;赛车游戏也尝用来模仿动感含糊,如狂野飙车,极品飞车等。 径向含糊还是实现体积光照的一种技术手段之一,如下图: 径向含糊的原理图形学中含糊的大抵原理都是一样的:就是从原像素四周去寻找左近像素的色彩,来独特影响以后的像素色彩。如高斯含糊就是将原像素周围像素的色彩加权求和作为原像素的色彩以达到含糊的目标。 不同的含糊就是取周边像素和加权求和的算法不太一样。径向含糊的特点是从某个中心点向外散射扩散,因而其须要采样的像素来自于以后的像素点和中心点的连线上,通过参数能够管制采样的数量和采样步进的间隔。像素的色彩是由该像素的点与中心点之间连线上进行采样,而后求将这些采样点色彩的加权均匀。依据径向含糊的个性,离指标点越近采样点越密集,反之亦然。 因而,实现径向含糊的大抵流程如下: 确定径向含糊的中心点,个别为画布的中心点,或这个某个对象的中心点在屏幕投影所在的地位。(留神中心点是2维坐标)计算以后像素和中心点的间隔和向量线段。在线段下面进行采样,加权。将含糊的后果和原图进行一个叠加合成(可能须要)webgl实现径向含糊径向含糊是一个后处理过程,径向含糊能够对动态的图片施加成果,也能够对动静渲染的图像施加成果。本示例中将对动静的图像施加成果。先上一张图看看成果: 首先绘制的几个圆环对象,而后对绘制的图像施加径向含糊。 渲染到纹理要施加径向含糊,首先要把圆环绘制到texture对象下面,咱们晓得,通过framebuffer的技术,能够实现把绘制成果输入到贴图对象上。无关framebuffer的技术,不属于本文重点介绍的内容,如果读者不相熟,能够自行查找相干材料。也能够参考:渲染到纹理。 输出贴图对象要把贴图对象输入到屏幕下面,咱们须要结构一个矩形对象,该对象正好是webgl坐标系中的四个顶点,代码如下: function quad() { var pos = [-1,1,0, -1,-1,0, 1,-1,0, 1,1,0], st = [0,1,0,0,1,0, 1,1], idx = [0,1,2,0,2,3]; return { p:pos, t:st, i:idx, }}上述对象能够正好把一个贴图对象残缺的输入到屏幕上(webgl坐标系) 实现径向含糊径向含糊的次要在着色器语言中进行实现,而且次要是在片元着色器中,上面是片元着色器的代码: var ofs = `precision mediump float;uniform sampler2D texture;uniform float strength;varying vec2 vTexCoord;const float tFrag = 1.0 / 512.0;const float nFrag = 1.0 / 30.0;const vec2 centerOffset = vec2(256.0, 256.0);float rnd(vec3 scale, float seed) { return fract(sin(dot(gl_FragCoord.stp + seed, scale)) * 43758.5453 + seed);}vec4 fragRadialBlur(){ vec2 fc = vec2(gl_FragCoord.s, 512.0 - gl_FragCoord.t); vec2 fcc = fc - centerOffset; vec3 destColor = vec3(0.0); float random = rnd(vec3(12.9898, 78.233, 151.7182), 0.0); float totalWeight = 0.0; for (float i = 0.0; i <= 30.0; i++) { float percent = (i + random) * nFrag; float weight = percent - percent * percent; vec2 t = fc - fcc * percent * strength * nFrag; destColor += texture2D(texture, t * tFrag).rgb * weight; totalWeight += weight; } return vec4(destColor / totalWeight, 1.0);}void main(void) { gl_FragColor = fragRadialBlur(); }`;随机函数首先申明了一个rnd函数,此函数是一个简略的随机数生成器,当给定向量和种子值时,将返回0到1范畴内的随机数。应用随机数,是为了让含糊的成果出现肯定的随机状态,而不是依照某种一致性的准则进行含糊。rnd 在每次片元着色器中都会调用,因而要尽量应用轻量化的实现,不然可能会造成性能负载。 ...

August 25, 2020 · 2 min · jiezi

关于webgl:前端图形学从入门到放弃002-教练我想学矩阵

本文纲要矩阵和线性变换是什么?webgl如何实现缩放和旋转?平移不是线性变换,那该怎么办?webgl如何实现平移?明天的主菜是“矩阵”在上一篇中咱们曾经实现了应用webgl绘制图形这个小指标《前端图形学从入门到放弃》001 画一个三角形明天咱们来探讨一个新的话题矩阵咱们都晓得空间中的点咱们能够用向量示意,例如二维立体中的点(1,1)就示意第一象限的点:而多个点就能组成图形,这也是上一篇文章中咱们说过的。理论生产中这些图形往往并不会固定在画面中不懂,例如咱们能够对图形进行旋转,缩放,挪动。实际上这个过程就是将图形的顶点组进行了旋转,缩放,挪动,成为了新的顶点组,再由新的顶点组绘制成新的图形。 例如咱们要将由点A(0,0),B(1,0),C(0,1)组成的三角形放大一倍,那么咱们很容易晓得放大后的点ÂḂĆ的坐标 Âx = Ax2 = 02 = 0Ây = Ay2 = 02 = 0Ḃx = Bx2 = 12 = 2Ḃy = By2 = 02 = 0Ćx = Cx2 = 02 = 0Ćy = Cy2 = 12 = 2数学家嫌这一番操作太过麻烦,而点又是能够写成向量模式的,要是能把操作简化成Â = M*A的模式就再好不过了,于是 ⎡ 2 0 ⎤ Â = ⎪ ⎪ * A ⎣ 0 2 ⎦ 真是一顿操作猛如虎,一句不懂二百五 解剖矩阵举证代表了一种计算,如上咱们应用了一个二维矩阵 ⎡ A B ⎤ ⎣ C D ⎦ 与一个二维向量相乘,会失去一个新的二维向量,计算公式如下 ...

August 9, 2020 · 2 min · jiezi

关于webgl:前端图形学从入门到放弃001-画一个三角形

这是面向前端的图形学课程。心愿用通俗的语言为大家解释清图形学的一些概念。咱们应用的前端最容易webgl,尽管未免还是要接触GLSL,别打我,这曾经是最简略的!咱们开始第一节,矩阵....不还是画个三角形吧! webgl是什么?说人话webgl就是个工具,能够拿来画图的,它依赖于canvas,在canvas上你能够获取2d的上下文,也能够获取webgl的上下文。相似宝可梦新手村能够选蒜头王八也能够选黄皮耗子 所以第一步咱们就创立一个canvas,并获取webgl上下文 <canvas id="canvas" width="1000" height="1000"></canvas><script>var canvas = document.querySelector("#canvas");var gl = canvas.getContext("webgl");</script> 开始擦滑板咯!小画家这样咱们就获取了canvas的掌控权,canvas相当于一块画布,在画图之前咱们得像保障画面是洁净的。gl提供了两个api来做这件事:gl.clearColor与gl.clear gl.clearColor承受(r,g,b,a)的色彩数据,相当于给画布选一个底色;gl.clear用来革除buffer,至于什么是buffer咱们前面会讲。这里只须要晓得gl在没次绘图时都能够记录色彩和深度两个buffer,再次绘制时须要革除! 顶点着色器和片段着色器着色器是足以燃烧你学习webgl的激情的魔鬼。但了解之后你也会感觉恍然大悟!首先三维空间的物体不论多简单都是一些集合体,所谓点动成线,线动成面,面动成体。所以点是形容空间物体的最小单元。 顶点着色器就是用来解决咱们传入的顶点的,在下节课咱们将应用顶点着色器对三角形进行旋转,缩放,平移等操作。而与之绝对的是片段着色器,它次要解决围成图形的上色工作。这并不是明确的定义,但有助于你的了解:顶点着色器提供裁剪空间坐标值而片断着色器提供色彩值 着色器的语言与js不同是一品种c语言,就是大学计算机学的那种须要main函数的语言。所以作色器的语法总结起来就是 // 各种变量 balabalavoid main() { //各种操作 balabala}上文咱们说过能够把变量传入着色器,因为作色器当初咱们来说下常见的变量 Attributes(属性):属性用来指明怎么从缓冲中获取所需数据并将它提供给顶点着色器。 例如你可能在缓冲中用三个32位的浮点型数据存储一个地位值。buffer(缓冲):缓冲是发送到GPU的一些二进制数据序列,通常状况下缓冲数据包含地位,法向量,纹理坐标,顶点色彩值等。 你能够存储任何数据。Uniforms(全局变量):全局变量在着色程序运行前赋值,在运行过程中全局无效。Textures(纹理):纹理是一个数据序列,能够在着色程序运行中随便读取其中的数据。大多数状况咱们不会本人写材质,就间接用纹理了。Varyings(可变量):可变量是一种顶点着色器给片断着色器传值的形式,按照渲染的图元是点, 线还是三角形,顶点着色器中设置的可变量会在片断着色器运行中获取不同的插值。上面咱们来写一个最简略的顶点作色器 gl承受一个字符串的作色器代码,你能够应用数组或任意模式提供这个字符串,我集体通常写在一个script标签中: <script id="vertex-shader-2d" type="notjs"> // 一个属性变量,将会从缓冲中获取数据 attribute vec2 vertPosition; attribute vec3 vertColor; varying vec3 fragColor; // 所有着色器都有一个main办法 void main() { fragColor = vertColor; // gl_Position 是一个顶点着色器次要设置的变量 gl_Position = vec4(vertPosition,0.0,1.0); }</script>这里咱们定义了两个属性vertPosition与vertColor用来存储传入的地位与色彩信息,可变量 fragColor会持续传递给片段着色器应用。内置变量gl_Position的值是四维向量vec4(x,y,z,1.0),前三个参数示意顶点的xyz坐标值,第四个参数是浮点数1.0因为案例中咱们只须要绘制一个立体内的三角形,所以z值被咱们设为0。与之绝对咱们也能写出片段着色器: <script id="fragment-shader-2d" type="notjs"> // 片断着色器没有默认精度,所以咱们须要设置一个精度 // mediump是一个不错的默认值,代表“medium precision”(中等精度) precision mediump float; varying vec3 fragColor; void main() { // gl_FragColor是一个片断着色器次要设置的变量 gl_FragColor = vec4(fragColor, 1.0); // }</script>应用作色器webgl让初学者窝火的另一个起因是,他的编程逻辑很像底层语言,而非javascript,没有很多封装。做一件小事往往要执行多个办法。例如咱们上面要应用作色器,写的这段语法: ...

August 9, 2020 · 2 min · jiezi

关于webgl:前端图形学从入门到放弃001-画一个三角形

这是面向前端的图形学课程。心愿用通俗的语言为大家解释清图形学的一些概念。咱们应用的前端最容易webgl,尽管未免还是要接触GLSL,别打我,这曾经是最简略的!咱们开始第一节,矩阵....不还是画个正方形吧! webgl是什么?说人话webgl就是个工具,能够拿来画图的,它依赖于canvas,在canvas上你能够获取2d的上下文,也能够获取webgl的上下文。相似宝可梦新手村能够选蒜头王八也能够选黄皮耗子 所以第一步咱们就创立一个canvas,并获取webgl上下文 <canvas id="canvas" width="1000" height="1000"></canvas><script>var canvas = document.querySelector("#canvas");var gl = canvas.getContext("webgl");</script> 开始擦滑板咯!小画家这样咱们就获取了canvas的掌控权,canvas相当于一块画布,在画图之前咱们得像保障画面是洁净的。gl提供了两个api来做这件事:gl.clearColor与gl.clear gl.clearColor承受(r,g,b,a)的色彩数据,相当于给画布选一个底色;gl.clear用来革除buffer,至于什么是buffer咱们前面会讲。这里只须要晓得gl在没次绘图时都能够记录色彩和深度两个buffer,再次绘制时须要革除! 定点着色器和片段着色器着色器是足以燃烧你学习webgl的激情的魔鬼。但了解之后你也会感觉恍然大悟!首先三维空间的物体不论多简单都是一些集合体,所谓点动成线,线动成面,面动成体。所以点是形容空间物体的最小单元。 定点着色器就是用来解决咱们传入的顶点的,在下节课咱们将应用顶点着色器对三角形进行旋转,缩放,平移等操作。而与之绝对的是片段着色器,它次要解决围成图形的上色工作。这并不是明确的定义,但有助于你的了解:顶点着色器提供裁剪空间坐标值而片断着色器提供色彩值 着色器的语言与js不同是一品种c语言,就是大学计算机学的那种须要main函数的语言。所以作色器的语法总结起来就是 // 各种变量 balabalavoid main() { //各种操作 balabala}上文咱们说过能够把变量传入着色器,因为作色器当初咱们来说下常见的变量 Attributes(属性):属性用来指明怎么从缓冲中获取所需数据并将它提供给顶点着色器。 例如你可能在缓冲中用三个32位的浮点型数据存储一个地位值。buffer(缓冲):缓冲是发送到GPU的一些二进制数据序列,通常状况下缓冲数据包含地位,法向量,纹理坐标,顶点色彩值等。 你能够存储任何数据。Uniforms(全局变量):全局变量在着色程序运行前赋值,在运行过程中全局无效。Textures(纹理):纹理是一个数据序列,能够在着色程序运行中随便读取其中的数据。大多数状况咱们不会本人写材质,就间接用纹理了。Varyings(可变量):可变量是一种顶点着色器给片断着色器传值的形式,按照渲染的图元是点, 线还是三角形,顶点着色器中设置的可变量会在片断着色器运行中获取不同的插值。上面咱们来写一个最简略的顶点作色器 gl承受一个字符串的作色器代码,你能够应用数组或任意模式提供这个字符串,我集体通常写在一个script标签中: <script id="vertex-shader-2d" type="notjs"> // 一个属性变量,将会从缓冲中获取数据 attribute vec2 vertPosition; attribute vec3 vertColor; varying vec3 fragColor; // 所有着色器都有一个main办法 void main() { fragColor = vertColor; // gl_Position 是一个顶点着色器次要设置的变量 gl_Position = vec4(vertPosition,0.0,1.0); }</script>这里咱们定义了两个属性vertPosition与vertColor用来存储传入的地位与色彩信息,可变量 fragColor会持续传递给片段着色器应用。内置变量gl_Position的值是四维向量vec4(x,y,z,1.0),前三个参数示意顶点的xyz坐标值,第四个参数是浮点数1.0因为案例中咱们只须要绘制一个立体内的三角形,所以z值被咱们设为0。与之绝对咱们也能写出片段着色器: <script id="fragment-shader-2d" type="notjs"> // 片断着色器没有默认精度,所以咱们须要设置一个精度 // mediump是一个不错的默认值,代表“medium precision”(中等精度) precision mediump float; varying vec3 fragColor; void main() { // gl_FragColor是一个片断着色器次要设置的变量 gl_FragColor = vec4(fragColor, 1.0); // }</script>应用作色器webgl让初学者窝火的另一个起因是,他的编程逻辑很像底层语言,而非javascript,没有很多封装。做一件小事往往要执行多个办法。例如咱们上面要应用作色器,写的这段语法: ...

August 9, 2020 · 2 min · jiezi