Libgdx如何使用着色器的3D [英] Libgdx how to use shader in 3D

查看:677
本文介绍了Libgdx如何使用着色器的3D的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我达到了我的WIP游戏,我想让它更眼吸引人的一个点。目前,我添加一些 Ambientlight Directionla光环保并渲染我的场景吧。但现在我想自定义的着色器添加到它。所以我一直在寻找一些教程,由于某种原因,几乎所有的教程中,他们使用了另一种版本使用着色器在他们的游戏:

I reached a point in my wip game, where I want to make it more eye-appealing. Currently I add some Ambientlight and a Directionla-light to an Environment and render my scene with it. But now I want to add a custom Shader to it. So I have been looking for some tutorials and for some reason in almost every tutorial they have used another "version" of using Shader in their game:

  • ModelBatch A 字符串的FileHandle 顶点/片断 -shader
  • 创建一个 ShaderProgram 与顶点和片段着色器
  • 创建一个新的 DefaultShader 这个顶点和片段着色器
  • 创建一个类,它实现着色器和使用本 ShaderClass
  • Giving the ModelBatch a String or FileHandle vertex/fragment-shader
  • Creating a ShaderProgram with vertex and fragment Shader.
  • Creating a new DefaultShader with this vertex and fragment Shader.
  • Creating a class, which implements Shader and use this ShaderClass.

我觉得有更多的possibilitis,因为还有 ShaderProvider 和其他类为好。
我这一切posibilities的有点混乱的原因。所以我找人谁可以在正确的方向指向我。
为了方便你,我告诉你,我有什么,我需要:
我有:

I think there are more possibilitis, because there is also ShaderProviderand other classes as well.
I am a bit confused cause of all this posibilities. so I am looking for someone who can point me in the right direction.
To make it easier for you i tell you what i have and what I need:
I have:

  1. A ModelBatch 应引起一切。
  2. 阵列< ModelInstance> 实例,对此我想申请的着色器
  3. A 纹理法线,无论是存储为纹理秒。
  4. 位置方向颜色我的光芒,给定为 Vector3类型其实力给出浮动
  5. 颜色环境光线和其强度,给出 Vector3类型的浮法
  6. 光衰减给出 Vector3类型
  1. A ModelBatch which should draw everything.
  2. An Array<ModelInstance> instances, to which i wanna apply the Shader.
  3. A Texture and its NormalMap, both stored as Textures.
  4. The position, the direction and the color of my light, given as Vector3 and its strength given as float.
  5. The color of the ambient light and its strength, given as Vector3 and float.
  6. The light "Falloff" given as Vector3.

我需要:

  1. 要绑定的纹理法线贴图着色器
  2. 给光POS机,方向,颜色和强度着色器
  3. 提供的ambientlight颜色和强度着色器
  4. 提供的衰减矢量到着色器
  5. 使用该着色器阵列,它们都画有我的<$ C所有的实例 $ C> ModelBatch 。
  1. To bind the Texture and its Normal Map to the Shader.
  2. Give the light pos, direction, color and strength to the Shader.
  3. Give the ambientlight color and strength to the Shader.
  4. Give the Falloff Vector to the Shader.
  5. Use this Shader for all "instances" in the Array, which are all drawn with my ModelBatch.

另一件事,我想能够做的是,用不同的纹理 S代表不同的型号。 我有我所有的 ModleInstance s的纹理材料。我有正常的地图,所有这些不同的纹理秒。现在我希望能够绑定正确的纹理法线贴图着色,根据纹理材料 Modelinstance的

Another thing I would like to be able to do is, using different Textures for different models. I have all my ModleInstances with a textured Material. And I have the normal map for all those different Textures. Now i want to be able to bind the right Texture and Normal Map to the Shader, depending on the Texture in the Material of the Modelinstance.

一个更高级的东西,我想如果可能的话,使用不同的着色器 S代表不同的 ModelTypes 在我的游戏(石墙使用着色器没有镜面反射和反射,而Metalwalls使用镜面反射例如)。

