Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >WebGL -动画精灵+动画坐标

WebGL -动画精灵+动画坐标
EN

Stack Overflow用户
提问于 2017-11-29 19:23:01
回答 1查看 746关注 0票数 0

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

也就是说,对于动画中的特定精灵,给出了0,1的纹理坐标,然后再用另一个坐标进行转换。

转换可能导致0,1之外的坐标,这是重复所需的。

问题是-我提供精灵作为纹理地图集。因此,选择一个精灵意味着在0,1中得到一个子矩形。因为这个精灵介于其他人之间,所以没有办法重复--毕竟,如果纹理坐标在精灵矩形之外移动,其他精灵就会被采样。

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

在WebGL中有什么方法可以同时实现纹理重复和精灵动画吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-11-30 00:58:39

如果您知道雪碧在地图集中的位置,那么您就不能计算一个纹理坐标模块,即片段着色器中的纹理坐标模块

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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);

这是否适用于你的特殊情况,我不知道,但也许它给你一些想法。

工作实例:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
const vs = `
void main() {
  // using a point sprite because it's easy but the concept 
  // is the same.
  gl_Position = vec4(0, 0, 0, 1);
  gl_PointSize = 40.0;
}
`;

const fs = `
precision mediump float;

// I'm passing these in as uniforms but you can pass them in as varyings
// from buffers if that fits your needs better

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

uniform sampler2D someTexture;

void main() {
  // this would normally come from a varying but lazy so using point sprite
  vec2 texcoord = gl_PointCoord.xy;  
  
  vec2 spriteRange = (spriteEndUV - spriteStartUV);
  vec2 uv = spriteStartUV + fract(texcoord + animatedUV) * spriteRange;

  vec4 color = texture2D(someTexture, uv);
  
  gl_FragColor = color;
}
`;

// use the canvas to make a texture atlas with one sprite
const ctx = document.querySelector("#atlas").getContext("2d");
const w = ctx.canvas.width;
const h = ctx.canvas.height
const sx = 30;
const sy = 40;
const sw = 50;
const sh = 60;
ctx.fillStyle = "red";
ctx.fillRect(0, 0, w, h);
ctx.fillStyle = "blue";
ctx.fillRect(sx, sy, sw, sh);
ctx.fillStyle = "yellow";
ctx.font = "45px sans-serif";
ctx.textAlign = "center";
ctx.textBaseline = "middle";
ctx.fillText("G", sx + sw / 2, sy + sh / 2);

// compute texcoods for sprite
const spriteStartUV = [ sx / w, sy / h ];
const spriteEndUV = [ (sx + sw) / w, (sy + sh) / h ];

const gl = document.querySelector("#webgl").getContext("webgl");
const programInfo = twgl.createProgramInfo(gl, [vs, fs]);

const tex = twgl.createTexture(gl, {
  src: ctx.canvas,
});

function render(time) {
  time *= 0.001;  // seconds
  gl.useProgram(programInfo.program);
  twgl.setUniforms(programInfo, {
    animatedUV: [time, time * 1.1],
    spriteStartUV: spriteStartUV,
    spriteEndUV: spriteEndUV,
    someTexture: tex,
  });
  gl.drawArrays(gl.POINTS, 0, 1);  // draw 1 point
  requestAnimationFrame(render);
}
requestAnimationFrame(render);
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
canvas { border: 1px solid black; margin: 2px; }
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<script src="https://twgljs.org/dist/4.x/twgl.min.js"></script>
<canvas id="atlas"></canvas>
<canvas id="webgl"></canvas>

如果你想要它重复更多,那么增加你的纹理和弦,或者增加一个复调器。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
const vs = `
void main() {
  // using a point sprite because it's easy but the concept 
  // is the same.
  gl_Position = vec4(0, 0, 0, 1);
  gl_PointSize = 40.0;
}
`;

const fs = `
precision mediump float;

// I'm passing these in as uniforms but you can pass them in as varyings
// from buffers if that fits your needs better

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

uniform sampler2D someTexture;

void main() {
  // this would normally come from a varying but lazy so using point sprite
  vec2 texcoord = gl_PointCoord.xy * 3.;  // this * 3 could already be
                                          // in your texcoords
  
  vec2 spriteRange = (spriteEndUV - spriteStartUV);
  vec2 uv = spriteStartUV + fract(texcoord + animatedUV) * spriteRange;

  vec4 color = texture2D(someTexture, uv);
  
  gl_FragColor = color;
}
`;

