LoginSignup
8
8

More than 5 years have passed since last update.

環境マッピング

Last updated at Posted at 2016-09-07

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);

参考
初めてのThree.js 第2版――WebGLのためのJavaScript 3Dライブラリ

8
8
1

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
8
8