Skip to content

glslify/glsl-perturb-normal

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

9 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

glsl-perturb-normal

stable

demo-image

(click for demo)

Perturb a normal in the fragment shader using a normal map. This can be used to add surface detail during per-pixel lighting.

Note: You need to enable GL_OES_standard_derivatives.

#extension GL_OES_standard_derivatives : enable

varying vec3 vNormal;
varying vec2 vUv;
varying vec3 vViewPosition;

uniform sampler2D normalMap;

#pragma glslify: perturb = require('glsl-perturb-normal')

void main() {
  //extract normal map from your texture
  vec3 normalRGB = texture2D(normalMap, vUv).rgb;

  //expand into -1.0 .. 1.0 range
  vec3 normalMap = normalRGB * 2.0 - 1.0;
  
  //get surface normal and camera-space position
  vec3 N = normalize(vNormal);
  vec3 V = normalize(vViewPosition);

  //perturb the normal
  vec3 normal = perturb(normalMap, N, V, vUv);

  //... lighting
}

Usage

NPM

vec3 perturbed = perturb(vec3 M, vec3 N, vec3 V, vec2 texcoord)

Perturbs a normal where:

  • M is a unit vector from your normal map (e.g. decoded from a RGB texture)
  • N is the normalized surface normal
  • V is the normalized camera-space position
  • texcoord is the UV coordinates of your mesh

This uses GL_OES_standard_derivatives to compute the derivatives, so it may not work on older or low-end devices.

Credits

The algorithm here is from Chris­t­ian Schüler's blog post Normal Mapping Without Precomputed Tangents.

License

MIT. See LICENSE.md for details.