我终于努力学习如何编写着色器,并且我对它们的工作原理有了相当不错的了解。问题是,我无法检索统一结构的统一位置。现在我知道你必须查询每个单独的内部成员的位置,我正在做,而且我也知道如果 GL 确定统一不影响最终输出,它就会被优化掉(老实说这不是丝毫没有坏事)。
问题是,它没有找到用于影响片段着色器输出的制服。
在我的着色器类中,我有一个名为“GetAndStoreUniformLocation”的函数(我喜欢用名称来描述 - 确保清楚该函数的作用)!这个函数只是抓取给定统一名称的位置并将其插入 map ,所以我不必在每一帧都查询 OpenGL 的位置(我不确定这可能会或可能不会优化多好...在这个阶段还处于试验阶段)。此功能适用于所有由标准类型组成的制服。
问题(TL;DR):
为什么我无法从着色器中检索“ Material ”制服成员的位置?它不应该被优化掉,我正在将“material.*”(其中 * 是成员名称)传递给 glGetUniformLocation()。
我觉得我可能遗漏了一些明显的东西,但我已经在 OpenGL 文档和其他人的类似问题的帖子上搜索过,到目前为止没有提供任何有用的东西,只有优化删除的建议制服,但是,我怀疑是这种情况,因为它正在输出中使用。
我已经尝试在加载、编译和链接着色器后直接调用 glGetUniformLocation(),用于矩阵制服(成功)和 Material 。*制服(失败)。
代码
加载着色器后,我激活它以便访问统一位置,然后调用:
v_primaryShader.GetAndStoreUniformLocation("material.ambient");
v_primaryShader.GetAndStoreUniformLocation("material.diffuse");
v_primaryShader.GetAndStoreUniformLocation("material.specular");
Shader::GetAndStoreUniformLocation(const GLchar* uniformName)
void Shader::GetAndStoreUniformLocation(const GLchar* uniformName)
{
GLint location = glGetUniformLocation(this->v_programID, uniformName);
if (location != -1)
{
v_uniformLocations.insert(std::pair<const GLchar*, GLint>(uniformName, location));
Debug::LogDebug("Uniform stored for shader '" + v_name + "': name: '" + std::string(uniformName) + "', location: '" + std::to_string(location) + "'");
return;
}
ThrowException("Shader>GetAndStoreUniformLocation: Could not find uniform '" + std::string(uniformName) + "' in shader '" + this->v_name + "'.");
}
着色器::调试(无效)
void Shader::Debug(void) const
{
GLint i;
GLint count;
GLint size;
GLenum type;
const GLsizei bufSize = 25;
GLchar name[bufSize];
GLsizei length;
Debug::LogDebug("Debugging shader '" + this->v_name + "':");
glGetProgramiv(this->v_programID, GL_ACTIVE_ATTRIBUTES, &count);
Debug::LogDebug(" - Attributes (" + std::to_string(count) + " in total; numbers do not correspond to locations!): ");
for (i = 0; i < count; i++)
{
glGetActiveAttrib(this->v_programID, (GLuint)i, bufSize, &length, &size, &type, name);
int location = glGetAttribLocation(this->v_programID, name);
Debug::LogDebug(" - Attribute " + std::to_string(i) + " = name: '" + name + "', location: " + std::to_string(location) + ", type: " + TypeToString(type));
}
glGetProgramiv(this->v_programID, GL_ACTIVE_UNIFORMS, &count);
Debug::LogDebug(" - Uniforms (" + std::to_string(count) + " in total; numbers do not correspond to locations!): ");
for (i = 0; i < count; i++)
{
glGetActiveUniform(this->v_programID, (GLuint)i, bufSize, &length, &size, &type, name);
int location = glGetUniformLocation(this->v_programID, name);
Debug::LogDebug(" - Uniform " + std::to_string(i) + " = name: '" + name + "', location: " + std::to_string(location) + ", type: " + TypeToString(type));
}
}
片段着色器(GLSL):
#version 440
struct Material
{
vec3 ambient;
vec3 diffuse;
vec3 specular;
//sampler2D diffuse_texture;
//sampler2D specular_texture;
};
in vec3 pass_position;
in vec3 pass_normal;
in vec2 pass_uv;
uniform Material material;
uniform sampler2D texture0; // TODO: remove later
uniform vec3 light_position;
uniform vec3 camera_position;
out vec4 result;
void main(void)
{
// Ambient light
vec3 _ambient_final = material.ambient;
// Diffuse light
vec3 _position_to_light_directional_vector = normalize(light_position - pass_position);
float _diffuse_dot_product = clamp(dot(_position_to_light_directional_vector, pass_normal), 0, 1);
vec3 _diffuse_final = material.diffuse * _diffuse_dot_product;
// Specular light
vec3 _light_to_position_directional_vector = normalize(light_position - pass_position);
vec3 _reflect_directional_vector = normalize(reflect(_light_to_position_directional_vector, normalize(pass_normal)));
vec3 _position_to_view_directional_vector = normalize(pass_position - camera_position);
float _specular_constant = pow(max(dot(_position_to_view_directional_vector, _reflect_directional_vector), 0), 70); // final number = smoothness
vec3 _specular_final = material.specular * _specular_constant;
// Attenuation (todo)
// Final light (todo)
result = texture(texture0, pass_uv) * (vec4(_ambient_final, 1.F) + vec4(_diffuse_final, 1.F) + vec4(_specular_final, 1.F));
}
结果(错误)
Shader 类还有一个 Debug() 函数,可以打印所有属性和制服。我得到的输出是:
(call to v_primaryShader.Debug() )
[ DEBUG ] Debugging shader 'primary':
[ DEBUG ] - Attributes (3 in total; numbers do not correspond to locations!):
[ DEBUG ] - Attribute 0 = name: 'vertex_normal', location: 1, type: vec3
[ DEBUG ] - Attribute 1 = name: 'vertex_position', location: 0, type: vec3
[ DEBUG ] - Attribute 2 = name: 'vertex_uv', location: 2, type: vec2
[ DEBUG ] - Uniforms (6 in total; numbers do not correspond to locations!):
[ DEBUG ] - Uniform 0 = name: 'camera_position', location: 0, type: vec3
[ DEBUG ] - Uniform 1 = name: 'light_position', location: 1, type: vec3
[ DEBUG ] - Uniform 2 = name: 'model_matrix', location: 2, type: mat4
[ DEBUG ] - Uniform 3 = name: 'projection_matrix', location: 3, type: mat4
[ DEBUG ] - Uniform 4 = name: 'texture0', location: 4, type: sampler2D
[ DEBUG ] - Uniform 5 = name: 'view_matrix', location: 5, type: mat4
(calls to v_primaryShader.GetAndStoreUniformLocation() )
[ DEBUG ] Uniform stored for shader 'primary': name: 'model_matrix', location: '2'
[ DEBUG ] Uniform stored for shader 'primary': name: 'view_matrix', location: '5'
[ DEBUG ] Uniform stored for shader 'primary': name: 'projection_matrix', location: '3'
[ DEBUG ] Uniform stored for shader 'primary': name: 'light_position', location: '1'
[ DEBUG ] Uniform stored for shader 'primary': name: 'camera_position', location: '0'
[ CRITICAL ] Exception during phase 'LOAD'
[ CRITICAL ] Shader>GetAndStoreUniformLocation: Could not find uniform 'material.ambient' in shader 'primary'.
,所以它肯定让所有其他制服都很好。但是“ Material ”无处可寻,但是,正如您在着色器代码中看到的那样,“ Material ”结构的内部成员用于照明,用于颜色的最终输出。是的,我完全知道代码可能不正确或未优化......但是当我放下样板时,我只需要在其中添加一堆东西以使其在基本级别上工作。 Lighting 在制作结构之前一直在工作(之前,我只是使用硬编码值)
最佳答案
事实证明,问题是 IDE 删除了将 Assets (着色器、纹理等)复制到构建目录的批处理文件,并且没有迹象表明发生了这种情况,也没有任何真正的原因。我已经把文件放回去了,现在可以用了。 我可能真的应该检查构建目录中的着色器文件以确保它是最新的,但我并没有想到这一点(如果我更聪明的话,它肯定应该有) ,但在我的困惑和沮丧中,我一直在寻找代码中的错误。
绝对是一个意想不到的结果,但我很高兴这意味着代码/驱动程序没有错误。
关于c++ - 着色器统一要么优化不当要么找不到,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57893002/