THREE.js 環境マップ

by manthrax

HTML

<script type="importmap">
            {
            "imports": {
              "three": "https://threejs.org/build/three.module.js",
              "three/addons/": "https://threejs.org/examples/jsm/"
            }
        }
        </script>

CSS

html,
body,
canvas {
  margin: 0;
  padding: 0;
  width: 100%;
  height: 100%;
  display: block;
  background: white;
}

JavaScript

import * as THREE from 'three'
import { OrbitControls } from 'three/addons/controls/OrbitControls.js'
import { RGBELoader } from 'three/addons/loaders/RGBELoader.js'

async function init() {
    // WebGL renderer
    const renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });
    //renderer.toneMapping = THREE.ACESFilmicToneMapping;
    //renderer.outputEncoding = THREE.sRGBEncoding;
    renderer.setSize(window.innerWidth, window.innerHeight);
    document.body.appendChild(renderer.domElement);

    // Scene, Camera
    const scene = new THREE.Scene();

    const hdrUrl = 'https://dl.polyhaven.org/file/ph-assets/HDRIs/hdr/1k/abandoned_greenhouse_1k.hdr';

	const envMap = await (new RGBELoader()).loadAsync(hdrUrl);
   envMap.mapping = THREE.EquirectangularReflectionMapping;
/*
	 const texture = await new RGBELoader().loadAsync(hdrUrl);
     const gen = new THREE.PMREMGenerator(renderer);
     const envMap = gen.fromEquirectangular(texture).texture;
     texture.dispose();
     gen.dispose();*/
   // scene.environment = envMap;
    //scene.background = envMap;

let cubeTarget = new THREE.WebGLCubeRenderTarget(256);
cubeTarget.fromEquirectangularTexture(renderer,envMap);

    const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight,  0.1, 1000);
    camera.position.set(0, 0, 3);

    // OrbitControls
    const controls = new OrbitControls(camera, renderer.domElement);

	// Shaders
    const vertexShader = `
		out vec3 vReflect;

		void main() {
    		vec4 worldPosition = modelMatrix * vec4(position, 1.0);
    		vec3 worldNormal = normalize(mat3(modelMatrix) * normal);
    		vec3 incident = normalize(worldPosition.xyz - cameraPosition);
    		vReflect = reflect(incident, worldNormal);
    		gl_Position = projectionMatrix * viewMatrix * vec4(position, 1.0);
		}
	`;
	const fragmentShader = `
		uniform samplerCube envMapF;

		in vec3 vReflect;
		out vec4 color;

		void main() {
        	// color = vec4(vReflect, 1.0);
   ...