Issue with shaders/matrices - can't see object

落花浮王杯 提交于 2019-12-05 08:09:54

To answer this question it is going to take a decent amount of explanation and code. I will first start with the code:

LibGDX Code:

public class Test extends Game {
    private final FPSLogger fpsLogger = new FPSLogger();
    private ShaderProgram shader;
    private Mesh mesh;
    Matrix4 projection = new Matrix4();
    Matrix4 view = new Matrix4();
    Matrix4 model = new Matrix4();
    Matrix4 combined = new Matrix4();
    Matrix4 modelView = new Matrix4();
    Matrix3 normalMatrix = new Matrix3();
    Vector3 axis = new Vector3(1, 0, 1).nor();
    float angle = 45;

    private static final float[] light = { 20, 20, 20 };

    private static final float[] amb = { 0.2f, 0.2f, 0.2f, 1.0f };
    private static final float[] dif = { 0.5f, 0.5f, 0.5f, 1.0f };
    private static final float[] spec = { 0.7f, 0.7f, 0.7f, 1.0f };

    public Test() {}

    @Override public void create() {
        this.mesh = Shapes.genCube();
        ShaderProgram.pedantic = false;
        final String location = "shaders/phong";
        this.shader = new ShaderProgram(Gdx.files.internal(location + ".vsh").readString(), Gdx.files.internal(location + ".fsh").readString());
        if (!this.shader.isCompiled()) {
            Gdx.app.log("Problem loading shader:", this.shader.getLog());
        }

        Gdx.gl20.glEnable(GL20.GL_DEPTH_TEST);
    }

    @Override public void render() {
        super.render();
        this.fpsLogger.log();

        this.angle += Gdx.graphics.getDeltaTime() * 40.0f;
        final float aspect = Gdx.graphics.getWidth() / (float) Gdx.graphics.getHeight();
        this.projection.setToProjection(1.0f, 20.0f, 60.0f, aspect);
        this.view.idt().trn(0, 0, -2.0f);
        this.model.setToRotation(this.axis, this.angle);
        this.combined.set(this.projection).mul(this.view).mul(this.model);
        this.modelView.set(this.view).mul(this.model);

        Gdx.gl20.glViewport(0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
        Gdx.gl20.glClear(GL20.GL_COLOR_BUFFER_BIT | GL20.GL_DEPTH_BUFFER_BIT);
        this.shader.begin();

        this.shader.setUniformMatrix("mvpMatrix", this.combined);
        this.shader.setUniformMatrix("mvMatrix", this.modelView);
        this.shader.setUniformMatrix("normalMatrix", this.normalMatrix.set(this.modelView).inv().transpose());
        this.shader.setUniform4fv("ambientColor", amb, 0, 4);
        this.shader.setUniform4fv("diffuseColor", dif, 0, 4);
        this.shader.setUniform4fv("specularColor", spec, 0, 4);
        this.shader.setUniform3fv("vLightPosition", light, 0, 3);

        this.mesh.render(this.shader, GL20.GL_TRIANGLES);

        this.shader.end();
    }

    @Override public void dispose() {
        if (this.mesh != null) {
            this.mesh.dispose();
        }
        if (this.shader != null) {
            this.shader.dispose();
        }
    }
}

Vertex Shader (phong.vsh)

attribute vec3 a_position;
attribute vec3 a_normal;
uniform mat4 mvpMatrix;  // mvp = ModelViewProjection
uniform mat4 mvMatrix; // mv = ModelView
uniform mat3 normalMatrix;
uniform vec3 vLightPosition;

varying vec3 vVaryingNormal;
varying vec3 vVaryingLightDir;

void main(void) {
    vVaryingNormal = normalMatrix * a_normal;
    vec4 vPosValue = vec4(a_position.x, a_position.y, a_position.z, 1.0);
    vec4 vPosition4 = mvMatrix * vPosValue;
    vec3 vPosition3 = a_position;
    vVaryingLightDir = normalize(vLightPosition - vPosition3);
    gl_Position = mvpMatrix * vPosValue;
}

Fragment Shader (phong.fsh)

#ifdef GL_ES
precision mediump float;
#endif

uniform vec4 ambientColor;
uniform vec4 diffuseColor;
uniform vec4 specularColor;
varying vec3 vVaryingNormal;
varying vec3 vVaryingLightDir;

void main(void) {
    float diff = max(0.0, dot(normalize(vVaryingNormal), normalize(vVaryingLightDir)));
    vec4 color = diff * diffuseColor;
    color += ambientColor;
    vec3 vReflection = normalize(reflect(-normalize(vVaryingLightDir),normalize(vVaryingNormal)));
    float spec = max(0.0, dot(normalize(vVaryingNormal), vReflection));

    if(diff != 0) {
        float fSpec = pow(spec, 128.0);
        color.rgb += vec3(fSpec, fSpec, fSpec);
    }

    gl_FragColor = color;
}

Explanation:

It doesn't look like a very good Phong shader because the normals for the cube are not properly calculated. Which you can find inside of the Shapes.genCube() but I will leave that for you to fix since I've provided everything else.

Make sure to look over the shader code, this is OpenGL ES 2.0 GLSL, which is different than the OpenGL 3.3 GLSL you have posted. These are some of the few differences between the versions.

What you need to do is make sure the values you provide the shader match the shader's variables. You also need to make sure to setup your matrices correctly and supply proper values for the light so that it displays correctly.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!