1

どうぶつの森のゲームに似たシェーダー効果を作成することに興味があります (この例を使用して私を撃たないでください)。地形に沿って前後に移動すると、世界が「湾曲」し、丸い面にいるような感覚になります。問題は、この種の効果を 2D 横スクロールに適用したいということです。

Terraria のようなゲームを想像してみてください。画面の両端 (左右) がわずかに下向きに曲がっていて、湾曲しているように見えます。

そのような効果を達成する方法を説明する記事を見つけようとしましたが、役立つ方向指示の方法はあまりありません. これが最も組織化された、または適切な質問ではないことはわかっていますが、助けていただければ幸いです。

4

1 に答える 1

0

Although I am not a fan of answering my own questions, I think I have found a way to achieve this effect and would like to share. By setting up a basic vertex shader, I was able to manipulate the location of the vertex along the y-axis depending on how far away it was from the center of the screen (the origin in my case). I originally used a linear absolute value equation to see how it worked, and I got something like this: enter image description here This is obviously a strange effect, but it is getting very close to what I want to achieve. I figured I would also try leveling the effect out by dividing the absolute value of the vertices' distance from the origin by some scalar. I started with 32 and the result was much more reasonable: enter image description here

As you can see, there is only a slight bend in the terrain.

This is all nice and all, but it isn't a "curve" yet. It is just an upside down 'V' with a bit of squashing done. So from here, it was easy to apply a nice curve by using a parabola and just flattening it out in the same fashion. The result was this: enter image description here The result was a very nice curve that I could modify to be any intensity I wanted. I also tried applying the graph of a 3rd degree equation, but it gave more of a try-hard 3D feel. I suppose I could apply the graph of a circle so I can accurately get the proper curve when I am on a planet with a specified radius, but I am satisfied for now.

The code turned out to be only a few lines long. Here is the GLSL code for the vertex shader:

#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
}

EDIT: This approach does have a serious issue though. All vertical lines will remain vertical due to the fact they are not shifted along the x-axis properly. This is shown by the following image: enter image description here This gives an extremely unnatural look, and I have yet to come up with a proper solution to this.

于 2013-06-19T19:08:25.710 に答える