A more "advanced" thing, I would like to if it is possible, is using different Shaders for different ModelTypes in my game (Stonewall uses a Shader without "Specularity" and "Reflection", while Metalwalls use Specularity for example).

什么是做这种事情Libgdx最好的方法是什么? 我怎么可以绑定不同的变量我有吗? (随着ShaderProgram我可以使用 setUniformi 为例)。

What would be the best way to do this things in Libgdx? How can i bind the different variables i have? (With ShaderProgram i can use setUniformi for example).

非常感谢。如果您需要了解更多信息,或者如果它是很难理解让我知道,我将努力创造一个更好的问题。

Thanks a lot. If you need more information or if it is hard to understand let me know and i will try to create a better question.

编辑:我想在我的情况下创建一个新的着色器类,最好的方法,它实现着色器。但我想听到的所有其他可能性,他们的优点和缺点的,关于设计,性能和可能的限制。

I think the best way in my case creating a new Shader class, which implements Shader. But i would like to hear about all the other possibilities, their pros and their cons, regarding design, performance and possible restrictions.

推荐答案

渲染管线的3D API的一个总体的解释可以发现的此处本教程指导您创建一个新的着色器从头开始。和本教程展示如何自定义使用属性将数据传递到着色器。 本wiki页面还介绍了如何使用材料 属性键,其中属性 DefaultShader 支持。

An overall explanation of rendering pipeline of the 3d api can be found here. This tutorial guides you in creating a new Shader from scratch. And this tutorial show how to use custom attributes to pass data to the shader. This wiki page also explains how to use Material Attributes and which Attributes the DefaultShader supports.

在LibGDX有一个着色器 ShaderProgram 之间的差异。一个 ShaderProgram 是唯一的GPU实现(包括顶点和片段着色器程序),它基本上仅编译GLSL文件。你可以,例如,设置 ShaderProgram 制服,并用它来渲染一个网格。但 ShaderProgram 本身并不知道它应该如何渲染模型。

In LibGDX there's a difference between a Shader and ShaderProgram. A ShaderProgram is only the GPU implementation (both the vertex and fragment shader program), which is basically only the compiled GLSL files. You can, for example, set uniforms on ShaderProgram and use it to render a mesh. But the ShaderProgram itself does not "know" how it should render a model.

