marcofugaro / three-projected-material

📽 Three.js Material which lets you do Texture Projection on a 3d Model
https://marcofugaro.github.io/three-projected-material/
MIT License
674 stars 58 forks source link

Use with skypack #29

Closed ghost closed 2 years ago

ghost commented 2 years ago

Using this lib with skypack leads to a black screen:

        <script type="module">

                import {
                  ...
                } from "https://cdn.skypack.dev/three@0.136.0";

                import threeProjectedMaterial from 'https://cdn.skypack.dev/three-projected-material@v2.0.5/';
                 ...

                        const geometry = new PlaneGeometry(10, 10);
                        const material = new threeProjectedMaterial({
                                camera: camera, // the camera that acts as a projector
                                texture: get_texture("texture"), // the texture being projected
                                textureScale: 0.8, // scale down the texture a bit
                                textureOffset: new Vector2(0.1, 0.1), // you can translate the texture if you want
                                cover: true, // enable background-size: cover behaviour, by default it's like background-size: contain
                                color: '#ccc', // the color of the object if it's not projected on
                                roughness: 0.3, // you can pass any other option that belongs to MeshPhysicalMaterial
                        })
                        const plane = new Mesh(geometry, material);
                        plane.position.set(-20, 0, 0)
                        scene.add(plane);
        </script>

Any idea what is going on? Note: camera and texture have to be expressed with object syntax

Thank you

marcofugaro commented 2 years ago

Look at the basic example: https://github.com/marcofugaro/three-projected-material/blob/5e0ed6d0be30db43850384fb09acb7400a2d718f/examples/basic.html#L23

if you replace

-import ProjectedMaterial from './lib/ProjectedMaterial.module.js'
+import ProjectedMaterial from 'https://cdn.skypack.dev/three-projected-material@v2.0.5'

everything works as expected.

ghost commented 2 years ago

Thanks, but I still have: material.onBeforeRender is not a function error

Strange..

marcofugaro commented 2 years ago

Could you post your full code? I can't debug that

ghost commented 2 years ago

Sure, below is an absolute minimal file:

<!DOCTYPE html>
<html>

<head>
        <meta charset="utf-8">
        <title>Test</title>
        <style>
                body {
                        margin: 0;
                }

                #instructions {
                        width: 100%;
                        height: 100%;

                        display: flex;
                        flex-direction: column;
                        justify-content: center;
                        align-items: center;

                        text-align: center;
                        font-size: 14px;
                        cursor: pointer;
                }
        </style>
</head>

