parallax mapping
by sogrey
HTML
<script src="https://threejs.org/build/three.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>
CSS
body { margin: 0; position: fixed; }
canvas { width: 100%; height: 100%; display: block; }
JavaScript
// Parallax Occlusion shaders from
// http://sunandblackcat.com/tipFullView.php?topicid=28
// No tangent-space transforms logic based on
// http://mmikkelsen3d.blogspot.sk/2012/02/parallaxpoc-mapping-and-no-tangent.html
var ParallaxShader = {
// Ordered from fastest to best quality.
modes: {
none: "NO_PARALLAX",
basic: "USE_BASIC_PARALLAX",
steep: "USE_STEEP_PARALLAX",
occlusion: "USE_OCLUSION_PARALLAX", // a.k.a. POM
relief: "USE_RELIEF_PARALLAX"
},
uniforms: {
"bumpMap": { value: null },
"map": { value: null },
"parallaxScale": { value: null },
"parallaxMinLayers": { value: null },
"parallaxMaxLayers": { value: null }
},
vertexShader: [
"varying vec2 vUv;",
"varying vec3 vViewPosition;",
"varying vec3 vNormal;",
"void main() {",
" vUv = uv;",
" vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );",
" vViewPosition = -mvPosition.xyz;",
" vNormal = normalize( normalMatrix * normal );",
" gl_Position = projectionMatrix * mvPosition;",
"}"
].join( "\n" ),
fragmentShader: [
"uniform sampler2D bumpMap;",
"uniform sampler2D map;",
"uniform float parallaxScale;",
"uniform float parallaxMinLayers;",
"uniform float parallaxMaxLayers;",
"varying vec2 vUv;",
"varying vec3 vViewPosition;",
"varying vec3 vNormal;",
"#ifdef USE_BASIC_PARALLAX",
" vec2 parallaxMap( in vec3 V ) {",
" float initialHeight = texture2D( bumpMap, vUv ).r;",
// No Offset Limitting: messy, floating output at grazing angles.
//"vec2 texCoordOffset = parallaxScale * V.xy / V.z * initialHeight;",
// Offset Limiting
" vec2 texCoordOffset = parallaxScale * V.xy * initialHeight;",
" return vUv - texCoordOffset;",
" }",
"#else",
" vec2 parallaxMap( in vec3 V ) {",
// Determine number of layers from angle between V and N
" float numLayers = mix( parallaxMaxLayers, parallaxMinLayers, abs( dot( vec3( 0.0, 0.0, 1.0 ), V ) ) );",
" float layerHeight = 1.0 / numLayers;",
" float...