🪨

Nomad Sculptでテクスチャを適用してThree.jsで表示する

2025/02/08に公開

個人的備忘録です。表題についてのまとめです。

成果物

Nomad Sculpt(Texture) x Three.js sample page

上記のサンプルページを表示すると、glTFファイルが読み込まれて画面に表示されます。
形状はただの球体なのですが、岩のテクスチャを適用しているため、ゴツゴツした凹凸があるように見えますね。
また、Three.jsのスポットライトもしっかりと適用されています。

参考リンク集

https://www.youtube.com/watch?v=oO0wkGVeu4g

今回のサンプルを作成するにあたり、丸パクリ参考にした動画が上記になります。
大変助かりました!
Nomad Sculptでリアルなテクスチャを適用する方法は、上記の動画をご確認ください。


https://ambientcg.com/
動画内で紹介されているテクスチャの配布サイトです。

https://ambientcg.com/view?id=Rock030
今回利用したテクスチャは、上記の「Rock 030」です。


Nomad SculptからglTFファイルを出力して、Tree.jsに読み込ませるまではNomad Sculpt から出力した glTF を Three.js で表示するまでのサンプルコードにまとめています。

glTFファイルをThree.jsで表示する

下記が主となるTypeScriptコードです。
基本的にNomad Sculpt から出力した glTF を Three.js で表示するまでのサンプルコードと同じ構成のため、詳細な解説は省きます。

import * as THREE from "three";
import { GLTFLoader, type GLTF } from "three/addons/loaders/GLTFLoader.js";
import { OrbitControls } from "three/addons/controls/OrbitControls.js";

const PATH = "公開サイトのパス" || "/";

const width = window.innerWidth;
const height = window.innerHeight;

// レンダラー
const renderer = new THREE.WebGLRenderer({
	antialias: true,
});
renderer.setPixelRatio(window.devicePixelRatio || 1);
renderer.setSize(width, height);
renderer.shadowMap.enabled = true;

// シーン
const scene = new THREE.Scene();

// カメラ
const camera = new THREE.PerspectiveCamera(45, width / height, 1, 10000);
camera.position.set(10, 10, 10);
camera.lookAt(scene.position);

// 地面
const planeGeometry = new THREE.PlaneGeometry(10, 10);
const planeMaterial = new THREE.MeshStandardMaterial({ color: 0x213573 });
const plane = new THREE.Mesh(planeGeometry, planeMaterial);
plane.rotation.x = -Math.PI / 2;
plane.receiveShadow = true;
scene.add(plane);

// 平行光源
const directionalLight = new THREE.DirectionalLight(0xffffff);
directionalLight.position.set(1, 1, 1);
scene.add(directionalLight);

// 環境光源
const ambientLight = new THREE.AmbientLight(0xffffff, 1.0);
scene.add(ambientLight);

// スポットライト
const spotLight = new THREE.SpotLight(0xffffff, 24, 12, Math.PI / 4, 10, 0.5);
spotLight.position.set(0, 8, 0);
spotLight.castShadow = true;
spotLight.shadow.mapSize.set(4096, 4096);
scene.add(spotLight);
const spotLightHepler = new THREE.SpotLightHelper(spotLight);
scene.add(spotLightHepler);

// OrbitControls
const orbitController = new OrbitControls(camera, renderer.domElement);
orbitController.minDistance = 0.1;
orbitController.maxDistance = 10000;
orbitController.autoRotateSpeed = 1.0;

// gltfオブジェクト
let gltfObject: GLTF;
let gltfObjectHelper: THREE.BoxHelper;

// gltfファイルの読み込み
const gltfLoader = new GLTFLoader();
gltfLoader.load(`${PATH}/assets/models/model.glb`, (data) => {
	gltfObject = data;

	gltfObject.scene.scale.set(4, 4, 4);
	gltfObject.scene.position.set(0, 2.5, 0);
	scene.add(gltfObject.scene);

	gltfObjectHelper = new THREE.BoxHelper(gltfObject.scene, 0xffff00);
	scene.add(gltfObjectHelper);
});

// DOMに追加
const wrapper = document.querySelector<HTMLDivElement>("#app");
wrapper?.appendChild(renderer.domElement);

// 画面に表示+アニメーション
const ticker = () => {
	requestAnimationFrame(ticker);
	// helperの更新
	spotLightHepler.update();
	if (gltfObjectHelper) gltfObjectHelper.update();
	// orbitControlsの更新
	orbitController.update();
	renderer.render(scene, camera);
};
ticker();

// リサイズ
const resize = () => {
	const width = window.innerWidth;
	const height = window.innerHeight;

	renderer.setPixelRatio(window.devicePixelRatio);
	renderer.setSize(width, height);

	camera.aspect = width / height;
	camera.updateProjectionMatrix();
};

let resizeTimeout: number | null;
window.addEventListener("resize", () => {
	if (resizeTimeout) {
		clearTimeout(resizeTimeout);
	}
	resizeTimeout = window.setTimeout(resize, 200);
});

まとめ

以上、「Nomad Sculptでテクスチャを適用してThree.jsで表示する」でした。
Three.jsにテクスチャを持ってくるのは、けっこう面倒な印象がありましたが、案外スンナリできました。

解説動画や素材を公開してくださる方々に感謝です!

それでは、また!

Discussion