着色器/矩阵问题 - 看不到对象 [英] Issue with shaders/matrices - can't see object

查看:151
本文介绍了着色器/矩阵问题 - 看不到对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正试图在屏幕上放一个立方体并点亮它。我想在立方体上使用phong阴影。

I'm attempting to put a cube on the screen and light it. I'd like a phong shading on the cube.

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

When I run my code, I can see a background image but no cube.

我很确定立方体本身是正确的,因为我设法用纯色着色器显示它。

I'm fairly sure the cube itself is correct as I've managed to display it with a solid-colour shader.

我是设法让着色器程序编译,但我根本看不到立方体。我不知道GLES / LibGdx是否有运行时异常的机制,但我在日志中看不到任何内容。

I've managed to get the shader program to compile but I can't see the cube at all. I don't know if GLES/LibGdx have a mechanism for run-time exceptions but I can't see anything in the logs.

我假设


  • 模型不在视野范围内

  • 模型呈现透明

  • 两者

我试图将我的代码削减到相信的地方问题在于。如果您还需要查看其他内容,请询问。

I've tried to pare down my code to where I believe the problem lies. If you need to see anything else, just ask.

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";



渲染



Render

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



Vertex Shader



Vertex Shader

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



片段着色器



Fragment Shader

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






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


Can someone point me in the right direction?

推荐答案

要回答这个问题,需要大量的解释和代码。我将首先介绍代码:

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

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

Vertex Shader(phong.vsh )

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

片段着色器(phong.fsh)

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

说明:

它看起来不像一个非常好的Phong着色器,因为没有正确计算立方体的法线。您可以在Shapes.genCube()中找到,但我会留下您修复,因为我已经提供了其他所有内容。

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.

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

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.

这篇关于着色器/矩阵问题 - 看不到对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