马黑黑 发表于 2025-6-3 12:19

ThreeJS加载外部模型并播放模型动画演示

本帖最后由 马黑黑 于 2025-6-3 12:21 编辑 <br /><br /><style>
        .artBox { font-size: 18px; }
        .artBox > p { margin: 10px 0; line-height: 30px; }
        .artBox mark { background: lightblue; padding: 4px 8px; }
        #prevBox { position: fixed; top: 0; right: 0; bottom: 0; left: 0; background: beige; display: none; padding: 0; overflow: hidden; z-index: 1000; margin: 0; }
        #prevBox::after { position: absolute; content: '关闭预览'; bottom: 10px; left: calc(50% - 40px); padding: 0 4px; width: 80px; height: 30px; line-height: 30px; text-align: center; border: 1px solid #efe; border-radius: 6px; background: #eee; font-size: 14px; box-shadow: 2px 2px 6px rgba(0,0,0,.25); cursor: pointer; }
        iframe { position: relative; width: 100%; height: 100%; border: none; outline: none; box-sizing: border-box; margin: 0; }
</style>

<div id="prevBox"></div>
<div class="artBox">
        <div id="hEdiv"><pre id="hEpre">
&lt;div style="margin: 8px auto; position: absolute; color: #eee;"&gt;
        &lt;button id="btnPlay" value="btn"&gt;暂停/继续动画&lt;/button&gt;&lt;span&gt; (提示:动画可手动翻转)&lt;/span&gt;
&lt;/div&gt;

&lt;script type="importmap"&gt;
        {
                "imports": {
                        "three": "https://unpkg.ihwx.cn/three@0.176.0/build/three.module.js",
                        "three/addons/": "https://unpkg.ihwx.cn/three@0.176.0/examples/jsm/"
                }
}
&lt;/script&gt;

&lt;script type="module"&gt;
    import * as THREE from "three"; // 主模块
    import { OrbitControls } from "three/addons/controls/OrbitControls.js"; // 相机轨道控制器
    import { GLTFLoader } from "three/addons/loaders/GLTFLoader.js"; // GLTF模型加载器

        const scene = new THREE.Scene(); // 场景
        const clock = new THREE.Clock(); // 时钟
        const camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 1, 1000); // 相机
        camera.position.set(5, 0, 10); // 相机位置
        const renderer = new THREE.WebGLRenderer({ antialias: true }); // 渲染器
        renderer.setSize(window.innerWidth, window.innerHeight); // 渲染范围
        //renderer.outputEncoding = THREE.sRGBEncoding; // 保真(可选)
        const controls = new OrbitControls(camera, renderer.domElement); // 加载相机轨道控制器
        document.body.appendChild(renderer.domElement); // 渲染器元素加载到文档

        scene.add(new THREE.AmbientLight(0xcccccc), new THREE.PointLight(0xffffff, 100)); // 场景加载环境光和点光源

        let mixer; // 动画混合气变量

        // 加载 .gbl 模型
        new GLTFLoader().load('https://638183.freep.cn/638183/web/3models/Parrot.glb', function (gltf) {
                const model = gltf.scene; // 模型节点
                const scale = 0.05; // 模型缩放系数
                model.scale.set(scale, scale, scale); // 模型缩放
                scene.add(model); // 模型节点加入到场景
                mixer = new THREE.AnimationMixer(model); // 动画混合气变量赋值
                // 若模型有动画则运行之
                if (gltf.animations.length &gt; 0) {
                        const clip = mixer.clipAction(gltf.animations);
                        clip.play();
                }
                animate(); // 运行动画函数
        });

        // 窗口自适应
        window.onresize = () =&gt; {
                camera.aspect = window.innerWidth / window.innerHeight;
                camera.updateProjectionMatrix();
                renderer.setSize(window.innerWidth, window.innerHeight);
        }

        // 动画函数
        function animate() {
                requestAnimationFrame(animate);
                const delta = clock.getDelta(); // 动画频率
                mixer.update(delta); // 更新动画数据
                renderer.render(scene, camera);
        }

        btnPlay.onclick = () =&gt; clock.running ? clock.stop() : clock.start(); // 动画交互
&lt;/script&gt;
        </pre></div>
        <blockquote><button id="btnPrev">运行代码</button></blockquote>
</div>

<script type="module">
        import hlight from 'https://638183.freep.cn/638183/web/helight/helight1.js';
        hlight.hl(hEdiv, hEpre);
       
        const preView = (htmlCode, targetBox) => {
                if (targetBox.innerHTML) return;
                const iframe = document.createElement('iframe');
                htmlCode = htmlCode + '<style>body {margin: 0; }</style>';
                iframe.srcdoc = htmlCode;
                targetBox.appendChild(iframe);
                targetBox.style.display = 'block';
                targetBox.onclick = () => {
                        targetBox.innerHTML = '';
                        targetBox.style.display = 'none';
                }
        };

        const value = hEpre.textContent;
        btnPrev.onclick = () => preView(value, prevBox);
</script>

红影 发表于 2025-6-3 14:23

.gbl 模型,这个好像是第一次看到,这个模型就是展示里的那只鹦鹉么?

