Three.js: custom defines to default materials

Created on 9 Feb 2017  路  5Comments  路  Source: mrdoob/three.js

Description of the problem

I've got a couple of effects i've tried to implement on top of three.js but in order to get them to work with default materials or shadows, i needed to hack the WebGLRenderer. In r78, i could just override a few functions (like WebGLPrograms) and inject some GLSL.

In 84 this seems impossible, there is no THREE namespacing so THREE.Vector3 is Vector3, THREE.WebGLPrograms is undefined etc.

See this for more details.

The other use case i'd have is for adding custom TBN information, and unpacking it.

This all got me thinking, shadows aside, could there be a mechanism to inject custom logic into the default materials? Something like:

var MyFancyInjection = {
  defines:['foo','bar'],
  vertexHelpers: {
     foo: 'float random( vec2 input ) { ... };'
  },
  vertexTransform:{
     foo: ' transformed = doSomethingWithTransformed( transformed );'
  },
  fragmentEnd:{
     bar: ' gl_FragColor.xyz *= .5;'
  },
  ....
  //or
  shaderChunks:{
    begin_vertex: myBeginVertexOverride
  }
  ...
}
var material = new THREE.MeshPhongMaterial({
   userOverride: myFancyInjection
});

Then have the program figure out what needs to be done, does it take a chunk from cache, or the provided one, does it inject attributes, or just a define etc.

The shadowmap only needs the position information, no normals, so in case of a custom TBN or transformation it would only care about transformation. Perhaps this could be used with useSkinning and useMorphing but it would require on settling for a "transformation" flag of sorts to always be included.

Just a thought.

Three.js version
  • [ ] Dev
  • [x] r84
  • [ ] ...
Browser
  • [x] All of them
  • [ ] Chrome
  • [ ] Firefox
  • [ ] Internet Explorer
OS
  • [x] All of them
  • [ ] Windows
  • [ ] Linux
  • [ ] Android
  • [ ] IOS
Hardware Requirements (graphics card, VR Device, ...)

Most helpful comment

It's doable:

THREE.ShaderLib[ 'phong' ].fragmentShader = THREE.ShaderLib[ 'phong' ].fragmentShader.replace(

    "gl_FragColor = vec4( outgoingLight, diffuseColor.a );",

    "#ifndef CUSTOM\n\
        gl_FragColor = ( gl_FrontFacing ) ? vec4( outgoingLight, diffuseColor.a ) : diffuseColor;\n\
    #else\n\
        gl_FragColor = ( gl_FrontFacing ) ? vec4( outgoingLight, diffuseColor.a ) : vec4( diffuse, opacity );\n\
    #endif"

);

Usage:

var material = new THREE.MeshPhongMaterial( { color: 0xff0000 } );

material.defines = material.defines || {};
material.defines.CUSTOM = "";

All 5 comments

It's doable:

THREE.ShaderLib[ 'phong' ].fragmentShader = THREE.ShaderLib[ 'phong' ].fragmentShader.replace(

    "gl_FragColor = vec4( outgoingLight, diffuseColor.a );",

    "#ifndef CUSTOM\n\
        gl_FragColor = ( gl_FrontFacing ) ? vec4( outgoingLight, diffuseColor.a ) : diffuseColor;\n\
    #else\n\
        gl_FragColor = ( gl_FrontFacing ) ? vec4( outgoingLight, diffuseColor.a ) : vec4( diffuse, opacity );\n\
    #endif"

);

Usage:

var material = new THREE.MeshPhongMaterial( { color: 0xff0000 } );

material.defines = material.defines || {};
material.defines.CUSTOM = "";

ooh nice i didnt know about this,

I've yet to take it for a spin, but this is super nice. What could be done about shadows though?

Hmm.. its not entirely flexible, i'm not sure where to put my attributes. I'm trying to append it to common, but it's present in both frag and vert. I see that gamma is always defined for fragment, so maybe look for that? Or use something like color_pars_vertex.glsl?

edit

piggybacking on color_pars_vertex works like a charm, but i notice its not present in depth_vertex. @WestLangley, could we perhaps globally add IS_INSTANCED? Would help with the shadow map.

Could change this pull to test the geometry for InstancedBufferGeometry? I'm not sure though if it would need all the flags, should instances be drawn while skinned and morphed?

So, i was able to completely pull of what i had in mind with zero hacking thanks to three undocumented features.

Material.defines
Material.customDepthMaterial
Material.customDistanceMaterial
Was this page helpful?
0 / 5 - 0 ratings

Related issues

alexprut picture alexprut  路  3Comments

filharvey picture filharvey  路  3Comments

konijn picture konijn  路  3Comments

ghost picture ghost  路  3Comments

boyravikumar picture boyravikumar  路  3Comments