# Change color of shader

**URL:** <https://discourse.threejs.org/t/change-color-of-shader/46933>\
**Category:** Questions\
**Tags:** geometry, shaders\
**Created:** [January 16, 2023, 3:36pm UTC](https://discourse.threejs.org/t/change-color-of-shader/46933 "2023-01-16T15:36:16Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![rodrigorod](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/rodrigorod/32/32567_2.png) [@rodrigorod](https://discourse.threejs.org/u/rodrigorod)\
**Post date:** [January 16, 2023, 3:36pm UTC](https://discourse.threejs.org/t/change-color-of-shader/46933/1 "2023-01-16T15:36:16Z")

</div>

Hello, I made this morphic shape and I’d like to change the gradient of It, I’m somehow lost on how to do it. Would anyone give me ideas ?

 ![Screenshot 2023-01-16 at 16.33.13](https://canada1.discourse-cdn.com/flex035/uploads/threejs/original/3X/a/9/a97ac8e04abd8bff0877ecc0476c32989482c1ec.jpeg)

Here’s my code

```javascript
import * as THREE from 'three';
import openSimplexNoise from 'https://cdn.skypack.dev/open-simplex-noise';
import {Vector3, Vector4} from "three";
import {vector} from "three/addons/nodes/core/NodeBuilder.js";

/**
 * Scene
 *
 * @type {Scene}
 */
const scene = new THREE.Scene();

/**
 * Camera
 *
 * @type {PerspectiveCamera}
 */
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);

/**
 * Renderer
 *
 * @type {WebGLRenderer}
 */
const renderer = new THREE.WebGLRenderer({
  canvas: document.querySelector('#bg'),
  alpha: true,
  antialias: true
});

init();

function init() {
  // Camera positions
  camera.position.x = 0;
  camera.position.y = 10;
  camera.position.z = 0;
  camera.lookAt(0, 0, 0);

  // Renderer
  renderer.setPixelRatio(window.devicePixelRatio);
  renderer.setSize(window.innerWidth, window.innerHeight);
  renderer.outputEncoding = THREE.sRGBEncoding;
  renderer.shadowMap.enabled = true;

  // Lighting
  const pointLight = new THREE.PointLight(0xc1c1c1, 1, 100);
  pointLight.position.set(20, 20, 20);
  const ambientLight = new THREE.AmbientLight(0x222222);

  // Helpers
  const gridHelper = new THREE.GridHelper(200, 50);

  scene.add(
    ambientLight,
    pointLight,
    gridHelper
  );
}

// Sphere

let sphereGeometry = new THREE.SphereGeometry(4, 200, 200);
sphereGeometry.positionData = [];

let v3 = new THREE.Vector3();

for (let i = 0; i < sphereGeometry.attributes.position.count; i++) {
  v3.fromBufferAttribute(sphereGeometry.attributes.position, i);
  sphereGeometry.positionData.push(v3.clone());
}

let sphereMesh = new THREE.ShaderMaterial({
  uniforms: {
    // -- THIS IS WHERE COLOR IS HANDLED --
    colorA: { type: 'vec3', value: new Vector3(0.5, 0.5, 0.5) },
  },
  vertexShader: document.getElementById('vertex').textContent,
  fragmentShader: document.getElementById('fragment').textContent,
});

let sphere = new THREE.Mesh(sphereGeometry, sphereMesh);
scene.add(sphere);

let noise = openSimplexNoise.makeNoise4D(Date.now());
let clock = new THREE.Clock();

window.addEventListener("resize", () => {
  camera.aspect = innerWidth / innerHeight;
  camera.updateProjectionMatrix();
  renderer.setSize(innerWidth, innerHeight)
});

// Animate loop

function animate() {
  requestAnimationFrame(animate);

  let t = clock.getElapsedTime() / 1.;

  sphereGeometry.positionData.forEach((p, idx) => {
    let setNoise = noise(p.x, p.y, p.z, t * 1.05);
    v3.copy(p).addScaledVector(p, setNoise);
    sphereGeometry.attributes.position.setXYZ(idx, v3.x, v3.y, v3.z);
  })
  sphereGeometry.computeVertexNormals();
  sphereGeometry.attributes.position.needsUpdate = true;

  renderer.render(scene, camera);
}

animate();

```

Here’s my fragment

```javascript
<script id="fragment" type="text/glsl">
    uniform vec3 colorA;

    #define NORMAL

    #if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( TANGENTSPACE_NORMALMAP )

        varying vec3 vViewPosition;

    #endif

    #include <packing>
    #include <uv_pars_fragment>
    #include <normal_pars_fragment>
    #include <bumpmap_pars_fragment>
    #include <normalmap_pars_fragment>
    #include <logdepthbuf_pars_fragment>
    #include <clipping_planes_pars_fragment>

    void main() {

        #include <clipping_planes_fragment>
        #include <logdepthbuf_fragment>
        #include <normal_fragment_begin>
        #include <normal_fragment_maps>

        gl_FragColor = vec4( normalize( normal ) * colorA + 0.5, 1.0 );

        #ifdef OPAQUE

            gl_FragColor.a = 1.0;

        #endif

    }
</script>

```

Here’s my vertex

```javascript
<script id="vertex" type="text/glsl">
    #define NORMAL

    #if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( TANGENTSPACE_NORMALMAP )

        varying vec3 vViewPosition;

    #endif

    #include <common>
    #include <uv_pars_vertex>
    #include <displacementmap_pars_vertex>
    #include <normal_pars_vertex>
    #include <morphtarget_pars_vertex>
    #include <skinning_pars_vertex>
    #include <logdepthbuf_pars_vertex>
    #include <clipping_planes_pars_vertex>

    void main() {

        #include <uv_vertex>

        #include <beginnormal_vertex>
        #include <morphnormal_vertex>
        #include <skinbase_vertex>
        #include <skinnormal_vertex>
        #include <defaultnormal_vertex>
        #include <normal_vertex>

        #include <begin_vertex>
        #include <morphtarget_vertex>
        #include <skinning_vertex>
        #include <displacementmap_vertex>
        #include <project_vertex>
        #include <logdepthbuf_vertex>
        #include <clipping_planes_vertex>

    #if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( TANGENTSPACE_NORMALMAP )

        vViewPosition = - mvPosition.xyz;

    #endif

    }
</script>

```

---

<div class="post-metadata">

**Author:** ![rodrigorod](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/rodrigorod/32/32567_2.png) [@rodrigorod](https://discourse.threejs.org/u/rodrigorod)\
**Post date:** [January 16, 2023, 3:44pm UTC](https://discourse.threejs.org/t/change-color-of-shader/46933/2 "2023-01-16T15:44:04Z")

</div>

I’m guessing it is from this line :

`gl_FragColor = vec4( normalize( normal ) * colorA + 0.5, 1.0 );`

How should I do it to play with RGB values ?

---

<div class="post-metadata">

**Author:** ![tfoller](https://avatars.discourse-cdn.com/v4/letter/t/3e96dc/32.png) [@tfoller](https://discourse.threejs.org/u/tfoller)\
**Post date:** [January 16, 2023, 9:08pm UTC](https://discourse.threejs.org/t/change-color-of-shader/46933/3 "2023-01-16T21:08:40Z")

</div>

In general, gl\_FragColor is a **vec4** type variable, it has 4 components - RGBA, each component is a **float** type value from 0 to1, for example:

```javascript
float r = 0.5;
float g = 0.0;
float b = 0.25;
float a = 1.0;
gl_FragColor = vec4(r, g, b, a); // an equivalent of 128/0/64/1 or 0x800040FF

```

or, the same

```javascript
vec3 rgb = vec3(0.5, 0.0, 0.25);
float a = 1.0;
gl_FragColor = vec4(rgb, a);

```

in your case **normalize(normal)** and **colorA** are **vec3** types with 3 floating point components each, they are multiplied component-wise and 0.5 is added to each component of the result:

```javascript
vec3 nn = normalize(normal);
vec3 clr = colorA;
vec3 rgb = nn * clr + 0.5; // vec3(nn.r * clr.r + 0.5, nn.g * clr.g + 0.5, nn.b * clr.b + 0.5)

```

---

<div class="post-metadata">

**Author:** ![hofk](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/hofk/32/44944_2.png) [@hofk](https://discourse.threejs.org/u/hofk)\
**Post date:** [January 17, 2023, 11:29am UTC](https://discourse.threejs.org/t/change-color-of-shader/46933/4 "2023-01-17T11:29:23Z")

</div>

> [@rodrigorod](#):
>
> I’m somehow lost on how to do it.

It sounds like you are a shader beginner.

Then [Shader Beginner](https://hofk.de/main/ShaderBook/) (de/en) from the [collection](https://discourse.threejs.org/t/collection-of-examples-from-discourse-threejs-org/4315) might be something for you. 🙂

---

<div class="post-metadata">

**Author:** ![rodrigorod](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/rodrigorod/32/32567_2.png) [@rodrigorod](https://discourse.threejs.org/u/rodrigorod)\
**Post date:** [January 17, 2023, 12:58pm UTC](https://discourse.threejs.org/t/change-color-of-shader/46933/6 "2023-01-17T12:58:09Z")

</div>

@hofk @tfoller Thanks for your help, and this collection is really cool !

I’ll try to do something on my side.

The result I want is the colors to be gray, white, black-ish, is it also a solution to apply some kind of black & white filter / lighting ?

---

<div class="post-metadata">

**Author:** ![tfoller](https://avatars.discourse-cdn.com/v4/letter/t/3e96dc/32.png) [@tfoller](https://discourse.threejs.org/u/tfoller)\
**Post date:** [January 17, 2023, 9:59pm UTC](https://discourse.threejs.org/t/change-color-of-shader/46933/7 "2023-01-17T21:59:40Z")

</div>

Grey colors simply have the same amount of red green and blue in them, there is no filter.

But there are many ways to calculate that amount from the original red green and blue in the colored image. It’s a messy topic that involves many different standards and particulars of human vision.

I made a fiddle some time ago to compare some of those ways to make black & white image or desaturate (which, as it turns out, is not the same thing):

> **[Edit fiddle - JSFiddle - Code Playground](https://jsfiddle.net/tfoller/rpqg3emf/17/)**
>
> Test your JavaScript, CSS, HTML or CoffeeScript online with JSFiddle code editor.

In your case you could try Photoshop desaturate:

```javascript
vec3 sRGB = normalize( normal ) * colorA + 0.5;
float bw = (min(sRGB.r, min(sRGB.g, sRGB.b)) + max(sRGB.r, max(sRGB.g, sRGB.b))) * 0.5;
gl_FragColor = vec4(vec3(bw), 1.0);

```

---

<div class="post-metadata">

**Author:** ![Lawrence3DPK](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/lawrence3dpk/32/29184_2.png) [@Lawrence3DPK](https://discourse.threejs.org/u/Lawrence3DPK)\
**Post date:** [January 17, 2023, 10:08pm UTC](https://discourse.threejs.org/t/change-color-of-shader/46933/8 "2023-01-17T22:08:21Z")

</div>

Isn’t the issue here the inclusion of the “normal” fragment as this would return colors of a standard normal map?

---

<div class="post-metadata">

**Author:** ![tfoller](https://avatars.discourse-cdn.com/v4/letter/t/3e96dc/32.png) [@tfoller](https://discourse.threejs.org/u/tfoller)\
**Post date:** [January 17, 2023, 10:12pm UTC](https://discourse.threejs.org/t/change-color-of-shader/46933/9 "2023-01-17T22:12:56Z")

</div>

> [@Lawrence3DPK](#):
>
> colors of a standard normal map

I think that’s what’s currently colorizing the shape, xyz(rgb) components of normals, the question here is how to transform those.
