「既存の GLSL シェーダを OGSFX 形式に変換する」のセクションで説明したように、各シェーダ ステージにはそのそれぞれに対する GLSLShader のブロックがあり、それらには使用する関数が含まれています。
次に示すサンプルは、2 つのステージで同じ関数を使うためのコードを作成する方法について説明します。
// 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; } }
// 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 プリプロセッサ命令」を参照してください。
// 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 }; } }