使用着色器的Libgdx、Alpha文本不起作用



使用Stage操作在文本中应用alpha(使用着色器)时遇到一些问题。我正在使用Group添加Window actor和Window添加Label actor。小组中的另一个参与者正在精细地应用Actions alpha,但我的标签(使用着色器绘制)不起作用,与其他小部件不同的是,我的文本标签正在应用着色器。

font.frag均匀采样2D u_ texture;

varying vec4 v_color;
varying vec2 v_texCoord;
const float smoothing = 0.2;
void main() {
    float distance = texture2D(u_texture, v_texCoord).a;
    float alpha = smoothstep(0.5 - smoothing, 0.5 + smoothing, distance);
    gl_FragColor = vec4(texture2D(u_texture, v_texCoord).rgb, alpha);
}

font.vert

uniform mat4 u_projTrans;
attribute vec4 a_position;
attribute vec2 a_texCoord0;
attribute vec4 a_color;
varying vec4 v_color;
varying vec2 v_texCoord;
void main() {
    gl_Position = u_projTrans * a_position;
    v_texCoord = a_texCoord0;
    v_color = a_color;
}

我的标签将标签从Libgdx扩展到应用着色器,

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.g2d.Batch;
public class Label extends com.badlogic.gdx.scenes.scene2d.ui.Label {
    boolean shaderActive = false;
    public Label(CharSequence text, LabelStyle style) {
        super(text, style);
        if(style.font.getScaleX() > 1f)
            shaderActive = true;
    }
    @Override
    public void draw(Batch batch, float parentAlpha) {
        if(shaderActive) {
            batch.setShader(Assets.assetFont.fontShader);
        }
        super.draw(batch, parentAlpha);
        batch.setShader(null);          
    }
}

工作代码

private void initStage() {
    // TODO Stage Here
    stage = new Stage();
    stage.setViewport(viewport);
    Window w2 = new Window("",
            new WindowStyle(Assets.assetFont.blackBoldVSmall, Color.BLACK,
                    new Image(Assets.assetHUD.windowFrame).getDrawable()) );
    w2.setSize(1200, 675);
    w2.setPosition(40, 0);
    Label lbl2 = new Label("Touch here to Jump !", new LabelStyle(Assets.assetFont.goldBoldNormal, Color.GRAY));
    lbl2.setPosition(Settings.width/2, Settings.height/2);
    w2.add(lbl2);
    groupTouchHere.addActor(w2);    
    stage.addActor(groupTouchHere); 
    // sequence of action
    SequenceAction sequence = new SequenceAction(
        Actions.fadeIn(0.4f, Interpolation.circleOut), 
        Actions.fadeOut(0.4f, Interpolation.circleIn));
    SequenceAction sequenceTotal = new SequenceAction(sequence, Actions.repeat(4, sequence));
    groupTouchHere.addAction(sequenceTotal);
}
public void update(float deltaTime){
    stage.act();
}

我不是着色器专家,但我以我认为简单的方式成功地做到了这一点。(我可能很困惑)。

在我的java代码中,我的Main函数中有一个变量,它保存alpha值(我只在游戏状态转换中使用一个):

public static float newAlph = 1;

在我的*.vert文件中,我声明了一个统一变量,以alpha作为输入,然后将其值设置为一个可变变量,这样.frag文件就可以获得它。

...
uniform float u_newAlpha;
varying float v_newAlpha;
...
void main() {
    ...
    v_newAlpha = u_newAlpha;
}

然后在.frag文件中,我声明相同的可变变量,并简单地乘以alpha。

...
varying float v_newAlpha;
...
void main() {
    ...
    gl_FragColor = vec4(v_color.rgb, alpha*v_newAlpha);
}

最后,当调用着色器时,我设置alpha值(这将在draw方法中的标签类中进行)

sb.setShader(fontShader);
fontShader.setUniformf("u_newAlpha", Main.newAlph);

因此,即使其他正在渲染的所有对象的alpha都在更改,该着色器也会使用它所具有的alpha来渲染任何正在渲染的对象。

在我的例子中,我使用了主类中的一个公共变量,但您的绘制方法将alpha作为输入,因此将其设置为.vert文件中的统一变量应该可以工作。

这样你就会有:

public void draw(Batch batch, float parentAlpha) {
        if(shaderActive) {
            batch.setShader(Assets.assetFont.fontShader);
        }
        Assets.assetFont.fontShader.setUniformf("u_newAlpha", parentAlpha);
        super.draw(batch, parentAlpha);
        batch.setShader(null);          
    }

如果有道理,请告诉我!

最新更新