【问题标题】:GLKit's GLKBaseEffect and custom shadersGLKit 的 GLKBaseEffect 和自定义着色器
【发布时间】:2012-06-11 15:06:10
【问题描述】:

我一直在研究我遇到的这个问题,但我似乎无法很好地理解它来解决它,所以我想我不妨把它扔在那里,聪明的一群可能会有一些想法。 :P

基本上,我从事 iPhone 项目已经有一段时间了,我可以奢侈地使用所有最新的框架和目标 5.1。所以我一直在使用 GLKit 和 GLKBaseEffect 对我来说效果很好。我开始使用 GLKBaseEffect 而不是编写自己的着色器的原因是我不太了解 glsl。然而,要求变得更加精确,而基本效果似乎不再削减它。

由于我已经在使用基础效果进行所有变换,我希望我可以保持基础效果不变,但如果有任何意义,可以在顶部添加 glsl 类型的着色器。

我的旧方法看起来像这样(这是在一个循环中渲染所有对象,其中一个对象包含变换、网格和其他一些对这个问题不太重要的东西,例如纹理、材质等)

ObjectBase *obj = [ResourceManager.shared getObjectNamed:name inScene:sceneName];
GLKMatrix4 modelview = effect.transform.modelviewMatrix;
effect.transform.modelviewMatrix = GLKMatrix4Multiply(effect.transform.modelviewMatrix, obj.transform);

[effect prepareToDraw];
[obj render];

effect.transform.modelviewMatrix = modelView;

这里我们获取一个对象来渲染和变换(即平移、旋转和缩放)对象,然后我们渲染它,渲染本身获取对象的网格,绑定缓冲区并渲染它。

到目前为止一切顺利。

然而,我想做的是,在[obj render]; 调用期间,我希望对象也可以执行glUseProgram(someProgram); 之类的操作,添加更多专门的着色​​器代码。

我想有人可能会争辩说我正在尝试为我的顶点着色器使用基础效果,并希望为我的片段着色器使用“普通”着色器。至少这是我想我想做的。

我一直在尝试一些事情。

我试图只创建片段着色器和glUseProgram,但是它说我在设置和编译时需要一个顶点和一个片段着色器。我还尝试创建一个空的顶点着色器,结果不是很好,我不知道会发生什么,但我猜它会否决基础效果。

最后,我倾向于接受最好放弃基础效果并一直编写自己的着色器。我只是觉得窗外的工作量很大,所以我想看看我能节省多少。

我明白我对着色器的理解是给我带来最多问题的部分,所以请耐心等待。

【问题讨论】:

    标签: ios shader glkit


    【解决方案1】:

    我只是想为对它们感兴趣的人给出我的结论。

    我所做的实际上是将 GLBaseEffect 全部扔掉并实现了我自己的着色器代码。

    我最大的问题是我并没有真正理解可以说是全有或全无

    我可能是错的,所以任何对我错的地方的更正将不胜感激,我真的不想欺骗任何阅读本文的人。

    我在努力中发现了几个关键点:

    • GLKBaseEffect,旨在模仿早期版本的 OpenGLES 中看到的固定功能管道。因此它包装了通用着色器代码,因此您不必太在意它。您将拥有基本功能,但它的可扩展性并不高。
    • 如果您编写自己的着色器代码,您仍然可以使用 GLKit 的简洁功能,例如纹理加载器、数学库等。因此,如果您想要更复杂或可定制的东西(凹凸贴图、卡通着色等),完全值得重写正确渲染所需的样板代码。我最初所做的是使用 GLKBaseEffect 在场景中进行定向,因为它非常舒适且易于使用。然而,当我想做更多(切线空间法线贴图)时,我有点卡住了,因为我无法添加到由 GLKBaseEffect 处理的着色器程序中。
    • 着色器真的没有我想象的那么可怕!我只是不知道它的真正含义,我很惊讶我已经阅读了这么多关于它们的内容,但仍然不明白着色器基本上是替换固定功能管道的程序。就这么简单。

    我想这已经足够了,只是想跟进并添加我到目前为止收集的点点滴滴。

    【讨论】:

    • 嗨,qrikko,我可以通过电子邮件向您发送有关潜在项目的信息吗?感谢您的详细回答!
    • 当然,没问题,我总是试图让 SO 筋疲力尽,因为它对这么多人来说是一个如此重要的资源。 :)
    • 啊,我以为是公开的,抱歉。 qrikko@gmail.com
    【解决方案2】:

    正如您所发现的,您不能只使用片段着色器而留下顶点着色器。这是因为两者都有不同的任务。顶点着色器处理每个顶点方面:计算顶点数据、纹理(uv)等,最后绘制面(三角形)。片段着色器处理屏幕上(或视口中)每个像素的确切绘制内容。当您只提供片段着色器时,您告诉您的顶点数据是什么,而只是告诉 OpenGL 对像素做一些事情。而且这些像素什么都没有/乱码(我不确定是哪个),因为您的顶点着色器没有做任何事情。

    使用 GLKEffect 时,调用 [yourEffect prepareToDraw] 方法会处理着色器等问题。

    如果您只想使用一对普通着色器,为什么不使用 XCode OpenGL 游戏模板中提供的那一个呢?当你运行它时,它有两个立方体,一个使用 GLKit 渲染,另一个以正常方式渲染。虽然我认为这对于大多数效果来说是不够的。如果您想了解更多关于着色器的信息,可以查看NeHe GLSL 介绍article。它是关于 GLSL 以及如何在代码中编写和使用着色器。你可能想看看Diney Bomfim'sAll About Shaders 的文章和这个page

    在大多数情况下使用 GLKit 是不错的选择,因为它可以让您免于编写大量无用的重复代码。例如,您不必经历如此多的具有不同颜色编码和每像素位数(每种格式)的图像格式,而所有这些都可以使用GLKTextureLoader

    【讨论】:

    • 我似乎完全忘记说谢谢你提供的链接确实拓宽了我的理解。我很高兴我问了,即使在问的时候我觉得我不知道我实际上要求的是什么……很好地弄清楚了;)谢谢。
    • 非常感谢。我对我的着色器正在编译和链接但没有输出任何东西感到沮丧。删除调用 prepareToDraw 就可以了。生活是美好的!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-05-17
    • 2012-04-23
    • 2012-09-28
    • 2012-10-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多