带有WebGL的Sprite动画如何工作?
问题描述:
虽然有很多关于如何渲染精灵的教程,但我已经知道如何以面向对象的方式为我的精灵制作动画。比方说,我有一个播放器 - class
带有WebGL的Sprite动画如何工作?
class Player{
constructor(){
this.textureAtlasPath = 'textures/player.jpg'
this.uvCoords = [0,0,1,0,1,1,0,1]
}
}
因此,如果player.jpg
只包含一个纹理(如一个字符),我认为这是非常明确的,那我使用UV坐标[0,0,1,0,1,1,0,1]
。但让我们说player.jpg
包含4个纹理(角色朝上,角色朝左,角色朝下,角色朝下)。我所做的就是将在4个UV坐标UV坐标(顶点着色器内),并视框FE:
if(currentFrame < 15)
//use uv coord subdivision 1
if(currentFrame < 30)
//use uv coord subdivision 2
to be continued.....
所以我的问题是: 难道我细分顶点/片段着色器内的紫外线COORDS或者我在CPU上计算它们?如果是这样,我将它们存储在4个不同的缓冲区或只有1个缓冲区?如果可能的话,你能提供一个代码示例吗? 附加说明:我希望我的所有动画小精灵都有4种运动状态,所以f.e.整个图像是64x64,它包含4个16x16纹理。
答
也许最常见的方法是使用具有单位四边形纹理坐标的单位四边形并通过纹理矩阵来乘以纹理坐标以选择所需纹理的一部分。
// vertex shader
attribute vec2 texcoord;
...
uniform mat4 texMatrix;
...
varying vec2 v_texcoord;
...
void main() {
...
v_texcoord = (texMatrix * vec4(texcoord, 0, 1)).xy;
}
见3210
如果您不旋转,你可以缩短通过只是路过的UV胶印和UV规模
// vertex shader
attribute vec2 texcoord;
...
uniform vec2 uvOffset;
uniform vec2 uvScale;
...
varying vec2 v_texcoord;
...
void main() {
...
v_texcoord = texcoord * uvScale + uvOffset;
}
如果所有的精灵大小相同计划对于一个给定的纹理(比如说所有纹理都是40x20),那么你也可以通过传入单个精灵的大小或者精灵的数量,纹理的大小和精灵数量来计算着色器中的UV。
你使用哪一个取决于你想要的灵活性和你需要多少速度。我几乎总是选择第一种方法,它是最灵活的。如果它对我的需求来说太慢,那我就开始优化。