User effects that want to cooperate with geometry shaders
have to override plugs PLUG_geometry_vertex_xxx
.
The exact specification of these plugs is
in Section A.4, “Geometry shader plugs”.
Overriding these plugs allows to pass-through or blend custom vertex attributes
needed by the effects. By correctly overriding them, the user effects
can work regardless if the geometry shader is linked or not.
To override these plugs, user effects must include an
EffectPart
with type
set to "GEOMETRY"
.
This EffectPart
code is optional. It will be used
if an other effect will provide a main()
entry
for geometry shaders, and discarded otherwise.
Our goal throughout this paper is to make effects independent
from each other, and composable with each other.
See the example compositing_shaders/geometry_shader_optional.x3dv
in our demo models.
It shows that all kinds of effects, including geometry shader effects,
may be created and applied independently from each other.
As always, just placing two or more effects together
on the X3D effects
field makes them automatically
cooperate.
There is one obstacle here.
In case of user-defined vertex attributes, using the geometry shader
means that the attribute name must change on its way from
the vertex shader to the fragment shader. That is because you have
to use different input and output names for this attribute inside the geometry shader.
On the other hand, when there is no geometry shader,
attribute name must be exactly the same in both the vertex shader and
fragment shader. This means that creating a vertex, fragment
and geometry shader combo in which the geometry shader
is optional is not possible in pure shading language like GLSL.
To overcome this, we automatically define a symbol HAS_GEOMETRY_SHADER
for all fragment shaders' parts.
This way we can write in the fragment shader code like:
#ifdef HAS_GEOMETRY_SHADER #define my_attribute my_attribute_fragment #endif in float my_attribute;
Such fragment shader can receive its input either
from the geometry shader (under the name my_attribute_fragment
)
or straight from the vertex shader (under the name
my_attribute
).