Extending default shader in three.js - three.js

I would like to extend the default lambert material shader of three.js.
I basically would like to add some custom code at the end of the default fragment shader so the last line will apply my color transformations.
It's there any simple way to do that? Or should I rewrite a completely new one adding the default code on it?

I've created a custom ShaderMaterial using the predefined blocks from the default materials.

Related

Three.js. MeshPhongMaterial has a uniform called diffuse. Why is it is not exposed nor can it be set?

In Three.js I am looking closely at the glsl source for MeshPhongMaterial. I notice the fragment shader relies on a uniform named diffuse. However there does not appear to be any way to set it. There is also an uniform named color that can be set and does indeed alter what looks like the diffuse color. Huh?
Is color copied to diffuse under the hood somehow? Can someone untangle this mystery for me.
If you look or search though the source you'll find it's set based on the color of the material
For example here
MeshPhongMaterial is not a subclass of ShaderMaterial even though they both extend Material.
Internally WebGLRenderer keeps track of / knows how to deal with two different things:
Any ShaderMaterial with any uniform. This means that you can make an exact copy of MeshPhongMaterial using ShaderMaterial and instead of myMaterial.color you'd have myMaterial.uniforms.color.
"Built-in" materials and their properties. For these, WebGLRenderer is aware of all the possible properties these materials expose. Gman has pointed out where in the code this happens (one of the places). For each material WebGLRenderer internally creates a ShaderMaterial but instead of handling it's uniforms like it would with any other such material, it manually keeps track and updates everything.
The built-in materials make little sense, since you can easily pipe foo.bar to foo.uniforms.bar using getters and setters leaving the renderer to only deal with shader materials.
If you really really want a uniform created for a built in material, you have to wait until the renderer creates them, and you can tap into this process with material.onBeforeCompile = shader=>{} (the shader object will contain the uniforms).

Print custom MeshStandardMaterial in THREE.js

I am trying to implement new custom features to the MeshStandardMaterial, in particular I would like to add the possibility to add two normal map that use different UV sets. Then I will combine them inside the fragment shader.
So far I have "doubled" meshstandardmaterial and make WebGLProgram insert keyword like "Use NormalMap2". The next step would be to mess around with actual glsl code.
Is there some way to print fragment shader or some how look what has been passed to it?
The easiest way to debug my code was to use webGL inspector, it shows me what texture has been passed to the shader and also it shows me all shader code

custom attributes using threejs

I was reading on ThreeJS custom attributes and got confused about how to set them up.
So i've seen that we add an attribute to the geometry attribute list and then the same to the ShaderMaterial attributes list ?
My question is how to add custom attributes in 3js ?
The new version (r67) features RawShaderMaterial which allows full control of attributes/shaders. Here's an example:
http://threejs.org/examples/webgl_buffergeometry_rawshader.html
If you want something less "raw" but still performant, here's an example using BufferGeometry and ShaderMaterial:
http://threejs.org/examples/webgl_buffergeometry_custom_attributes_particles.html
And, if you want to use Geometry here's an example of that too:
http://threejs.org/examples/webgl_custom_attributes.html

How can I extend CanvasRenderer in Three.js for a custom material?

What's the best way to extend CanvasRenderer in Three.js for a custom material?
I've got a ShaderMaterial for customized dashed lines in WebGL, but I need CanvasRenderer support as well. I figure I could create a custom material that extends the Material class. But I'm sure I'll have to extend Canvas Renderer in some way. How should I go about that? Copy and paste, creating a new class entirely?
Here is a jsFiddle (http://jsfiddle.net/VyP29/1/) . of what I want to do, but in WebGL. I need the lines to stay a consistent length so it will probably have to be implemented by expanding a single line to multiple lines and gaps (for the CanvasRenderer).

Flat shading OpenGL using Three.js

I am trying to simulate the OpenGL flat shading model using Three.js. My idea is creating an example like http://en.wikipedia.org/wiki/File:Phong-shading-sample.jpg. I was trying to change some different shading models but I cannot obtain the desired result.
Is it possible to create this scene in three.js?
Thanks in advance
Materials e.g. the MeshBasicMaterial have an option called "shading". It can be set to THREE.None, THREE.FlatShading, THREE.SmoothShading.
I am not sure if you need a light source in the first place or wether you have to enable shading for a the whole scene. Look at the demos at the Three.js website for something with shading.

Resources