在我的游戏中,我想为每种情况创建单独的GLSL着色器.在举例来说,如果我将有3款车型character,shiny sword并且blury ghost我想设置renderShader,animationShader并lightingShader到character,然后renderShader,lightingShader和specularShader到shiny sword,最后我想设置renderShader,lightingShader并blurShader到blury ghost.
本renderShader应通过投影,世界等矩阵相乘顶点的位置,这是fragmet着色器应该简单纹理设置为模型.
animationShader 应该通过给定的骨骼变换来变换顶点.
lightingShader应该做照明,specularLighting应该做镜面照明.
blurShader 应该做模糊效果.
首先,我如何在不同的着色器上进行多个顶点变换?因为animationShader应该计算顶点的动画位置,然后renderShader应该获得该位置并通过某些矩阵对其进行转换.
其次,如何在不同的着色器上更改片段的颜色?
基本的想法是,我希望能够为每个sutuations /效果使用不同的着色器,我不知道如何实现它.
我需要知道如何在opengl中使用这些着色器,以及我应该如何使用GLSL以便所有着色器相互完成,并且着色器不关心是否使用了另一个着色器.
实际上,对于着色器阶段的每种组合,您都必须创建单独的着色器程序。为了节省工作和冗余,您可以使用某种缓存结构为每个请求的组合仅创建一次程序,并在每次请求时重复使用它。
您可以对着色器阶段执行类似的操作。然而,着色器阶段无法与多个编译单元链接(然而,这是 OpenGL 开发中为实现这一目标而不断努力的成果,OpenGL-4 的可分离着色器是实现这一目标的垫脚石)。但您可以从多个来源编译着色器。因此,您可以将每个所需效果的函数编写到单独的源中,然后在编译时将它们组合起来。并再次使用缓存结构将源模块组合映射到着色器对象。
假设您想要一些模块化。为此,我们可以利用 glShaderSource 接受多个源字符串的事实,它只是连接起来。您编写了许多着色器模块。一个进行逐顶点照明计算
uniform vec3 light_positions[N_LIGHT_SOURCES];
out vec3 light_directions[N_LIGHT_SOURCES];
out vec3 light_halfdirections[N_LIGHT_SOURCES];
void illum_calculation()
{
for(int i = 0; i < N_LIGHT_SOURCES; i++) {
light_directions[i] = ...;
light_halfdirections[i] = ...;
}
}
Run Code Online (Sandbox Code Playgroud)
您将其放入illum_calculation.vs.glslmod(文件名和扩展名是任意的)。接下来你有一个执行骨骼动画的小模块
uniform vec4 armature_pose[N_ARMATURE_BONES];
uniform vec3 armature_bones[N_ARMATURE_BONES];
in vec3 vertex_position;
void skeletal_animation()
{
/* ...*/
}
Run Code Online (Sandbox Code Playgroud)
把这个放进去illum_skeletal_anim.vs.glslmod。然后你就有了一些通用的标题
#version 330
uniform ...;
in ...;
Run Code Online (Sandbox Code Playgroud)
以及一些包含主函数的公共尾部,该函数调用所有不同的阶段
void main() {
skeletal_animation();
illum_calculation();
}
Run Code Online (Sandbox Code Playgroud)
等等。现在,您可以按正确的顺序将所有这些模块加载到单个着色器阶段中。您可以对所有着色器阶段执行相同的操作。片段着色器很特殊,因为它可以同时写入多个帧缓冲区目标(在足够大的 OpenGL 版本中)。从技术上讲,你可以在阶段之间传递很多变化。因此,您可以在每个帧缓冲区目标的着色器阶段之间传递一组自己的变量。然而,几何形状和变换后的顶点位置对于所有这些都是通用的。
| 归档时间: |
|
| 查看次数: |
1234 次 |
| 最近记录: |