// create texture atlas with one sprite
const ctx = document.querySelector("#atlas").getContext("2d");
const w = ctx.canvas.width;
const h = ctx.canvas.height
const sx = 30;
const sy = 40;
const sw = 50;
const sh = 60;
ctx.fillStyle = "red";
ctx.fillRect(0, 0, w, h);
ctx.fillStyle = "blue";
ctx.fillRect(sx, sy, sw, sh);
ctx.fillStyle = "yellow";
ctx.font = "45px sans-serif";
ctx.textAlign = "center";
ctx.textBaseline = "middle";
ctx.fillText("G", sx + sw / 2, sy + sh / 2);

// compute texture coords for sprite in atlas
const spriteStartUV = [ sx / w, sy / h ];
const spriteEndUV = [ (sx + sw) / w, (sy + sh) / h ];

const gl = document.querySelector("#webgl").getContext("webgl");
const programInfo = twgl.createProgramInfo(gl, [vs, fs]);

const tex = twgl.createTexture(gl, {
  src: ctx.canvas,
});

function render(time) {
  time *= 0.001;  // seconds
  gl.useProgram(programInfo.program);
  twgl.setUniforms(programInfo, {
    animatedUV: [time, time * 1.1],
    spriteStartUV: spriteStartUV,
    spriteEndUV: spriteEndUV,
    someTexture: tex,
  });
  gl.drawArrays(gl.POINTS, 0, 1);  // draw 1 point
  requestAnimationFrame(render);
}
requestAnimationFrame(render);
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
canvas { border: 1px solid black; margin: 2px; }
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<script src="https://twgljs.org/dist/4.x/twgl.min.js"></script>
<canvas id="atlas"></canvas>
<canvas id="webgl"></canvas>

注意,上面的示例使用制服,但您也可以使用每个顶点spriteStartUV、spriteEndUV和任何其他使用属性并将数据添加到缓冲区的数据。

更新

用更多的精灵来使它更清晰,它使用的是纹理地图集

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
const vs = `
uniform vec4 u_position;
void main() {
  // using a point sprite because it's easy but the concept 
  // is the same.
  gl_Position = u_position;
  gl_PointSize = 40.0;
}
`;

const fs = `
precision mediump float;

// I'm passing these in as uniforms but you can pass them in as varyings
// from buffers if that fits your needs better

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

uniform sampler2D someTexture;

void main() {
  // this would normally come from a varying but lazy so using point sprite
  vec2 texcoord = gl_PointCoord.xy * 3.;  // this * 3 could already be
                                          // in your texcoords
  
  vec2 spriteRange = (spriteEndUV - spriteStartUV);
  vec2 uv = spriteStartUV + fract(texcoord + animatedUV) * spriteRange;

  vec4 color = texture2D(someTexture, uv);
  
  gl_FragColor = color;
}
`;

// create texture atlas with 36 sprites
const ctx = document.querySelector("#atlas").getContext("2d");
const w = ctx.canvas.width;
const h = ctx.canvas.height;
ctx.fillStyle = "red";
ctx.fillRect(0, 0, w, h);

const sw = 16;
const sh = 16;
const spritesAcross = w / sw | 0;
const spriteData = [];
const backgroundColors = [
  "#884", "#848", "#488", "#448", "#484", "#488", "#222",
];
"ABCDEFGHIIJKLMNOPQRSTUVWXYZ0123456789".split('').forEach((letter, ndx) => {
  const sx = ndx % spritesAcross * sw;   
  const sy = (ndx / spritesAcross | 0) * sh;
  ctx.fillStyle = backgroundColors[ndx % backgroundColors.length];
  ctx.fillRect(sx, sy, sw, sh);
  ctx.fillStyle = "yellow";
  ctx.font = "16px sans-serif";
  ctx.textAlign = "center";
  ctx.textBaseline = "middle";
  ctx.fillText(letter, sx + sw / 2, sy + sh / 2);
  spriteData.push({
    spriteStartUV: [ sx / w, sy / h ],
    spriteEndUV: [ (sx + sw) / w, (sy + sh) / h ],
  });
});

// compute texture coords for sprite in atlas
const gl = document.querySelector("#webgl").getContext("webgl");
const programInfo = twgl.createProgramInfo(gl, [vs, fs]);

const tex = twgl.createTexture(gl, {
  src: ctx.canvas,
});

function render(time) {
  time *= 0.001;  // seconds
  gl.useProgram(programInfo.program);
  for (let i = 0; i < 100; ++i) {
    const spriteInfo = spriteData[i % spriteData.length];
    const t = time + i;
    twgl.setUniforms(programInfo, {
      u_position: [Math.sin(t * 1.2), Math.sin(t * 1.3), 0, 1],
      animatedUV: [t, t * 1.1],
      spriteStartUV: spriteInfo.spriteStartUV,
      spriteEndUV: spriteInfo.spriteEndUV,
      someTexture: tex,
    });
    gl.drawArrays(gl.POINTS, 0, 1);  // draw 1 point
  }
  requestAnimationFrame(render);
}
requestAnimationFrame(render);
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
canvas { border: 1px solid black; margin: 2px; }
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<script src="https://twgljs.org/dist/4.x/twgl.min.js"></script>
<canvas id="atlas"></canvas>
<canvas id="webgl"></canvas>

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47565382

