8. Threejs案例-SVG渲染器和WEBGL渲染器对比_threejs svg-程序员宅基地

技术标签: svg  webgl  threejs  WebGLRenderer  渲染器  Threejs  SVGRenderer  

8. Threejs案例-SVG渲染器和WEBGL渲染器对比

实现效果

效果

知识点

SVG渲染器 (SVGRenderer)

SVGRenderer 被用于使用 SVG 来渲染几何数据,所产生的矢量图形在以下几个方面十分有用:

  • 动画标志 logo 或者图标 icon
  • 可交互的 2D3D 图表或图形
  • 交互式地图
  • 复杂的或包含动画的用户界面

SVGRenderer 具有很多优势。它产生清晰并且锐利的图像输出,它和实际视口分辨率无关。
SVG 元素可以通过 CSS 来控制样式;并且由于它可以添加诸如标题或者描述文字之类的元数据 (
对于搜索引擎或者屏幕阅读器十分有用) ,因此它具有十分良好的可访问性。

然而,SVG 也有一些十分重要的限制:

  • 没有高级的着色器
  • 不支持纹理
  • 不支持阴影
方法
clear()

告诉渲染器来清除其绘图表面。

getSize()

返回一个包含有渲染器宽和高的对象。

render(scene, camera)

使用 camera 来渲染一个 scene

setClearColor(color, alpha)

设置 clearColor 以及 clearAlpha

setPrecision(precision)

设置用于创建路径的数据的精度。

setQuality()

设置渲染质量。可能的值有 lowhigh

setSize(width, height)

改变渲染器尺寸。

基础线条材质 (LineBasicMaterial)

一种用于绘制线框样式几何体的材质。

属性
color

材质的颜色,默认值为白色。

fog

材质是否受雾影响。默认为 true

linewidth

控制线宽。默认值为 1

linecap

定义线两端的样式。可选值为 butt, roundsquare。默认值为 round

linejoin

定义线连接节点的样式。可选值为 round, bevelmiter。默认值为 round

代码

<!DOCTYPE html>
<html lang="zh">
<head>
    <title></title>
    <meta charset="UTF-8">
    <script src="ThreeJS/three.js"></script>
    <script src="ThreeJS/jquery.js"></script>
    <script src="ThreeJS/Projector.js"></script>
    <script src="ThreeJS/SVGRenderer.js"></script>

</head>
<body>
<p>
    <button id="myButton1">启用SVG渲染器</button>
    <button id="myButton2">启用WebGL渲染器</button>
