如何将 image/video 添加到从 Blender 加载的场景中的特定对象
How to add image/video to a specific object on loaded scene from Blender
我有一个从 Blender 导入的场景。我在场景中有几个屏幕,我想在这些屏幕上添加一个 image/video。
注意:我正在使用 OOP 模型创建应用程序
我已经使用 gltfLoader 导入了场景,我正在等待加载所有资源
this.resources.on('ready', () => {
// Setup
this.controlRoom = new ControlRoom()
this.tvScreen4x4 = new tvScreen4x4()
})
ControlRoom 是实际场景,另一个是所有屏幕中的一个网格。
import * as THREE from 'three'
import Experience from "../../Experience.js"
export default class tvScreen4x4 {
constructor() {
this.experience = new Experience()
this.scene = this.experience.scene
this.resources = this.experience.resources
// Setup
this.setTexture()
this.setMaterial()
this.updateMesh()
}
setTexture() {
this.texture = {}
this.texture.normal = this.resources.items.tvScreen4x4
}
setMaterial() {
this.material = new THREE.MeshStandardMaterial({
map: this.texture.normal
})
}
updateMesh() {
this.scene.traverse((child) => {
if (child instanceof THREE.Mesh && child.name === 'tv_4x4_screen') {
child.material = this.material
child.material.needsUpdate = true
console.log(child.material);
}
})
}
}
this.resources.items.tvScreen4x4
正在退回我定制的商品 source.js
export default [
{
name: 'controlRoom',
type: 'gltfModel',
path: 'models/controlroom.gltf'
},
{
name: 'tvScreen4x4',
type: 'texture',
path: 'textures/screen.jpg'
},
{
name: 'tvScreen5x4',
type: 'texture',
path: 'textures/screen.jpg'
},
{
name: 'tvScreen6x4',
type: 'texture',
path: 'textures/screen.jpg'
}
]
console.log(child.material)returns如下:
我做错了什么纹理没有显示在那个屏幕上?控制台记录 returns 正确的地图。
加载纹理,将纹理应用到你想要的对象上,然后将模型添加到场景中:
const texture = new THREE.TextureLoader().load(imageUrl);
new GLTFLoader().load(modelUrl, (gltf) => {
gltf.scene.traverse((object) => {
if (object.isMesh && object.name === "SCREEN") {
object.material.map = texture;
}
});
scene.add(gltf.scene);
});
演示:
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
canvas {
display: block;
}
<script type="module">
import * as THREE from "https://cdn.jsdelivr.net/npm/three@0.121.1/build/three.module.js";
import { OrbitControls } from "https://cdn.jsdelivr.net/npm/three@0.121.1/examples/jsm/controls/OrbitControls.js";
import { GLTFLoader } from "https://cdn.jsdelivr.net/npm/three@0.121.1/examples/jsm/loaders/GLTFLoader.js";
import { DRACOLoader } from "https://cdn.jsdelivr.net/npm/three@0.121.1/examples/jsm/loaders/DRACOLoader.js";
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
const cameraMin = 0.0001;
const aspect = window.innerWidth / window.innerHeight;
const camera = new THREE.PerspectiveCamera(75, aspect, cameraMin, 1000);
const controls = new OrbitControls(camera, renderer.domElement);
const scene = new THREE.Scene();
const model =
"https://vazxmixjsiawhamofees.supabase.co/storage/v1/object/public/models/iphone-x/model.gltf";
const image =
"https://media.istockphoto.com/photos/colorful-umbrellas-for-sale-in-luang-prabang-laos-picture-id918965792";
const loader = new GLTFLoader();
const dracoLoader = new DRACOLoader();
dracoLoader.setDecoderPath(
"https://raw.githubusercontent.com/mrdoob/three.js/dev/examples/js/libs/draco/"
);
loader.setDRACOLoader(dracoLoader);
const texture = new THREE.TextureLoader().load(image);
loader.load(model, (gltf) => {
gltf.scene.traverse((object) => {
if (!object.isMesh) return;
if (object.name === "SCREEN") {
object.material.map = texture;
// console.log(object);
}
});
const box = new THREE.Box3().setFromObject(gltf.scene);
const center = box.getCenter(new THREE.Vector3());
gltf.scene.position.x += gltf.scene.position.x - center.x;
gltf.scene.position.y += gltf.scene.position.y - center.y;
gltf.scene.position.z += gltf.scene.position.z - center.z;
scene.add(gltf.scene);
});
camera.position.z = 5;
const ambientLight = new THREE.AmbientLight();
scene.add(ambientLight);
(function animate() {
requestAnimationFrame(animate);
renderer.setSize(window.innerWidth, window.innerHeight);
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
controls.update();
renderer.render(scene, camera);
})();
</script>
我找到了解决问题的办法。代码是正确的,并且场景已按应有的方式导入。我没有做对的一件事是我如何导出 Blender 场景。
导出场景时,我应该勾选 UV 和几何部分。如下图。
所以这更像是搅拌机的问题,而不是 Three.js
我有一个从 Blender 导入的场景。我在场景中有几个屏幕,我想在这些屏幕上添加一个 image/video。
注意:我正在使用 OOP 模型创建应用程序
我已经使用 gltfLoader 导入了场景,我正在等待加载所有资源
this.resources.on('ready', () => {
// Setup
this.controlRoom = new ControlRoom()
this.tvScreen4x4 = new tvScreen4x4()
})
ControlRoom 是实际场景,另一个是所有屏幕中的一个网格。
import * as THREE from 'three'
import Experience from "../../Experience.js"
export default class tvScreen4x4 {
constructor() {
this.experience = new Experience()
this.scene = this.experience.scene
this.resources = this.experience.resources
// Setup
this.setTexture()
this.setMaterial()
this.updateMesh()
}
setTexture() {
this.texture = {}
this.texture.normal = this.resources.items.tvScreen4x4
}
setMaterial() {
this.material = new THREE.MeshStandardMaterial({
map: this.texture.normal
})
}
updateMesh() {
this.scene.traverse((child) => {
if (child instanceof THREE.Mesh && child.name === 'tv_4x4_screen') {
child.material = this.material
child.material.needsUpdate = true
console.log(child.material);
}
})
}
}
this.resources.items.tvScreen4x4
正在退回我定制的商品 source.js
export default [
{
name: 'controlRoom',
type: 'gltfModel',
path: 'models/controlroom.gltf'
},
{
name: 'tvScreen4x4',
type: 'texture',
path: 'textures/screen.jpg'
},
{
name: 'tvScreen5x4',
type: 'texture',
path: 'textures/screen.jpg'
},
{
name: 'tvScreen6x4',
type: 'texture',
path: 'textures/screen.jpg'
}
]
console.log(child.material)returns如下:
我做错了什么纹理没有显示在那个屏幕上?控制台记录 returns 正确的地图。
加载纹理,将纹理应用到你想要的对象上,然后将模型添加到场景中:
const texture = new THREE.TextureLoader().load(imageUrl);
new GLTFLoader().load(modelUrl, (gltf) => {
gltf.scene.traverse((object) => {
if (object.isMesh && object.name === "SCREEN") {
object.material.map = texture;
}
});
scene.add(gltf.scene);
});
演示:
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
canvas {
display: block;
}
<script type="module">
import * as THREE from "https://cdn.jsdelivr.net/npm/three@0.121.1/build/three.module.js";
import { OrbitControls } from "https://cdn.jsdelivr.net/npm/three@0.121.1/examples/jsm/controls/OrbitControls.js";
import { GLTFLoader } from "https://cdn.jsdelivr.net/npm/three@0.121.1/examples/jsm/loaders/GLTFLoader.js";
import { DRACOLoader } from "https://cdn.jsdelivr.net/npm/three@0.121.1/examples/jsm/loaders/DRACOLoader.js";
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
const cameraMin = 0.0001;
const aspect = window.innerWidth / window.innerHeight;
const camera = new THREE.PerspectiveCamera(75, aspect, cameraMin, 1000);
const controls = new OrbitControls(camera, renderer.domElement);
const scene = new THREE.Scene();
const model =
"https://vazxmixjsiawhamofees.supabase.co/storage/v1/object/public/models/iphone-x/model.gltf";
const image =
"https://media.istockphoto.com/photos/colorful-umbrellas-for-sale-in-luang-prabang-laos-picture-id918965792";
const loader = new GLTFLoader();
const dracoLoader = new DRACOLoader();
dracoLoader.setDecoderPath(
"https://raw.githubusercontent.com/mrdoob/three.js/dev/examples/js/libs/draco/"
);
loader.setDRACOLoader(dracoLoader);
const texture = new THREE.TextureLoader().load(image);
loader.load(model, (gltf) => {
gltf.scene.traverse((object) => {
if (!object.isMesh) return;
if (object.name === "SCREEN") {
object.material.map = texture;
// console.log(object);
}
});
const box = new THREE.Box3().setFromObject(gltf.scene);
const center = box.getCenter(new THREE.Vector3());
gltf.scene.position.x += gltf.scene.position.x - center.x;
gltf.scene.position.y += gltf.scene.position.y - center.y;
gltf.scene.position.z += gltf.scene.position.z - center.z;
scene.add(gltf.scene);
});
camera.position.z = 5;
const ambientLight = new THREE.AmbientLight();
scene.add(ambientLight);
(function animate() {
requestAnimationFrame(animate);
renderer.setSize(window.innerWidth, window.innerHeight);
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
controls.update();
renderer.render(scene, camera);
})();
</script>
我找到了解决问题的办法。代码是正确的,并且场景已按应有的方式导入。我没有做对的一件事是我如何导出 Blender 场景。
导出场景时,我应该勾选 UV 和几何部分。如下图。
所以这更像是搅拌机的问题,而不是 Three.js