问题在标题中。
控制台错误
LWJGL Version: 3.0.0 build 90
GLFW Version: 3.2.0 Win32 WGL EGL VisualC DLL
OpenGL Version: 4.0.0 NVIDIA 372.70
java.lang.Exception: Can't find uniform: lightColor
at com.ms.shaders.ShaderProgram.getUniformLocation(ShaderProgram.java:50)
at com.ms.shaders.Shaders.createUniforms(Shaders.java:32)
ShaderProgram
public class ShaderProgram {
private int programID;
private int vertexShaderID;
private int fragmentShaderID;
private Map<String, Integer> uniforms;
public ShaderProgram() {
uniforms = new HashMap<>();
}
public void createProgram() throws Exception {
programID = glCreateProgram();
if(programID == 0) {
throw new Exception("Failed to create program");
}
}
public void createShaders(String vertexFile, String fragmentFile) throws Exception {
vertexShaderID = shadersLoader(vertexFile, GL_VERTEX_SHADER);
}
protected void bindAttribute(int attribute, String name) {
glBindAttribLocation(programID, attribute, name);
}
public void getUniformLocation(String uniform) throws Exception {
int uniformLocation = glGetUniformLocation(programID, uniform);
if(uniformLocation < 0) {
throw new Exception("Can't find uniform: " + uniform);
}
uniforms.put(uniform, uniformLocation);
}
public void floatUniforms(String uniform, float value) {
glUniform1f(uniforms.get(uniform), value);
}
public void intUniforms(String uniform, int value) {
glUniform1i(uniforms.get(uniform), value);
}
public void booleanUniforms(String uniform, boolean value) {
float load = 0;
if(value) {
load = 1;
}
glUniform1f(uniforms.get(uniform), load);
}
public void vectorUniforms(String uniform, Vector3f value) {
glUniform3f(uniforms.get(uniform), value.x, value.y, value.z);
}
public void matrixUniforms(String uniform, Matrix4f value) {
FloatBuffer buffer = BufferUtils.createFloatBuffer(16);
value.get(buffer);
glUniformMatrix4fv(uniforms.get(uniform), false, buffer);
}
public int shadersLoader(String shader, int type) throws Exception {
int shaderID = glCreateShader(type);
glShaderSource(shaderID, shader);
glCompileShader(shaderID);
if(glGetShaderi(shaderID, GL_COMPILE_STATUS) == 0) {
throw new Exception("Failed to compile Shader: " + glGetShaderInfoLog(shaderID, 1024));
}
glAttachShader(programID, shaderID);
return shaderID;
}
public void linkProgram() throws Exception {
glLinkProgram(programID);
if(glGetProgrami(programID, GL_LINK_STATUS) == 0) {
throw new Exception("Failed to link program: " + glGetProgramInfoLog(programID, 1024));
}
glValidateProgram(programID);
if(glGetProgrami(programID, GL_VALIDATE_STATUS) == 0) {
throw new Exception("Failed to validate program: " + glGetProgramInfoLog(programID, 1024));
}
}
public void bind() {
glUseProgram(programID);
}
public void unbind() {
glUseProgram(0);
}
public void cleanUp() {
unbind();
if(programID != 0) {
if(vertexShaderID != 0) {
glDetachShader(programID, vertexShaderID);
glDeleteShader(vertexShaderID);
}
if(fragmentShaderID != 0) {
glDetachShader(programID, fragmentShaderID);
glDeleteShader(fragmentShaderID);
}
glDeleteProgram(programID);
}
}
}
着色
public class Shaders extends ShaderProgram {
private static final String VERTEX_SHADER = "vertexShader.txt";
private static final String FRAGMENT_SHADER = "fragmentShader.txt";
public void init() throws Exception {
createProgram();
createShaders(FileLoader.loadResources(VERTEX_SHADER), FileLoader.loadResources(FRAGMENT_SHADER));
linkProgram();
createUniforms();
}
public void bindAttributes() {
bindAttribute(0, "position");
bindAttribute(1, "textureCoords");
bindAttribute(2, "normal");
}
public void createUniforms() throws Exception {
getUniformLocation("transformationMatrix");
getUniformLocation("projectionMatrix");
getUniformLocation("viewMatrix");
getUniformLocation("lightPosition");
getUniformLocation("lightColor");
getUniformLocation("shineDamper");
getUniformLocation("reflectivity");
}
}
fragmentShader.txt
#version 400 core
in vec2 outTextureCoords;
in vec3 surfaceNormal;
in vec3 toLightVector;
in vec3 toCameraVector;
out vec4 outColor;
uniform sampler2D textureSampler;
uniform vec3 lightColor;
uniform float shineDamper;
uniform float reflectivity;
void main()
{
vec3 unitNormal = normalize(surfaceNormal);
vec3 unitLightVector = normalize(toLightVector);
float nDotl = dot(unitNormal, unitLightVector);
float brightness = max(nDotl, 0.2);
vec3 diffuse = brightness * lightColor;
vec3 unitVectorToCamera = normalize(toCameraVector);
vec3 lightDirection = -unitLightVector;
vec3 reflectedLightDirection = reflect(lightDirection, unitNormal);
float specularFactor = dot(reflectedLightDirection, unitVectorToCamera);
specularFactor = max(specularFactor, 0.0);
float dampFactor = pow(specularFactor, shineDamper);
vec3 finalSpecular = dampFactor * reflectivity * lightColor;
outColor = vec4(diffuse, 1.0) * texture(textureSampler, outTextureCoords) + vec4(finalSpecular, 1.0);
}
如果我尝试删除lightColor,请在shineDamper制服中进行错误切换。
EDITED
如果我把全部放在Renderer课程中,问题就不存在......为什么?
这是我设置制服的课程:
UniformCreation
public class UniformsCreation {
private Transformation transformation;
private ShaderProgram shaders;
private float FOV = (float) Math.toRadians(60.0f);
private float zNEAR = 0.01f;
private float zFAR = 1000.0f;
public UniformsCreation() {
transformation = new Transformation();
shaders = new ShaderProgram();
}
public void renderer(Entity[] entity, Camera camera, Light light) {
createProjectionMatrix();
createTransformationMatrix(entity);
createViewMatrix(camera);
createLight(light, Texture.getShineDamper(), Texture.getReflection());
}
public Matrix4f createProjectionMatrix() {
Matrix4f projectionMatrix = new Matrix4f();
projectionMatrix = transformation.createProjectionMatrix(
FOV,
Main.getWIDTH(),
Main.getHEIGHT(),
zNEAR,
zFAR);
shaders.matrixUniforms("projectionMatrix", projectionMatrix);
return projectionMatrix;
}
public Matrix4f createTransformationMatrix(Entity[] entity) {
Matrix4f transformationMatrix = new Matrix4f();
for(Entity entities : entity) {
transformationMatrix = transformation.createTransformationMatrix(
entities.getPosition(),
entities.getRotation(),
entities.getScale());
shaders.matrixUniforms("transformationMatrix", transformationMatrix);
entities.getMesh().render();
}
return transformationMatrix;
}
public Matrix4f createViewMatrix(Camera camera) {
Matrix4f viewMatrix = new Matrix4f();
viewMatrix = transformation.createViewMatrix(camera);
shaders.matrixUniforms("viewMatrix", viewMatrix);
return viewMatrix;
}
public void createLight(Light light, float damper, float reflectivity) {
shaders.vectorUniforms("lightPosition", light.getPosition());
shaders.vectorUniforms("lightColor", light.getColor());
shaders.floatUniforms("shineDamper", damper);
shaders.floatUniforms("reflectivity", reflectivity);
}
}
如果我删除lightColor,shineDamper和reflectivity制服,则错误为:
java.lang.NullPointerException
at com.ms.shaders.ShaderProgram.matrixUniforms(ShaderProgram.java:83)
at com.ms.utils.UniformsCreation.createProjectionMatrix(UniformsCreation.java:46)
at com.ms.utils.UniformsCreation.renderer(UniformsCreation.java:29)
at com.ms.renderer.Renderer.render(Renderer.java:42)
at com.ms.MineSmooth.gameLoop(MineSmooth.java:93)
at com.ms.MineSmooth.run(MineSmooth.java:56)
at java.lang.Thread.run(Unknown Source)
答案 0 :(得分:0)
负均匀位置为perfectly cromulent:
虽然不是严格意义上的错误,但有些人想知道为什么glGetUniformLocation 返回-1。如果你没有使用制服,那就是司机 将优化你的制服。司机非常善于优化 码。如果您使用的是制服,但没有计算出任何值 从那个制服贡献到着色器的任何输出(直接 或间接),制服通常会被优化。通常这不是问题,因为如果你传递-1而不是a 有效统一的位置到glUniform调用,他们会悄然做 无论如何都没有。但如果拼错变量,你也会得到-1 命名为glGetUniformLocation,所以请记住这一点。
通过shader introspection API枚举统一名称,以检查拼写错误。