-
Notifications
You must be signed in to change notification settings - Fork 10
Basic ShaderWriter usage
sdw::ShaderWriter
allows to write a shader by defining functions needed to declare the following:
- Control statements.
- Constants declarations.
- Specialization constants declarations.
- Combined images declarations.
- Sampled images declarations.
- Storage images declarations.
- Shader input variables declarations.
- Shader output variables declarations.
- Local variables declarations.
- Structure type declarations.
- Uniform buffer declarations.
- Storage buffer declarations.
- Push constant buffer declarations.
Additionally, sdw::ShaderWriter
is derived in shader stage specific
classes:
sdw::VertexWriter
sdw::TessellationControlWriter
sdw::TessellationEvaluationWriter
sdw::GeometryWriter
sdw::FragmentWriter
sdw::ComputeWriter
sdw::TaskShader
sdw::MeshShader
sdw::CallableShader
sdw::RayAnyHitShader
sdw::RayClosestHitShader
sdw::RayGenerationShader
sdw::RayMissShader
Each one of them exposes the access to its built-in inputs and outputs (all listed in their respective header file).
sdw::
types, in their constructor, need an sdw::ShaderWriter
, an expression (ast::Expr
) and an enabled status.
You will never use them directly, since the sdw::ShaderWriter
base class exposes all necessary functions to declare all types of variables.
When you want to declare a local variable with a type, say for the following glsl : vec3 a;
, you will use:
auto a = writer.declLocale< sdw::Vec3 >( "a" );
If you want to set the value of a
with something, like in the following glsl : a = vec3( 0.0, 1.0, 0.0 );
, you will use the matching composite ctor helper, this way:
a = vec3( 0.0_f, 1.0_f, 0.0_f );
Note the use of the custom literal suffix _f
which builds an sdw::Float
from the given literal.
You have literal suffixes for bool int, uint, and double, respectively _b
, _i
, _u
and _d
.
You can declare a local variable with an initialisation value, which allows you to not specify the template parameter :
auto a = writer.declLocale( "a", vec3( 0.0_f, 1.0_f, 0.0_f ) );
And then a
will be deduced as an sdw::Vec3
.
Example:
sdw::FragmentWriter writer;
// Shader inputs
auto mapHdr = writer.declCombinedImg< FImg2DRgba32 >( "mapHdr"
, 0u //binding
, 0u ); // set
auto uv = writer.declInput< Vec2 >( "uv"
, 0u ); // location
auto hdrConfig = writer.declUniformBuffer<>( "HdrConfig"
, 1u // binding
, 0u ); // set
auto uboExposure = hdrConfig.declMember< Float >( "uboExposure" );
auto uboGamma = hdrConfig.declMember< Float >( "uboGamma" );
hdrConfig.end();
// Shader outputs
auto fragOutput = writer.declOutput< Vec4 >( "fragOutput"
, 0 ); // location
// Helper functions
auto applyGamma = writer.implementFunction< Vec3 >( "applyGamma"
, [&]( Float const & gamma, Vec3 const & hdr )
{
writer.returnStmt( pow( max( hdr, vec3( 0.0_f ) ), vec3( 1.0_f / gamma ) ) );
}
, InFloat{ writer, "gamma" }
, InVec3{ writer, "hdr" } );
// Main
writer.implementMainT< VoidT, VoidT >( [&]( FragmentIn in
, FragmentOut out )
{
auto hdrColor = writer.declLocale( "hdrColor"
, mapHdr.sample( uv ).rgb() );
hdrColor *= vec3( uboExposure );
fragOutput = vec4( applyGamma( uboGamma, hdrColor ), 1.0_f );
} );