问题描述
我达到了我的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
aString
orFileHandle
vertex/fragment
-shader - Creating a
ShaderProgram
with vertex and fragmentShader
. - Creating a new
DefaultShader
with this vertex and fragmentShader
. - Creating a class, which implements
Shader
and use thisShaderClass
.
我觉得有更多的possibilitis,因为还有 ShaderProvider
和其他类为好。
我这一切posibilities的有点混乱的原因。所以我找人谁可以在正确的方向指向我。
为了方便你,我告诉你,我有什么,我需要:
我有:
I think there are more possibilitis, because there is also ShaderProvider
and 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:
- A
ModelBatch
应引起一切。 - 的
阵列< ModelInstance>
实例,对此我想申请的着色器
。 - A
纹理
和法线
,无论是存储为纹理
秒。 - 的
位置
的方向
和颜色
我的光芒,给定为Vector3类型
其实力给出浮动
。 - 的
颜色
环境光线和其强度,给出Vector3类型的
和浮法
。 - 光衰减给出
Vector3类型
。
- A
ModelBatch
which should draw everything. - An
Array<ModelInstance>
instances, to which i wanna apply theShader
. - A
Texture
and itsNormalMap
, both stored asTexture
s. - The
position
, thedirection
and thecolor
of my light, given asVector3
and its strength given asfloat
. - The
color
of the ambient light and its strength, given asVector3
andfloat
. - The light "Falloff" given as
Vector3
.
我需要:
- 要绑定的
纹理
和法线贴图
到着色器
。 - 给光POS机,方向,颜色和强度
着色器
。 - 提供的ambientlight颜色和强度
着色器
。 - 提供的
衰减
矢量到着色器
。 - 使用该
着色器
在阵列
,它们都画有我的<$ C所有的实例 $ C> ModelBatch 。
- To bind the
Texture
and itsNormal Map
to theShader
. - Give the light pos, direction, color and strength to the
Shader
. - Give the ambientlight color and strength to the
Shader
. - Give the
Falloff
Vector to theShader
. - Use this
Shader
for all "instances" in theArray
, which are all drawn with myModelBatch
.
另一件事,我想能够做的是,用不同的纹理
S代表不同的型号。我有我所有的 ModleInstance
s的纹理材料
。我有正常的地图,所有这些不同的纹理
秒。现在我希望能够绑定正确的纹理
和法线贴图
到着色
,根据纹理
在材料
的 Modelinstance的
。
Another thing I would like to be able to do is, using different Texture
s for different models.I have all my ModleInstance
s with a textured Material
. And I have the normal map for all those different Texture
s. 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 Shader
s 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
并添加了默认实现对于大多数材料
属性
。看看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
和一个没有质感,但与 ColorAttribute.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 ModelInstance
s (or to be more precise two Renderable
s), one with a TextureAttribute.Diffuse
and one without texture but with a ColorAttribute.Diffuse
. Then most commonly, the ShaderProvider needs to create two different Shader
s. 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程序是专门为顶点和物质的属性组合编译。看一看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的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!