每种情况的GLSL着色器

Qua*_*hey 5 opengl glsl

在我的游戏中,我想为每种情况创建单独的GLSL着色器.在举例来说,如果我将有3款车型character,shiny sword并且blury ghost我想设置renderShader,animationShaderlightingShadercharacter,然后renderShader,lightingShaderspecularShadershiny sword,最后我想设置renderShader,lightingShaderblurShaderblury ghost.

renderShader应通过投影,世界等矩阵相乘顶点的位置,这是fragmet着色器应该简单纹理设置为模型.

animationShader 应该通过给定的骨骼变换来变换顶点.

lightingShader应该做照明,specularLighting应该做镜面照明.

blurShader 应该做模糊效果.

首先,我如何在不同的着色器上进行多个顶点变换?因为animationShader应该计算顶点的动画位置,然后renderShader应该获得该位置并通过某些矩阵对其进行转换.

其次,如何在不同的着色器上更改片段的颜色?

基本的想法是,我希望能够为每个sutuations /效果使用不同的着色器,我不知道如何实现它.

我需要知道如何在opengl中使用这些着色器,以及我应该如何使用GLSL以便所有着色器相互完成,并且着色器不关心是否使用了另一个着色器.

dat*_*olf 3

实际上,对于着色器阶段的每种组合,您都必须创建单独的着色器程序。为了节省工作和冗余,您可以使用某种缓存结构为每个请求的组合仅创建一次程序,并在每次请求时重复使用它。

您可以对着色器阶段执行类似的操作。然而,着色器阶段无法与多个编译单元链接(然而,这是 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 版本中)。从技术上讲,你可以在阶段之间传递很多变化。因此,您可以在每个帧缓冲区目标的着色器阶段之间传递一组自己的变量。然而,几何形状和变换后的顶点位置对于所有这些都是通用的。