SVGRenderer是 Three.js 中一个专门用于将 3D 场景渲染为 SVG(可缩放矢量图形)格式的渲染器。与 WebGLRenderer 使用 GPU 渲染 3D 图形不同,SVGRenderer 使用 CPU 生成 SVG 输出,适合用于生成静态的 2D 图像、矢量图形或可视化效果,不适用于实时交互或动画。
SVGRenderer 有七个方法
<template>
<div id="parkingLot" ref="parkingLot">
</div>
</template>
<script setup>
import { ref, onMounted, onUnmounted } from "vue";
import * as THREE from 'three';
import hdrImg from "@public/hdr/bgImage.hdr"
import imgPng from "@public/rg.png"
import person from "@public/person.jpg"
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';
import { SVGRenderer, SVGObject } from 'three/addons/renderers/SVGRenderer.js';
const parkingLot = ref();
onMounted(async () => {
const DOMEl = parkingLot.value;
// 获取 DOMEl 的宽度和高度,以设置渲染器的大小。
const width = DOMEl.clientWidth;
const height = DOMEl.clientHeight;
const renderer = new SVGRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.setQuality( 'low' );
DOMEl.appendChild( renderer.domElement );
const scene = new THREE.Scene();
renderer.setClearColor(0x000000);
const camera = new THREE.PerspectiveCamera( 75, width / height, 0.1, 1000 );
camera.position.set( 0, 80, 0 );
camera.lookAt( 0, 0, 0 );
// 禁用颜色管理
THREE.ColorManagement.enabled = false;
// 加载并显示二维码的几何体
const loader = new THREE.BufferGeometryLoader();
loader.load('https://raw.githubusercontent.com/mrdoob/three.js/refs/heads/master/examples/models/json/QRCode_buffergeometry.json', function (geometry) {
// 使用加载的几何体创建一个新的 Mesh
mesh = new THREE.Mesh(geometry, new THREE.MeshLambertMaterial({ vertexColors: true }));
mesh.scale.x = mesh.scale.y = mesh.scale.z = 2; // 设置缩放
scene.add(mesh); // 将该 Mesh 添加到场景中
});
// 创建两个立方体并添加到场景中
const boxGeometry = new THREE.BoxGeometry(100, 100, 100);
// 第一个立方体:蓝色,半透明
let mesh = new THREE.Mesh(boxGeometry, new THREE.MeshBasicMaterial({ color: 0x0000ff, opacity: 0.5, transparent: true }));
mesh.position.x = 500;
mesh.rotation.x = Math.random();
mesh.rotation.y = Math.random();
mesh.scale.x = mesh.scale.y = mesh.scale.z = 2;
scene.add(mesh);
// 第二个立方体:随机颜色
mesh = new THREE.Mesh(boxGeometry, new THREE.MeshBasicMaterial({ color: Math.random() * 0xffffff }));
mesh.position.x = 500;
mesh.position.y = 500;
mesh.rotation.x = Math.random();
mesh.rotation.y = Math.random();
mesh.scale.x = mesh.scale.y = mesh.scale.z = 2;
scene.add(mesh);
// 创建一个平面并添加到场景中
mesh = new THREE.Mesh(new THREE.PlaneGeometry(100, 100), new THREE.MeshBasicMaterial({ color: Math.random() * 0xffffff, side: THREE.DoubleSide }));
mesh.position.y = -500;
mesh.scale.x = mesh.scale.y = mesh.scale.z = 2;
scene.add(mesh);
// 创建一个圆柱体并添加到场景中
mesh = new THREE.Mesh(new THREE.CylinderGeometry(20, 100, 200, 10), new THREE.MeshBasicMaterial({ color: Math.random() * 0xffffff }));
mesh.position.x = -500;
mesh.rotation.x = -Math.PI / 2;
mesh.scale.x = mesh.scale.y = mesh.scale.z = 2;
scene.add(mesh);
// 创建一个多边形场地并添加到场景中
const geometry = new THREE.BufferGeometry();
const material = new THREE.MeshBasicMaterial({ vertexColors: true, side: THREE.DoubleSide });
const v = new THREE.Vector3();
const v0 = new THREE.Vector3();
const v1 = new THREE.Vector3();
const v2 = new THREE.Vector3();
const color = new THREE.Color();
const vertices = [];
const colors = [];
for (let i = 0; i < 100; i++) {
// 随机生成三角形的三个顶点
v.set(Math.random() * 1000 - 500, Math.random() * 1000 - 500, Math.random() * 1000 - 500);
v0.set(Math.random() * 100 - 50, Math.random() * 100 - 50, Math.random() * 100 - 50);
v1.set(Math.random() * 100 - 50, Math.random() * 100 - 50, Math.random() * 100 - 50);
v2.set(Math.random() * 100 - 50, Math.random() * 100 - 50, Math.random() * 100 - 50);
v0.add(v);
v1.add(v);
v2.add(v);
color.setHex(Math.random() * 0xffffff);
// 创建一个三角形的顶点并设置颜色
vertices.push(v0.x, v0.y, v0.z);
vertices.push(v1.x, v1.y, v1.z);
vertices.push(v2.x, v2.y, v2.z);
colors.push(color.r, color.g, color.b);
colors.push(color.r, color.g, color.b);
colors.push(color.r, color.g, color.b);
}
geometry.setAttribute('position', new THREE.Float32BufferAttribute(vertices, 3));
geometry.setAttribute('color', new THREE.Float32BufferAttribute(colors, 3));
const group = new THREE.Mesh(geometry, material);
group.scale.set(2, 2, 2);
scene.add(group);
// 创建多个精灵并添加到场景中
for (let i = 0; i < 50; i++) {
const material = new THREE.SpriteMaterial({ color: Math.random() * 0xffffff });
const sprite = new THREE.Sprite(material);
sprite.position.x = Math.random() * 1000 - 500;
sprite.position.y = Math.random() * 1000 - 500;
sprite.position.z = Math.random() * 1000 - 500;
sprite.scale.set(64, 64, 1); // 设置精灵的缩放
scene.add(sprite);
}
// 使用自定义 SVG 图形创建对象并添加到场景中
const node = document.createElementNS('http://www.w3.org/2000/svg', 'circle');
node.setAttribute('stroke', 'black');
node.setAttribute('fill', 'red');
node.setAttribute('r', '40');
for (let i = 0; i < 50; i++) {
const object = new SVGObject(node.cloneNode());
object.position.x = Math.random() * 1000 - 500;
object.position.y = Math.random() * 1000 - 500;
object.position.z = Math.random() * 1000 - 500;
scene.add(object);
}
// 从文件加载 SVG 并将其转换为对象添加到场景中
const fileLoader = new THREE.FileLoader();
fileLoader.load('https://raw.githubusercontent.com/mrdoob/three.js/refs/heads/master/examples/models/svg/hexagon.svg', function (svg) {
const node = document.createElementNS('http://www.w3.org/2000/svg', 'g');
const parser = new DOMParser();
const doc = parser.parseFromString(svg, 'image/svg+xml');
node.appendChild(doc.documentElement);
const object = new SVGObject(node);
object.position.x = 500;
scene.add(object);
});
// 创建光源并添加到场景中
const ambient = new THREE.AmbientLight(0x80ffff);
scene.add(ambient);
const directional = new THREE.DirectionalLight(0xffff00);
directional.position.set(-1, 0.5, 0);
scene.add(directional);
// 创建 OrbitControls 实例,用于控制摄像机
const controls = new OrbitControls(camera, renderer.domElement);
// 设置控制器的目标点为原点
controls.target.set(0, 0, 0);
// 动画函数
function animate() {
requestAnimationFrame(animate);
group.rotation.x += 0.01; // 使多边形场地不断旋转
controls.update(); // 更新 OrbitControls
renderer.render(scene, camera); // 渲染场景
}
animate();
});
</script>
<style lang="scss" scoped="scoped">
#parkingLot {
width: 940px;
height: 940px;
border: 1px solid #ccc;
margin: 30px auto;
}
</style>
方法
- clear () : undefined 告诉渲染器来清除其绘图表面。
- getSize () : Object 返回一个包含有渲染器宽和高的对象。
- render ( scene : Scene, camera : Camera ) : undefined 使用camera来渲染一个scene。
- setClearColor ( color : Color, alpha : number ) : undefined 设置clearColor(空白颜色)以及clearAlpha(空白Alpha)。
- setPrecision ( precision : Number ) : undefined 设置用于创建路径的数据的精度。
- setQuality () : undefined 设置渲染质量。可能的值有low和high(默认值)。
- setSize ( width : Number, height : Number ) : undefined 改变渲染器尺寸为(width, height)。