Skip to content
fireball87 edited this page Jan 28, 2020 · 6 revisions

Even simple programs often need to make use of a number of different shader effects. This article explains how to load OpenGL shader files into instances of Ultraviolet's Effect class using the OpenGL implementation of the Framework.

Effect Files

In Ultraviolet's OpenGL implementation, effects are XML files with the following layout.

<?xml version="1.0" encoding="utf-8" ?>
<Effect>
  <Technique Name="TechniqueName">
    <Pass Name="PassName">
      <VertexShader>VertexShaderAsset</VertexShader>
      <FragmentShader>FragmentShaderAsset</FragmentShader>
    </Pass>
  </Technique>
</Effect>

An effect has one or more <Technique> elements which correspond to the values of the Effect.Techniques property.

A technique has one or more <Pass> elements which correspond to the values of the EffectTechnique.Passes property.

A technique pass has exactly one <VertexShader> element, containing the relative path of the file containing the vertex shader, and exactly one <FragmentShader> element, containing the relative path of the file containing the fragment shader. Both of these files should contain the raw GLSL code of the shader in question.

Effect Files, Simplified

For simple scenarios, you don't actually need to create an XML file at all. If your effect has a single technique with a single pass, you can just load one of the shaders directly:

var effect = content.Load<Effect>("shader.frag");
// or...
var effect = content.Load<Effect>("shader.vert");

So long as the content manager can locate a corresponding vertex/fragment shader with the same name as the shader being loaded, it will automatically construct an effect from that pair of shaders.

Effect Parameters

The Effect object creates its parameters from the uniforms exposed by its component shaders. When you set a given effect parameter, for example...

effect.Parameters["Foo"].SetValue(bar);

...any uniforms named Foo in any of the effect's shader programs will be set to the value bar. This means that any uniforms with the same name that exist within the same effect must have the same data type.

Using Custom Effects

Once you have defined an effect file, you can load it in the usual way through a ContentManager:

var effect = contentManager.Load<Effect>("path/to/Effect");

The Effect object can then be used in the same way as one of Ultraviolet's built-in effects.

foreach (var pass in effect.CurrentTechnique.Passes)
{
    pass.Apply();

    // render the scene
}
Clone this wiki locally