1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【メモ】Three.jsでObjectのTextureを切り替える

Last updated at Posted at 2020-11-04

きっかけ

WebXRの仕事でTexture切り替えをすることになった。
大層なものは作っていないが、動くものをメモで残しておきたい。
本番はVue.jsでやるものの、まずはJavaScriptでやる方法から残しておく。
Vue.js版も投稿しました

やりたいこと

CubeのTextureを

circle.png
から
gori128.png
に切り替える

ソースコード

まずはCubeを表示させて、Textureを張る。
SelectBoxでTextureのイメージを切り替える。

changeTexture.html
<!DOCTYPE html>
<html>

<head>
	<meta charset=utf-8>
	<title>change texture</title>
	<select onchange="onChange(this.value)">
		<option value="circle.png">Circle</option>
		<option value="gori128.png">Gori</option>
	</select>
</head>

<body>
	<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/85/three.min.js"></script>
	<script>
		// scene
		const scene = new THREE.Scene();

		// renderer
		const renderer = new THREE.WebGLRenderer({ alpha: true, antialias: true }); // force background transparent
		renderer.setSize(window.innerWidth, window.innerHeight);
		document.body.appendChild(renderer.domElement);

		// camera
		const camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 1, 1000);
		camera.position.set(0, 0, 10);

		// light
		const light = new THREE.AmbientLight(0xffffff);
		scene.add(light);

		// cube
		const cubeGeometry = new THREE.BoxGeometry(1, 1, 1);
		const cubeMaterial = new THREE.MeshBasicMaterial({
			map: new THREE.TextureLoader().load("circle.png")
		});
		const cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
		cube.name = "cube" // need name to find object afterwards

		scene.add(cube);
		render();

		function render() {
			cube.rotation.x += 0.1;
			cube.rotation.y += 0.1;
			requestAnimationFrame(render);
			renderer.render(scene, camera);
		}

		function onChange(val) {
			const object = scene.getObjectByName("cube"); // find obj by name
			object.material.map = new THREE.TextureLoader().load(val);
			object.material.needsUpdate = true; // necessary
		}
	</script>
</body>

</html>

プロジェクトの起動

http-serverを使う。
Three.jsのテクスチャ関連は、Http起動してあげないと読み込まない。

$npm install --global http-server
$http-server . -p 8000

ブラウザにアクセス

結果

  1. ○が表示される
    image.png

  2. テクスチャ切り替え
    image.png

  3. Goriちゃんに切り替わった
    image.png

メモ

Cubeオブジェクトに名前を付けておいて、後からCubeを検索してMaterialを更新する。
needsUpdate = true; がないと、Materialは更新されない。

テクスチャの貼り方はググると色々やり方がありそうなものの、thee.js公式ホームページによると、THREE.TextureLoaderが一番一般的なやり方のよう。
Cubeの6面に違うイメージを張る場合にはTHREE.CubeTextureLoaderが良い。
SkyBoxみたいなのに役立つ。↓昔作ったSkyBoxのメモ。いつかまたキレイにしたい。

skybox.js
class Skybox {
    constructor(urls) {
        var texCube = new THREE.CubeTextureLoader().load(urls);
        texCube.format = THREE.RGBFormat;
        texCube.mapping = THREE.CubeReflectionMapping;

        // skybox用のマテリアルを生成
        var cubeShader = THREE.ShaderLib["cube"];
        var cubeMat = new THREE.ShaderMaterial({
            fragmentShader: cubeShader.fragmentShader,
            vertexShader: cubeShader.vertexShader,
            uniforms: cubeShader.uniforms,
            depthWrite: false,
            side: THREE.BackSide,
        });

        cubeMat.uniforms["tCube"].value = texCube;

        // Skybox用ジオメトリ生成
        var d = 10000;
        var cubeGeo = new THREE.BoxGeometry(d, d, d);
        this.cubeMesh = new THREE.Mesh(cubeGeo, cubeMat);
        return this.cubeMesh
    }
}
1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?