我有兴趣创建类似于游戏的着色器效果(不要因为使用此示例而射击我)动物穿越。当您沿着地形向前和向后移动时,世界会“弯曲”,给人一种圆形表面的感觉。问题是,我想将这种效果应用于 2D 横向卷轴。
想象一个像泰拉瑞亚这样的游戏,屏幕的两端(左右两侧)略微向下弯曲以产生弯曲的错觉。
我试图找到一篇解释如何实现这种效果的文章,但我没有太多有用的方向指示方式。我知道这不是最有条理或最恰当的问题,但任何帮助将不胜感激。
我有兴趣创建类似于游戏的着色器效果(不要因为使用此示例而射击我)动物穿越。当您沿着地形向前和向后移动时,世界会“弯曲”,给人一种圆形表面的感觉。问题是,我想将这种效果应用于 2D 横向卷轴。
想象一个像泰拉瑞亚这样的游戏,屏幕的两端(左右两侧)略微向下弯曲以产生弯曲的错觉。
我试图找到一篇解释如何实现这种效果的文章,但我没有太多有用的方向指示方式。我知道这不是最有条理或最恰当的问题,但任何帮助将不胜感激。
虽然我不喜欢回答自己的问题,但我想我已经找到了实现这种效果的方法,并愿意分享。通过设置一个基本的顶点着色器,我能够根据它与屏幕中心的距离(在我的例子中是原点)来操纵顶点沿 y 轴的位置。我最初使用线性绝对值方程来查看它是如何工作的,我得到了这样的结果: 这显然是一个奇怪的效果,但它已经非常接近我想要达到的效果了。我想我也会尝试通过将顶点与原点的距离的绝对值除以某个标量来平衡效果。我从 32 开始,结果更合理:
如您所见,地形只有轻微的弯曲。
这一切都很好,但它还不是“曲线”。它只是一个倒置的“V”,做了一点挤压。所以从这里开始,很容易通过使用抛物线并以相同的方式将其展平来应用漂亮的曲线。结果是这样的: 结果是一条非常漂亮的曲线,我可以将其修改为我想要的任何强度。我还尝试应用 3 次方程的图形,但它给人的感觉更像是一种尝试性的 3D 感觉。我想我可以应用圆图,这样当我在具有指定半径的行星上时,我可以准确地得到正确的曲线,但我现在很满意。
代码原来只有几行。这是顶点着色器的 GLSL 代码:
#version 150
varying vec4 vertColor; //Just to send the color data to the fragment shader
uniform float tx; //Passed by the Java program to ensure the terrain curvature
//is sinked by with player's movement, this value is usually
//in the "lookThroughCamera" method where you handle the game
//world's translation when the player moves
void main(void) {
float v0 = gl_Vertex[1] - pow((gl_Vertex[0] + tx) / 64, 2); //this will be the new y-value for the vertex.
//It takes the original y-value and subtracts
//the absolute value of the x-value plus the offset
//on the x-axis of the player divided by 64 all to
//the power of 2. The division by 64 levels the
//curve out enough so it looks acceptable
vec4 pos = vec4(gl_Vertex[0], v0, gl_Vertex[2], gl_Vertex[3]); //create the new position with the changed y-value
gl_Position = gl_ModelViewProjectionMatrix * pos; //multiply it by your projection and modelview matrices
vertColor = gl_Color.argb; //more color stuff that has nothing to do with the rest
}
编辑:这种方法确实有一个严重的问题。所有垂直线都将保持垂直,因为它们没有沿 x 轴正确移动。下图显示了这一点: 这看起来非常不自然,我还没有想出一个合适的解决方案。