</p>
<div id="myContainer"></div>
<script>
    // 初始化一个变量,用于决定是否使用SVG渲染器
    let isSVGRenderer = true;
    
    // 创建SVG渲染器,并设置其大小为窗口大小
    const myRenderer1 = new THREE.SVGRenderer();
    myRenderer1.setSize(window.innerWidth, window.innerHeight);
    
    // 创建WebGL渲染器,开启抗锯齿功能,并设置其大小为窗口大小
    const myRenderer2 = new THREE.WebGLRenderer({
      antialias: true});
    myRenderer2.setSize(window.innerWidth, window.innerHeight);
    
    // 创建一个透视相机,设置其视场角度和位置
    const myCamera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);
    myCamera.position.z = 4;
    
    // 创建一个场景,并设置其背景色为白色
    const myScene = new THREE.Scene();
    myScene.background = new THREE.Color(0xffffff);
    
    // 创建一个用于存储顶点坐标的数组
    const myVertices = [];
    let i;
    
    // 通过循环生成顶点坐标,并存储到myVertices数组中
    for (i = 0; i <= 150; i++) {
      
        const v = (i / 150) * (Math.PI * 2);
        const x = Math.sin(v);
        const z = Math.cos(v);
        myVertices.push(x, 0, z);
    }
    
    // 创建一个几何体,并设置其位置属性
    const myGeometry = new THREE.BufferGeometry();
    myGeometry.setAttribute('position', new THREE.Float32BufferAttribute(myVertices, 3));
    
    // 创建三个线段,设置其材质、大小和旋转属性,并将它们添加到场景中
    for (i = 1; i <= 3; i++) {
      
        const myMaterial = new THREE.LineBasicMaterial({
      
            color: Math.random() * 0xffffff,
            linewidth: 20
        });
        let myLine = new THREE.Line(myGeometry, myMaterial);
        myLine.scale.setScalar(i / 3);
        myScene.add(myLine);
    }
    
    // 调用animate函数来渲染图形
    animate();
    
    // animate函数用于更新和渲染场景中的物体,并启动动画循环
    function animate() {
      
        let myOffset = 0;
        const myTime = performance.now() / 1000; // 获取当前时间并计算出时间差
        myScene.traverse(function (child) {
       // 遍历场景中的每个物体,更新其旋转属性
            child.rotation.x = myOffset + (myTime / 3); // 在x轴上旋转物体,并随时间变化产生动画效果
            child.rotation.z = myOffset + (myTime / 4); // 在z轴上旋转物体,并随时间变化产生动画效果
            myOffset++; // 每次循环时增加旋转角度,以产生连续的动画效果
        });
        let myRenderer = myRenderer1; // 根据isSVGRenderer变量的值选择渲染器,默认为SVG渲染器
        $("#myContainer").html(''); // 清空指定的容器元素的内容,以便将渲染器的DOM元素添加进去
        if (isSVGRenderer) {
       // 如果选择SVG渲染器,则使用myRenderer1渲染器进行渲染
            myRenderer = myRenderer1;
        } else {
       // 如果选择WebGL渲染器,则使用myRenderer2渲染器进行渲染
            myRenderer = myRenderer2;
        }
        $("#myContainer").append(myRenderer.domElement); // 将渲染器的DOM元素添加到指定的容器中,以便在网页上显示渲染结果
        myRenderer.render(myScene, myCamera); // 使用指定的渲染器和相机渲染场景,并将结果输出到DOM元素中
        requestAnimationFrame(animate); // 使用requestAnimationFrame函数启动动画循环,继续下一帧的渲染和动画效果生成
    }
    
    //响应单击“启用SVG渲染器”按钮
    $("#myButton1").click(function () {
      
        isSVGRenderer = true;
    });
    //响应单击“启用WebGL渲染器”按钮
    $("#myButton2").click(function () {
      
        isSVGRenderer = false;
    });
</script>
</body>
</html>


演示链接

示例链接

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/m0_51180924/article/details/135976660

智能推荐

【深度学习】归一化_深度学习 那些情况 要做 归一化-程序员宅基地

文章浏览阅读1.8w次,点赞8次,收藏11次。​ 以前在神经网络训练中,只是对输入层数据进行归一化处理,却没有在中间层进行归一化处理。要知道,虽然我们对输入数据进行了归一化处理,但是输入数据经过 $ \sigma(WX+b) $ 这样的矩阵乘法以及非线性运算之后,其数据分布很可能被改变,而随着深度网络的多层运算之后,数据分布的变化将越来越大。如果我们能在网络的中间也进行归一化处理,是否对网络的训练起到改进作用呢?答案是肯定的。​ 这种在神经网络中间层也进行归一化处理,使训练效果更好的方法,就是批归一化Batch Normalization(BN)。_深度学习 那些情况 要做 归一化

微信小程序支付接口实现(java后台)_小程序后台java支付接口-程序员宅基地

文章浏览阅读1.2w次,点赞12次,收藏101次。#(Notice:以下所有经验也是我根据网上的经验整理的,如有侵权可以联系我删除,QQ 654303408。 有问题讨论也可联系我,QQ同上。)#(Tips:我是第一次开发,一个刚毕业的java工程师,我觉得我并非天赋异禀,我能学会,相信聪敏的你,一定可以)#(PS:目前微信拥有无可撼动的人口基数,越来越多的项目开发是基于微信小程序,或者APP。但是支付方式无非两种,一种是支付宝,一种是微信支..._小程序后台java支付接口

python web server_用Python建立最简单的web服务器-程序员宅基地

文章浏览阅读27次。第一个python Web程序——简单的Web服务器。与其它Web后端语言不同,Python语言需要自己编写Web服务器。如果你使用一些现有的框架的话,可以省略这一步;如果你使用Python CGI编程的话,也可以省略这一步;用Python建立最简单的web服务器利用Python自带的包可以建立简单的web服务器。在DOS里cd到准备做服务器根目录的路径下,输入命令:python -m Web服务..._pyjwt webserver

【图像重建指标 Metrics】均方误差RMSE及平均绝对误差MAE的定义和区别_rmse与mae有换算公式吗-程序员宅基地

