在LibGDX实施梯形精灵 [英] Implementing trapezoidal sprites in LibGDX

查看:653
本文介绍了在LibGDX实施梯形精灵的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图创建一个简单的2D游戏程序动画引擎,它可以让我创造好看的动画了少量图像(类似于这种方法的,但对于2D:的 http://www.gdcvault.com/play/1020583/Animation-Bootcamp-An-Indie -Approach

I'm trying to create a procedural animation engine for a simple 2D game, that would let me create nice looking animations out of a small number of images (similar to this approach, but for 2D: http://www.gdcvault.com/play/1020583/Animation-Bootcamp-An-Indie-Approach)

目前,我有不同的动画对象保存数据的关键帧,关键帧是彩车的数组重新presenting以下内容:

At the moment I have keyframes which hold data for different animation objects, the keyframes are arrays of floats representing the following:

translateX,translateY,将scaleX,的scaleY,旋转(度)

translateX, translateY, scaleX, scaleY, rotation (degrees)

我想如果skewX,skewY,taperTop和taperBottom添加到这个列表中,但我无法正确渲染他们。

I'd like to add skewX, skewY, taperTop, and taperBottom to this list, but I'm having trouble properly rendering them.

这是我尝试在实施锥度精灵的顶部,给它一个梯形:

This was my attempt at implementing a taper to the top of the sprite to give it a trapezoid shape:

float[] vert = sprite.getVertices();
vert[5] += 20; // top-left vertex x co-ordinate
vert[10] -= 20; // top-right vertex x co-ordinate

batch.draw(texture, vert, 0, vert.length);

不幸的是生产一些奇怪的纹理变形。

Unfortunately this is producing some weird texture morphing.

我有一点谷歌和计算器周围一看,发现这一点,这似乎是我遇到的问题:

I had a bit of a Google and a look around StackOverflow and found this, which appears to be the problem I'm having:

http://www.xyzw.us/~cass/qcoord/

不过,我不明白它背后的数学(什么是S,T,R和Q?)。

However I don't understand the maths behind it (what are s, t, r and q?).

有人可以解释它简单一点?

Can someone explain it a bit simpler?

推荐答案

基本上,少了四类似于一个矩形,外观越差由于线性插值整个形状纹理坐标的影响。两个三角形组成的四元被拉伸至不同的尺寸,因此,线性内插使接缝非常引人注目。

Basically, the less a quad resembles a rectangle, the worse the appearance due to the effect of linearly interpolating the texture coordinates across the shape. The two triangles that make up the quad are stretched to different sizes, so linear interpolation make the seam very noticeable.

每个顶点的纹理坐标进行线性插值的每个片段的片段着色器处理。纹理坐标通常存储与已分割出来的对象的大小,因此坐标是在0-1的范围内,与纹理的边缘相应的(在这个范围之外和值被夹紧或缠绕)。这也是通常的3D建模程序是如何出口的网格。

The texture coordinates of each vertex are linearly interpolated for each fragment that the fragment shader processes. Texture coordinates typically are stored with the size of the object already divided out, so the coordinates are in the range of 0-1, corresponding with the edges of the texture (and values outside this range are clamped or wrapped around). This is also typically how any 3D modeling program exports meshes.

使用梯形,我们可以限制扭曲pre-乘以纹理的宽度,然后协调后除以宽出质感线性插值后的坐标。这是象弯曲的两个三角形之间的对角线使得其斜率处于即在梯形的较宽侧的角更水平。下面是有助于说明它的图像。

纹理坐标pssed与组件的二维矢量通常前$ P $ U和V,也称为S和T.但是,如果你想要的大小划分出来的组件,你需要一个或多个组件,你是要通过插值后来划分,而这就是所谓的Q分量。 (该P分量将被用作在纹理第三位置,如果你正在寻找了在3D纹理代替2D纹理的东西)。

Texture coordinates are usually expressed as a 2D vector with components U and V, also known as S and T. But if you want to divide the size out of the components, you need one more component that you are going to divide by after interpolation, and this is called the Q component. (The P component would be used as the third position in the texture if you were looking up something in a 3D texture instead of a 2D texture).

现在,这里是最困难的部分... libgdx的SpriteBatch不支持Q分量额外的顶点属性必要的。所以,你既可以克隆SpriteBatch并认真办理,并修改它拥有在texCoord属性的额外组件,或者你可以尝试重新用现有的颜色属性,尽管它存储为一个无符号字节。

Now here comes the hard part... libgdx's SpriteBatch doesn't support the extra vertex attribute necessary for the Q component. So you can either clone SpriteBatch and carefully go through and modify it to have an extra component in the texCoord attribute, or you can try to re-purpose the existing color attribute, although it's stored as an unsigned byte.

无论如何,你将需要pre-宽度分割纹理坐标。简化这个的一种方法是,代替使用的四元为4个顶点的实际大小,获得梯形的顶部和底部的宽度之比,因此,我们可以把顶端部分为1的宽度和因此离开他们独自一人。

Regardless, you will need pre-width-divided texture coordinates. One way to simplify this is to, instead of using the actual size of the quad for the four vertices, get the ratio of the top and bottom widths of the trapezoid, so we can treat the top parts as width of 1 and therefore leave them alone.

float bottomWidth = taperBottom / taperTop;

然后,你需要修改TextureRegion现有的纹理坐标的宽度pre-相乘。我们可以留在梯形单独由于上述简化的顶侧的顶点,但两窄侧顶点的U和V坐标需要由 bottomWidth 。您将需要重新计算,并把它们放到你的顶点数组每次更改TextureRegion或锥度值一次。

Then you need to modify the TextureRegion's existing texture coordinates to pre-multiply them by the widths. We can leave the vertices on the top side of the trapezoid alone because of the above simplification, but the U and V coordinates of the two narrow-side vertices need to be multiplied by bottomWidth. You would need to recalculate them and put them into your vertex array every time you change the TextureRegion or one of the taper values.

在顶点着色器,你将需要额外的Q分量传递给片段着色器。在片段着色器,我们通常使用的大小划分纹理坐标这样看我们的纹理颜色:

In the vertex shader, you would need to pass the extra Q component to the fragment shader. In the fragment shader, we normally look up our texture color using the size-divided texture coordinates like this:

vec4 textureColor = texture2D(u_texture, v_texCoords);

但在我们的例子中,我们仍然需要通过Q分量来划分:

but in our case we still need to divide by that Q component:

vec4 textureColor = texture2D(u_texture, v_texCoords.st / v_texCoords.q);

然而,这会导致依赖纹理读出,因为我们正在修改矢量之前它被传递到纹理函数。 GLSL提供了一个功能,可自动完成上述任务(我认为不会导致依赖纹理读取):

However, this causes a dependent texture read because we are modifying a vector before it is passed into the texture function. GLSL provides a function that automatically does the above (and I assume does not cause a dependent texture read):

vec4 textureColor = texture2DProj(u_texture, v_texCoords); //first two components automatically divided by last component

这篇关于在LibGDX实施梯形精灵的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