ade*_*art 5 three.js texturepacker
我正在尝试从 ThreeJS 中的 Texturepacker 加载 spritesheet,其中包含图像和 json。该图像有一堆小精灵打包在一起,json 定义了图像中小精灵的位置和大小。
我尝试了3种加载方法。
使用具有不同偏移量的多个纹理实例的方法应该可以正常工作,因为我没有复制源图像,但是当我通过切换材质的纹理来运行动画时,它会使用大量的 RAM,就好像它将整个源精灵表复制到内存中一样为每一个。如果我更改动画的纹理偏移而不是使用纹理副本,它可以正常工作,但偏移更改将应用于使用相同源精灵表的每个对象。
WebGLRenderTarget 方法需要一个相机和场景来裁剪纹理以及添加到场景中的精灵。此输出无法使用,因为它不会生成原始纹理的 1:1 裁剪,而且加载速度非常慢。有没有办法在 ThreeJS 中将纹理 1:1 渲染到较小的缓冲区?
Canvas 方法效果最好,我为每个精灵创建一个画布元素,并将精灵表裁剪到每个精灵中。这是 1:1 且质量良好,但使用 spritesheet 的要点是 GPU 仅需要处理单个图像,并且这需要 HTML 加载程序。理想情况下,我不想将精灵表裁剪为较小的纹理缓冲区。
为什么将相同的大源图像与多个 THREE.Texture 对象一起使用会占用如此多的内存?我预计它只需要在内存中保留单个纹理,并且纹理对象只会显示具有不同偏移量的相同纹理。
我找到了一种有效的方法。
首先,我通过从通过 ThreeJS ImageLoader 加载的 spritesheet 图像创建 WebGLTexture 来加载纹理,该图像存储在 _spritesheets[textureID].texture 中。
let texture = this._spritesheets[textureID].texture;
let gl = this._renderer.getContext();
let webGLTexture = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, webGLTexture);
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, texture);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
Run Code Online (Sandbox Code Playgroud)
然后我将纹理对象的 webGL 纹理参数设置为此,并将其 webglInit 值设置为 true,这样它就不会创建新的缓冲区。
let frames = textureJSON.frames;
for (let frameID of Object.keys(frames)) {
let frame = frames[frameID];
let t = new THREE.Texture(texture);
let data = frame.frame;
t.repeat.set(data.w / texture.width, data.h / texture.height);
t.offset.x = data.x / texture.width;
t.offset.y = 1 - data.h / texture.height - data.y / texture.height;
let textureProperties = this._renderer.properties.get(t);
textureProperties.__webglTexture = webGLTexture;
textureProperties.__webglInit = true;
this._textures[frameID] = {};
this._textures[frameID].texture = t;
this._textures[frameID].settings = { wrapS: 1, wrapT: 1, magFilter: THREE.LinearFilter, minFilter: THREE.NearestFilter };
}
Run Code Online (Sandbox Code Playgroud)
spritesheet JSON 通过 ThreeJS FileLoader 加载。然后,我按帧 ID 将精灵存储在 _textures 对象中,并可以将它们分配给材质的贴图属性。
| 归档时间: |
|
| 查看次数: |
1301 次 |
| 最近记录: |