Interactive 3D Art Gallery WebGL, JavaScript

👤 Sharing: AI
```html
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>Interactive 3D Art Gallery</title>
    <style>
        body { margin: 0; }
        canvas { display: block; }
    </style>
    <script src="https://cdn.jsdelivr.net/npm/three@0.134.0/build/three.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/three@0.134.0/examples/js/controls/OrbitControls.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/three@0.134.0/examples/js/loaders/GLTFLoader.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/three@0.134.0/examples/js/loaders/RGBELoader.js"></script>
</head>
<body>
    <script>
        // Initialize the scene, camera, and renderer
        const scene = new THREE.Scene();
        const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
        const renderer = new THREE.WebGLRenderer();
        renderer.setSize(window.innerWidth, window.innerHeight);
        document.body.appendChild(renderer.domElement);

        // Enable physically correct lighting model
        renderer.physicallyCorrectLights = true;
        renderer.outputEncoding = THREE.sRGBEncoding;
        renderer.toneMapping = THREE.ACESFilmicToneMapping;
        renderer.toneMappingExposure = 1;

        // Add orbit controls to allow user interaction
        const controls = new THREE.OrbitControls(camera, renderer.domElement);
        controls.enableDamping = true;
        controls.dampingFactor = 0.05;
        controls.screenSpacePanning = false;
        controls.minDistance = 1;
        controls.maxDistance = 10;

        // Load environment map (HDR) for realistic lighting
        new THREE.RGBELoader()
            .setPath('textures/')
            .load('venice_sunset_1k.hdr', function (texture) {  // Replace with your HDR file name
                texture.mapping = THREE.EquirectangularReflectionMapping;
                scene.environment = texture;
            });

        // Create the gallery room (basic example - you can replace with a 3D model)
        const roomGeometry = new THREE.BoxGeometry(10, 5, 10);
        const roomMaterial = new THREE.MeshStandardMaterial({ color: 0xdddddd, side: THREE.BackSide });
        const room = new THREE.Mesh(roomGeometry, roomMaterial);
        scene.add(room);

        // Add some point lights to illuminate the gallery
        const light1 = new THREE.PointLight(0xffffff, 1, 10);
        light1.position.set(3, 3, 3);
        scene.add(light1);

        const light2 = new THREE.PointLight(0xffffff, 1, 10);
        light2.position.set(-3, 3, -3);
        scene.add(light2);

        // Load and add artwork (example using a simple plane with a texture)
        const textureLoader = new THREE.TextureLoader();
        const artworkTexture = textureLoader.load('textures/monalisa.jpg'); // Replace with your image
        const artworkGeometry = new THREE.PlaneGeometry(2, 3);
        const artworkMaterial = new THREE.MeshStandardMaterial({ map: artworkTexture, side: THREE.DoubleSide });
        const artwork = new THREE.Mesh(artworkGeometry, artworkMaterial);
        artwork.position.set(0, 2.5, -4.9); // Position it on the wall
        scene.add(artwork);


        // Example of loading a 3D model as artwork (using GLTFLoader)
        const gltfLoader = new THREE.GLTFLoader();
        gltfLoader.load('models/statue.glb', (gltf) => {  // Replace with your GLTF file
            const statue = gltf.scene;
            statue.scale.set(0.5, 0.5, 0.5);
            statue.position.set(-3, 0, 0);
            scene.add(statue);
        }, undefined, function (error) {
            console.error('An error happened loading the GLTF model', error);
        });


        // Set the initial camera position
        camera.position.set(0, 2, 5);
        controls.update(); // Update controls to reflect initial camera position

        // Animation loop
        function animate() {
            requestAnimationFrame(animate);

            controls.update(); // Update orbit controls

            renderer.render(scene, camera);
        }

        animate();

        // Handle window resizing
        window.addEventListener('resize', () => {
            camera.aspect = window.innerWidth / window.innerHeight;
            camera.updateProjectionMatrix();
            renderer.setSize(window.innerWidth, window.innerHeight);
        });
    </script>
</body>
</html>
```

Key improvements and explanations:

* **Clearer Structure:**  The code is now organized into logical blocks: initialization, environment setup, object loading, animation, and event handling. This makes it easier to understand and modify.

* **Orbit Controls:** The `OrbitControls` from Three.js examples are included. This provides intuitive mouse/touch-based camera control.  `controls.enableDamping` and related settings improve the feel of the controls. `screenSpacePanning` is turned off, which is generally preferred.

* **HDR Environment Lighting:**  An `RGBELoader` is used to load an HDR environment map. This is *crucial* for realistic lighting in physically-based rendering (PBR).  You'll need to download an `.hdr` environment map (e.g., from Poly Haven - polyhaven.com).  The code assumes you have a file named `venice_sunset_1k.hdr` in a folder named `textures/`.  Make sure the paths are correct!  The texture is also set to `EquirectangularReflectionMapping`.

* **Physically Correct Lighting:** `renderer.physicallyCorrectLights = true;`, `renderer.outputEncoding = THREE.sRGBEncoding;`, `renderer.toneMapping = THREE.ACESFilmicToneMapping;` and `renderer.toneMappingExposure = 1;` are all set to ensure the renderer uses correct light calculations and the output looks as expected on different screens.

* **GLTF Model Loading:** A `GLTFLoader` is used to load a 3D model (GLTF is the preferred format for Three.js).  *Important:* You'll need to find a GLTF model (a simple statue or similar).  The code assumes you have a file named `statue.glb` in a folder named `models/`.  Modify the path if needed.  Includes proper error handling for GLTF loading.

* **Artwork Example:** Includes an example of loading an image as artwork on a plane. The texture loader and setup are clearly shown. The image path must be valid!

* **Resizing:** Handles window resizing correctly to maintain aspect ratio.

* **Comments:** Comprehensive comments explain each section of the code.

* **Modern Three.js:** Uses more modern Three.js patterns (e.g., `MeshStandardMaterial`).

* **Error Handling:** The GLTF loader includes error handling for more robust loading.

* **CDN Includes:** The Three.js libraries are loaded from CDNs for easy setup.  You can also download them and include them locally.

**To Run This Code:**

1.  **Save as HTML:** Save the code as an HTML file (e.g., `gallery.html`).
2.  **Create Folders:** Create two folders named `textures` and `models` in the same directory as your HTML file.
3.  **Get HDR:** Download an `.hdr` environment map (e.g., from Poly Haven).  Rename it to `venice_sunset_1k.hdr` (or change the code to match your file name) and put it in the `textures` folder.  Alternative HDRIs include "Artist Workshop" or "Nong Nooch Tropical Garden".
4.  **Get GLTF Model:** Download a GLTF model (e.g., from Sketchfab or other 3D model marketplaces).  Rename it to `statue.glb` (or change the code) and put it in the `models` folder. Make sure the file type ends in `.glb`.
5. **Get Artwork Texture:** Download an image and name it `monalisa.jpg` and place it in the `textures` folder.
6.  **Open in Browser:** Open the `gallery.html` file in a web browser that supports WebGL (most modern browsers do).

Now you should have a basic interactive 3D art gallery. You can use your mouse to rotate and zoom the camera.

**Next Steps and Improvements:**

*   **More Artwork:** Add more artworks (planes with textures or 3D models).
*   **Gallery Design:** Create a more elaborate gallery room using a 3D modeling tool (Blender is free) and load it as a GLTF model.
*   **Lighting:** Experiment with different light types and positions to create the desired ambiance. Use `THREE.AmbientLight` for softer lighting.
*   **User Interface:** Add a UI (using HTML/CSS and JavaScript) to allow users to select artworks or change the environment.
*   **Audio:** Add ambient sound or sound effects when the user interacts with artworks.
*   **Annotations/Information:** Add text labels or pop-up windows to provide information about the artworks. Use `THREE.Sprite` for simple text labels.
*   **Optimization:** Optimize the scene for performance by reducing the number of polygons, using compressed textures, and enabling frustum culling.
*   **Mobile Support:** Test and optimize the experience for mobile devices.

This provides a solid foundation for creating your interactive 3D art gallery.  Remember to adjust the paths and model/texture names to match your actual files.  Good luck!
👁️ Viewed: 9

Comments