A.2. Fragment shader plugs

void PLUG_fragment_eye_space(
  const vec4 vertex_eye,
  inout vec3 normal_eye)

Process the vertex and normal in eye space, at the fragment shader. You can modify the normal vector here, this is useful for bump mapping.

Note that if you modify here normal vector, you may have to take care to properly negate it. When gl_FrontFacing is false, we're looking at the other side than where standard gl_Normal was pointing. For example, for bump mapping, it's most sensible to negate only the Z component of the normal vector in tangent space.

Note that this "plug" exists only when using Phong shading, not Gouraud shading.

void PLUG_texture_color(
  inout vec4 texture_color,
  [const in samplerXxx texture,]
  const in vec4 tex_coord)

Calculate or modify the texture color. This plug is available for texture effects. The second parameter is special: for ShaderTexture, it doesn't exist at all. For other texture nodes, the sampler type depends on the corresponding X3D texture node: sampler2D for 2D textures, sampler3D for 3D textures, samplerCube for cube maps, and sampler2DShadow for GeneratedShadowMap.

void PLUG_main_texture_apply(
  inout vec4 fragment_color,
  const in vec3 normal_eye)

Called right after main texture was applied. The main texture is

  • diffuseTexture in case of Phong Material

  • emissiveTexture in case of UnlitMaterial

  • baseTexture in case of PhysicalMaterial

This plug is called always, even if the main texture is not actually present. You can change the fragment color now, for various effects.

There's a big difference between how Phong and Gouraud shading interact with this plug:

  • In Phong shading, this plug is called before the lighting was applied. Because for Phong shading, the texture is the input for the lighting equation parameter.

  • In Gouraud shading this plug is called after the lighting was applied. Because for Gouraud shading, the texture is applied in the fragment shader, and it is mixed with the color calculated from lights in the vertex shader.

void PLUG_texture_apply(
  inout vec4 fragment_color,
  const in vec3 normal_eye)

Deprecated name for PLUG_main_texture_apply. Do not use in new code.

void PLUG_fragment_modify(
  inout vec4 fragment_color)

Called after lighting (including shadows) and textures are applied (regardless of whether Phong or Gouraud shading is used). But before gamma correction (to change color from linear to monitor color-space) and tone mapping are done. This is probably the most useful plug to intuitively "change the fragment color".

void PLUG_fog_apply(
  inout vec4 fragment_color,
  const vec3 normal_eye_fragment)

At this point, the fog is applied. Again you can change here the fragment color, as you desire. This is called after lighting, textures and standard fog are all applied. You can use this to apply custom fog equation.

This happens after gamma correction (to change color from linear to monitor color-space) and tone mapping are done (because fog is done in final color space, to have fog color easily matching background and UI, see https://castle-engine.io/fog).

void PLUG_fragment_end(
  const in vec4 fragment_color)

Do the final processing of the fragment. This is called after applying both textures and fog, and cannot modify the fragment color anymore. This is useful for operations like alpha-testing the fragment.