GLSL着色器圆圈正在摇摆,因为它在libgdx中改变了大小



在libgdx中,我创建了一个着色器来执行过渡效果,其中一个圆在图像顶部形成,其中圆形外部的所有东西都是黑色的,圆圈内的一切都如正常显示。这个圆圈开始大,一无所获。但是我有一个问题,因为圆圈正在缩小,它四处摆动。我还发现,在使用着色器之前,在使用着色器创建一个也随时间缩小的圆圈时,我也有这个问题。我认为问题与浮点数或圆圈呈现方式有关。无论如何,我需要知道,我该如何修复它,以便我可以使圆圈顺利地缩小?

这是一个gif,证明了我的摇摆圈问题(我需要光滑(:我的摇摆圈

这是我的片段着色器代码:

varying vec4 v_color;
varying vec3 v_position;
varying vec2 v_texCoord0;
uniform vec2 u_resolution;
uniform sampler2D u_sampler2D;
uniform float u_radius;
uniform int u_hasCircle;
void main() {
    vec4 color = texture2D(u_sampler2D, v_texCoord0) * v_color;
    vec2 relativePosition = gl_FragCoord.xy / u_resolution - .5;
    relativePosition.x *= u_resolution.x / u_resolution.y;
    float len = length(relativePosition);
    if (u_hasCircle == 1 && len > u_radius) {
        color = vec4(0, 0, 0, 1);
    }
    gl_FragColor = color;
}

这是我在此之前运行的顶点着色器代码:

属性vec4 a_color;属性vec3 a_position;属性VEC2 A_TEXCOORD0;

均匀MAT4 U_PROJTRANS;统一VEC3 U_DISTORT;

varying vec4 v_color;
varying vec3 v_position;
varying vec2 v_texCoord0;
void main() {
    v_color = a_color;
    v_position = a_position;
    v_texCoord0 = a_texCoord0;
    gl_Position = u_projTrans * vec4(a_position, 1.0);
}

当我想过渡到运行时,u_hascircle将传递1,否则将传递0。过渡运行时,我从传递u_radius 1开始,然后使用libgdx中的floataction逐渐将值降低到0。我将这些值发送给着色器一次。

这是与着色器交互的相关libgdx Java代码:

public class PlayWorld extends Group implements InputProcessor, Disposable
{
    //various members
    private PlayScreen screen;
    private OrthographicCamera camera;
    private FloatAction transitionToBattleAction;
    private final float TRANS_TO_BATTLE_DURATION = 10f;
    private float circleSize;
    private boolean hasCircle = false;
    public PlayWorld(PlayWorld playWorld) {
        this.playWorld = playWorld;
        camera = new OrthographicCamera();
        tiledMap = new TiledMapActor(camera);
        addActor(tiledMap);
        transitionToBattleAction = new FloatAction();
    }
    //function that triggers transition
    public void enterBattle() {
        transitionToBattleAction.reset();
        transitionToBattleAction.setStart(0);
        transitionToBattleAction.setEnd(1);
        transitionToBattleAction.setDuration(TRANS_TO_BATTLE_DURATION);
        addAction();
    }
    // this function gets called every frame
    @Override
    public void act(float delta) {
        super.act(delta);
        if (transitionToBattleAction.getValue() == 0) {
            //this function is defined in code shown below
            tiledMap.unsetCircleSize();
        } else if (transitionToBattleAction.getValue() < 1) {
            //this function is defined in code shown below
            tiledMap.setCircleSize(
                1 - transitionToBattleAction.getValue());
        } else if (transitionToBattleAction.getValue() == 1) {
            //this function is defined in code shown below
            tiledMap.setCircleSize(
                1 - transitionToBattleAction.getValue());
            transitionToBattleAction.restart();
            screen.getGame().setScreen("battle");
        } else if (transitionToBattleAction.getValue() > 1) {
            //this function is defined in code shown below
            tiledMap.unsetCircleSize();
          transitionToBattleAction.restart();
        }                
    }
    //this gets called whenever the window resizes
    public void resize(int width, int height) {
        // this function is defined in code shown below
        tiledMap.resize(width, height);
    }
    //various other methods
}

public class TiledMapActor extends Actor implements InputProcessor, Disposable
{
    //various variables
    private ShaderProgram shader;
    private OrthographicCamera camera;
    private TiledMap map;
    private OrthogonalTiledMapRenderer renderer;
    private float UNIT_SCALE = 1 / 16f;
    public TiledMapActor(OrthographicCamera camera) {
        super();
        this.camera = camera;
        map = new TmxMapLoader().load("myMap.tmx");
        renderer = new OrthogonalTiledMapRenderer(map, UNIT_SCALE);
        shader = new ShaderProgram(
            Gdx.files.internal("shaders/myshader.vsh"), 
            Gdx.files.internal("shaders/myshader.fsh");
        System.out.println(
            shader.isCompiled() ? 
                "shader compiled" : shader.getLog());
        renderer.getBatch().setShader(shader);
        shader.begin();
        shader.setUniformi("u_hasCircle", 0);
        shader.end();
    }
    // this is called every time the window changes size
    // from the PlayScreen class, see code above
    public void resize(int width, int height) {
        camera.viewportWidth = width;
        camera.viewportHeight = height;
        camera.update();
        shader.begin();
        shader.setUniformf("u_resolution", (float)width, (float)height);
        shader.end();
    }
    //this method is called from code above, seen PlayScreen class code
    //
    public void setCircleSize(float circleSize) {
        this.circleSize = circleSize;
        hasCircle = true;
        shader.begin();
        shader.setUniformf("u_radius", circleSize);
        shader.setUniformi("u_hasCircle", 1);
        shader.end();
    }
    //this method is called from code above, seen PlayScreen class code
    //
    public void unsetCircleSize() {
        hasCircle = false;
        shader.begin();
        shader.setUniformi("u_hasCircle", 0);
        shader.end();
    }
    // Various other methods
}

,所以我发现了这个问题,愚蠢的我!一旦启动,我都在重新进入过渡场景。我通过使用布尔标志来告诉我过渡是否启动,并且只有在尚未设置该布尔标志时才开始过渡。然后,在过渡完成后的某个点,我将布尔标志设置为false,以便再次发生过渡!

相关内容

  • 没有找到相关文章

最新更新