gpt4 book ai didi

opengl - libgdx如何在3D中使用着色器

转载 作者:行者123 更新时间:2023-12-02 01:24:32 29 4
gpt4 key购买 nike

在我的wip游戏中,我想达到一个吸引眼球的地步。目前,我在Ambientlight中添加了一些Directionla-lightEnvironment并用它渲染场景。但是现在我想向其中添加一个自定义的Shader。因此,我一直在寻找一些教程,并且出于某种原因,在几乎每个教程中,他们都在游戏中使用了Shader的另一个“版本”:

  • ModelBatch一个StringFileHandle vertex/fragment -shader
  • 用顶点和片段ShaderProgram创建一个Shader
  • 使用此顶点和片段DefaultShader创建新的Shader
  • 创建一个类,该类实现Shader并使用此ShaderClass

  • 我认为还有更多可能性,因为还有 ShaderProvider和其他类。
    我对所有这些可能性感到困惑。所以我正在寻找可以指出正确方向的人。
    为了让您更轻松,我告诉您我拥有什么和我需要什么:
    我有:
  • 应该绘制所有内容的ModelBatch
  • 我想向其应用Array<ModelInstance>Shader实例。
  • 一个Texture及其NormalMap,都存储为Texture
  • 我的光的positiondirectioncolor表示为Vector3,其强度表示为float
  • 环境光及其强度的color,指定为Vector3float
  • 以“Vector3”形式给出的“Falloff”灯。

  • 我需要:
  • Texture及其Normal Map绑定(bind)到Shader
  • 将灯光位置,方向,颜色和强度赋予Shader
  • Shader提供环境光的颜色和强度。
  • Falloff向量提供给Shader
  • 将此Shader用于Array中所有与我的ModelBatch一起绘制的“实例”。

  • 我想做的另一件事是,对不同的模型使用不同的 Texture
    我所有的 ModleInstance都带有带纹理的 Material。我拥有所有这些不同 Texture的法线贴图。现在,我希望能够根据 TextureNormal Map中的 Shader将正确的 TextureMaterial绑定(bind)到 Modelinstance

    我想,如果可能的话,更“高级”的事情是对我的游戏中的不同 Shader使用不同的 ModelTypes(Stonewall使用不带“Specularity”和“Reflection”的 Shader,而Metalwalls使用 Specularity)。

    在Libgdx中执行此操作的最佳方法是什么?
    如何绑定(bind)我拥有的不同变量? (例如,使用ShaderProgram,我可以使用 setUniformi)。

    非常感谢。如果您需要更多信息或难以理解,请告诉我,我将尝试提出一个更好的问题。

    编辑:我认为最好的方法是创建一个新的 Shader类,该类实现 Shader。但是我想听听有关设计,性能和可能的限制的所有其他可能性,它们的优缺点。

    最佳答案

    可以在here中找到有关3d api渲染管道的总体说明。 This tutorial指导您从头开始创建新的Shaderthis tutorial展示了如何使用自定义属性将数据传递到着色器。 This wiki page还说明了如何使用Material Attributes以及Attributes支持的DefaultShader

    在LibGDX中,ShaderShaderProgram之间存在区别。 ShaderProgram 只是GPU实现(顶点和片段着色器程序),基本上只是编译后的GLSL文件。例如,您可以在ShaderProgram上设置制服,然后用它来渲染网格。但是ShaderProgram本身并不“知道”如何呈现模型。
    Shader接口(interface)旨在弥合ShaderProgramRenderable(后者是模型的最小可渲染部分)之间的间隙。因此,Shader最通常会封装ShaderProgram并确保设置正确的制服等。(请注意,严格来说Shader不必封装ShaderProgram。例如,在删除GLES1支持之前,还有一个GLES1着色器可以管理固定渲染管道,而不是封装ShaderProgram)

    BaseShader 类是abstract帮助器类,它实现Shader接口(interface),封装了ShaderProgram并添加了一些帮助器方法来轻松设置制服。如果您扩展此类,则可以轻松实现registerset统一,例如像这样:

    public class MyShader extends BaseShader {
    public final int u_falloff = register("u_falloff");
    ...
    @Override
    public void render (final Renderable renderable) {
    set(u_falloff, 15f);
    ...
    super.render(renderable);
    }
    }

    这会将名为“u_falloff”的统一设置为指定值 15f(它将调用setUniformX)。如果 ShaderProgram(glsl文件)未实现名为“u_falloff”的统一名称,则它将简单地忽略该调用。您也可以使用 if (has(u_falloff)) { /* calculate falloff and set it */ }进行检查。 BaseShader还增加了为每个制服使用 ValidatorSetter的可能性。
    DefaultShader扩展了 BaseShader并为大多数 Material Attributes添加了默认实现。如果要查看每个制服的名称,请看看 at the source。实际上,如果使用与DefaultShader相同的统一命名,则可以仅指定glsl文件,并让DefaultShader负责设置统一。当然,可以扩展DefaultShader以添加其他制服。

    当您调用 ModelBatch#render(...)时, ModelBatch将查询 ShaderProvider以获取要使用的 Shader。这是因为顶点属性和 Material 属性的每种可能组合都可能需要不同的 Shader。例如,如果您有两个 ModelInstance(或更准确地说,两个 Renderable),一个具有 TextureAttribute.Diffuse,一个没有纹理但具有 ColorAttribute.Diffuse。然后,最常见的是,ShaderProvider需要创建两个不同的 Shader。请注意,它们可以属于同一类(例如DefaultShader),但是底层的GLSL文件可能不同。
    DefaultShader使用预处理器宏(ubershader)来处理此问题。根据顶点属性和 Material 属性,它将 #define多个标志,从而使glsl程序专门针对顶点和 Material 属性的组合进行编译。如果您想了解如何完成,请查看 the glsl files

    因此,实际上,您可能需要拥有自己的 ShaderProvider和自己的 Shader(通过从头开始实现,扩展 BaseShader或扩展 DefaultShader)。您可以为此扩展 DefaultShaderProvider,并在需要时退回到 DefaultShader,例如:
    public class MyShaderProvider extends DefaultShaderProvider {
    ... // implement constructor
    @Override
    protected Shader createShader (final Renderable renderable) {
    if (renderable.material.has(MyCustomAttribute.Type))
    return new MyShader(renderable);
    else
    return super.createShader(renderable);
    }
    }

    tl; dr如果要使用自己的ubershader或修改版的ubershader,使用与默认着色器相同的制服,则只需提供glsl文件。如果要使用相同的制服,但要添加一两个额外的制服,则扩展DefaultShader可能很容易。否则(或者如果您正在学习着色器),我建议按照 This tutorial中所述从头开始创建着色器。

    关于opengl - libgdx如何在3D中使用着色器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22553409/

    29 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com