I’m trying to create custom blending effects for InstancedMesh objects with ShaderMaterial. The standard THREE.JS blend modes like Additive and Subtractive work okay but they don’t match what I see in my Figma mockup.
In Figma I’m using mix-blend-mode overlay between all the circular shapes. I found some GLSL overlay blend functions and tried adding them to my fragment shader:
uniform vec3 colorArray[6];
uniform float stepValues[6];
varying vec2 texCoords;
float overlayBlend(float baseVal, float blendVal) {
return baseVal < 0.5 ? (2.0 * baseVal * blendVal) : (1.0 - 2.0 * (1.0 - baseVal) * (1.0 - blendVal));
}
vec3 overlayBlend(vec3 baseColor, vec3 blendColor) {
return vec3(
overlayBlend(baseColor.r, blendColor.r),
overlayBlend(baseColor.g, blendColor.g),
overlayBlend(baseColor.b, blendColor.b)
);
}
vec3 overlayBlend(vec3 baseColor, vec3 blendColor, float alpha) {
return (overlayBlend(baseColor, blendColor) * alpha + baseColor * (1.0 - alpha));
}
void main() {
vec3 finalColor = mix(colorArray[0], colorArray[1], smoothstep(stepValues[0], stepValues[1], texCoords.y));
finalColor = mix(finalColor, colorArray[2], smoothstep(stepValues[1], stepValues[2], texCoords.y));
finalColor = mix(finalColor, colorArray[3], smoothstep(stepValues[2], stepValues[3], texCoords.y));
finalColor = mix(finalColor, colorArray[4], smoothstep(stepValues[3], stepValues[4], texCoords.y));
finalColor = mix(finalColor, colorArray[5], smoothstep(stepValues[4], stepValues[5], texCoords.y));
gl_FragColor = vec4(overlayBlend(finalColor.rgb, ???), 1.0);
}
The issue is I think I need sampler2D uniforms and texture2D calls to make this work properly. But how do I generate those textures? Should I render each instance separately to different render targets and store all the textures? I’m not sure about the best approach here.