我正试图在屏幕上放一个立方体并点亮它。我想在立方体上加一个阴影。
当我运行我的代码时,我可以看到背景图像,但没有立方体。
我很确定立方体本身是正确的,因为我已经设法用纯色着色器显示它。
我设法让shader程序编译但我根本看不到立方体。我不知道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);
}
}
有人能指出我正确的方向吗?
答案 0 :(得分:4)
要回答这个问题,需要大量的解释和代码。我将首先介绍代码:
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不同。这些是版本之间的一些差异。
您需要做的是确保您为着色器提供的值与着色器的变量匹配。您还需要确保正确设置矩阵并为灯提供正确的值,以便正确显示。