cssAudio - Activefile-genericCSS - ActiveGeneric - ActiveHTML - ActiveImage - ActiveJS - ActiveSVG - ActiveText - Activefile-genericVideo - ActiveLovehtmlicon-new-collectionicon-personicon-teamlog-outoctocatpop-outspinnerstartv

Pen Settings

CSS Base

Vendor Prefixing

Add External CSS

These stylesheets will be added in this order and before the code you write in the CSS editor. You can also add another Pen here, and it will pull the CSS from it. Try typing "font" or "ribbon" below.

Quick-add: + add another resource

Add External JavaScript

These scripts will run in this order and before the code in the JavaScript editor. You can also link to another Pen here, and it will run the JavaScript from it. Also try typing the name of any popular library.

Quick-add: + add another resource

Code Indentation

     

Save Automatically?

If active, Pens will autosave every 30 seconds after being saved once.

Auto-Updating Preview

If enabled, the preview panel updates automatically as you code. If disabled, use the "Run" button to update.

            
              
<img src="https://cors-anywhere.herokuapp.com/http://www.radiolights.com/CODEPEN/b-grasslight-big2.jpg" class="hidden"/>
<img src="https://cors-anywhere.herokuapp.com/http://www.radiolights.com/CODEPEN/b-backgrounddetailed62.jpg" class="hidden"/>
<img src="https://cors-anywhere.herokuapp.com/http://www.radiolights.com/CODEPEN/b-grasslight-big-nm2.jpg" class="hidden"/>

<script id="fragmentShaderNoise" type="x-shader/x-fragment">

			//
			// Description : Array and textureless GLSL 3D simplex noise function.
			//      Author : Ian McEwan, Ashima Arts.
			//  Maintainer : ijm
			//     Lastmod : 20110409 (stegu)
			//     License : Copyright (C) 2011 Ashima Arts. All rights reserved.
			//               Distributed under the MIT License. See LICENSE file.
			//

			uniform float time;
			varying vec2 vUv;

			vec4 permute( vec4 x ) {

				return mod( ( ( x * 34.0 ) + 1.0 ) * x, 289.0 );

			}

			vec4 taylorInvSqrt( vec4 r ) {

				return 1.79284291400159 - 0.85373472095314 * r;

			}

			float snoise( vec3 v ) {

				const vec2 C = vec2( 1.0 / 6.0, 1.0 / 3.0 );
				const vec4 D = vec4( 0.0, 0.5, 1.0, 2.0 );

				// First corner

				vec3 i  = floor( v + dot( v, C.yyy ) );
				vec3 x0 = v - i + dot( i, C.xxx );

				// Other corners

				vec3 g = step( x0.yzx, x0.xyz );
				vec3 l = 1.0 - g;
				vec3 i1 = min( g.xyz, l.zxy );
				vec3 i2 = max( g.xyz, l.zxy );

				vec3 x1 = x0 - i1 + 1.0 * C.xxx;
				vec3 x2 = x0 - i2 + 2.0 * C.xxx;
				vec3 x3 = x0 - 1. + 3.0 * C.xxx;

				// Permutations

				i = mod( i, 289.0 );
				vec4 p = permute( permute( permute(
						 i.z + vec4( 0.0, i1.z, i2.z, 1.0 ) )
					   + i.y + vec4( 0.0, i1.y, i2.y, 1.0 ) )
					   + i.x + vec4( 0.0, i1.x, i2.x, 1.0 ) );

				// Gradients
				// ( N*N points uniformly over a square, mapped onto an octahedron.)

				float n_ = 1.0 / 7.0; // N=7

				vec3 ns = n_ * D.wyz - D.xzx;

				vec4 j = p - 49.0 * floor( p * ns.z *ns.z );  //  mod(p,N*N)

				vec4 x_ = floor( j * ns.z );
				vec4 y_ = floor( j - 7.0 * x_ );    // mod(j,N)

				vec4 x = x_ *ns.x + ns.yyyy;
				vec4 y = y_ *ns.x + ns.yyyy;
				vec4 h = 1.0 - abs( x ) - abs( y );

				vec4 b0 = vec4( x.xy, y.xy );
				vec4 b1 = vec4( x.zw, y.zw );


				vec4 s0 = floor( b0 ) * 2.0 + 1.0;
				vec4 s1 = floor( b1 ) * 2.0 + 1.0;
				vec4 sh = -step( h, vec4( 0.0 ) );

				vec4 a0 = b0.xzyw + s0.xzyw * sh.xxyy;
				vec4 a1 = b1.xzyw + s1.xzyw * sh.zzww;

				vec3 p0 = vec3( a0.xy, h.x );
				vec3 p1 = vec3( a0.zw, h.y );
				vec3 p2 = vec3( a1.xy, h.z );
				vec3 p3 = vec3( a1.zw, h.w );

				// Normalise gradients

				vec4 norm = taylorInvSqrt( vec4( dot( p0, p0 ), dot( p1, p1 ), dot( p2, p2 ), dot( p3, p3 ) ) );
				p0 *= norm.x;
				p1 *= norm.y;
				p2 *= norm.z;
				p3 *= norm.w;

				// Mix final noise value

				vec4 m = max( 0.6 - vec4( dot( x0, x0 ), dot( x1, x1 ), dot( x2, x2 ), dot( x3, x3 ) ), 0.0 );
				m = m * m;
				return 42.0 * dot( m*m, vec4( dot( p0, x0 ), dot( p1, x1 ),
											  dot( p2, x2 ), dot( p3, x3 ) ) );

			}

			float surface3( vec3 coord ) {

				float n = 0.0;

				n += 1.0 * abs( snoise( coord ) );
				n += 0.5 * abs( snoise( coord * 2.0 ) );
				n += 0.25 * abs( snoise( coord * 4.0 ) );
				n += 0.125 * abs( snoise( coord * 8.0 ) );

				return n;

			}

			void main( void ) {

				vec3 coord = vec3( vUv, -time );
				float n = surface3( coord );

				gl_FragColor = vec4( vec3( n, n, n ), 1.0 );

			}

		</script>

		<script id="vertexShader" type="x-shader/x-vertex">

			varying vec2 vUv;
			uniform vec2 scale;
			uniform vec2 offset;

			void main( void ) {

				vUv = uv * scale + offset;
				gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );

			}

		</script>

