Animation WebGL-动画精灵&x2B;动画坐标

Animation WebGL-动画精灵&x2B;动画坐标,animation,glsl,webgl,Animation,Glsl,Webgl,我需要运行精灵动画和动画坐标 也就是说,[0,1]中的纹理坐标是为动画中的某个特定精灵指定的,然后它被另一个坐标转换 平移可能导致[0,1]之外的坐标,这是重复所需的 问题在于,我将精灵作为纹理图集提供。 因此,选择精灵意味着在[0,1]中获得一个子矩形。 由于该精灵位于其他精灵之间,因此无法重复-毕竟,如果纹理坐标移动到精灵矩形之外,则将对其他精灵进行采样 精灵在纹理图集中给出是必要的-我使用的是实例渲染,其中每个实例都可以在动画中使用任何精灵,据我所知,实现这一点的唯一方法是使用纹理图集(或

我需要运行精灵动画和动画坐标

也就是说,[0,1]中的纹理坐标是为动画中的某个特定精灵指定的,然后它被另一个坐标转换

平移可能导致[0,1]之外的坐标,这是重复所需的

问题在于,我将精灵作为纹理图集提供。 因此,选择精灵意味着在[0,1]中获得一个子矩形。 由于该精灵位于其他精灵之间,因此无法重复-毕竟,如果纹理坐标移动到精灵矩形之外,则将对其他精灵进行采样

精灵在纹理图集中给出是必要的-我使用的是实例渲染,其中每个实例都可以在动画中使用任何精灵,据我所知,实现这一点的唯一方法是使用纹理图集(或OpenGL中的纹理数组等)


tl;dr-是否有一种方法可以在WebGL中实现纹理重复和精灵动画?

如果您知道精灵在地图集中的位置,那么您就不能在片段着色器中计算该范围的纹理坐标模吗

vec2 animatedUV;      // animation value
vec2 spriteStartUV;   // corner uv coord for sprite in atlas
vec2 spriteEndVU;     // opposite corner uv coord for sprite in atlas

vec2 spriteRange = (spriteEndUV - spriteStartUV);
vec2 uv = spriteStartUV + fract(texcoord + animatedUV) * spriteRange;

vec4 color = texture2D(someTexture, uv);
我不知道这是否适用于你的特殊情况,但也许它能给你一些想法

工作示例:

const vs=`
void main(){
//使用点精灵是因为它很简单,但是
//是一样的。
gl_位置=vec4(0,0,0,1);
gl_PointSize=40.0;
}
`;
常数fs=`
精密中泵浮子;
//我把它们当作制服传进来,但你可以把它们当作士兵传进来
//如果这能更好地满足您的需求,请使用缓冲区
均匀向量2 animatedUV;//动画价值
统一vec2 spriteStartUV;//atlas中sprite的角uv坐标
均匀矢量2 spriteEndUV;//阿特拉斯中精灵的对角uv坐标
纹理均匀;
void main(){
//这通常来自一个变化但懒惰的点精灵
vec2 texcoord=gl_PointCoord.xy;
vec2 spriteRange=(spriteEndUV-spriteStartUV);
vec2 uv=spriteStartUV+fract(texcoord+animatedUV)*spriteRange;
vec4颜色=纹理2D(某些纹理,uv);
gl_FragColor=颜色;
}
`;
//使用画布制作带有一个精灵的纹理图集
const ctx=document.querySelector(#atlas”).getContext(“2d”);
常数w=ctx.canvas.width;
常数h=ctx.canvas.height
常数sx=30;
常数sy=40;
常数sw=50;
常数sh=60;
ctx.fillStyle=“红色”;
ctx.fillRect(0,0,w,h);
ctx.fillStyle=“蓝色”;
ctx.fillRect(sx、sy、sw、sh);
ctx.fillStyle=“黄色”;
ctx.font=“45px无衬线”;
ctx.textAlign=“中心”;
ctx.textb基线=“中间”;
ctx.fillText(“G”,sx+sw/2,sy+sh/2);
//计算精灵的特克斯库兹
常数spriteStartUV=[sx/w,sy/h];
常数spritenduv=[(sx+sw)/w,(sy+sh)/h];
const gl=document.querySelector(#webgl”).getContext(“webgl”);
const programInfo=twgl.createProgramInfo(gl[vs,fs]);
常量tex=twgl.createTexture(gl{
src:ctx.canvas,
});
函数渲染(时间){
时间*=0.001;//秒
总账使用程序(programInfo.program);
twgl.设置制服(程序信息{
animatedUV:[时间,时间*1.1],
spriteStartUV:spriteStartUV,
spriteEndUV:spriteEndUV,
一些纹理:特克斯,
});
gl.drawArray(gl.POINTS,0,1);//绘制1点
请求动画帧(渲染);
}
请求动画帧(渲染)
canvas{边框:1px纯黑色;边距:2px;}

如果你知道精灵在地图集中的位置,那么你就不能在片段着色器中计算一个纹理坐标模,该范围

vec2 animatedUV;      // animation value
vec2 spriteStartUV;   // corner uv coord for sprite in atlas
vec2 spriteEndVU;     // opposite corner uv coord for sprite in atlas

vec2 spriteRange = (spriteEndUV - spriteStartUV);
vec2 uv = spriteStartUV + fract(texcoord + animatedUV) * spriteRange;

vec4 color = texture2D(someTexture, uv);
我不知道这是否适用于你的特殊情况,但也许它能给你一些想法

工作示例:

const vs=`
void main(){
//使用点精灵是因为它很简单,但是
//是一样的。
gl_位置=vec4(0,0,0,1);
gl_PointSize=40.0;
}
`;
常数fs=`
精密中泵浮子;
//我把它们当作制服传进来,但你可以把它们当作士兵传进来
//如果这能更好地满足您的需求,请使用缓冲区
均匀向量2 animatedUV;//动画价值
统一vec2 spriteStartUV;//atlas中sprite的角uv坐标
均匀矢量2 spriteEndUV;//阿特拉斯中精灵的对角uv坐标
纹理均匀;
void main(){
//这通常来自一个变化但懒惰的点精灵
vec2 texcoord=gl_PointCoord.xy;
vec2 spriteRange=(spriteEndUV-spriteStartUV);
vec2 uv=spriteStartUV+fract(texcoord+animatedUV)*spriteRange;
vec4颜色=纹理2D(某些纹理,uv);
gl_FragColor=颜色;
}
`;
//使用画布制作带有一个精灵的纹理图集
const ctx=document.querySelector(#atlas”).getContext(“2d”);
常数w=ctx.canvas.width;
常数h=ctx.canvas.height
常数sx=30;
常数sy=40;
常数sw=50;
常数sh=60;
ctx.fillStyle=“红色”;
ctx.fillRect(0,0,w,h);
ctx.fillStyle=“蓝色”;
ctx.fillRect(sx、sy、sw、sh);
ctx.fillStyle=“黄色”;
ctx.font=“45px无衬线”;
ctx.textAlign=“中心”;
ctx.textb基线=“中间”;
ctx.fillText(“G”,sx+sw/2,sy+sh/2);
//计算精灵的特克斯库兹
常数spriteStartUV=[sx/w,sy/h];
常数spritenduv=[(sx+sw)/w,(sy+sh)/h];
const gl=document.querySelector(#webgl”).getContext(“webgl”);
const programInfo=twgl.createProgramInfo(gl[vs,fs]);
常量tex=twgl.createTexture(gl{
src:ctx.canvas,
});
函数渲染(时间){
时间*=0.001;//秒
总账使用程序(programInfo.program);
twgl.设置制服(程序信息{
animatedUV:[时间,时间*1.1],
spriteStartUV:spriteStartUV,
spriteEndUV:spriteEndUV,
一些纹理:特克斯,
});
gl.drawArray(gl.POINTS,0,1);//绘制1点
请求动画帧(渲染);
}
请求动画帧(渲染)
canvas{边框:1px纯黑色;边距:2px;}


可以使用包含纹理坐标w的数组