使用three.js实现引用obj文件模型,并添加事件进行边框高亮显示

使用前请先到three.JS官网下载所需文件,如在使用引用的文件时,控制台报以下错误:Uncaught TypeError: Failed to resolve module specifier "three.js". Relative references must start with either "/", "./", or "../".

需要到引用的文件中第一句 import...from three 这里,将three修改为../../../build/three.module.js(找到自己文件路径下的three.module.js)

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Three.js引用obj文件与mtl材质,并为模型添加点击事件的呼吸灯效果</title>
</head>


<body>
</body>

<script type="module">

    draw();
    import * as THREE from './file/three.js-master/build/three.module.js'
    import { OrbitControls } from './file/three.js-master/examples/jsm/controls/OrbitControls.js'
    import { OBJLoader } from './file/three.js-master/examples/jsm/loaders/OBJLoader.js'
    import { MTLLoader } from './file/three.js-master/examples/jsm/loaders/MTLLoader.js'
    import { EffectComposer } from './file/three.js-master/examples/jsm/postprocessing/EffectComposer.js'
    import { RenderPass } from './file/three.js-master/examples/jsm/postprocessing/RenderPass.js'
    import { OutlinePass } from './file/three.js-master/examples/jsm/postprocessing/OutlinePass.js'
    import { ShaderPass } from './file/three.js-master/examples/jsm/postprocessing/ShaderPass.js'
    import { FXAAShader } from './file/three.js-master/examples/jsm/shaders/FXAAShader.js'
    import { GammaCorrectionShader } from './file/three.js-master/examples/jsm/shaders/GammaCorrectionShader.js';
    var renderer;
    var container, stats;
    var camera, scene, renderer, controls, light;
    var composer, effectFXAA, outlinePass;
    let selectedObjects = [];
    const raycaster = new THREE.Raycaster();
    const mouse = new THREE.Vector2();
    const obj3d = new THREE.Object3D();
    const group = new THREE.Group();

    function init() {
        container = document.createElement('div');
        document.body.appendChild(container);
        const width = window.innerWidth;
        const height = window.innerHeight;
        scene = new THREE.Scene();
        renderer = new THREE.WebGLRenderer();
        renderer.shadowMap.enabled = true;
        renderer.setClearColor(0x000000);
        renderer.setSize(width, height);
        document.body.appendChild(renderer.domElement);
        scene = new THREE.Scene();
        scene.add(new THREE.AmbientLight(0xffffff));
        light = new THREE.PointLight
            (0xffffff);
        light.position.set(0, 10, 0);
        //告诉平行光需要开启阴影投射
        light.castShadow = false;
        scene.add(light);
        camera = new THREE.PerspectiveCamera(90, window.innerWidth / window.innerHeight, 0.1, 100, 1);
        camera.position.set(-20, 20, 20); //设置相机位置
        camera.lookAt(scene.position); //设置相机方向(一般都是指向的场景对象(中心))
        //辅助工具
        var helper = new THREE.AxesHelper(0);
        scene.add(helper);
        var mtlLoader = new MTLLoader();
        //加载mtl文件
        mtlLoader.load('./obj/ces.mtl', function (material) {
            var objLoader = new OBJLoader();
            //设置当前加载的纹理
            objLoader.setMaterials(material);
            // objLoader.setPath('/lib/assets/models/');
            objLoader.load('./obj/ces.obj', function (object) {
                //将模型缩放并添加到场景当中
                object.scale.set(5, 5, 5);
                scene.add(object);
            })
        });
        // 可加可不加
        // scene.add(group);
        // group.add(obj3d);  
        composer = new EffectComposer(renderer);
        const renderPass = new RenderPass(scene, camera);
        composer.addPass(renderPass);
        outlinePass = new OutlinePass(new THREE.Vector2(window.innerWidth, window.innerHeight), scene, camera);
        composer.addPass(outlinePass);
        outlinePass.visibleEdgeColor.set(0x0000ff);
        //高亮发光描边厚度
        outlinePass.edgeThickness = 1;
        //高亮描边发光强度
        outlinePass.edgeStrength = 10;
        //模型闪烁频率控制,默认0不闪烁
        outlinePass.pulsePeriod = 1;
        effectFXAA = new ShaderPass(FXAAShader);
        effectFXAA.uniforms['resolution'].value.set(1 / window.innerWidth, 1 / window.innerHeight);
        // 解决使用outlinePass产生色差问题
        const effectColorSpaceConversion = new ShaderPass(GammaCorrectionShader);
        composer.addPass(effectColorSpaceConversion);
        composer.addPass(effectFXAA);
        renderer.domElement.style.touchAction = 'none';
        // renderer.domElement.addEventListener('pointermove', onPointerMove);   鼠标悬浮
        renderer.domElement.addEventListener('click', onPointerMove);  //鼠标点击

        function onPointerMove(event) {
            // if (event.isPrimary === false) return;  如果是点击事件 注释这句话
            mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
            mouse.y = - (event.clientY / window.innerHeight) * 2 + 1;
            checkIntersection();
        }

        function addSelectedObject(object) {
            selectedObjects = [];
            selectedObjects.push(object);
        }

        function checkIntersection() {
            raycaster.setFromCamera(mouse, camera);
            const intersects = raycaster.intersectObject(scene, true);
            if (intersects.length > 0) {
                const selectedObject = intersects[0].object;
                addSelectedObject(selectedObject);
                outlinePass.selectedObjects = selectedObjects;
            } else {
                outlinePass.selectedObjects = [];
            }
        }
    }

    //用户交互插件 鼠标左键按住旋转,右键按住平移,滚轮缩放
    var controls;

    function initControls() {
        controls = new OrbitControls(camera, renderer.domElement);
        // 如果使用animate方法时,将此函数删除
        //controls.addEventListener( 'change', render );
        // 使动画循环使用时阻尼或自转 意思是否有惯性
        controls.enableDamping = true;
        //动态阻尼系数 就是鼠标拖拽旋转灵敏度
        //controls.dampingFactor = 0.25;
        //是否可以缩放
        controls.enableZoom = true;
        //是否自动旋转
        controls.autoRotate = false;
        //设置相机距离原点的最远距离
        controls.minDistance = 1;
        //设置相机距离原点的最远距离
        controls.maxDistance = 200;
        //是否开启右键拖拽
        controls.enablePan = true;
    }

    function render() {
        renderer.render(scene, camera);
    }

    //窗口变动触发的函数
    function onWindowResize() {

        camera.aspect = window.innerWidth / window.innerHeight;
        camera.updateProjectionMatrix();
        render();
        renderer.setSize(window.innerWidth, window.innerHeight);

    }

    function animate() {
        requestAnimationFrame(animate);
        const timer = performance.now();
        composer.render();
    }


    function draw() {
        init()
        animate();
        initControls();
        window.onresize = onWindowResize;
    }