<div class="link">
<a href="https://twitter.com/cjgammon">@cjgammon</a>
</div>

<div id="loader">
  <h1>wait for it...</h1>
</div>
<div id="container"></div>
            
          
!
            
              html{
  min-height: 100%;
}

canvas{
  background: transparent;
  opacity: 0;
}

body {
  margin: 0;
  overflow: hidden;
  min-height: 100%;
  background: #050505;
background-repeat: no-repeat;
  background-position: center;
}

#loader{
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  
  h1{
    color: white;
    letter-spacing: .1em;
    font-weight: 100;
    font-family: sans-serif;
  }
}

.link{
  position: fixed;
  bottom: 0;
  left: 0;
  margin: 10px;
  font-family: sans-serif;
  font-weight: 100;
  
  a{
    color: black;
    text-decoration: none;
    
    &:hover{
      text-decoration: underline;
    }
  }
}

.hidden{
  display: none;
}
            
          
!
            
              	if (!Detector.webgl) Detector.addGetWebGLMessage();

	var SCREEN_WIDTH = window.innerWidth;
	var SCREEN_HEIGHT = window.innerHeight;

	var renderer, container, stats;

	var camera, scene;
	var cameraOrtho, sceneRenderTarget;

	var uniformsNoise, uniformsNormal,
	  heightMap, normalMap,
	  quadTarget;

	var directionalLight, pointLight;

	var terrain;

	var specularMap;

	var textureCounter = 0;

	var animDelta = 0,
	  animDeltaDir = -1;
	var lightVal = 0,
	  lightDir = 1;

	var clock = new THREE.Clock();

	var morph, morphs = [];

	var updateNoise = true;

	var animateTerrain = false;

	var textMesh1;
	var diffuseTexture1,
	  diffuseTexture2,
	  detailTexture;

	var pars = {
	  minFilter: THREE.LinearFilter,
	  magFilter: THREE.LinearFilter,
	  format: THREE.RGBFormat
	};


    container = document.getElementById('container');

	  // SCENE (FINAL)

	  scene = new THREE.Scene();
	  scene.fog = new THREE.Fog(0x050505, 2000, 4000);

	  // RENDERER

	  renderer = new THREE.WebGLRenderer();
	  renderer.setClearColor(scene.fog.color);
	  renderer.setPixelRatio(window.devicePixelRatio);
	  renderer.setSize(SCREEN_WIDTH, SCREEN_HEIGHT);
	  renderer.shadowMap.enabled = true;
	  renderer.shadowMap.type = THREE.PCFSoftShadowMap;
	  container.appendChild(renderer.domElement);

	  //

	  renderer.gammaInput = true;
	  renderer.gammaOutput = true;


	  // SCENE (RENDER TARGET)

	  sceneRenderTarget = new THREE.Scene();

	  cameraOrtho = new THREE.OrthographicCamera(SCREEN_WIDTH / -2, SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2, SCREEN_HEIGHT / -2, -10000, 10000);
	  cameraOrtho.position.z = 100;

	  sceneRenderTarget.add(cameraOrtho);


	specularMap = new THREE.WebGLRenderTarget(2048, 2048, pars);
	specularMap.texture.generateMipmaps = false;

	var mlib = {};
	var loader = new THREE.TextureLoader();
	loader.crossOrigin = '';
	loader.load("https://cors-anywhere.herokuapp.com/http://www.radiolights.com/CODEPEN/b-grasslight-big2.jpg", function(texture) {
	  diffuseTexture1 = texture;
	  loadTextures();
	  applyShader(THREE.LuminosityShader, diffuseTexture1, specularMap);
	});

	loader.load("https://cors-anywhere.herokuapp.com/http://www.radiolights.com/CODEPEN/b-backgrounddetailed62.jpg", function(texture) {
	  diffuseTexture2 = texture;
	  loadTextures();
	});

	loader.load("https://cors-anywhere.herokuapp.com/http://www.radiolights.com/CODEPEN/b-grasslight-big-nm2.jpg", function(texture) {
	  detailTexture = texture;
	  loadTextures();
	});


	function init() {
    


	  // CAMERA

	  camera = new THREE.PerspectiveCamera(40, SCREEN_WIDTH / SCREEN_HEIGHT, 2, 4000);
	  camera.position.set(-1200, 800, 1200);
    
    console.log(camera);

	  controls = new THREE.OrbitControls(camera);
	  controls.target.set(0, 0, 0);

	  controls.rotateSpeed = 1.0;
	  controls.zoomSpeed = 1.2;
	  controls.panSpeed = 0.8;
	  controls.maxPolarAngle = 90 * Math.PI / 180;

	  controls.keys = [65, 83, 68];


	  // LIGHTS

	  scene.add(new THREE.AmbientLight(0x556380));

	  directionalLight = new THREE.DirectionalLight(0x8d4a23, 0.12);
	  directionalLight.position.set(1500, 3000, 0);
	  directionalLight.castShadow = true;
	  directionalLight.shadowCameraNear = 50;
	  directionalLight.shadowCameraFar = 10000;
	  directionalLight.shadowCameraLeft = -2000;
	  directionalLight.shadowCameraRight = 2000;
	  directionalLight.shadowCameraTop = 2000;
	  directionalLight.shadowCameraBottom = -2000;
	  directionalLight.shadowMapWidth = 1024;
	  directionalLight.shadowMapHeight = 1024;
	  //directionalLight.shadowCameraVisible = true;

	  scene.add(directionalLight);

	  pointLight = new THREE.PointLight(0x594b1d, 4, 4000);
	  pointLight.position.set(1000, 0, 0);
	  scene.add(pointLight);

	  // HEIGHT + NORMAL MAPS

	  var normalShader = THREE.NormalMapShader;

	  var rx = 256,
	    ry = 256;

	  heightMap = new THREE.WebGLRenderTarget(rx, ry, pars);
	  heightMap.texture.generateMipmaps = false;

	  normalMap = new THREE.WebGLRenderTarget(rx, ry, pars);
	  normalMap.texture.generateMipmaps = false;

	  uniformsNoise = {

	    time: {
	      type: "f",
	      value: 1.0
	    },
	    scale: {
	      type: "v2",
	      value: new THREE.Vector2(1.5, 1.5)
	    },
	    offset: {
	      type: "v2",
	      value: new THREE.Vector2(0, 0)
	    }

	  };

	  uniformsNormal = THREE.UniformsUtils.clone(normalShader.uniforms);

	  uniformsNormal.height.value = 0.05;
	  uniformsNormal.resolution.value.set(rx, ry);
	  uniformsNormal.heightMap.value = heightMap;

	  var vertexShader = document.getElementById('vertexShader').textContent;

	  // TEXTURES
	  diffuseTexture1.wrapS = diffuseTexture1.wrapT = THREE.RepeatWrapping;
	  diffuseTexture2.wrapS = diffuseTexture2.wrapT = THREE.RepeatWrapping;
	  detailTexture.wrapS = detailTexture.wrapT = THREE.RepeatWrapping;
	  specularMap.wrapS = specularMap.wrapT = THREE.RepeatWrapping;

	  // TERRAIN SHADER

	  var params = [
	    ['heightmap', document.getElementById('fragmentShaderNoise').textContent, vertexShader, uniformsNoise, false],
	    ['normal', normalShader.fragmentShader, normalShader.vertexShader, uniformsNormal, false],
	  ];

	  for (var i = 0; i < params.length; i++) {

	    material = new THREE.ShaderMaterial({
	      uniforms: params[i][3],
	      vertexShader: params[i][2],
	      fragmentShader: params[i][1],
	      lights: params[i][4],
	      fog: true
	    });

	    mlib[params[i][0]] = material;

	  }

	  var plane = new THREE.PlaneBufferGeometry(SCREEN_WIDTH, SCREEN_HEIGHT);

	  quadTarget = new THREE.Mesh(plane, new THREE.MeshBasicMaterial({
	    color: 0x000000
	  }));
	  quadTarget.position.z = -500;
	  sceneRenderTarget.add(quadTarget);

	  // TERRAIN MESH

	  var geometryTerrain = new THREE.PlaneBufferGeometry(6000, 6000, 256, 256);

	  THREE.BufferGeometryUtils.computeTangents(geometryTerrain);

	  terrain = new THREE.Mesh(geometryTerrain, new THREE.MeshLambertMaterial({
	    color: 0xe2c5be,
	    map: diffuseTexture1,
	    aoMap: detailTexture,
	    lightMap: diffuseTexture1,
	  }));

	  terrain.position.set(0, -125, 0);
	  terrain.rotation.x = -Math.PI / 2;
	  terrain.visible = true;
	  terrain.receiveShadow = true;
	  scene.add(terrain);



	  // EVENTS

	  onWindowResize();

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

	  // COMPOSER

	  renderer.autoClear = false;

	  renderTargetParameters = {
	    minFilter: THREE.LinearFilter,
	    magFilter: THREE.LinearFilter,
	    format: THREE.RGBFormat,
	    stencilBuffer: false
	  };

	  renderTarget = new THREE.WebGLRenderTarget(SCREEN_WIDTH, SCREEN_HEIGHT, renderTargetParameters);
	  renderTarget.texture.generateMipmaps = false;

	  effectBloom = new THREE.BloomPass(0.6);
	  var effectBleach = new THREE.ShaderPass(THREE.BleachBypassShader);

	  hblur = new THREE.ShaderPass(THREE.HorizontalTiltShiftShader);
	  vblur = new THREE.ShaderPass(THREE.VerticalTiltShiftShader);

	  var bluriness = 6;

	  hblur.uniforms['h'].value = bluriness / SCREEN_WIDTH;
	  vblur.uniforms['v'].value = bluriness / SCREEN_HEIGHT;

	  hblur.uniforms['r'].value = vblur.uniforms['r'].value = 0.5;

	  effectBleach.uniforms['opacity'].value = 0.65;

	  composer = new THREE.EffectComposer(renderer, renderTarget);

	  var renderModel = new THREE.RenderPass(scene, camera);

	  vblur.renderToScreen = true;

	  composer = new THREE.EffectComposer(renderer, renderTarget);

	  composer.addPass(renderModel);

	  composer.addPass(effectBloom);
	  //composer.addPass( effectBleach );

	  composer.addPass(hblur);
	  composer.addPass(vblur);

	  var size = 3000;
	  for (i = 0; i < 200; i += 1) {
	    addTree(-size / 2 + Math.random() * size, -size / 2 + Math.random() * size);
	  }

	  var loader = document.getElementById('loader');
	  loader.style.display = 'none';

	  var canvas = document.getElementsByTagName('canvas');
	  canvas[0].style.opacity = '1';
	}

	function addTree(x, z) {
	  var group = new THREE.Object3D();

	  // radiusAtTop, radiusAtBottom, height, segmentsAroundRadius, segmentsAlongHeight,
	  var geo = new THREE.CylinderGeometry(15, 20, 150, 6, 4);
	  var mat = new THREE.MeshPhongMaterial({
	    color: 0xe66f73,
	    shading: THREE.FlatShading
	  });

	  var shape = new THREE.Mesh(geo, mat);
	  shape.position.set(0, -50, 0);
	  shape.castShadow = true;
	  shape.receiveShadow = true;
	  group.add(shape);

	  var size = Math.round(Math.random());
	  var s = 0.3 + Math.random() * 0.7;

	  //top colors
	  var r2 = 246;
	  var g2 = 205;
	  var b2 = 118;

	  //bottom colors
	  var r1 = 253;
	  var g1 = 240;
	  var b1 = 205;

	  var l = 5 + size;

	  for (i = 0; i < l; i += 1) {

	    var r = r1 + (i / l) * (r2 - r1);
	    var g = g1 + (i / l) * (g2 - g1);
	    var b = b1 + (i / l) * (b2 - b1);

	    c = new THREE.Color(r / 255, g / 255, b / 255); //0xf6ce76;

	    // pyramid
	    var geo = new THREE.CylinderGeometry(i * 5, 50 + (i * 10), 75, 5, 5);
	    var mat = new THREE.MeshPhongMaterial({
	      color: c,
	      shading: THREE.FlatShading
	    });

	    if (i > 0) {
	      rot = -0.05 + Math.random() * 0.1;
	    } else {
	      rot = 0;
	    }

	    var shape = new THREE.Mesh(geo, mat);
	    shape.position.set(0, 150 - (i * 35), 0);
	    shape.rotation.set(rot, 0, rot);
	    shape.castShadow = true;
	    shape.receiveShadow = true;
	    group.add(shape);

	  }

	  var y = 0 - ((1 - s) * 150);
	  group.position.set(x, y, z);
	  group.scale.set(s, s, s);
	  scene.add(group);

	}

	function onWindowResize(event) {

	  SCREEN_WIDTH = window.innerWidth;
	  SCREEN_HEIGHT = window.innerHeight;

	  renderer.setSize(SCREEN_WIDTH, SCREEN_HEIGHT);

	  camera.aspect = SCREEN_WIDTH / SCREEN_HEIGHT;
	  camera.updateProjectionMatrix();

	}

	function applyShader(shader, texture, target) {

	  var shaderMaterial = new THREE.ShaderMaterial({

	    fragmentShader: shader.fragmentShader,
	    vertexShader: shader.vertexShader,
	    uniforms: THREE.UniformsUtils.clone(shader.uniforms)

	  });

	  shaderMaterial.uniforms["tDiffuse"].value = texture;

	  var sceneTmp = new THREE.Scene();

	  var meshTmp = new THREE.Mesh(new THREE.PlaneBufferGeometry(SCREEN_WIDTH, SCREEN_HEIGHT), shaderMaterial);
	  meshTmp.position.z = -500;

	  sceneTmp.add(meshTmp);

	  renderer.render(sceneTmp, cameraOrtho, target, true);

	}

	//

	function loadTextures() {

	  textureCounter += 1;
    
	  if (textureCounter == 3) {

	    init();
	    animate();

	  }

	}

	//

	function animate() {

	  requestAnimationFrame(animate);

	  render();

	}

	function render() {

	  var delta = clock.getDelta();

	  if (terrain) {

	    controls.update();

	    var time = Date.now() * 0.001;

	    var fLow = 0.1,
	      fHigh = 0.6;

	    lightVal = THREE.Math.clamp(lightVal + 0.5 * delta * lightDir, fLow, fHigh);

	    var valNorm = (lightVal - fLow) / (fHigh - fLow);

	    scene.fog.color.setHSL(2.6, 0.1, lightVal);

	    renderer.setClearColor(scene.fog.color);

	    directionalLight.intensity = THREE.Math.mapLinear(valNorm, 0, 1, 0.1, 1.15);
	    pointLight.intensity = THREE.Math.mapLinear(valNorm, 0, 1, 0.9, 1.5);

	    if (updateNoise) {

	      animDelta = THREE.Math.clamp(animDelta + 0.00075 * animDeltaDir, 0, 0.05);

	      quadTarget.material = mlib["heightmap"];
	      renderer.render(sceneRenderTarget, cameraOrtho, heightMap, true);

	      quadTarget.material = mlib["normal"];
	      renderer.render(sceneRenderTarget, cameraOrtho, normalMap, true);
	    }

	    composer.render(0.1);
	  }

	}
            
          
!
999px
Loading ..................

Console