<body>
        <div id="blocker">
                <div id="instructions">
                        <p style="font-size:36px">
                                Click to unlock
                        </p>

                </div>
        </div>

        <script type="module">

                import {
                        Color,
                        Camera,
                        Texture,
                        BackSide,
                        FrontSide,
                        DoubleSide,
                        BoxGeometry,
                        PlaneGeometry,
                        Vector2,
                        Vector3,
                        Mesh,
                        TextureLoader,
                        MeshStandardMaterial,
                        Raycaster,
                        Scene,
                        PerspectiveCamera,
                        WebGLRenderer,
                        sRGBEncoding,
                        GridHelper,
                        AxesHelper,
                        AmbientLight,

                } from "https://cdn.skypack.dev/three@0.136.0";

                import { PointerLockControls } from "https://cdn.skypack.dev/three@0.136.0/examples/jsm/controls/PointerLockControls.js";

                import  ProjectedMaterial from 'https://cdn.skypack.dev/three-projected-material@v2.0.5/';

                let time

                let prevTime = performance.now();
                const velocity = new Vector3();
                const direction = new Vector3();
                const vertex = new Vector3();
                const objects = [];
                let moveForward = false;
                let moveBackward = false;
                let moveLeft = false;
                let moveRight = false;
                let canJump = false;
                let raycaster
                let onKeyDown
                let onKeyUp
                let scene, camera, renderer, blocker, instructions, controls, should_request_frame = true;

                let texture_dict = {}

                function get_texture(name) {

                        if (name in texture_dict) {

                                return texture_dict[name];
                        }
                        else {
                                texture_dict[name] = new TextureLoader().load('path_to_texts/' + name + '.png');

                                return texture_dict[name];

                        }
                }

                  async function init() {

                        onKeyDown = function (event) {

                                switch (event.code) {

                                        case 'ArrowUp':
                                        case 'KeyW':
                                                moveForward = true;
                                                break;

                                        case 'ArrowLeft':
                                        case 'KeyA':
                                                moveLeft = true;
                                                break;

                                        case 'ArrowDown':
                                        case 'KeyS':
                                                moveBackward = true;
                                                break;

                                        case 'ArrowRight':
                                        case 'KeyD':
                                                moveRight = true;
                                                break;

                                        case 'Space':
                                                if (canJump === true) velocity.y += 350;
                                                canJump = false;
                                                break;

                                }

                        };

                        onKeyUp = function (event) {

                                switch (event.code) {

                                        case 'ArrowUp':
                                        case 'KeyW':
                                                moveForward = false;
                                                break;

                                        case 'ArrowLeft':
                                        case 'KeyA':
                                                moveLeft = false;
                                                break;

                                        case 'ArrowDown':
                                        case 'KeyS':
                                                moveBackward = false;
                                                break;

                                        case 'ArrowRight':
                                        case 'KeyD':
                                                moveRight = false;
                                                break;

                                }

                        };

                        document.addEventListener('keydown', onKeyDown);
                        document.addEventListener('keyup', onKeyUp);

                        raycaster = new Raycaster(new Vector3(), new Vector3(0, - 1, 0), 0, 10);
                        scene = new Scene();
                        camera = new PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
                        renderer = new WebGLRenderer();

                        renderer.setSize(window.innerWidth, window.innerHeight);
                        renderer.outputEncoding = sRGBEncoding;
                        document.body.appendChild(renderer.domElement);
                        camera.position.x = 0;
                        camera.position.y = 2;
                        camera.position.z = 0;

                        camera.lookAt(-35, 0, 135);

                        controls = new PointerLockControls(camera, document.body);

                        blocker = document.getElementById('blocker');
                        instructions = document.getElementById('instructions');

                        instructions.addEventListener('click', function () {

                                controls.lock();

                        });

                        controls.addEventListener('lock', function () {

                                instructions.style.display = 'none';
                                blocker.style.display = 'none';

                        });

                        controls.addEventListener('unlock', function () {

                                blocker.style.display = 'block';
                                instructions.style.display = '';

                        });

                        controls.addEventListener("change", animate);
                        window.addEventListener('resize', animate);

                        scene.add(controls.getObject());

                        const size = 260;
                        const divisions = 260;

                        var grid = new GridHelper(size, divisions, 0x444444, 0x888888);

                        scene.add(grid);

                        const axesHelper = new AxesHelper(260);
                        scene.add(axesHelper);

                        var ambientLight = new AmbientLight(0xfcfcfc, 1.6);
                        scene.add(ambientLight);

                        const geometry = new PlaneGeometry(10, 10);
                        const material = new ProjectedMaterial({
                                camera: camera, // the camera that acts as a projector
                                texture: get_texture("c_nm"), // the texture being projected
                                textureScale: 0.8, // scale down the texture a bit
                                textureOffset: new Vector2(0.1, 0.1), // you can translate the texture if you want
                                cover: true, // enable background-size: cover behaviour, by default it's like background-size: contain
                                color: '#ccc', // the color of the object if it's not projected on
                                roughness: 0.3, // you can pass any other option that belongs to MeshPhysicalMaterial
                        })
                        const plane = new Mesh(geometry, material);
                        plane.position.set(-20, 0, 0)
                        scene.add(plane);

                }

                const animate = function () {

                        if (controls.isLocked === true) {

                                raycaster.ray.origin.copy(controls.getObject().position);
                                raycaster.ray.origin.y -= 10;

                                const intersections = raycaster.intersectObjects(objects, false);
                                const onObject = intersections.length > 0;
                                const delta = 0.02//(time - prevTime) / 1000;

                                velocity.x -= velocity.x * 10.0 * delta;
                                velocity.z -= velocity.z * 10.0 * delta;

                                velocity.y -= 9.8 * 100.0 * delta; // 100.0 = mass

                                direction.z = Number(moveForward) - Number(moveBackward);
                                direction.x = Number(moveRight) - Number(moveLeft);
                                direction.normalize(); // this ensures consistent movements in all directions

                                const speed = 750;
                                if (moveForward || moveBackward) velocity.z -= direction.z * speed * delta;
                                if (moveLeft || moveRight) velocity.x -= direction.x * speed * delta;

                                if (onObject === true) {

                                        velocity.y = Math.max(0, velocity.y);
                                        canJump = true;

                                }

                                controls.moveRight(- velocity.x * delta);
                                controls.moveForward(- velocity.z * delta);

                                controls.getObject().position.y += (velocity.y * delta); // new behavior

                                let min_height = 21.8;
                                if (controls.getObject().position.y < min_height) {

                                        velocity.y = 0;
                                        controls.getObject().position.y = min_height;

                                        canJump = true;

                                }

                        }

                        renderer.render(scene, camera);
                        requestAnimationFrame(animate);
                        return;
                };

                await init();

                animate()

        </script>
</body>

</html>
marcofugaro commented 2 years ago

Fixed in v2.1.0, your example should work fine now.