</script>


</html>

  • 18
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,以下是一个基于three.js的示例代码,用于导入obj文件进行纹理映射: ```javascript // 创建场景和摄像机 const scene = new THREE.Scene(); const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000); camera.position.z = 5; // 创建渲染器并将其添加到DOM中 const renderer = new THREE.WebGLRenderer(); renderer.setSize(window.innerWidth, window.innerHeight); document.body.appendChild(renderer.domElement); // 创建光源并将其添加到场景中 const light = new THREE.DirectionalLight(0xffffff, 1); light.position.set(1, 1, 1).normalize(); scene.add(light); // 创建物体 let objLoader = new THREE.OBJLoader(); let textureLoader = new THREE.TextureLoader(); textureLoader.load('texture.jpg', (texture) => { objLoader.load('model.obj', (object) => { object.traverse((child) => { if (child instanceof THREE.Mesh) { child.material.map = texture; } }); scene.add(object); }); }); // 渲染循环 function animate() { requestAnimationFrame(animate); renderer.render(scene, camera); } animate(); ``` 在这个示例代码中,我们创建了场景、摄像机和渲染器,并将渲染器添加到页面中。我们还创建了一个光源,用于照场景中的物体。接着,我们使用THREE.OBJLoader和THREE.TextureLoader来加载obj文件和纹理图片。在加载完成后,我们将纹理映射到物体上,并将物体添加到场景中。最后,我们启动了一个渲染循环,用于不断更新场景和摄像机的状态,并进行渲染。 请注意,这只是一个示例代码,具体实现可能会因为实际应用环境和需求的不同而有所变化。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值