Skip to content
Fran edited this page Mar 28, 2016 · 3 revisions

Table of Contents

Predefined shaders

xml3d.js has three predefined material models, which are probably sufficient for most of the use-cases. If not, it's easy to define custom material shaders.

Matte

Renders an object with a solid color, without taking into account any light sources.

URN
urn:xml3d:material:matte
Supported parameters
Name Type Default Description
diffuseColor <float3> 1 1 1 The object's RGB diffuse color component.
useVertexColor <bool> false Setting this to "true" will render the object using the supplied vertex colors. If no vertex colors are supplied the object will be rendered with a flat red fallback shader.
Supported textures
None

Diffuse

Renders a diffuse shaded object without specular highlights. This material does not assume an implicit light source in scenes with no lights defined.

URN
urn:xml3d:material:diffuse
Supported parameters
Name Type Default Description
diffuseColor <float3> 1 1 1 The object's RGB diffuse color component.
emissiveColor <float3> 0 0 0 The object's RGB emissive color component.
ambientIntensity <float> 0 The ambient lighting component of the object, to be multiplied with its diffuseColor.
opacity <float> 1 The opacity of the object, with 1 being opaque and 0 being fully transparent.
useVertexColor <bool> false Setting this to "true" will render the object using the supplied vertex colors. If no vertex colors are supplied the object will be rendered with a flat red fallback shader.
Supported textures
Name Behavior
diffuseTexture RGB multiplied with diffuseColor, A multiplied with opacity
emissiveTexture RGB multiplied with emissiveColor, A ignored

Phong

Renders a phong shaded object with specular highlights. In scenes without any visible lights defined this material will effectively render the object with only its emissive color and/or texture.

URN
urn:xml3d:material:phong
Supported parameters
Name Type Default Description
diffuseColor <float3> 1 1 1 The object's RGB diffuse color component.
emissiveColor <float3> 0 0 0 The object's RGB emissive color component.
specularColor <float3> 0 0 0 The object's RGB specular color component.
shininess <float> 0.5 A scalar for the object's specular exponent, to be multiplied by 128 (eg. a value of 0.5 will give a specular exponent of 64)
ambientIntensity <float> 0 The ambient lighting component of the object, to be multiplied with its diffuseColor.
opacity <float> 1 The opacity of the object, with 1 being opaque and 0 being fully transparent.
useVertexColor <bool> false Setting this to "true" will render the object using the supplied vertex colors. If no vertex colors are supplied the object will be rendered with a flat red fallback shader.
Supported textures
Name Behavior
diffuseTexture RGB multiplied with diffuseColor, A multiplied with opacity
emissiveTexture RGB multiplied with emissiveColor, A ignored
specularTexture RGB multiplied with specularColor, A ignored

Custom material shaders

Registering a custom shader to the system is easy, here shown for a simple eyelight shader:

XML3D.materials.register("eyelight", {

    vertex : [
        "attribute vec3 position;",
        "attribute vec3 normal;",
        "attribute vec3 color;",

        "varying vec3 fragNormal;",
        "varying vec3 fragVertexPosition;",
        "varying vec3 fragEyeVector;",
        "varying vec3 fragVertexColor;",

        "uniform mat4 modelViewProjectionMatrix;",
        "uniform mat4 modelViewMatrix;",
        "uniform mat3 normalMatrix;",
        "uniform vec3 cameraPosition;",

        "void main(void) {",
        "    gl_Position = modelViewProjectionMatrix * vec4(position, 1.0);",
        "    fragNormal = normalize(normalMatrix * normal);",
        "    fragVertexPosition = (modelViewMatrix * vec4(position, 1.0)).xyz;",
        "    fragEyeVector = normalize(fragVertexPosition);",
        "    fragVertexColor = color;",
        "}"
    ].join("\n"),

    fragment : [
        "#ifdef GL_ES",
          "precision highp float;",
        "#endif",

        "uniform float ambientIntensity;",
        "uniform vec3 diffuseColor;",
        "uniform vec3 emissiveColor;",
        "uniform float shininess;",
        "uniform vec3 specularColor;",
        "uniform float opacity;",
        "uniform mat4 viewMatrix;",
        "uniform bool useVertexColor;",

        "varying vec3 fragNormal;",
        "varying vec3 fragVertexPosition;",
        "varying vec3 fragEyeVector;",
        "varying vec3 fragVertexColor;",

        "void main(void) {",
        "  if (opacity < 0.95) discard;\n",
        "  vec3 objDiffuse = diffuseColor;",
        "  if (useVertexColor) ",
        "     objDiffuse *= fragVertexColor;",

        "  vec3 color = emissiveColor + (ambientIntensity * objDiffuse);\n",
        "  vec3 normal = fragNormal;",
        
        "  vec3 eyeVec = normalize(-fragVertexPosition);",     
        "  vec3 lightVec = eyeVec;",
        "  float diffuse = max(0.0, dot(normal, lightVec)) ;",
        "  float specular = pow(max(0.0, dot(normal, eyeVec)), shininess*128.0);",

        "  color = color + diffuse*objDiffuse + specular*specularColor;",
        "  gl_FragColor = vec4(color, max(0.0, opacity));",
        "}"
    ].join("\n"),

    addDirectives: function(directives, lights, params) {
      // Add directives to the shader, depending on lights and parameters
    },
    attributes: { // All vertex attributes and whether they're required
        position: { required: true },
        normal  : { required: true },
        color   : null           //Optional
    },
    uniforms: { // Used shader parameters with default values
        diffuseColor    : [1.0, 1.0, 1.0],
        emissiveColor   : [0.0, 0.0, 0.0],
        specularColor   : [1.0, 1.0, 1.0],
        opacity         : 1.0,
        shininess       : 0.5,
        ambientIntensity: 0.0,
        useVertexColor : false
    },

    samplers: { // Add name of samplers the shader needs
    }
});

Now one can refer to the new material via the URN: urn:xml3d:material:eyelight, e.g. like this:

<material id="eyelight-blue" model="urn:xml3d:material:eyelight">
   <float3 name="diffuseColor">0 0 0.8</float3>
</material>

The predefined materials work the same way. For a more complex example, see the phong shader definition.

Clone this wiki locally