coin_shaders_page(3)

πŸ“¦
version 4.0.10 Β· 4 versions
, in fedora 43, fedora 44

πŸ’– coin_shaders_page πŸ’–

okay bestie, you found the page all about shaders in Coin β€” this is coin_shaders_page(3), and it's lowkey the glow-up era of Coin. Let's get into it 🫢


✨ NAME ✨

  • coin_shaders_page β€” shaders in Coin πŸ’…

🌈 DESCRIPTION 🌈

Coin 2.5 added support for shaders, and the main characters in this story are SoShaderProgram, SoVertexShader, SoFragmentShader, and SoGeometryShader. A typical scene graph with shaders looks something like this:

Separator {
  ShaderProgram {
    shaderObject [
      VertexShader {
        sourceProgram "myvertexshader.glsl"
        parameter [
          ShaderParameter1f { name "myvertexparam" value 1.0 }
        ]
      }
      FragmentShader {
        sourceProgram "myfragmentshader.glsl"
        parameter [
          ShaderParameter1f { name "myfragmentparam" value 2.0 }
        ]
      }
    ]
  }
  Cube { }
}

This will render the cube with the vertex and fragment shaders specified in myvertexshader.glsl and myfragmentshader.glsl. Coin also supports ARB shaders and Cg shaders (if the Cg library is installed) β€” but fr fr, we recommend using GLSL, because that's the shader language we're focusing mostly on supporting. πŸ‘‘


πŸŽ€ The named parameters Coin hands you for free

Coin defines some named parameters that can be added by the application programmer, and which will be automatically updated by Coin while traversing the scene graph. No cap, they just show up pre-updated:

  • coin_texunit[n]_model β€” Set to 0 when texturing is disabled, and to SoTextureImageElement::Model if there's a current texture on the state for unit n.
  • coin_light_model β€” Set to 1 for PHONG, 0 for BASE_COLOR lighting.
  • coin_two_sided_lighting β€” Set to 1 for two-sided, 0 for normal.

πŸ¦‹ The iconic per-fragment Phong example

Example scene graph that renders per fragment OpenGL Phong lighting for one light source. The shaders assume the first light source is a directional light. This is the case if you open the file in a standard examiner viewer. (iykyk πŸ‘€)

The iv-file:

Separator {
  ShaderProgram {
    shaderObject [
      VertexShader {
        sourceProgram "perpixel_vertex.glsl"
      }
      FragmentShader {
        sourceProgram "perpixel_fragment.glsl"
      }
    ]
  }
  Complexity { value 1.0 }
  Material { diffuseColor 1 0 0 specularColor 1 1 1 shininess 0.9 }
  Sphere { }

  Translation { translation 3 0 0 }
  Material { diffuseColor 0 1 0 specularColor 1 1 1 shininess 0.9 }
  Cone { }

  Translation { translation 3 0 0 }
  Material { diffuseColor 0.8 0.4 0.1 specularColor 1 1 1 shininess 0.9 }
  Cylinder { }
}

The vertex shader (perpixel_vertex.glsl):

varying vec3 ecPosition3;
varying vec3 fragmentNormal;

void main(void)
{
  vec4 ecPosition = gl_ModelViewMatrix * gl_Vertex;
  ecPosition3 = ecPosition.xyz / ecPosition.w;
  fragmentNormal = normalize(gl_NormalMatrix * gl_Normal);

  gl_Position = ftransform();
  gl_FrontColor = gl_Color;
}

The fragment shader (perpixel_fragment.glsl):

varying vec3 ecPosition3;
varying vec3 fragmentNormal;

void DirectionalLight(in int i,
                      in vec3 normal,
                      inout vec4 ambient,
                      inout vec4 diffuse,
                      inout vec4 specular)
{
  float nDotVP; // normal . light direction
  float nDotHV; // normal . light half vector
  float pf;     // power factor

  nDotVP = max(0.0, dot(normal, normalize(vec3(gl_LightSource[i].position))));
  nDotHV = max(0.0, dot(normal, vec3(gl_LightSource[i].halfVector)));

  if (nDotVP == 0.0)
    pf = 0.0;
  else
    pf = pow(nDotHV, gl_FrontMaterial.shininess);

  ambient += gl_LightSource[i].ambient;
  diffuse += gl_LightSource[i].diffuse * nDotVP;
  specular += gl_LightSource[i].specular * pf;
}

void main(void)
{
  vec3 eye = -normalize(ecPosition3);
  vec4 ambient = vec4(0.0);
  vec4 diffuse = vec4(0.0);
  vec4 specular = vec4(0.0);
  vec3 color;

  DirectionalLight(0, normalize(fragmentNormal), ambient, diffuse, specular);

  color =
    gl_FrontLightModelProduct.sceneColor.rgb +
    ambient.rgb * gl_FrontMaterial.ambient.rgb +
    diffuse.rgb * gl_Color.rgb +
    specular.rgb * gl_FrontMaterial.specular.rgb;

  gl_FragColor = vec4(color, gl_Color.a);
}

🌸 and that's the whole page, bestie. go make something shiny with it. ✨

Version 4.0.10 πŸ¦‹ Thu Jun 25 2026 00:00:00 β€” mwah, xoxo, go slay your scene graph πŸ’œπŸŽ€

πŸ“¦ where this page comes from