我试图在屏幕上放一个立方体并将其点亮。我想在立方体上涂上丁字裤。

运行代码时,我可以看到背景图像,但看不到立方体。

我相当确定多维数据集本身是正确的,因为我设法使用了单色着色器进行显示。

我设法使着色器程序得以编译,但我根本看不到该多维数据集。我不知道GLES/LibGdx是否具有运行时异常的机制,但我在日志中看不到任何内容。

我假设

  • 该模型不在视野范围内
  • 该模型将呈现为透明

  • 我试图将代码缩减到我认为问题所在的位置。如果您需要查看其他内容,请询问。

    设置
    shader = new ShaderProgram(
            Gdx.files.internal("shaders/phongVertexShader.glsl"),
            Gdx.files.internal("shaders/phongFragmentShader.glsl"));
    if (!shader.isCompiled()) {
        throw new IllegalStateException(shader.getLog());
    }
    mesh = Shapes.genCube();
    mesh.getVertexAttribute(Usage.Position).alias = "a_position";
    mesh.getVertexAttribute(Usage.Normal).alias = "a_normal";
    

    使成为
    public void onRender() {
        Gdx.gl.glClearColor(0, 0, 0, 1);
        Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
        batch.setProjectionMatrix(camera.combined);
    
        angle += Gdx.graphics.getDeltaTime() * 40.0f;
        float aspect = Gdx.graphics.getWidth()
                / (float) Gdx.graphics.getHeight();
        projection.setToProjection(1.0f, 20.0f, 60.0f, aspect);
        view.idt().trn(0, 0, -2.0f);
        model.setToRotation(axis, angle);
        combined.set(projection).mul(view).mul(model);
    
        Gdx.gl20.glViewport(0, 0, Gdx.graphics.getWidth(),
            Gdx.graphics.getHeight());
    
        shader.begin();
    
        float[] light = {10, 10, 10};
    
        shader.setUniformMatrix("mvpMatrix", combined);
        shader.setUniformMatrix("mvMatrix", new Matrix4().translate(0, 0, -10));
        shader.setUniform3fv("vLightPosition", light, 0, 3);
    
        mesh.render(shader, GL20.GL_TRIANGLES);
        shader.end();
    }
    

    顶点着色器
    #version 330
    in vec4 vVertex;
    in vec3 vNormal;
    uniform mat4 mvpMatrix;  // mvp = ModelViewProjection
    uniform mat4 mvMatrix; // mv = ModelView
    uniform mat3 normalMatrix;
    uniform vec3 vLightPosition;
    smooth out vec3 vVaryingNormal;
    smooth out vec3 vVaryingLightDir;
    
    void main(void) {
        vVaryingNormal = normalMatrix * vNormal;
        vec4 vPosition4 = mvMatrix * vVertex;
        vec3 vPosition3 = vPosition4.xyz / vPosition4.w;
        vVaryingLightDir = normalize(vLightPosition - vPosition3);
        gl_Position = mvpMatrix * vVertex;
    }
    

    片段着色器
    #version 330
    out vec4 vFragColor;
    uniform vec4 ambientColor;
    uniform vec4 diffuseColor;
    uniform vec4 specularColor;
    smooth in vec3 vVaryingNormal;
    smooth in vec3 vVaryingLightDir;
    
    void main(void) {
        float diff = max(0.0, dot(normalize(vVaryingNormal), normalize(vVaryingLightDir)));
        vFragColor = diff * diffuseColor;
        vFragColor += 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, 32.0);
            vFragColor.rgb += vec3(fSpec, fSpec, fSpec);
        }
    }
    

    有人可以指出我正确的方向吗?

    最佳答案

    为了回答这个问题,将需要大量的解释和代码。我将首先从代码开始:

    LibGDX代码:

    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();
            }
        }
    }
    

    顶点着色器(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;
    }
    

    片段着色器(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;
    }
    

    解释:

    它看起来不像是很好的Phong着色器,因为没有正确计算立方体的法线。您可以在Shapes.genCube()内部找到该文件,但是由于我提供了其他所有内容,因此我将其留给您修复。

    确保查看着色器代码,这是OpenGL ES 2.0 GLSL,它与您发布的OpenGL 3.3 GLSL不同。这些是版本之间的一些差异。

    您需要做的是确保您提供的着色器值与着色器的变量匹配。您还需要确保正确设置矩阵并为光提供正确的值,以便正确显示。

    10-07 19:22
    查看更多