感谢你的问题。我没有看到你的代码,所以不能明确判断出是程序的问题。但我可以给你一些思路。
首先,不管是webgl还是threejs如果想实现gif图动态变化,核心一点就是需要实时读取gif图每一帧的数据,因为gif本身是自带动画的。如果你直接将gif作为纹理贴图直接贴到模型上他是不能实现动态变化的。
其次,如果你要实现gif的自动播放效果,你需要将gif每一帧的图片数据解析出来,然后再去实时传到threejs纹理上面就可以。一般常用gif图片解析库有,omggif和giflib,这两个库都可以实现每一帧率的解析,接下来我们以omggif为例子吧,具体看看代码如何操作。
1、加载gif图片并解析帧数据
let gif = './aaa.gif'; //你的地址
fetch(gif )
.then((res1) => res1.arrayBuffer())
.then((res2) => {
let gifarr = new Uint8Array(res2);
let gifparse = OMGIF.parseGIF(gifarr );
let frames = gifparse .frames.map((frame) => frame.canvas);
});
2、将帧数据转换为threejs纹理。
在threejs中,可以使用THREE.TextureLoader或THREE.CanvasTexture来加载纹理,THREE.CanvasTexture与基本纹理类几乎相同,只是它将needsUpdate设置为立即。这非常符合gif的特点。
let texture = new THREE.CanvasTexture(frame);
3、将解析出来的数据创建放到threejs纹理对象即可。webgl的话就是imagetexture2D那一大块api哈。
let material = new THREE.MeshBasicMaterial({ map: texture });
4、下面就是将纹理赋值到几何上面了,代码很常见
let geometry = new THREE.PlaneGeometry(100, 100);
let mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);
5、后面是很关键的了,就是实时更新纹理,说白了就是更新解析出来的gif帧数据
function render() {
requestAnimationFrame(render);
mesh.material.map.needsUpdate = true;
renderer.render(scene, camera);
}
render();
上面就是大致的思路,因为表达能力有限,希望可以抛引玉。
threejs有个库 three-gif-texture
https://blog.csdn.net/printf_hello/article/details/129640355?spm=1001.2014.3001.5501
再详细补充下原生webgl如何去搞gif哈。
其实上面已经解释了大部分webgl和threejs中去解决gif去动态表达的方法。
步骤1是完全一样的,不管是webgl还是threejs,这个大家如果看一下我推荐的omggif就会明白。
步骤2其实就是纹理创建的过程,threejs已经封装好了,webgl还需要自己调用api去组织。
步骤3,是webgl将纹理赋值给几何体的过程,这个我们通常是将步骤2中的数据通过
同时别忘了shader里面也需要定义
还有就是你需要在原生的databuffer中定义uv坐标哈,确保纹理位置符合你的要求。
步骤4更新纹理
要实时更新纹理,需要将新的图像数据写入纹理对象。为此,可以使用gl.texSubImage2D()方法。该方法将在指定的纹理级别上替换部分或全部纹理图像数据。需要指定纹理类型,纹理级别,纹理的起始坐标和大小,以及图像的格式和数据类型。详情你看下面的api介绍吧texSubImage2D
最后
懂了。谢谢老师,然后我想知道您的omggif是什么版本呢,我下载的omggifjs怎么没有parseGIF这个方法
@xieky 按照冰哥的思路,使用了omggif库:https://github.com/deanm/omggif,在原始的webgl上画出gif动画,具体代码如下,连接中可以看:
https://www.icegl.cn/addons/cms/archives/showcode?id=147
你疑惑的代码如下:
效果如下: