OGSFX のシェーダ ステージ間で共通の機能を共有する

既存の GLSL シェーダを OGSFX 形式に変換する」のセクションで説明したように、各シェーダ ステージにはそのそれぞれに対する GLSLShader のブロックがあり、それらには使用する関数が含まれています。

次に示すサンプルは、2 つのステージで同じ関数を使うためのコードを作成する方法について説明します。

.ogsfx ファイル内で複製された関数

// World-view-projection transformation.
uniform mat4 gWVPXf : WorldViewProjection;

attribute vs_input
{
    vec3 in_position : POSITION;
};
 
attribute vs_to_ps
{
    // None
};
 
attribute ps_output 
{
    vec4 out_color : COLOR0;
}
 
GLSLShader VS
{
    vec4 convertVec3ToVec4(vec3 input)
    {
        return vec4(input, 1);
    }
 
    void main() 
    {
        gl_Position = gWVPXf*convertVec3ToVec4(in_position);
    }
}
 
GLSLShader PS1
{
    vec4 convertVec3ToVec4(vec3 input)
    {
        return vec4(input, 1);
    }
 
    vec4 computeTransparency(vec3 color3)
    {
        vec4 color4 = convertVec3ToVec4(color3);
         
        float alpha = 1;
        // ... perform a number of calculations
        color4.w = alpha;
 
        return color4;
    }
 
    void main()
    {
        out_color = computeTransparency(vec3(1, 0, 0));
    }
}
 
GLSLShader PS2
{
    vec4 convertVec3ToVec4(vec3 input)
    {
        return vec4(input, 1);
    }
 
    vec4 computeTransparency(vec3 color3)
    {
        vec4 color4 = convertVec3ToVec4(color3);
 
        float alpha = 1;
        // ... perform a number of calculations
        color4.w = alpha;
 
        return color4;
    }
 
    void main()
    {
        out_color = computeTransparency(vec3(0, 1, 0));
    }
}
  
technique Main
{
    pass p1
    {
        VertexShader (in vs_input, out vs_to_ps) = VS;
        PixelShader (in vs_to_ps, out ps_output) = PS1;
    }
 
    pass p2
    {
        VertexShader (in vs_input, out vs_to_ps) = VS;
        PixelShader (in vs_to_ps, out ps_output) = PS2;
    }
}

.ogsfx ファイル内で暗黙的に共有された関数

// World-view-projection transformation.
uniform mat4 gWVPXf : WorldViewProjection;

attribute vs_input
{
    vec3 in_position : POSITION;
};
 
attribute vs_to_ps
{
    // None
};
 
attribute ps_output 
{
    vec4 out_color : COLOR0;
}
 
// Declare the functions that can be shared among all the shader stages
GLSLShader Common_Functions
{
    vec4 convertVec3ToVec4(vec3 input)
    {
        return vec4(input, 1);
    }
}
  
// Declare the functions that can be shared among the pixel shader stages
GLSLShader Common_Pixel_Functions
{
    vec4 computeTransparency(vec3 color3)
    {
        vec4 color4 = convertVec3ToVec4(color3);
 
        float alpha = 1;
        // ... perform a number of calculations
        color4.w = alpha;
 
        return color4;
    }
}
 
GLSLShader VS
{
    void main() 
    {
        gl_Position = gWVPXf*convertVec3ToVec4(in_position);
    }
}
 
GLSLShader PS1
{
    void main()
    {
        out_color = computeTransparency(vec3(1, 0, 0));
    }
}
 
GLSLShader PS2
{
    void main()
    {
        out_color = computeTransparency(vec3(0, 1, 0));
    }
}
  
technique Main
{
    pass p1
    {
        // Declare the vertex shader stage to include the functions
        // from the VS GLSLShader block.
        // The stage will also include all the functions
        // from blocks that do not contain a main().
        // The vertex shader stage will then contain functions from
        // Common_Functions, Common_Pixel_Functions and VS.
        VertexShader (in vs_input, out vs_to_ps) = VS;
 
        // The pixel shader stage will contain functions from
        // Common_Functions, Common_Pixel_Functions and PS1.
        PixelShader (in vs_to_ps, out ps_output) = PS1;
    }
 
    pass p2
    {
        VertexShader (in vs_input, out vs_to_ps) = VS;
        PixelShader (in vs_to_ps, out ps_output) = PS2;
    }
}
注:

暗黙的に共有されているシェーダは、シェーダ コンパイラに負荷を与える場合があります。たとえば、computeTransparency は、たとえこれが使用されていなくても、頂点シェーダによって処理されます。また、すべての GLSL 組み込み関数/キーワードがすべてのシェーダ ステージに対して使用可能ではないため、コンパイルが失敗する場合があります。たとえば、discard はピクセル シェーダ ステージでのみ使用でき、頂点シェーダでは失敗します。 ただし、プリプロセッサ命令を使用することにより、指定のシェーダ ステージの間にコードの一部のみを有効にすることができます。「OGSFX プリプロセッサ命令」を参照してください。

.ogsfx ファイル内で関数を明示的に共有

// World-view-projection transformation.
uniform mat4 gWVPXf : WorldViewProjection;

attribute vs_input
{
    vec3 in_position : POSITION;
};
 
attribute vs_to_ps
{
    // None
};
 
attribute ps_output 
{
    vec4 out_color : COLOR0;
}
 
// Declare the functions that can be shared among all the stages
GLSLShader Common_Functions
{
    vec4 convertVec3ToVec4(vec3 input)
    {
        return vec4(input, 1);
    }
}
 
// Declare the functions that can be shared among the pixel shader stages
GLSLShader Common_Pixel_Functions
{
    vec4 computeTransparency(vec3 color3)
    {
        vec4 color4 = convertVec3ToVec4(color3);
 
        float alpha = 1;
        // ... perform a number of calculations
        color4.w = alpha;
 
        return color4;
    }
}
 
GLSLShader VS
{
    void main() 
    {
        gl_Position = gWVPXf*convertVec3ToVec4(in_position);
    }
}
 
GLSLShader PS1
{
    void main()
    {
        out_color = computeTransparency(vec3(1, 0, 0));
    }
}
 
GLSLShader PS2
{
    void main()
    {
        out_color = computeTransparency(vec3(0, 1, 0));
    }
}
  
technique Main
{
    pass p1
    {
        // Declare the vertex shader stage to include ONLY the functions
        // from the Common_Functions and VS GLSLShader blocks
        // Note that the order is important as each block will only 'know'
        // the functions that have been included in previous blocks
        VertexShader (in vs_input, out vs_to_ps) = { Common_Functions, VS };
 
        // Declare the vertex shader stage to include ONLY the functions
        // from Common_Functions, Common_Pixel_Functions and PS1
        PixelShader (in vs_to_ps, out ps_output) = { Common_Functions, Common_Pixel_Functions, PS1 };
    }
 
    pass p2
    {
        VertexShader (in vs_input, out vs_to_ps) = { Common_Functions, VS };
        PixelShader (in vs_to_ps, out ps_output) = { Common_Functions, Common_Pixel_Functions, PS2 };
    }
}