Skip to content

Extending built-in materials, instances of ShaderMaterial and shader objects of onBeforeCompile.

License

Notifications You must be signed in to change notification settings

alvin-tosh/THREE.extendMaterial

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

20 Commits
 
 
 
 
 
 

Repository files navigation

Extending Materials

Plugin for extending built-in materials, instances of ShaderMaterial and built-in materials as well as shader objects of onBeforeCompile.

Demo: Creating new materials based on MeshStandardMaterial and custom depth material for shadows

THREE.extendMaterial( constructor|material|shaderMaterial [, options])

For patching in onBeforeCompile: THREE.patchShader( object [, options])

const myMaterial = THREE.extendMaterial(THREE.MeshPhongMaterial, {

    // Will be prepended to vertex and fragment code
    header: 'varying vec3 vEye;',


    // Insert code lines by hinting at a existing
    vertex: {

        // Inserts the line after #include <fog_vertex>
        
        '#include <fog_vertex>': 'vEye = normalize(cameraPosition - w.xyz);',

        // Replaces a line (@ prefix) inside of the project_vertex include

        'project_vertex': {
            '@vec4 mvPosition = modelViewMatrix * vec4( transformed, 1.0 );': 'vec4 mvPosition = modelViewMatrix * vec4( transformed * 0.5, 1.0 );'
        }
    },
    fragment: {
        '#include <envmap_fragment>': 'diffuseColor.rgb += pow(dot(vNormal, vEye), 3.0);'
    },


    // Properties to apply to the new THREE.ShaderMaterial
    material: {
        skinning: true
    },


    // Uniforms (will be applied to existing or added) as value or uniform object
    uniforms: {
        diffuse: new THREE.Color(0xffffff),
        emissive: {
            value: new THREE.Color('pink')
        }
    }

});

Patching shader code

Code can be appended, prepended and replaced by providing some indicating line code (typically includes like above) and a prefix to define if the code should be appended, prepended to the hinted line or replace it.

Prefix Insertion
none append
? prepend
@ replace

Templates

When creating a material variation such as a depth material and the previous patched code should be applied too, defining a template will apply all previous patches again. This is useful when creating alternative versions, for example a custom depth material that also respects custom vertex transformations.

For example you extended MeshStandardMaterial with some vertex distortions to add wind motion, in order t

const depthMaterial = THREE.extendMaterial( THREE.MeshDepthMaterial, {
	
	template: myMaterial
	
});

Release notes

Version 2

  • A new THREE.CustomMaterial which stays more compatible to the in-built materials when extending those
  • class property in options to use another material class than ShaderMaterial (e.g CustomMaterial)
  • mixed property in uniforms to pass them from templates
  • linked property in uniforms to share them when used as template but not when extending them, this ensures you don't have to sync. uniforms from your original material with the depth material for shadows for example
  • Compatibility with RawShaderMaterial
  • Uniforms can be given now as wrapper-object or their value
  • Cloning materials now respects shared uniforms
  • Alias THREE.extendMaterial as shorter alternative to THREE.ShaderMaterial.extend
  • Fixed compatibility with minified THREE bundles
  • Templates (applying of previous code patches and inheriting properties)
  • Sharing of uniform wrapper by defining a shared {shared: true, value: .. } boolean in a uniform object
  • vertexHeader, fragmentHeader, vertexEnd, fragmentEnd added wich will only add the given string to the corresponding part while the "End" ones will add the string at the end of the main function
  • Constants (defines) which are a boolean false will get removed as they are mainly used with #ifdef in THREE what causes a false positive for this condition
  • customDepthMaterial and customDistanceMaterial can be also defined on materials now, so it doesn't need to be assigned for every new mesh with this material
  • Uniforms are reduced to what has been defined at least with null and necessary pairs (for example normalMapScale when normalMap is defined), this saves a large amount of uniforms that aren't used
  • Lights uniforms are now shared instead cloned for every material (it's a huge set), internally THREE assigns the value for all equally anyway

About

Extending built-in materials, instances of ShaderMaterial and shader objects of onBeforeCompile.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • JavaScript 62.0%
  • TypeScript 36.9%
  • Other 1.1%