このセクションでは、簡単な例による一般的なシナリオを使って、既存の GLSL シェーダを .ogsfx 形式に変換する方法を説明します。それぞれのサンプルでは、比較のために、GLSL と OGSFX における同等のコードを示します。ごく簡単な例で開始し、次第に複雑なシナリオへと進みます。
GLSL では、頂点シェーダとピクセル(またはフラグメント)シェーダはシェーダ ステージごとに個別にコンパイルされ、同一のプログラムにリンクされる必要があります。そのため、ピクセル シェーダと頂点シェーダは通常はそれぞれ .glslv および .glslf という拡張子で 2 つの異なるファイルに保存されます。
一方、.ogsfx ファイルには、1 つのファイルにすべてのステージが格納されます。
// World-view-projection transformation. uniform mat4 gWVPXf; // The vertex shader input - coming from the application in vec3 in_position; // The vertex shader ouput - going to the pixel shader // None void main() { gl_Position = gWVPXf*vec4(in_position, 1); }
// The pixel shader input - coming from the vertex shader // None // The pixel shader output - going to the target out vec4 out_color; void main() { out_color = vec4(1, 0, 0, 1); }
// World-view-projection transformation. uniform mat4 gWVPXf : WorldViewProjection; // The vertex shader input - coming from the application attribute vs_input { vec3 in_position : POSITION; }; // The vertex shader ouput and also the pixel shader input attribute vs_to_ps { // None }; // The pixel shader output attribute ps_output { vec4 out_color : COLOR0; } // All the functions or constants that will be used by the vertex shader GLSLShader VS { // Only the main function, which is the same as the main function of the .glslv void main() { gl_Position = gWVPXf*vec4(in_position, 1); } } // All the functions or constants that will be used by the pixel shader GLSLShader PS { // Only the main function, which is the same as the main function of the .glslf void main() { out_color = vec4(1, 0, 0, 1); } } // Declaration of the techniques and passes - for this example, 1 technique with 1 pass technique Main { pass p0 { // We have 1 vertex shader stage that uses : // - the vs_input attribute as input, // - the vs_to_ps attribute as output, // - all functions declared in the GLSLShader block VS - must contain main() VertexShader (in vs_input, out vs_to_ps) = VS; // We have 1 pixel shader stage that uses : // - the vs_to_ps attribute as input, // - the ps_output attribute as output, // - all functions declared in the GLSLShader block PS - must contain main() PixelShader (in vs_to_ps, out ps_output) = PS; } }
// World-view-projection transformation. uniform mat4 gWVPXf; // No uniform for the vertex shader in vec3 in_position; void main() { gl_Position = gWVPXf*vec4(in_position, 1); }
// The solid color uniform and its default value uniform vec4 gSolidColor = vec4(1, 0, 0, 1); out vec4 out_color; void main() { out_color = gSolidColor; }
// World-view-projection transformation. uniform mat4 gWVPXf : WorldViewProjection; // The solid color uniform, its default value and several extra parameters uniform vec4 gSolidColor : DIFFUSE < // The UI name for this parameter in the Attribute Editor (AE) // If not set (or empty), the name of the uniform itself will be used string UIName = "Solid Color"; // The group in which to put this parameter in the AE // If not set (or empty), the parameter will not be added to any named group string UIGroup = "Editable Parameters"; // The value used to sort the parameters within the same group // If not set, the parameter will be placed in the same order as it appears // in the shader file, but after the parameters with a specified UIOrder int UIOrder = 1; // Specify the widget used to control the uniform value in the AE // Currently only "None" - the parameter will not be visible in the AE - // and "ColorPicker" - use the color picked widget - are supported; // any other value such as "Color" below will be ignored. // The GLSLShader plug-in will try to find the proper widget // based on the name of the attribute and its semantic (here DIFFUSE). string UIWidget = "Color"; > = {1, 0, 0, 1}; attribute vs_input { vec3 in_position : POSITION; }; attribute vs_to_ps { // None }; attribute ps_output { vec4 out_color : COLOR0; } GLSLShader VS { void main() { gl_Position = gWVPXf*vec4(in_position, 1); } } GLSLShader PS { void main() { out_color = gSolidColor; } } technique Main { pass p0 { VertexShader (in vs_input, out vs_to_ps) = VS; PixelShader (in vs_to_ps, out ps_output) = PS; } }
// World-view-projection transformation. uniform mat4 gWVPXf; // No uniform for the vertex shader in vec3 in_position; in vec2 in_texcoord; out vec2 out_texcoord; void main() { gl_Position = gWVPXf*vec4(in_position, 1); out_texcoord = in_texcoord; }
// The texture sampler uniform bound to the application's texture parameter uniform sampler2D gTextureSampler; in vec2 in_texcoord; out vec4 out_color; void main() { out_color = texture2D(gTextureSampler, in_texcoord); }
// World-view-projection transformation. uniform mat4 gWVPXf : WorldViewProjection; // The texture parameter will be visible in the Attribute Editor (AE) uniform texture2D gTexture < string UIName = "Texture"; string UIGroup = "Editable Parameters"; int UIOrder = 1; // Default texture file to load string ResourceName = "default_texture.png"; // Specify the type of texture : 1D, 2D, Cube ... string ResourceType = "2D"; >; // The texture sampler linked to the texture parameter, will not be visible in the AE uniform sampler2D gTextureSampler = sampler_state { // This sample belongs to the texture "gTexture" Texture = <gTexture>; }; attribute vs_input { vec3 in_position : POSITION; vec2 in_texcoord : TEXCOORD0; }; attribute vs_to_ps { vec2 out_texcoord; }; attribute ps_output { vec4 out_color : COLOR0; } GLSLShader VS { void main() { gl_Position = gWVPXf*vec4(in_position, 1); out_texcoord = in_texcoord; } } GLSLShader PS { void main() { out_color = texture2D(gTextureSampler, out_texcoord); } } technique Main { pass p0 { VertexShader (in vs_input, out vs_to_ps) = VS; PixelShader (in vs_to_ps, out ps_output) = PS; } }
前の ogsfx の実装では、テクスチャの座標値は、vs_to_ps アトリビュート構造の out_texcoord 変数を使って、頂点シェーダからピクセル シェーダに渡されました。これは頂点シェーダのステージでは適切ですが、ピクセル シェーダに対する入力として変数名 out_texcoord を使用することは不適切な場合があります。シェーダ ステージの入力構造と出力構造に名前を付けることができます(vs 入力と ps 出力を除く。これらは名前を付けないままにしておく必要があります)。たとえば、vs_to_ps アトリビュート構造内で変数 texcoord に名前を付け、vs 出力構造 vsOut と ps 入力構造 psIn に名前を付けます。
// World-view-projection transformation. uniform mat4 gWVPXf : WorldViewProjection; uniform texture2D gTexture < string UIName = "Texture"; string UIGroup = "Editable Parameters"; int UIOrder = 1; string ResourceName = "default_texture.png"; string ResourceType = "2D"; >; uniform sampler2D gTextureSampler = sampler_state { Texture = <gTexture>; }; attribute vs_input { vec3 in_position : POSITION; vec2 in_texcoord : TEXCOORD0; }; attribute vs_to_ps { vec2 texcoord; }; attribute ps_output { vec4 out_color : COLOR0; } GLSLShader VS { void main() { gl_Position = gWVPXf*vec4(in_position, 1); // Use the texcoord variable of the output structure vsOut.texcoord = in_texcoord; } } GLSLShader PS { void main() { // Use the texcoord variable of the input structure out_color = texture2D(gTextureSampler, psIn.texcoord); } } technique Main { pass p0 { VertexShader (in vs_input, out vs_to_ps vsOut) = VS; PixelShader (in vs_to_ps psIn, out ps_output) = PS; } }
1 つのジオメトリに赤のソリッド カラーを適用してから緑のソリッド カラーを適用する場合は、2 つの異なるピクセル シェーダを使用できます。
GLSL では、3 つのファイルを使用します。1 つは頂点シェーダ用で、もう 1 つは各ピクセル シェーダ用です。
.ogsfx では、次に示すように、1 つのファイルにすべてが含まれています。
// World-view-projection transformation. uniform mat4 gWVPXf; in vec3 in_position; void main() { gl_Position = gWVPXf*vec4(in_position, 1); }
out vec4 out_color; void main() { // red with some transparency out_color = vec4(1, 0, 0, 0.3); }
out vec4 out_color; void main() { // green with some transparency out_color = vec4(0, 1, 0, 0.3); }
// 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 { void main() { gl_Position = gWVPXf*vec4(in_position, 1); } } // The pixel shader that draws the red color GLSLShader PS_red { void main() { out_color = vec4(1, 0, 0, 0.3); } } // The pixel shader that draws the green color GLSLShader PS_green { void main() { out_color = vec4(0, 1, 0, 0.3); } } // Declare the technique with two passes, // one for the red color and another for the green technique Main { pass p_red { VertexShader (in vs_input, out vs_to_ps) = VS; PixelShader (in vs_to_ps, out ps_output) = PS_red; } pass p_green { VertexShader (in vs_input, out vs_to_ps) = VS; PixelShader (in vs_to_ps, out ps_output) = PS_green; } } // It is also possible to declare another technique // that can be selected via the GLSLShader Attribute Editor // or when loading the effect using the API // MHWRender::MShaderManager::getEffectsFileShader(fileName, techniqueName, ...) // For this technique, the order of the passes is inverted. technique Inverse { pass p_green { VertexShader (in vs_input, out vs_to_ps) = VS; PixelShader (in vs_to_ps, out ps_output) = PS_green; } pass p_red { VertexShader (in vs_input, out vs_to_ps) = VS; PixelShader (in vs_to_ps, out ps_output) = PS_red; } }