3d – GLSL Shade a box different colors for two ends with one material in Three.js

First, I knew the following basic knowledges,

Then, I can use shader to render 2D graphics on the Shadertoy or GLSL Sandbox Gallery cross-browser online editor through WebGL or with the cross-platform SHADERed IDE. It’s easy to use GLSL to draw 2D objects because 2D coordinates correspond to gl_Position. But I failed to use ShaderMaterial with the GLSL code to render a BoxGeometry I created in three.js. See the following code for my case.

var container;
var camera, scene, renderer;
var mesh;
var uniforms;

var clock = new THREE.Clock();


function init() {
    container = document.getElementById('container');

    camera = new THREE.PerspectiveCamera(40, window.innerWidth / window.innerHeight, 1, 3000);
    camera.position.z = 2.0;
    camera.position.y = 1.0;
    camera.rotation.x = -0.45;

    scene = new THREE.Scene();

    //var boxGeometry = new THREE.PlaneGeometry(0.75, 0.75, 1);
    var boxGeometry = new THREE.BoxGeometry(0.5, 0.5, 0.5, 1,1,1);

    uniforms = { u_time: { type: "f", value: 0.0 } };

    var material = new THREE.ShaderMaterial({
        uniforms: uniforms,
        side: THREE.DoubleSide,
        transparent: true,
        vertexShader: document.getElementById('vertexShader2').textContent,
        fragmentShader: document.getElementById('fragment_shader2').textContent

    mesh = new THREE.Mesh(boxGeometry, material);

    renderer = new THREE.WebGLRenderer();
    renderer.setClearColor(0xffffff, 1);


    window.addEventListener('resize', onWindowResize, false);


function onWindowResize(event) {
    camera.aspect = window.innerWidth / window.innerHeight;
    renderer.setSize(window.innerWidth, window.innerHeight);

function animate() {

function render() {
    var delta = clock.getDelta();
    uniforms.u_time.value += delta;
    mesh.rotation.y += delta * 0.5;
    renderer.render(scene, camera);
window.onerror = function (msg, url, line, col, error) {
    // Note that col & error are new to the HTML 5 spec and may not be 
    // supported in every browser.  It worked for me in Chrome.
    var extra = !col ? '' : 'ncolumn: ' + col;
    extra += !error ? '' : 'nerror: ' + error;

    // You can view the information in an alert to see things working like this:
    alert("Error: " + msg + "nurl: " + url + "nline: " + line + extra);

    // TODO: Report this error via ajax so you can keep track of what pages have JS issues

    var suppressErrorAlert = true;
    // If you return true, then error alerts (like in older versions of 
    // Internet Explorer) will be suppressed.
    return suppressErrorAlert;
    <!-- <script src="https://threejs.org/build/three.min.js"></script> -->
    <!-- <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r121/three.min.js"></script> -->
    <script src="https://cdn.jsdelivr.net/npm/three@0.130.1/build/three.min.js"></script>

    <div id="container"></div>

<script id="fragment_shader2" type="x-shader/x-fragment">
varying vec3 v_color;

void main( void ) {
    gl_FragColor = vec4(v_color, 1.);    
<script id="vertexShader2" type="x-shader/x-vertex">
varying vec3 v_color;
void main()
    v_color = vec3(position.z < 0.25, 0, position.z >= 0.25);
    vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );
    gl_Position = projectionMatrix * mvPosition;

<script id="fragment_shader" type="x-shader/x-fragment">
varying vec2 v_uv;

void main( void ) {
    vec2 uv = v_uv;
    // Zooms out by a factor of 2.0
    uv *= 2.0;
    // Shifts every axis by -1.0
    uv -= 1.0;
    // Base color for the effect
    vec3 color = vec3 ( .2, 1., 0. );

    // specify size of border. 0.0 - no border, 1.0 - border occupies the entire space
    vec2 borderSize = vec2(0.3); 

    // size of rectangle in terms of uv 
    vec2 rectangleSize = vec2(1.0) - borderSize; 

    // distance field, 0.0 - point is inside rectangle, 1.0 point is on the far edge of the border.
    float distanceField = length(max(abs(uv)-rectangleSize,0.0) / borderSize);
    // calculate alpha accordingly to the value of the distance field
    float alpha = 1.0 - distanceField;

    gl_FragColor = vec4(color, alpha);    

<script id="vertexShader" type="x-shader/x-vertex">
varying vec2 v_uv;
void main()
    v_uv = uv;
    vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );
    gl_Position = projectionMatrix * mvPosition;

    <div id="info">
        <a href="https://threejs.org/examples/#webgl_postprocessing_outline">WebGL Postprocessing Outline</a>
    <a href="https://threejs.org" target="_blank" rel="noopener">three.js</a> - Outline Pass by 
    <a href="http://eduperiment.com" target="_blank" rel="noopener">Prashant Sharma</a> and
    <a href="https://clara.io" target="_blank" rel="noopener">Ben Houston</a>
<script type="module" src="index.js"></script>

I guessed that it was because it could distinguish between vertexes in the same middle position of the +x sides and -x sides for v_color = vec3(position.x < 0.25, 0, position.x >= 0.25);.

Finally, I also knew that I can Split the geometry into groups with different materials, but I just want to use one ShaderMaterial to do this.

var geo = new THREE.BoxGeometry(48, 48, 48, 2);
var magnetMaterial = ('red', 'blue', 'green', 'purple', 'cyan', 'white', 'black', 'pink', 'orange', 'gray').map(it =>
    new THREE.MeshPhongMaterial({
        color: it, side: THREE.DoubleSide,
        polygonOffset: true, polygonOffsetFactor: 1

//Initializes the magnetic orientation to +x, red on the left side and blue on the right side.
//faces().materialIndex: -x,-x, +x,+x, +z,+z,+z,+z, -y,-y,-y,-y, -z,-z,-z,-z, +y,+y,+y,+y
// var faceColors = (1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0);
// console.log('faceColors', geo.faces.map((it, idx) => it.materialIndex = faceColors(idx))); // for Three.js 1.20

// let's regroup materialIndex of five faces of the two ends of the Cuboid (x+,x-,y+,y-,z+,z-)
console.log(geo.getIndex().count, geo.groups.slice(0));
(0, 1, 1, 0, 1, 0, 1, 0, 0, 1).forEach((val, idx) => geo.addGroup(6 * idx, 6, val));

Anyone could help me to explain and solve this problem because the gradient is not what I want?

Different colors (shadows) when using Graphics3D to plot polygons

I am trying to plot a list of polygons. I would like the color to be uniform, i.e yellow is strictly yellow. However, when I rotate it, the sides of the structure seem to have a shadow or just a different color i.e orange-ish instead of yellow. Here is the picture:

enter image description here

I think I can add something to the code to avoid this, but I am not sure what. I tried playing with the lighting and the MeshShading with no good results. Any help would be immensely appreciated.

plotting – GeoListPlot and interfering colors?

Exploring Wolfram Language databases.

  "City", {"Country" -> Entity["Country", "Netherlands"], 
   "Population" -> 
    GreaterThan[Quantity[500000, "People"]]}] // EntityList

I get 3 cities: Amsterdam, Rotterdam, The Hague

But Rotterdam is lacking as a red dot when I do:

  "City", {"Country" -> Entity["Country", "Netherlands"], 
   "Population" -> GreaterThan[Quantity[500000, "People"]]}]]

Is it just a matter of interfering colors?

gui design – Is feature to customize themes and colors for Mobile/Web Apps important for UX?

We are building a CRM like application but targeting micro businesses, consultants and etc.

While designing UI for our Mobile/Web App, my manager suggested us to inlcude themes, color and fonts customization so our users will be able to customize the look and feel of the App.

From my Point of View, I feel this is rather pointless, I don’t think users would care about theme customizations. To further my point, Facebook, linkedIn, or Whatsapp doesn’t have it….

So my question, is the feature of customizing themes and colors important for a good UX experience?

R heatmap: assign colors to values

I’ve found the following R code in the R graph gallery (https://www.r-graph-gallery.com/79-levelplot-with-ggplot2.html) for a heatmap and modified it a little bit:

# Library


# Dummy data
x <- LETTERS(1:20)
y <- paste0("var", seq(1,20))
data <- expand.grid(X=x, Y=y)
data$Z <- runif(400, -1, 2)

print (data)

# Heatmap 
ggplot(data, aes(X, Y, fill= Z)) + 
  geom_tile(color = "white",
            lwd = 0.5,
            linetype = 1)

My issue: I have three columns with values ranging from -1 to 2. Now I would like to assign defined colors to the values, f.e. as follows:
-1: color red, 0: color green, 1: color yellow, 2: color blue.

Is there a way to use the geom_tile function for my issue?

Thank you!

colors – Full dark-mode in Microsoft Word (2016): dark page background

With dark theme mode in Windows 10 the Office Word background stays white.

Without changing the color of the text background in a Word document while writing and reading there is no “dark mode” feel as the white background fills the view.

enter image description here

I am looking for some time for this feature that is available in LibreOffice under Tools-Options-Application colors

enter image description here

I am posting this in order to provide the answer.

algorithm – “Smoothing” colors in mutliple-color gradient in fragment shader

TL;DR How to better avoid some of the colors in the gradient looking like brighter/darker lines and make them blend in with neighboring colors. Not too concerned with performance/color accuracy but don’t like how my algorithm muddies up colors at higher blend settings.

Longer explanation

I initially wrote a straight-forward gradient algorithm which linearly transitions between colors. This works fine however there was one aspect that I didn’t like about the result: the points in the gradient where there is just the pure color stood out too much.

For example, on the image below the white color in the middle looks like a bright line – I would like to somehow soften this – going for aesthetics over color accuracy.

enter image description here

Idea behind algorithm attempt to smooth out “peaks”

The simple linear case, assuming 2 colors, can be represented as a graph with the proportion of color 1 represented by a straight line going from (0, 1) to (1, 0) (y = 1 – x) and another one (color 2) going from (0, 0) to (1, 1) (y = x). My idea is to limit the lowest and highest points, so that for example the lines become (0, 0.8) to (1, 0.1) and (0, 0.1) to (1, 0.8) and hence there is never just the single color shown. The top boundary is limited at 1 – (2 * bottom) because when there are more than 2 colors, the middle colors will have 2 neighbors.

The algorithm and resulting gradients are below. Even with high proportions of neighboring colors mixed in, I still think the “lines” (light red near the top, dark purple in the middle and light green near the bottom on the right sample) are too visible (this had an input of 10 colors, which my algorithm unfortunately also muddies up):

enter image description hereenter image description here

Is there a better approach to blur the boundaries? I thought about using a quadratic/curved function, but it seems like that will just lead to an even wider plateau, or a narrow but sharp peak depending on which way it’s facing.

#ifdef GL_ES
precision mediump float;

uniform vec2 iResolution;

//input - array of colors
uniform vec3 iColors(10);
//input - actual number of colors in the array
uniform int iNumColors; 

void main(void) {
    // x, y co-ordinates, 0 to 1
    vec2 uv = gl_FragCoord.xy / iResolution.xy;
    // flip y axis so first color is on top
    uv.y = 1.0 - uv.y;
    float transparency = 1.0;

    //if only one color, return uniform color
    if (iNumColors == 1) {
        gl_FragColor = vec4(iColors(0), transparency);

    // init to black - rgb channels 0 to 1
    vec3 color = vec3(0.);
    float colorWidth = 1.0 / float(iNumColors - 1);

    for (int i = 0; i < iNumColors; i++) {
        // location of "peak" of current color
        float midPoint = float(i) * colorWidth;
        float colorValue;
        float overlap = 0.25;
        float top = 1. - (overlap * 2.);
        float bottom = overlap;
        float height = top - bottom;
        float gradient = height / colorWidth;
        float yOffset;
        if (uv.y >= midPoint) {
            gradient *= -1.0;
            yOffset = top + (height * float(i));
        } else {
            yOffset = bottom - (height * float(i - 1));
        colorValue = yOffset + (gradient * uv.y);
        color += iColors(i) * max(0., colorValue);
    gl_FragColor = vec4(color, transparency);

art – Is it a good idea to give NPCs unnatural hair colors while keeping that of the PC a natural color?

The player-character is the most important character in the game, so it is a good idea to spend some effort into making them look unique. Every creative choice about the look of the PC should be deliberate and well-justified.

However, hair color is not the only way to do that. There are lots and lots of details you can add to a character to give them some unique touch.

I would argue that giving the player-character a realistic hair color while giving some NPCs fantastic hair colors might in fact not be the worst decision, because it will make it easier for the player to identify with the player-character. For example, did you notice that anime and manga, the art style which basically invented the idea that every color of the visible spectrum is a natural hair color, more often than not use natural haircolors for the protagonist and unnatural colors for supporting characters? This serves two effects:

  1. It is easier for the audience to identify with the protagonist
  2. Ironically, it helps the protagonist stand out, because they are the only character who does not have an unnatural hair color.