I am reffering to this method stackoverflow to easily let clipped objects appear capped by changing the fragmentShader before it compiles.
(I changed to this method rather than making stencils because I have multiple Objects with different capping-Colors, where I have got lost with all the stencilBuffers and renderOrders.)
However, I need to be able to modify the capping Color dynamically, because I will have multiple objects with different Colors, like so: (In my opinion, dead simple)
The material name defines the shader code used for rendering. If you have two meshes, using the same material, you can’t change the shader code to be different for each mesh, because there is only one shader code. So you can’t inject two different color values into the code.
You need to provide a uniform to the material and give it different values in the material constructor (which is what material.color is).
In your case, the easiest way is to use stencils.
Otherwise, you can either write a custom shader (and take care of illumination and other aspects yourself) or you can try to hack the material code in onBeforeCompile, for example, use emissive as the second color (backfaceColor). In that case, you need to add more replacements; to copy emissive to backfaceColor and make sure emissive is set to vec4(0.0) anywhere in the shader code (instead of the code using emissive uniform).
Thanks for your answer.
I kind of guessed I needed to change from MeshBasicMaterial to ShaderMaterial and define uniforms in advance. Its now working with the following code:
Using Stencils on multiple Objects, I always ran into the problem, that the last Clipping Plane also appeard on sibling Objects that actually have had their own clipping planes (with its own color-settings). see diagram below.
@PavelBoytchev
I used similar idea, with painting of back faces with a solid color, for example, to make that yellow sandbed Didn’t double the objects, just used gl_FrontFacing in patched materials.
Yeah, it’s an interesting approach to check gl_FrontFacing. I can’t recall whether there is an option in Three.js to provide a pair of materials – one for front facing triangles and a second one for back facing, without the need of custom shaders. SceneUtils.createMultiMaterialObject can be used for this, but it doubles the objects.
As far as I remember, clipping planes in THREE work in a way where fragment’s world coordinates are checked against being on one or another side of the plane, and fragments coming from the “wrong” side of the plane are simply discarded.
Since you’re writing a custom shader, you can relatively easily implement your own clipping planes or any other conditions (not necessarily a shape based) to discard fragments.
In your case, maybe there is a way to give objects IDs, pass them into a fragment shader, and apply different clipping logic based on the ID, might also help making stencil operations simpler.