# Normalmap on Textured Sphere example

**URL:** <https://discourse.processing.org/t/normalmap-on-textured-sphere-example/42715>\
**Category:** Gallery\
**Created:** [September 7, 2023, 5:17pm UTC](https://discourse.processing.org/t/normalmap-on-textured-sphere-example/42715 "2023-09-07T17:17:03Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![companje](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/companje/32/2418_2.png) [@companje](https://discourse.processing.org/u/companje)\
**Post date:** [September 7, 2023, 5:17pm UTC](https://discourse.processing.org/t/normalmap-on-textured-sphere-example/42715/1 "2023-09-07T17:17:03Z")

</div>

Hi everyone,

Just wanted to share this piece code I wrote earlier. It shows how to use a shader to apply a normalmap to a textured sphere. I hope it’s useful for others.

Best wishes,  
Rick

```auto
PShader shader;
PImage colormap, normalmap;
PShape shape;

void setup() {
  size(1169, 1169, P3D);
  shader = loadShader("frag-shader.glsl", "vert-shader.glsl");
  colormap = loadImage("colormaps/mercury.jpg");
  normalmap = loadImage("normalmaps/mercury.jpg");

  sphereDetail(100);
  fill(255);
  shape = createShape(SPHERE, 500);
  shape.setStroke(false);

  shader.set("colormap", colormap);
  shader.set("normalmap", normalmap);
 }

void draw() {
  float bumpDetail = map(mouseX,0,width,0,8);
  background(0);
  ortho();
  translate(width/2,height/2);
  shader.set("bumpDetail",bumpDetail);
  shader(shader);
  rotateY(frameCount/100.);
  shape(shape);
  text("bumpDetail:" + bumpDetail,0,20);
}

```

frag-shader.glsl

```plaintext
varying vec4 vertColor;
varying vec4 vertTexCoord;
varying vec3 lightDir;

uniform sampler2D colormap;
uniform sampler2D normalmap;
uniform float bumpDetail;

void main() {
  
  vec4 color = texture2D(colormap, vertTexCoord.st);

  //normalmap
  vec4 normalColor = texture2D(normalmap, vertTexCoord.st);
  vec3 normal = normalize(normalColor.rgb * 2. - 1.);
  float normalDotLight = max(dot(normal, normalize(lightDir)), 0.);
  float intensity = pow(normalDotLight,bumpDetail);
  
  if (intensity!=0.) color.rgb *= intensity;
  else color = vec4(1,0,0,1);

  gl_FragColor = color;
}

```

vert-shader.glsl

```plaintext
uniform mat4 modelview;
uniform mat4 transform;
uniform mat3 normalMatrix;
uniform mat4 texMatrix;

uniform vec4 lightPosition;
uniform vec3 lightNormal;

attribute vec4 position;
attribute vec4 color;
attribute vec3 normal;
attribute vec2 texCoord;

varying vec4 vertColor;
varying vec3 ecNormal;
varying vec3 lightDir;

varying vec4 vertTexCoord;

void main() {
  gl_Position = transform * position;
  vec3 ecPosition = vec3(modelview * position);

  ecNormal = normalize(normalMatrix * normal);
  lightDir = normalize(lightPosition.xyz - ecPosition);
  vertColor = color;

  vertTexCoord = texMatrix * vec4(texCoord, 1.0, 1.0);
}

```

 ![earth](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/3X/4/5/459563ea6c5b555ccafab63b28ab5ec960890f6a.jpeg)  
 ![earth-normalmap](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/3X/1/8/182a69665307d55ace28b1e74474aeba2d9eaf0a.jpeg)  
 ![earth-colormap](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/3X/d/7/d7ca5c145bc775cba19b06cb32fdb3801996f749.jpeg)