复制
相关文章
WebGL 动画
有一种动画书,就是快速翻动就可以看见里面的内容运动起来了。电脑动画和这个差不多,通过在动画区域内用一张新的图片代替旧的图片,并快速持续的改变,根据视觉暂留现象就在我们的大脑中形成了动画。 HTML5里面,我们通过下面的语句来实现画面的更替: window.requestAnimationFrame() 还是一脸懵逼?我们先用代码把第一段话翻译一下吧: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta n
孙亖
2018/06/07
9290
Python——动画精灵
前边已经讲到,看似简单的动画实际上并不简单。如果有大量图像在四处移动,要想跟踪每个图像“底下”有些什么,以便在移动图像时能够重绘,这要给很大的功夫。我们之前的小狗,因为背景是白色的,所以更容易一些。倘若背景上有一些图形,肯定会复杂得多。
py3study
2020/01/07
1.2K0
Python——动画精灵
【CSS3】CSS3 动画 ⑥ ( 动画属性示例 | 精灵图帧动画效果实现 )
实现逻辑是 设置 元素的 animation-timing-function 动画属性 , 使用 steps(n) 属性值指定动画步长 ;
韩曙亮
2023/10/15
5960
【CSS3】CSS3 动画 ⑥ ( 动画属性示例 | 精灵图帧动画效果实现 )
Unity精灵动画 2D碰撞
将包含多个小图的一张大图SpriteMode设置为Multiple,在SpriteEditor中将素材进行切割,得到小的图片资源
祝你万事顺利
2019/05/28
9980
HGE系列之九 管中窥豹(精灵动画)
这次的HGE之旅,让我们来看看精灵及动画的实现,毕竟对于一款2D游戏引擎来说,恐怕精灵和动画不是最重要的,也可算是最重要之一了吧:)
用户2615200
2018/08/02
6090
(译)SDL编程入门(14)动画精灵和VSync
动画简而言之就是展示一个又一个的图像来制造运动的假象。在这里我们将展示不同的精灵来制作一个简笔画的动画。
arcticfox
2020/10/19
9510
(译)SDL编程入门(14)动画精灵和VSync
原 透过WebGL 3D看动画Easing
image.png 50年前的这个月诞生了BASIC这门计算机语言,回想起自己喜欢上图形界面这行,还得归功于当年在win98下用QBASIC照葫芦画瓢敲了一段绘制奥运五环的代码,当带色彩的奥运五环呈现在自己面前时我已知道自己这辈子要走的路了。在这个忘本逐新的年代不见多少媒体提及这影响了几代人的BASIC语言的50年庆了。 如今消费者对用户体验的高要求,以远不能以静态平面图形打动人心,动画已是衡量前端产品用户体验不可忽视的重要因素,最近Facebook开源的Pop动画框架已发了iOS业界极大的关注,其实A
HT_hightopo
2018/06/05
4280
Threejs入门之十五:使用精灵模拟下雪效果
今天我们使用前面将的精灵模型来模拟一个下雪的场景 使用精灵模型实现下雪场景的核心思路 一.利用for循环随机生成雪花,生成的雪花位置随机 二.雪花下落动画,定义一个函数,让其y坐标递减,判断当y坐标值小于0时,重新将其设置为800 三.利用requestAnimationFrame循环执行上面的函数 实现代码如下: 1.新建文件夹,命名为snow,在该文件夹下新建一个images文件夹用于存放雪花图片 2.在根目录新建index.html文件和index.js文件 3.在index.html文件中引入threejs和index.js,并新建一个id为webgl的div
九仞山
2023/04/30
1.7K0
Threejs入门之十五:使用精灵模拟下雪效果
【Flutter】Animation 动画 ( AnimatedWidget 动画使用流程 | 创建动画控制器 | 创建动画 | 创建 AnimatedWidget 动画组件 | 动画运行 )
在上一篇博客 【Flutter】Animation 动画 ( Flutter 动画基本流程 | 创建动画控制器 | 创建动画 | 设置值监听器 | 设置状态监听器 | 布局中使用动画值 | 动画运行 ) 中 , 使用动画时 , 需要给动画添加值监听器 , 每当动画值更新后 , 都会回调该监听器 , 在监听器的回调方法中 , 需要调用 setState 方法 , 将该动画值设置给组件 ;
韩曙亮
2023/03/29
2K0
【Flutter】Animation 动画 ( AnimatedWidget 动画使用流程 | 创建动画控制器 | 创建动画 | 创建 AnimatedWidget 动画组件 | 动画运行 )
【Flutter 实战】动画序列、共享动画、路由动画
Flutter中组合动画使用Interval,Interval继承自Curve,用法如下:
老孟Flutter
2020/09/11
1.9K0
【Flutter 实战】动画序列、共享动画、路由动画
JavaScript 动画_jquery 动画
回调函数原理:函数可以作为一个参数。将这个函数作为参数传到另一个函数里面,当那个函数执行完之后,再执行传进去的这个函数,这个过程叫做回调。
全栈程序员站长
2022/11/04
2.4K0
透过WebGL 3D看动画Easing函数本质
本文主要介绍了动画框架的发展历程和现状,以及基于HT for Web的3D动画效果,并通过实例对各种动画效果进行了直观展示。
HT for Web
2018/01/03
8620
透过WebGL 3D看动画Easing函数本质
Android动画基础 | 概述、逐帧动画、视图动画
或者给<animation-list>添加android:oneshot="true"属性,也可实现:
凌川江雪
2019/05/14
4K0
Android动画基础 | 概述、逐帧动画、视图动画
【Android 属性动画】属性动画 Property Animation 简介 ( 属性动画简介 | 属性动画特性 )
文章目录 一、属性动画简介 二、属性动画特性 一、属性动画简介 ---- 属性动画简介 : 1.动画制作框架 : 属性动画系统 , 允许你 将任何可变的操作制作成动画 , 其功能很强大 ; 2.基本功能 : 使用该框架 , 可以 定义一个随时间改变的动画 ; 3.属性随时间改变 : 动画执行期间 , 修改任意对象的属性 , 其组件的变化生成一个动画 ; 4.不受可见性限制 : 即使 该组件不可见 , 或者绘制在屏幕外部 , 该动画也可以生效 ; 5.属性动画本质 : 属性动画在一个指定的时间段内 , 修改某
韩曙亮
2023/03/27
4.7K0
【Flutter】Animation 动画 ( AnimatedBuilder 动画使用流程 | 创建动画控制器 | 创建动画 | 创建动画作用的组件 | 关联动画与组件 | 动画执行 )
在上一篇博客 【Flutter】Animation 动画 ( AnimatedWidget 动画使用流程 | 创建动画控制器 | 创建动画 | 创建 AnimatedWidget 动画组件 | 动画运行 ) 中 , 使用了 AnimatedWidget 组件实现动画 , 省略了手动添加监听器 , 并在监听器中手动调用 setState 更新动画的操作 ;
韩曙亮
2023/03/29
1.8K0
【Flutter】Animation 动画 ( AnimatedBuilder 动画使用流程 | 创建动画控制器 | 创建动画 | 创建动画作用的组件 | 关联动画与组件 | 动画执行 )
JavaScript动画 —— 弹动动画
缓动和弹动都是那对象从已有位置移动到目标位置的方法。但是缓动是指物体滑动到目标点就停下来;而弹动是指物体来回反弹一段时间后,最终停在目标点的运动。
大师级码师
2021/09/19
1.6K0
《Flutter 动画系列》组合动画
老孟导读:在项目中动画效果很多时候是几种动画的组合,比如颜色、大小、位移等属性同时变化或者顺序变化,这篇文章讲解如何实现组合动画。
老孟Flutter
2020/09/11
1.3K0
动画
动画 代码如下: //动画js封装,moveElement()函数,需传四个参数, // elementID添加动画对象的ID,finalX 最终位置的left值,finalY 最终位置的TOP值, //interval动画的时间间隔,间接反映运动速度; function moveElement(elementID,finalX,finalY,interval){ //对浏览器的相关方法进行检测 if(!document.getElementById) return false;
天天_哥
2018/09/29
7880
Vue教程(动画-半场动画)
  上篇文章我们介绍了过渡动画的实现,包括完整的 入场 和 离场 动画,但是在实际过程中我们有时可能仅仅需要使用半场动画,比如淘宝购物车的下单处理等。
用户4919348
2019/07/22
1K0
Vue教程(动画-半场动画)
Android 动画总结(9) - 过渡动画
前面已经介绍过一部分 Activity 之间的过渡动画。现在讲的不是 Activity 转场,而是同一个页面的 View 之间的过渡。
三流之路
2018/09/11
2.5K0
Android 动画总结(9) - 过渡动画

相似问题

用EaselJS (WebGL)创建SpriteStage精灵动画

14

动画精灵

12

动画数组没有动画精灵

10

WebGL动画优化

11

精灵图像动画

115
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文