着色器界面旨在弥合的 ShaderProgram 渲染的差距(后者是模型的最小渲染的一部分)。因此,一个着色器最常用的封装 ShaderProgram 并确保其设置正确的制服等(请注意,严格说来着色器没有来封装 ShaderProgram 。例如GLES1支持被删除前,有也是一个GLES1着色器管理,而不是封装固定渲染管道 ShaderProgram

The Shader interface is intended to bridge the gap between the ShaderProgram and the Renderable (the latter being the smallest renderable part of a model). Thus a Shader most commonly encapsulates a ShaderProgram and makes sure it sets the correct uniforms etc. (Note that strictly speaking a Shader doesn't have to encapsulate a ShaderProgram. E.g. before GLES1 support was removed, there also was a GLES1 shader which managed the fixed rendering pipe instead of encapsulating a ShaderProgram)

借助 BaseShader 类是一个它实现了着色器接口抽象辅助类,封装在一个 ShaderProgram 和增加了一些辅助方法轻松设置制服。如果你扩展这个类,你可以很容易地注册设置均匀,如像这样的:

The BaseShader class is an abstract helper class which implements the Shader interface, encapsulated a ShaderProgram and adds some helper methods to easily set uniforms. If you extend this class, you can easily register and set uniform, e.g. like this:

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的unifom到指定值 15F (它会调用setUniformX)。如果 ShaderProgram (GLSL文件)不实行所谓的u_falloff一个统一的,它会简单地忽略呼叫。你也可以使用这个查询:如果(有(u_falloff)){/ *计算衰减,并设置* /} 。该 BaseShader 还增加了使用验证二传手每个均匀。

This will set the unifom called "u_falloff" to the specified value 15f (it will call setUniformX). If the ShaderProgram (glsl files) don't implement an uniform called "u_falloff", it will simply ignore the call. You could also check this using: if (has(u_falloff)) { /* calculate falloff and set it */ }. The BaseShader also adds the possibility to use a Validator and Setter for each uniform.

DefaultShader 延长 BaseShader 并添加了默认实现对于大多数材料 属性。看看<一href="https://github.com/libgdx/libgdx/blob/master/gdx/src/com/badlogic/gdx/graphics/g3d/shaders/DefaultShader.java#L78">at如果你想看到的每一个统一的命名来源的。在实践中,如果你使用相同的统一命名为DefaultShader做,有可能只指定GLSL文件,并让DefaultShader采取设置制服的照顾。当然也可以延长DefaultShader添加额外的制服。

The DefaultShader extends the BaseShader and adds a default implementation for most of the Material Attributes. Have a look at the source if you want to see the naming of each uniform. In practice, if you use the same uniform naming as the DefaultShader does, it is possible to only specify the glsl files and let the DefaultShader take care of setting the uniforms. Of course it is possible to extend the DefaultShader to add additional uniforms.

当你调用 ModelBatch#渲染(...) ModelBatch 将查询 ShaderProvider 着色器来使用。这是因为顶点的每一个可能的组合属性和材料属性可能需要不同的着色器。例如,如果您有两个 ModelInstance S(或更precise两个渲染 S),其中一个一个 TextureAttribute.Diffuse 和一个没有质感,但与 Col​​orAttribute.Diffuse 。然后最常见的是,ShaderProvider需要创建两个不同的着色器秒。需要注意的是,他们可以是相同的类(例如DefaultShader)的,但是,底层GLSL文件可能会有所不同。

When you call ModelBatch#render(...), the ModelBatch will query the ShaderProvider for a Shader to use. This is because every possible combination of vertex attributes and material attributes might require a different Shader. For example if you have two ModelInstances (or to be more precise two Renderables), one with a TextureAttribute.Diffuse and one without texture but with a ColorAttribute.Diffuse. Then most commonly, the ShaderProvider needs to create two different Shaders. Note that they can be of the same class (e.g. DefaultShader), but that the underlying GLSL files might be different.

DefaultShader 照顾这一点使用preprocessor宏(一个ubershader)。根据不同的顶点属性和材料属性,它会的#define 多个标志,导致GLSL​​程序是专门为顶点和物质的属性组合编译。看一看<一href="https://github.com/libgdx/libgdx/tree/master/gdx/src/com/badlogic/gdx/graphics/g3d/shaders">the如果你想看看如何做到这一点GLSL文件。

The DefaultShader takes care of this using preprocessor macros (an ubershader). Depending on the vertex attributes and material attributes, it will #define multiple flags, causing the glsl program to be compiled specifically for that combination of vertex and material attributes. Have a look at the glsl files if you want to see how this is done.

所以,在实践中,你可能会需要你拥有 ShaderProvider 和你自己的着色器(无论是从实现它从无到有,延长 BaseShader 或延长 DefaultShader )。您是否可以extends DefaultShaderProvider ,这和回落到 DefaultShader 如果需要的话,例如:

So, in practice you will likely need you own ShaderProvider and your own Shader (either by implementing it from scratch, extending BaseShader or extending DefaultShader). You can extends DefaultShaderProvider for this and fall back to the DefaultShader if needed, e.g.:

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;博士如果你想使用ubershader你自己或修改后的版本,使用相同的制服为默认着色器,则只需提供GLSL文件。如果你想用同样的制服,但增加一个额外的制服或两个,那么它可能是易于扩展DefaultShader。否则(或者,如果你正在学习的着色器),我会建议从头开始创建着色器在本作描述教程

这篇关于Libgdx如何使用着色器的3D的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