大家平时可能接触过 SVG,但是可能对 WebGL 不是很了解,SVG 主要是一种矢量图格式,给定对应的数据就可以绘制点、线和图形等,基于 XML 标记语言编写,可以在很小的体积下就能得到高清晰度图形,且支持任意形式的放大缩小而不失真;而 WebGL 是 HTML5 之后浏览器支持的一套图形的 API。
而 SVG 要么通过 DOM 支持,要么通过 Canvas Path2D 支持,在只有 WebGL2 的 Context 下却因为缺少相应的 API,所以无法支持 SVG,但团队成员在平时研究 3D / Threejs 源码时,发现源码中有类似将 SVG 渲染到 WebGL2 Context 上的逻辑,很感兴趣,所以就花时间抽出一个库,提供方便的 API 实现 SVG 在 WebGL2 Context 上的渲染:「svg-webgl-loader」,目前项目已经开源,感兴趣的同学可以去到如下地址查看代码
Github:https://github.com/elab-opensource/svg-webgl-loader[1]
NPM:svg-webgl-loader[2]
我们提供了 NPM 包安装和 CDN 导入两种使用方式,其中 NPM 包安装如下:
npm i svg-webgl-loader # yarn add svg-webgl-loader
CDN 链接如下:
<script src="https://unpkg.com/svg-webgl-loader/dist/js/index.umd.js"></script>
如果是通过 NPM 包安装,那么在你项目中正常导入使用即可:
import svgWebglLoader from "svg-webgl-loader";
如果你是通过 CDN 的形式引入,那么则可以以如下形式使用:
<script src="https://unpkg.com/svg-webgl-loader/dist/js/index.umd.js"></script>
const svgWebglLoader = window.svgWebglLoader
一个标准的使用方式则为传入对应 SVG 内容以及待渲染的 Canvas 节点,以及配置对应的参数:
import svgWebglLoader from "svg-webgl-loader";
import svgUrl from "./img/test.svg";
// 加载解析svg数据
const svgData = await svgWebglLoader(svgUrl);
// 绘制
svgData.draw({
canvas,
loc: {
x: 0,
y: 0,
width: 300,
height: 300,
},
});
一个实际的例子可以参考 CodeOpen 链接:
https://codepen.io/yh418807968/pen/GREMPXw?editors=1011[3]
如果需要,可以通过以下形式修改背景颜色:
let gl = canvas.getContext('webgl');
gl.clearColor(1, 1, 1, 1);
gl.clear(gl.COLOR_BUFFER_BIT);
使用:
const svgData = await svgWebglLoader(svgUrl);
svgData.draw(drawParams)
输入参数:
interface drawParams {
canvas: HTMLCanvasElement; // 待绘制的画布canvas
loc?: {
// 绘制区域
x: 0,
y: 0,
width?: 300, // 绘制宽度,默认为svg图片本身宽度
height?: 300, // 绘制宽度,默认为svg图片本身宽度
};
config?: {
needTrim?: true, // 是否需要去除svg边缘空白,默认false
needFill?: true, // 是否需要填充,默认true
needStroke?: true, // 是否需要描边, 默认true
};
}
调用之后产出的结果为渲染了 SVG 内容的 Canvas 对象,如果传入了对应的 canvas
参数,则为此传入的 Canvas 对象,否则会是在内部新建的 Canvas 对象。
svg-webgl-loader 主要是参考 Threejs 中加载渲染 SVG 的方案[4]:通过解析路径、路径离散化、三角化,将 SVG 分解为众多三角形,从而使得其可以采用 WebGL Shader 渲染。
以如下 SVG 为例:
<svg width="400" height="400" viewPort="0 0 400 400" version="1.1"
xmlns="http://www.w3.org/2000/svg">
<circle
style="stroke:yellow; fill:blue; stroke-width: 3;"
cx="61"
cy="48"
r="30" />
<polygon transform="translate(0, 60)" points="60,20 100,40 100,80 60,100 20,80 20,40" style="stroke:yellow; fill:blue; stroke-width: 3;"/>
</svg>
其中包含一个圆形和一个多边形,解析流程主要如下:
解析路径,即为 circle 和 polygon
填充:如果有 fill 属性,则进行填充
分别对 circle 和 polygon 路径进行离散化,获得 pointList
对 pointList 进行三角化
传入三角化数据,采用 shader 进行绘制
描边:如果有 fill 属性,则进行描边
类似于填充,分别对 circle 和 polygon 路径进行离散化,获得 pointList
根据 stroke-width,计算 pointList 对应的内外路径 innerPointList 和 outPointList
按一定规律连接内外点,并采用 shader 进行绘制
大致流程参考下图:
❝注意:图中三角化、离散化等数据不是准确数据,只是解释说明大致流程。
❞
包大小约 90 KB,主要分为 2 部分:axios 和 主体逻辑。
挑选了一个简单几何形状和一个复杂图形,分别看看耗时情况:
路径复杂度 | 表现 | 解析/渲染耗时 | |
---|---|---|---|
简单形状 | 一个rect | t | 18ms |
复杂图形 | 约240条path | 150ms |
可以看到解析/渲染时间大致在 20~150ms 间,视觉上基本没有延时或卡顿。不过,由于 GPU 的并行绘制方式,绘制时间其实很短,以上时间几乎都是数据解析时间(即在主线程上进行),因此在耗时上的后续优化方向主要是将一些循环计算等转移到 shader 中,由 GPU 统一并行处理。
耗时计算方式:
❝开始时间:网络请求完成,即获得 SVG 文件字符串为 startTime;
❞
❝由于 GPU 采用并行绘制,耗时很短且几乎不受数据大小影响,因此此处直接以 draw Call 命令调用完成的时间为 endTime。
❞
svg-webgl-loader 目前可以渲染绝大部分 SVG,你可以通过体验它了解 SVG 和 WebGL 的一部分原理,同时有助于你日后在使用它们或了解 Threejs 相关的原理。
svg-webgl-loader 的出生是因为兴趣使然,所以在功能上依然还有很多可扩展及优化的地方,具体列举如下。
svg-webgl-loader 中涉及到了大量 SVG 、Canvas 与 WebGL 相关的知识,探究它们的原理是困难而有趣的,如果你也有兴趣一起探索关于它们的奥妙,也可以联系小编拍砖哦~
同时,如果你对 svg-webgl-loader 感兴趣的话,别忘了去到对应的地址给我一个 Star 以鼓励我们改进的更好哦~
[1]https://github.com/elab-opensource/svg-webgl-loader:https://github.com/elab-opensource/svg-webgl-loader
[2]svg-webgl-loader:https://www.npmjs.com/package/svg-webgl-loader
[3]https://codepen.io/yh418807968/pen/GREMPXw?editors=1011:https://codepen.io/yh418807968/pen/GREMPXw?editors=1011
[4]方案:https://github.com/mrdoob/three.js/blob/dev/examples/webgl_loader_svg.html
本文由哈喽比特于3年以前收录,如有侵权请联系我们。
文章来源:https://mp.weixin.qq.com/s/an8kGFrqhPpedCtFVaS_ow
京东创始人刘强东和其妻子章泽天最近成为了互联网舆论关注的焦点。有关他们“移民美国”和在美国购买豪宅的传言在互联网上广泛传播。然而,京东官方通过微博发言人发布的消息澄清了这些传言,称这些言论纯属虚假信息和蓄意捏造。
日前,据博主“@超能数码君老周”爆料,国内三大运营商中国移动、中国电信和中国联通预计将集体采购百万台规模的华为Mate60系列手机。
据报道,荷兰半导体设备公司ASML正看到美国对华遏制政策的负面影响。阿斯麦(ASML)CEO彼得·温宁克在一档电视节目中分享了他对中国大陆问题以及该公司面临的出口管制和保护主义的看法。彼得曾在多个场合表达了他对出口管制以及中荷经济关系的担忧。
今年早些时候,抖音悄然上线了一款名为“青桃”的 App,Slogan 为“看见你的热爱”,根据应用介绍可知,“青桃”是一个属于年轻人的兴趣知识视频平台,由抖音官方出品的中长视频关联版本,整体风格有些类似B站。
日前,威马汽车首席数据官梅松林转发了一份“世界各国地区拥车率排行榜”,同时,他发文表示:中国汽车普及率低于非洲国家尼日利亚,每百户家庭仅17户有车。意大利世界排名第一,每十户中九户有车。
近日,一项新的研究发现,维生素 C 和 E 等抗氧化剂会激活一种机制,刺激癌症肿瘤中新血管的生长,帮助它们生长和扩散。
据媒体援引消息人士报道,苹果公司正在测试使用3D打印技术来生产其智能手表的钢质底盘。消息传出后,3D系统一度大涨超10%,不过截至周三收盘,该股涨幅回落至2%以内。
9月2日,坐拥千万粉丝的网红主播“秀才”账号被封禁,在社交媒体平台上引发热议。平台相关负责人表示,“秀才”账号违反平台相关规定,已封禁。据知情人士透露,秀才近期被举报存在违法行为,这可能是他被封禁的部分原因。据悉,“秀才”年龄39岁,是安徽省亳州市蒙城县人,抖音网红,粉丝数量超1200万。他曾被称为“中老年...
9月3日消息,亚马逊的一些股东,包括持有该公司股票的一家养老基金,日前对亚马逊、其创始人贝索斯和其董事会提起诉讼,指控他们在为 Project Kuiper 卫星星座项目购买发射服务时“违反了信义义务”。
据消息,为推广自家应用,苹果现推出了一个名为“Apps by Apple”的网站,展示了苹果为旗下产品(如 iPhone、iPad、Apple Watch、Mac 和 Apple TV)开发的各种应用程序。
特斯拉本周在美国大幅下调Model S和X售价,引发了该公司一些最坚定支持者的不满。知名特斯拉多头、未来基金(Future Fund)管理合伙人加里·布莱克发帖称,降价是一种“短期麻醉剂”,会让潜在客户等待进一步降价。
据外媒9月2日报道,荷兰半导体设备制造商阿斯麦称,尽管荷兰政府颁布的半导体设备出口管制新规9月正式生效,但该公司已获得在2023年底以前向中国运送受限制芯片制造机器的许可。
近日,根据美国证券交易委员会的文件显示,苹果卫星服务提供商 Globalstar 近期向马斯克旗下的 SpaceX 支付 6400 万美元(约 4.65 亿元人民币)。用于在 2023-2025 年期间,发射卫星,进一步扩展苹果 iPhone 系列的 SOS 卫星服务。
据报道,马斯克旗下社交平台𝕏(推特)日前调整了隐私政策,允许 𝕏 使用用户发布的信息来训练其人工智能(AI)模型。新的隐私政策将于 9 月 29 日生效。新政策规定,𝕏可能会使用所收集到的平台信息和公开可用的信息,来帮助训练 𝕏 的机器学习或人工智能模型。
9月2日,荣耀CEO赵明在采访中谈及华为手机回归时表示,替老同事们高兴,觉得手机行业,由于华为的回归,让竞争充满了更多的可能性和更多的魅力,对行业来说也是件好事。
《自然》30日发表的一篇论文报道了一个名为Swift的人工智能(AI)系统,该系统驾驶无人机的能力可在真实世界中一对一冠军赛里战胜人类对手。
近日,非营利组织纽约真菌学会(NYMS)发出警告,表示亚马逊为代表的电商平台上,充斥着各种AI生成的蘑菇觅食科普书籍,其中存在诸多错误。
社交媒体平台𝕏(原推特)新隐私政策提到:“在您同意的情况下,我们可能出于安全、安保和身份识别目的收集和使用您的生物识别信息。”
2023年德国柏林消费电子展上,各大企业都带来了最新的理念和产品,而高端化、本土化的中国产品正在不断吸引欧洲等国际市场的目光。
罗永浩日前在直播中吐槽苹果即将推出的 iPhone 新品,具体内容为:“以我对我‘子公司’的了解,我认为 iPhone 15 跟 iPhone 14 不会有什么区别的,除了序(列)号变了,这个‘不要脸’的东西,这个‘臭厨子’。