このセクションでは、簡単な例による一般的なシナリオを使って、既存の 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;
}
}