我正在尝试在屏幕上放置一个立方体并点亮它。我想要立方体上的 phong 阴影。
当我运行我的代码时,我可以看到背景图像但看不到立方体。
我相当确定立方体本身是正确的,因为我已经设法使用纯色着色器来显示它。
我已经成功编译了着色器程序,但我根本看不到立方体。我不知道 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 不同。这些是版本之间的一些差异。
您需要做的是确保您提供给着色器的值与着色器的变量相匹配。您还需要确保正确设置矩阵并为灯光提供正确的值,以便它正确显示。
关于java - 着色器/矩阵问题 - 看不到对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15398184/
总的来说,我对ruby还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用
在控制台中反复尝试之后,我想到了这种方法,可以按发生日期对类似activerecord的(Mongoid)对象进行分组。我不确定这是完成此任务的最佳方法,但它确实有效。有没有人有更好的建议,或者这是一个很好的方法?#eventsisanarrayofactiverecord-likeobjectsthatincludeatimeattributeevents.map{|event|#converteventsarrayintoanarrayofhasheswiththedayofthemonthandtheevent{:number=>event.time.day,:event=>ev
我想为Heroku构建一个Rails3应用程序。他们使用Postgres作为他们的数据库,所以我通过MacPorts安装了postgres9.0。现在我需要一个postgresgem并且共识是出于性能原因你想要pggem。但是我对我得到的错误感到非常困惑当我尝试在rvm下通过geminstall安装pg时。我已经非常明确地指定了所有postgres目录的位置可以找到但仍然无法完成安装:$envARCHFLAGS='-archx86_64'geminstallpg--\--with-pg-config=/opt/local/var/db/postgresql90/defaultdb/po
尝试通过RVM将RubyGems升级到版本1.8.10并出现此错误:$rvmrubygemslatestRemovingoldRubygemsfiles...Installingrubygems-1.8.10forruby-1.9.2-p180...ERROR:Errorrunning'GEM_PATH="/Users/foo/.rvm/gems/ruby-1.9.2-p180:/Users/foo/.rvm/gems/ruby-1.9.2-p180@global:/Users/foo/.rvm/gems/ruby-1.9.2-p180:/Users/foo/.rvm/gems/rub
我有一个表单,其中有很多字段取自数组(而不是模型或对象)。我如何验证这些字段的存在?solve_problem_pathdo|f|%>... 最佳答案 创建一个简单的类来包装请求参数并使用ActiveModel::Validations。#definedsomewhere,atthesimplest:require'ostruct'classSolvetrue#youcouldevencheckthesolutionwithavalidatorvalidatedoerrors.add(:base,"WRONG!!!")unlesss
好的,所以我的目标是轻松地将一些数据保存到磁盘以备后用。您如何简单地写入然后读取一个对象?所以如果我有一个简单的类classCattr_accessor:a,:bdefinitialize(a,b)@a,@b=a,bendend所以如果我从中非常快地制作一个objobj=C.new("foo","bar")#justgaveitsomerandomvalues然后我可以把它变成一个kindaidstring=obj.to_s#whichreturns""我终于可以将此字符串打印到文件或其他内容中。我的问题是,我该如何再次将这个id变回一个对象?我知道我可以自己挑选信息并制作一个接受该信
我的最终目标是安装当前版本的RubyonRails。我在OSXMountainLion上运行。到目前为止,这是我的过程:已安装的RVM$\curl-Lhttps://get.rvm.io|bash-sstable检查已知(我假设已批准)安装$rvmlistknown我看到当前的稳定版本可用[ruby-]2.0.0[-p247]输入命令安装$rvminstall2.0.0-p247注意:我也试过这些安装命令$rvminstallruby-2.0.0-p247$rvminstallruby=2.0.0-p247我很快就无处可去了。结果:$rvminstall2.0.0-p247Search
如果您尝试在Ruby中的nil对象上调用方法,则会出现NoMethodError异常并显示消息:"undefinedmethod‘...’fornil:NilClass"然而,有一个tryRails中的方法,如果它被发送到一个nil对象,它只返回nil:require'rubygems'require'active_support/all'nil.try(:nonexisting_method)#noNoMethodErrorexceptionanymore那么try如何在内部工作以防止该异常? 最佳答案 像Ruby中的所有其他对象
由于fast-stemmer的问题,我很难安装我想要的任何rubygem。我把我得到的错误放在下面。Buildingnativeextensions.Thiscouldtakeawhile...ERROR:Errorinstallingfast-stemmer:ERROR:Failedtobuildgemnativeextension./System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/bin/rubyextconf.rbcreatingMakefilemake"DESTDIR="cleanmake"DESTDIR=
我在Rails工作并有以下类(class):classPlayer当我运行时bundleexecrailsconsole然后尝试:a=Player.new("me",5.0,"UCLA")我回来了:=>#我不知道为什么Player对象不会在这里初始化。关于可能导致此问题的操作/解释的任何建议?谢谢,马里奥格 最佳答案 havenoideawhythePlayerobjectwouldn'tbeinitializedhere它没有初始化很简单,因为你还没有初始化它!您已经覆盖了ActiveRecord::Base初始化方法,但您没有调