文章浏览阅读1.3w次,点赞3次,收藏23次。RMSE和MAE能很好的反应图像的重建结果与真实结果间的差异。_rmse与mae有换算公式吗

Kotlin Gradle Junit单元测试print输出控制台_gradle 打印日志 system. out.print-程序员宅基地

文章浏览阅读3.4k次。背景默认情况下,Gradle 单元测试,是无法使用 System.out.println 这样打印变量信息的,这会让我们debug变得非常麻烦。百度网上很多方案,,但都比较麻烦,也很容易踩坑,。换了个搜索姿势,google了下,原来方案如此简单。解决在你的模块下的build.gradle.kts添加如下的配置:tasks.withType<Test> { this.testLogging { this.showStandardStreams = true _gradle 打印日志 system. out.print

Android基本组件之服务Service_安卓如果设置组服务-程序员宅基地

文章浏览阅读167次。Service的开启与关闭1.继承Service类2.在AndroidManifest.xml中注册<service android:name=".MyService" android:enabled="true" android:exported="true"></service>直接创建Service的话,前两步会自动执行3.通过Contex.startSer..._安卓如果设置组服务

随便推点

sqlmap的使用--绕过--自带脚本tamper_sqlmap绕过脚本-程序员宅基地

文章浏览阅读2.2k次,点赞2次,收藏11次。sqlmap在默认的的情况下除了使用char()函数防止出现单引号,没有对注入的数据进行修改,还可以使用–tamper参数对数据做修改来绕过waf等设备。命令格式:sqlmap -u [url] --tamper [模块名]通过使用whereis sqlmap查看sqlmap安装路径,自带的脚本一般是在usr/share/sqlmap/tamper下,我的是1.6.3版本一共有66个自带脚本下边引一些常用的脚本:apostrophemask.py适用数据库:ALL作用_sqlmap绕过脚本

换行分隔符_分隔符 换行-程序员宅基地

文章浏览阅读1.7k次。windows:\r\nlinux:\rmac:\n_分隔符 换行

waves效果器_混音选择困难2,Waves均衡器全介绍与理论使用心得-程序员宅基地

文章浏览阅读4.2k次,点赞2次,收藏8次。喜欢「音乐杂谈」这个主题的朋友可以关注我的头条号,将会在不定期发表一些音乐理论以外的音乐话题的文章或者是音乐知识的干货 。(此文为混音师天职老师 发布于今日头条的原创文章,转载请告知并注明出处)通篇写作整理下来差不多花了7个小时,不管怎样,施舍点个赞吧。哈哈哈!继上一次「音乐杂谈41」混音选择困难第一期,给大家介绍了Waves全家桶的大部分压缩器之后,本篇,我们将来看看,Waves全家桶的大部分均..._waves功能详解

在Android中播放音频和视频_android 播放语言视频-程序员宅基地

文章浏览阅读2.8k次。Android媒体包提供了可管理各种媒体类型的类。这些类可提供用于执行音频和视频操作。除了基本操作之外,还可提供铃声管理、脸部识别以及音频路由控制。本文说明了音频和视频操作。本文简介媒体包提供了可管理各种媒体类型的类。这些类可提供用于执行音频和视频操作。除了基本操作之外,还可提供铃声管理、脸部识别以及音频路由控制。本文说明了音频和视频操作。范围:_android 播放语言视频

Sublime and Markdown-程序员宅基地

文章浏览阅读2.7k次。Sublime & Markdown文章目录Sublime & Markdown安装 Sublime设置 Sublime安装插件Package ControlMarkdownEditingMarkdown PreviewLiveReloadauto-saveOmniMarkupPreviewerEvernote插件&主题插入图片Ctrl+vHTML语法Markdown语法...

android uboot log,RK3288 Android 8.1系统uboot logo过渡到kernel logo会花一下-程序员宅基地

文章浏览阅读695次。在调试RK3288 Android 8.1系统遇到一个问题:开机启动uboot logo过渡到kernel log的过程中会花掉直到没有显示,再出现kernel logo。分析:打印串口log时发现,uboot阶段显示一切正常,进入kernel以后就开始花掉了然后变成没有显示了,感觉像是慢慢掉电了一样,再继续查看log发现如下打印:[ 0.363167] Registered fiq deb..._mtk 转屏后 logo uboot 转kernel 显示异常

推荐文章

热门文章

相关标签