红影 发表于 2025-6-3 14:26

let mixer; // 动画混合气变量
这个好像也挺陌生的{:4_173:}

花飞飞 发表于 2025-6-3 14:27

glb模型最早的时候有见过,不过呢还可以有这么复杂式样到是没有想到。。
0.176.0这个JS加载也是头一回见,看来这个外部加载还是与众不同的
{:4_199:}

红影 发表于 2025-6-3 14:28

环境光和点光源的运用很奇妙,让鹦鹉的翅膀等地方好像映衬得出现了明暗变化{:4_204:}

花飞飞 发表于 2025-6-3 14:32

模型缩放系数设为0.05,决定模型大小。
如果设为1的话,大的看不到全貌了,跟鲲鹏一样。。这是为了大银幕设置的大小吧。

花飞飞 发表于 2025-6-3 14:39

这个点光源效果很奇妙,
无论把小鸟翻到什么角度,高光部分只是翅膀下方和翅膀背上靠身体那节存在。。。。
就跟那里装了个小灯似的。。{:4_173:}
闪亮闪亮的看着相当特别。。
点光源是第一次出现吧,以前没见过这种效果。

花飞飞 发表于 2025-6-3 14:42

期待更多的3D模型展示{:4_173:}应该有更多更漂亮的效果吧

梦江南 发表于 2025-6-3 15:03

一只漂亮在飞的鹦鹉,是用代码做出来的。厉害!

马黑黑 发表于 2025-6-3 18:01

梦江南 发表于 2025-6-3 15:03
一只漂亮在飞的鹦鹉,是用代码做出来的。厉害!

这个有3d模型资源

马黑黑 发表于 2025-6-3 18:09

红影 发表于 2025-6-3 14:23
.gbl 模型,这个好像是第一次看到,这个模型就是展示里的那只鹦鹉么?

万马奔腾就用过的

马黑黑 发表于 2025-6-3 18:12

花飞飞 发表于 2025-6-3 14:42
期待更多的3D模型展示应该有更多更漂亮的效果吧
3D模型需要有人制作,并且,得有较大的上传空间。我随随便便画条鱼就两三兆,画个小姑凉就20多兆,画个大菇凉就100多兆

顺便问一下,ps应该支持绘制3d图形吧?

win10有 3d查看器,还有3d画图(不过该画图已经在微软商店下架,win10自带,win11木有了)

马黑黑 发表于 2025-6-3 18:13

花飞飞 发表于 2025-6-3 14:39
这个点光源效果很奇妙,
无论把小鸟翻到什么角度,高光部分只是翅膀下方和翅膀背上靠身体那节存在。。。。 ...

光源原理差不多,不同光源效果不同

马黑黑 发表于 2025-6-3 18:14

花飞飞 发表于 2025-6-3 14:32
模型缩放系数设为0.05,决定模型大小。
如果设为1的话,大的看不到全貌了,跟鲲鹏一样。。这是为了大银幕 ...

3d的制作单位没有单位,看各人怎么弄。用的时候得查看一下效果,或用代码检测一下尺寸

马黑黑 发表于 2025-6-3 18:15

红影 发表于 2025-6-3 14:28
环境光和点光源的运用很奇妙,让鹦鹉的翅膀等地方好像映衬得出现了明暗变化

很漂亮吧?还可以弄成自发光的,就是相对复杂、抽象

马黑黑 发表于 2025-6-3 18:17

花飞飞 发表于 2025-6-3 14:27
glb模型最早的时候有见过,不过呢还可以有这么复杂式样到是没有想到。。
0.176.0这个JS加载也是头一回见, ...

3d 的制作可以是静态的,可以是带动画的,还可以有场景、骨架(几何形)、材质、相机、纹理、动画等等等等。
ThreeJS带版本号只是为了更牢靠,就固定使用指定版本。不带版本号的话,可能涉及到兼容性问题但也不一定

马黑黑 发表于 2025-6-3 18:19

红影 发表于 2025-6-3 14:26
let mixer; // 动画混合气变量
这个好像也挺陌生的

动画混合器,打错字了

这个变量的作用是拿到动画合成句柄,为动画函数提供操作依据。

杨帆 发表于 2025-6-3 19:21

好漂亮,谢谢马老师经典分享{:4_191:}

花飞飞 发表于 2025-6-3 20:22

马黑黑 发表于 2025-6-3 18:12
3D模型需要有人制作,并且,得有较大的上传空间。我随随便便画条鱼就两三兆,画个小姑凉就20多兆,画个大 ...

PS有3D图形,偶尔点进去过,但没用过。现在平面的都还没学会
不过应该有3D软件吧,PS这个只是顺带。
我用的温10,但画图没用过3D画图{:4_173:}

花飞飞 发表于 2025-6-3 20:23

马黑黑 发表于 2025-6-3 18:13
光源原理差不多,不同光源效果不同

这个差得有点多。。正常翅膀下方有,腹部也有,结果腹部并没有高亮。。就觉得是翅膀自己带个小灯吧{:4_170:}
页: [1] 2 3 4 5 6
查看完整版本: ThreeJS加载外部模型并播放模型动画演示