r78
デモ:https://mo49.github.io/qiita/20160908/envmap.html
skyboxをつくって、その中にオブジェクトを2つ配置。
sphereは他のオブジェクトも反射する動的環境マッピングをやってみる。
CubeMapオブジェクトをつくる
まず、サイコロの展開図みたいな6面の画像を用意する
CubeMap用の画像を配布しているサイト
http://www.humus.name/index.php?page=Textures
360度画像をCubeMap用に変換してくれるサイト
http://gonchar.me/panorama/
THETAの画像をCubeMap用に変換してくれるサイト
https://sites.google.com/site/ge56web/software/p2cc
画像をロードする
// cube texturesをロードする
createCubeMap (geom, imageFile) {
const PATH = './img/envmap/';
const FORMAT = '.jpg';
const URLS = [
PATH + 'posx' + FORMAT, PATH + 'negx' + FORMAT,
PATH + 'posy' + FORMAT, PATH + 'negy' + FORMAT,
PATH + 'posz' + FORMAT, PATH + 'negz' + FORMAT
];
const cubeTextureLoader = new THREE.CubeTextureLoader();
const textureCube = cubeTextureLoader.load(URLS);
return textureCube;
}
skyboxをつくる
shaderにCubeMapオブジェクトを渡す
skyboxをつくる
this.textureCube = this.createCubeMap();
this.textureCube.format = THREE.RGBFormat;
this.textureCube.mapping = THREE.CubeReflectionMapping; // 屈折
// CubeMapに基づいて環境を作成できる特殊なshader
const shader = THREE.ShaderLib["cube"];
shader.uniforms["tCube"].value = this.textureCube;
const material = new THREE.ShaderMaterial({
fragmentShader: shader.fragmentShader,
vertexShader: shader.vertexShader,
uniforms: shader.uniforms,
depthWrite: false,
side: THREE.DoubleSide
});
const skybox = new THREE.Mesh(new THREE.BoxGeometry(10000, 10000, 10000), material);
this.scene.add(skybox);
CubeCameraを使う
動的な環境マッピングには必須なcamera
カメラを用意
this.cubeCamera = new THREE.CubeCamera(0.1, 20000, 256);
this.scene.add(this.cubeCamera);
毎フレームごとに更新することも忘れずに。
カメラを更新する
render() {
・・・(中略)・・・
// 一度sphereを消してCubeMapを更新してから表示する
this.sphere.visible = false;
this.cubeCamera.updateCubeMap(this.renderer, this.scene);
this.sphere.visible = true;
}
Sphere, TorusKnotを追加
envMapにどのように環境を反射するか記述
sphere -> 動的環境マッピング
torusknot -> 静的環境マッピング
オブジェクトを追加
const sphereGeometry = new THREE.SphereGeometry(20, 15, 15);
const torusGeometry = new THREE.TorusKnotGeometry(60, 2, 256, 8, 4, 3, 1);
const torusGeometry2 = new THREE.TorusKnotGeometry(150, 2, 512, 8, 6, 4, 1);
const dynamicEnvMaterial = new THREE.MeshBasicMaterial({
envMap: this.cubeCamera.renderTarget, // cubeCameraを設定、シーン内の他のオブジェクトも反射
side: THREE.DoubleSide
});
const envMaterial = new THREE.MeshBasicMaterial({
envMap: this.textureCube, // 作成したcubeMapオブジェクトを設定することで、meshはその環境を反射
side: THREE.DoubleSide
});
this.sphere = new THREE.Mesh(sphereGeometry, dynamicEnvMaterial);
this.scene.add(this.sphere);
const torus = new THREE.Mesh(torusGeometry, envMaterial);
const torus2 = new THREE.Mesh(torusGeometry2, envMaterial);
torus.material.reflectivity = 1.0; // 反射率 (同じマテリアルを適応しているのでtorus2も影響を受けるのに注意)
this.scene.add(torus, torus2);