在现代(GL3.3 +)GPU上使用GLSL时,在制服上分支的可能成本是多少?
在我的引擎中,我已经到了我有很多着色器的地步.我有很多不同的质量预设.就目前而言,我在着色器中使用带if()的制服来选择不同质量的预设.然而,我担心通过重新编译着色器并使用#ifdef可以获得更好的性能.问题是当我重新编译着色器时需要担心跟踪和重置其他制服.
基本上我想知道的是我的恐惧是否毫无根据.在现代GPU上以均匀便宜的方式分支?我自己做了一些测试,发现两种方式差别不大,但我只测试了nVidia 680.
所以,我在GLSL和GLM之间遇到了一些奇怪之处.
如果我生成以下视图矩阵(C++):
vec3 pos(4, 1, 1);
vec3 dir(1, 0, 0);
mat4 viewMat = glm::lookAt(pos, pos+dir, vec3(0,0,1));
Run Code Online (Sandbox Code Playgroud)
然后,在glsl中,执行:
fragColour.rgb = vec3(inverse(viewMat) * vec4(0,0,0,1)) / 4.f;
Run Code Online (Sandbox Code Playgroud)
然后我希望屏幕变成粉红色,或(1.0,0.25,0.25).相反,我变黑了.
但是,如果我在GLM中执行此操作:
vec3 colour = vec3(glm::inverse(viewMat) * vec4(0,0,0,1)) / 4.f;
cout << glm::to_string(colour) << endl;
Run Code Online (Sandbox Code Playgroud)
我得到了期望的结果(1.0,0.25,0.25).
现在,如果我将viewMat更改为(C++):
vec3 pos(4, 1, 1);
vec3 dir(1, 0.000001, 0);
mat4 viewMat = glm::lookAt(pos, pos+dir, vec3(0,0,1));
Run Code Online (Sandbox Code Playgroud)
然后bam!我在GLSL和GLM中得到(1.0,0.25,0.25).
这对我来说毫无意义.为什么这样做?这个视图矩阵在GLSL中的其他任何地方都可以正常工作 - 我只是无法反转它.只要dirY == 0.f,就会发生这种情况.
另外,请提出问题标题的改进建议,我不确定它应该是什么.
编辑:此外,它似乎与lookAt的向上向量(我设置为Z无论如何)有任何关系.即使我设置为(0,1,0),也会发生同样的事情.一切都转向侧面,但我仍然无法反转GLSL中的视图矩阵.
编辑:好的,所以在derhass的建议中,我尝试发送倒置的视图矩阵.Bam,效果很好.所以,似乎我的GL实现确实无法反转该矩阵.这很容易成为我遇到的最奇怪的GL错误.但是,为什么在着色器中反转矩阵是一个坏主意的某种解释将是值得赞赏的.EditAgain:在我的引擎中发送倒置矩阵导致了巨大的帧率提升.绝对做到了.
借助 OpenGL 4.1 和 ARB_separate_shader_objects,我们能够在着色器程序中存储着色管道的不同阶段。众所周知,要使用它们,我们需要将它们附加到程序管道对象,然后将其绑定。
我的问题是,为什么我们需要程序管道对象?在我的渲染器中,我只有其中之一,我更改它的附件来更改着色器。我想不出在任何情况下您实际上想要不止一个。如果您存储许多管道对象,每个对象都包含着色器程序的不同组合,那么事情最终会比根本不使用单独的着色器更混乱。
那么,管道对象的用途是什么?更改附件是否比绑定不同的管道对象更昂贵?规范这样做的原因是什么,而不是让 glUseProgramStages 以与 glUseProgram 相同的方式操作?
我正在3D引擎中渲染反射表面.我需要执行两次模板操作.首先,我通过深度测试绘制出反射表面,以找到表面的可见区域.然后我需要将模型绘制到一个G-Buffer中,它也被模板化以找到绘制我的天空盒的区域.
绘制曲面:总是绘制,写入#1位
绘制模型:仅在设置位#1时绘制,写入位#2
我如何使用OpenGL执行此操作?我不确定glStencilFunc ref和掩码值之间的关系,以及glDepthMask值.
这是我遇到的一个问题的最小例子,我无法弄清楚我应该如何解决它:
#include <vector>
#include <memory>
class Thing {
};
class App {
public:
std::vector<std::unique_ptr<Thing>> thingVec;
void add_thing(Thing*);
};
void App::add_thing(Thing* thing) {
thingVec.push_back(std::unique_ptr<Thing>(thing));
}
int main() {
App app;
Thing thing;
app.add_thing(&thing);
}
Run Code Online (Sandbox Code Playgroud)
这个编译并运行没有任何问题,但是,当到达主要,段错误和吐出的结尾时:
Error in `/path/testapp': free(): invalid pointer: 0x00007fff97118070 ***
Run Code Online (Sandbox Code Playgroud)
任何可能的帮助?我想存储(唯一)指针的原因是Thing通常会派生出来.
编辑:一个有效的解决方案:
#include <vector>
#include <memory>
class Thing {
};
class App {
public:
std::vector<std::unique_ptr<Thing>> thingVec;
void add_thing(Thing*);
};
void App::add_thing(Thing* thing) {
thingVec.push_back(std::unique_ptr<Thing>(thing));
}
int main() {
App app;
Thing* thing = new Thing;
app.add_thing(thing);
}
Run Code Online (Sandbox Code Playgroud)
但根据我的理解,我应该能够完全避免使用new,并使用make_unique?我似乎无法找到make_unique实际定义的位置. …