FORK ME

console 命令行工具 X clear

                    
>
console
setTimeout(() => {
  const camera = createCamera();
  const scene = new THREE.Scene();
  createLights(scene);
  const uniforms = THREE.UniformsUtils.merge([
    THREE.UniformsLib["ambient"],
    THREE.UniformsLib["lights"],
    {uTime: {type: "f", value: 1}},
    THREE.ShaderLib.phong.uniforms
  ]);
  const geometry = createGeometry(5, 2);
  const material = createMaterial(uniforms);
  const mesh = new THREE.Mesh(geometry, material);
  scene.add(mesh);
  const renderer = createRenderer();
  const handleWindowResize = onWindowResize(camera, renderer, uniforms);
  handleWindowResize();
  window.addEventListener('resize', handleWindowResize, false);
  animate(renderer, scene, camera, uniforms, mesh);
}, 0);

function onWindowResize (camera, renderer, uniforms) {
  return event => {
    camera.aspect = window.innerWidth / window.innerHeight;
    camera.updateProjectionMatrix();
    renderer.setSize(window.innerWidth, window.innerHeight);
  }
}

function animate (renderer, scene, camera, uniforms, mesh) {
  requestAnimationFrame(() => {
    animate(renderer, scene, camera, uniforms, mesh);
  });
  uniforms.uTime.value += 0.05;
  mesh.rotation.x -= 0.002;
  mesh.rotation.y -= 0.003;
  renderer.render(scene, camera);
}

function createCamera () {
  const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 1, 1000);
  camera.position.z = 10;
  return camera;
}

function createLights (scene) {
  const ambientLight = new THREE.AmbientLight(0x999999);
  scene.add(ambientLight);
  const lights = [];
  lights[0] = new THREE.DirectionalLight(0xffffff, 1);
  lights[0].position.set(1, 0, 0);
  lights[1] = new THREE.DirectionalLight(0x15374F, 1);
  lights[1].position.set(0.75, 1, 0.5);
  lights[2] = new THREE.DirectionalLight(0x000C1C, 1);
  lights[2].position.set(-0.75, -1, 0.5);
  scene.add(lights[0]);
  scene.add(lights[1]);
  scene.add(lights[2]);
}

function createGeometry (radius, t) {
  const geometry = new THREE.IcosahedronGeometry(radius, t);
  return geometry;
}

function createMaterial (uniforms) {
  return new THREE.ShaderMaterial({
    uniforms,
    vertexShader: document.getElementById('phong-vertexShader').textContent,
    fragmentShader: document.getElementById('phong-fragmentShader').textContent,
    lights: true
  });
}

function createRenderer () {
  const renderer = new THREE.WebGLRenderer({
    antialias: true,
    alpha: true
  });
  renderer.setPixelRatio(window.devicePixelRatio);
  renderer.autoClear = false;
  renderer.setClearColor(0x000000, 0);
  const container = document.getElementById('js-app');
  container.appendChild(renderer.domElement);
  return renderer;
}
<div id="js-app"></div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/84/three.js"></script>

<script id="phong-vertexShader" type="x-shader/x-vertex">
	varying vec3 vRawNormal;
  #define PHONG
  varying vec3 vViewPosition;
  #ifndef FLAT_SHADED
    varying vec3 vNormal;
  #endif
  #include <common>
  #include <uv_pars_vertex>
  #include <uv2_pars_vertex>
  #include <displacementmap_pars_vertex>
  #include <envmap_pars_vertex>
  #include <color_pars_vertex>
  #include <fog_pars_vertex>
  #include <morphtarget_pars_vertex>
  #include <skinning_pars_vertex>
  #include <shadowmap_pars_vertex>
  #include <logdepthbuf_pars_vertex>
  #include <clipping_planes_pars_vertex>
  void main() {
  	vRawNormal = normal;
    #include <uv_vertex>
    #include <uv2_vertex>
    #include <color_vertex>
    #include <beginnormal_vertex>
    #include <morphnormal_vertex>
    #include <skinbase_vertex>
    #include <skinnormal_vertex>
    #include <defaultnormal_vertex>
  #ifndef FLAT_SHADED
    vNormal = normalize( transformedNormal );
  #endif
    #include <begin_vertex>
    #include <displacementmap_vertex>
    #include <morphtarget_vertex>
    #include <skinning_vertex>
    // transformed = position + normal * vElevation;
    #include <project_vertex>
    #include <logdepthbuf_vertex>
    #include <clipping_planes_vertex>
    vViewPosition = - mvPosition.xyz;
    #include <worldpos_vertex>
    #include <envmap_vertex>
    #include <shadowmap_vertex>
    #include <fog_vertex>
  }
</script>

<script id="phong-fragmentShader" type="x-shader/x-fragment">
	varying vec3 vRawNormal;
  //
  // GLSL textureless classic 3D noise "cnoise",
  // with an RSL-style periodic variant "pnoise".
  // Author:  Stefan Gustavson (stefan.gustavson@liu.se)
  // Version: 2011-10-11
  //
  // Many thanks to Ian McEwan of Ashima Arts for the
  // ideas for permutation and gradient selection.
  //
  // Copyright (c) 2011 Stefan Gustavson. All rights reserved.
  // Distributed under the MIT license. See LICENSE file.
  // https://github.com/stegu/webgl-noise
  //

  vec3 mod289(vec3 x)
  {
    return x - floor(x * (1.0 / 289.0)) * 289.0;
  }

  vec4 mod289(vec4 x)
  {
    return x - floor(x * (1.0 / 289.0)) * 289.0;
  }

  vec4 permute(vec4 x)
  {
    return mod289(((x*34.0)+1.0)*x);
  }

  vec4 taylorInvSqrt(vec4 r)
  {
    return 1.79284291400159 - 0.85373472095314 * r;
  }

  vec3 fade(vec3 t) {
    return t*t*t*(t*(t*6.0-15.0)+10.0);
  }

  // Classic Perlin noise
  float cnoise(vec3 P)
  {
    vec3 Pi0 = floor(P); // Integer part for indexing
    vec3 Pi1 = Pi0 + vec3(1.0); // Integer part + 1
    Pi0 = mod289(Pi0);
    Pi1 = mod289(Pi1);
    vec3 Pf0 = fract(P); // Fractional part for interpolation
    vec3 Pf1 = Pf0 - vec3(1.0); // Fractional part - 1.0
    vec4 ix = vec4(Pi0.x, Pi1.x, Pi0.x, Pi1.x);
    vec4 iy = vec4(Pi0.yy, Pi1.yy);
    vec4 iz0 = Pi0.zzzz;
    vec4 iz1 = Pi1.zzzz;

    vec4 ixy = permute(permute(ix) + iy);
    vec4 ixy0 = permute(ixy + iz0);
    vec4 ixy1 = permute(ixy + iz1);

    vec4 gx0 = ixy0 * (1.0 / 7.0);
    vec4 gy0 = fract(floor(gx0) * (1.0 / 7.0)) - 0.5;
    gx0 = fract(gx0);
    vec4 gz0 = vec4(0.5) - abs(gx0) - abs(gy0);
    vec4 sz0 = step(gz0, vec4(0.0));
    gx0 -= sz0 * (step(0.0, gx0) - 0.5);
    gy0 -= sz0 * (step(0.0, gy0) - 0.5);

    vec4 gx1 = ixy1 * (1.0 / 7.0);
    vec4 gy1 = fract(floor(gx1) * (1.0 / 7.0)) - 0.5;
    gx1 = fract(gx1);
    vec4 gz1 = vec4(0.5) - abs(gx1) - abs(gy1);
    vec4 sz1 = step(gz1, vec4(0.0));
    gx1 -= sz1 * (step(0.0, gx1) - 0.5);
    gy1 -= sz1 * (step(0.0, gy1) - 0.5);

    vec3 g000 = vec3(gx0.x,gy0.x,gz0.x);
    vec3 g100 = vec3(gx0.y,gy0.y,gz0.y);
    vec3 g010 = vec3(gx0.z,gy0.z,gz0.z);
    vec3 g110 = vec3(gx0.w,gy0.w,gz0.w);
    vec3 g001 = vec3(gx1.x,gy1.x,gz1.x);
    vec3 g101 = vec3(gx1.y,gy1.y,gz1.y);
    vec3 g011 = vec3(gx1.z,gy1.z,gz1.z);
    vec3 g111 = vec3(gx1.w,gy1.w,gz1.w);

    vec4 norm0 = taylorInvSqrt(vec4(dot(g000, g000), dot(g010, g010), dot(g100, g100), dot(g110, g110)));
    g000 *= norm0.x;
    g010 *= norm0.y;
    g100 *= norm0.z;
    g110 *= norm0.w;
    vec4 norm1 = taylorInvSqrt(vec4(dot(g001, g001), dot(g011, g011), dot(g101, g101), dot(g111, g111)));
    g001 *= norm1.x;
    g011 *= norm1.y;
    g101 *= norm1.z;
    g111 *= norm1.w;

    float n000 = dot(g000, Pf0);
    float n100 = dot(g100, vec3(Pf1.x, Pf0.yz));
    float n010 = dot(g010, vec3(Pf0.x, Pf1.y, Pf0.z));
    float n110 = dot(g110, vec3(Pf1.xy, Pf0.z));
    float n001 = dot(g001, vec3(Pf0.xy, Pf1.z));
    float n101 = dot(g101, vec3(Pf1.x, Pf0.y, Pf1.z));
    float n011 = dot(g011, vec3(Pf0.x, Pf1.yz));
    float n111 = dot(g111, Pf1);

    vec3 fade_xyz = fade(Pf0);
    vec4 n_z = mix(vec4(n000, n100, n010, n110), vec4(n001, n101, n011, n111), fade_xyz.z);
    vec2 n_yz = mix(n_z.xy, n_z.zw, fade_xyz.y);
    float n_xyz = mix(n_yz.x, n_yz.y, fade_xyz.x); 
    return 2.2 * n_xyz;
  }

  // Classic Perlin noise, periodic variant
  float pnoise(vec3 P, vec3 rep)
  {
    vec3 Pi0 = mod(floor(P), rep); // Integer part, modulo period
    vec3 Pi1 = mod(Pi0 + vec3(1.0), rep); // Integer part + 1, mod period
    Pi0 = mod289(Pi0);
    Pi1 = mod289(Pi1);
    vec3 Pf0 = fract(P); // Fractional part for interpolation
    vec3 Pf1 = Pf0 - vec3(1.0); // Fractional part - 1.0
    vec4 ix = vec4(Pi0.x, Pi1.x, Pi0.x, Pi1.x);
    vec4 iy = vec4(Pi0.yy, Pi1.yy);
    vec4 iz0 = Pi0.zzzz;
    vec4 iz1 = Pi1.zzzz;

    vec4 ixy = permute(permute(ix) + iy);
    vec4 ixy0 = permute(ixy + iz0);
    vec4 ixy1 = permute(ixy + iz1);

    vec4 gx0 = ixy0 * (1.0 / 7.0);
    vec4 gy0 = fract(floor(gx0) * (1.0 / 7.0)) - 0.5;
    gx0 = fract(gx0);
    vec4 gz0 = vec4(0.5) - abs(gx0) - abs(gy0);
    vec4 sz0 = step(gz0, vec4(0.0));
    gx0 -= sz0 * (step(0.0, gx0) - 0.5);
    gy0 -= sz0 * (step(0.0, gy0) - 0.5);

    vec4 gx1 = ixy1 * (1.0 / 7.0);
    vec4 gy1 = fract(floor(gx1) * (1.0 / 7.0)) - 0.5;
    gx1 = fract(gx1);
    vec4 gz1 = vec4(0.5) - abs(gx1) - abs(gy1);
    vec4 sz1 = step(gz1, vec4(0.0));
    gx1 -= sz1 * (step(0.0, gx1) - 0.5);
    gy1 -= sz1 * (step(0.0, gy1) - 0.5);

    vec3 g000 = vec3(gx0.x,gy0.x,gz0.x);
    vec3 g100 = vec3(gx0.y,gy0.y,gz0.y);
    vec3 g010 = vec3(gx0.z,gy0.z,gz0.z);
    vec3 g110 = vec3(gx0.w,gy0.w,gz0.w);
    vec3 g001 = vec3(gx1.x,gy1.x,gz1.x);
    vec3 g101 = vec3(gx1.y,gy1.y,gz1.y);
    vec3 g011 = vec3(gx1.z,gy1.z,gz1.z);
    vec3 g111 = vec3(gx1.w,gy1.w,gz1.w);

    vec4 norm0 = taylorInvSqrt(vec4(dot(g000, g000), dot(g010, g010), dot(g100, g100), dot(g110, g110)));
    g000 *= norm0.x;
    g010 *= norm0.y;
    g100 *= norm0.z;
    g110 *= norm0.w;
    vec4 norm1 = taylorInvSqrt(vec4(dot(g001, g001), dot(g011, g011), dot(g101, g101), dot(g111, g111)));
    g001 *= norm1.x;
    g011 *= norm1.y;
    g101 *= norm1.z;
    g111 *= norm1.w;

    float n000 = dot(g000, Pf0);
    float n100 = dot(g100, vec3(Pf1.x, Pf0.yz));
    float n010 = dot(g010, vec3(Pf0.x, Pf1.y, Pf0.z));
    float n110 = dot(g110, vec3(Pf1.xy, Pf0.z));
    float n001 = dot(g001, vec3(Pf0.xy, Pf1.z));
    float n101 = dot(g101, vec3(Pf1.x, Pf0.y, Pf1.z));
    float n011 = dot(g011, vec3(Pf0.x, Pf1.yz));
    float n111 = dot(g111, Pf1);

    vec3 fade_xyz = fade(Pf0);
    vec4 n_z = mix(vec4(n000, n100, n010, n110), vec4(n001, n101, n011, n111), fade_xyz.z);
    vec2 n_yz = mix(n_z.xy, n_z.zw, fade_xyz.y);
    float n_xyz = mix(n_yz.x, n_yz.y, fade_xyz.x); 
    return 2.2 * n_xyz;
  }

	float turbulence (vec3 p) {
    float t = -0.5;
    for (float f = 1.0; f <= 10.0; f++) {
    	float power = pow(2.0, f);
      t += abs(pnoise(vec3(power * p), vec3(10.0)) / power);
    }
    return t;
  }

  vec3 OCEAN = vec3(68.0 / 255.0, 68.0 / 255.0, 122.0 / 255.0); // '44447a';
  vec3 BEACH = vec3(158.0 / 255.0, 142.0 / 255.0, 119.0 / 255.0); // '9e8e77';
  vec3 TROPICAL_RAIN_FOREST = vec3(51.0 / 255.0, 119.0 / 255.0, 85.0 / 255.0); // '337755';
  vec3 TROPICAL_SEASONAL_FOREST = vec3(85.0 / 255.0, 153.0 / 255.0, 68.0 / 255.0); // '559944';
  vec3 GRASSLAND = vec3(136.0 / 255.0, 170.0 / 255.0, 85.0 / 255.0); // '88aa55';
  vec3 SUBTROPICAL_DESERT = vec3(210.0 / 255.0, 185.0 / 255.0, 139.0 / 255.0); // 'd2b98b';
  vec3 TEMPERATE_RAIN_FOREST = vec3(68.0 / 255.0, 136.0 / 255.0, 85.0 / 255.0); // '448855';
  vec3 TEMPERATE_DECIDUOUS_FOREST = vec3(103.0 / 255.0, 148.0 / 255.0, 89.0 / 255.0); // '679459';
  vec3 TEMPERATE_DESERT = vec3(201.0 / 255.0, 210.0 / 255.0, 155.0 / 255.0); // 'c9d29b';
  vec3 TAIGA = vec3(153.0 / 255.0, 170.0 / 255.0, 119.0 / 255.0); // '99aa77';
  vec3 SHRUBLAND = vec3(136.0 / 255.0, 153.0 / 255.0, 119.0 / 255.0); // '889977';
  vec3 SNOW = vec3(221.0 / 255.0, 221.0 / 255.0, 228.0 / 255.0); // 'dddde4';
  vec3 TUNDRA = vec3(187.0 / 255.0, 187.0 / 255.0, 170.0 / 255.0); // 'bbbbaa';
  vec3 BARE = vec3(136.0 / 255.0, 136.0 / 255.0, 136.0 / 255.0); // '888888';
  vec3 SCORCHED = vec3(85.0 / 255.0, 85.0 / 255.0, 85.0 / 255.0); // '555555';

  vec3 pickColor (float e, float m) {
    if (e < 0.1) return OCEAN;
    if (e < 0.12) return BEACH;
    if (e > 0.8) {
      if (m < 0.1) return SCORCHED;
      if (m < 0.2) return BARE;
      if (m < 0.5) return TUNDRA;
      return SNOW;
    }
    if (e > 0.6) {
      if (m < 0.33) return TEMPERATE_DESERT;
      if (m < 0.66) return SHRUBLAND;
      return TAIGA;
    }
    if (e > 0.3) {
      if (m < 0.16) return TEMPERATE_DESERT;
      if (m < 0.50) return GRASSLAND;
      if (m < 0.83) return TEMPERATE_DECIDUOUS_FOREST;
      return TEMPERATE_RAIN_FOREST;
    }
    if (m < 0.16) return SUBTROPICAL_DESERT;
    if (m < 0.33) return GRASSLAND;
    if (m < 0.66) return TROPICAL_SEASONAL_FOREST;
    return TROPICAL_RAIN_FOREST;
  }
  
  uniform float uTime;

  #define PHONG
  uniform vec3 diffuse;
  uniform vec3 emissive;
  uniform vec3 specular;
  uniform float shininess;
  uniform float opacity;
  #include <common>
  #include <packing>
  #include <color_pars_fragment>
  #include <uv_pars_fragment>
  #include <uv2_pars_fragment>
  #include <map_pars_fragment>
  #include <alphamap_pars_fragment>
  #include <aomap_pars_fragment>
  #include <lightmap_pars_fragment>
  #include <emissivemap_pars_fragment>
  #include <envmap_pars_fragment>
  #include <gradientmap_pars_fragment>
  #include <fog_pars_fragment>
  #include <bsdfs>
  #include <lights_pars>
  #include <lights_phong_pars_fragment>
  #include <shadowmap_pars_fragment>
  #include <bumpmap_pars_fragment>
  #include <normalmap_pars_fragment>
  #include <specularmap_pars_fragment>
  #include <logdepthbuf_pars_fragment>
  #include <clipping_planes_pars_fragment>
  void main() {
    float baseTime = uTime * 0.01;
    float vElevation = 1.0 - (10.0 * -0.1 * turbulence(vRawNormal * 0.5 + baseTime)) * 2.0;
    float vMoisture = 1.0 - (10.0 * -0.125 * turbulence(vRawNormal * 0.6 + baseTime)) * 2.0;
    #include <clipping_planes_fragment>
    vec4 diffuseColor = vec4( pickColor(min(1.0, vElevation * 0.3), vMoisture), opacity );
    ReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );
    vec3 totalEmissiveRadiance = emissive;
    #include <logdepthbuf_fragment>
    #include <map_fragment>
    #include <color_fragment>
    #include <alphamap_fragment>
    #include <alphatest_fragment>
    #include <specularmap_fragment>
    #include <normal_flip>
    #include <normal_fragment>
    #include <emissivemap_fragment>
    if (diffuseColor != vec4(OCEAN, opacity)) {
      specularStrength = 0.0;
    }
    #include <lights_phong_fragment>
    #include <lights_template>
    #include <aomap_fragment>
    vec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance;
    #include <envmap_fragment>
    gl_FragColor = vec4( outgoingLight, diffuseColor.a );
    #include <premultiplied_alpha_fragment>
    #include <tonemapping_fragment>
    #include <encodings_fragment>
    #include <fog_fragment>
  }
</script>
html {
  width: 100%;
  height: 100%;
  background: #000c1c;
  background: -moz-linear-gradient(top, #000c1c 0%, #15374f 50%, #000c1c 100%);
  background: -webkit-linear-gradient(top, #000c1c 0%, #15374f 50%, #000c1c 100%);
  background: linear-gradient(to bottom, #000c1c 0%, #15374f 50%, #000c1c 100%);
  filter: progid: DXImageTransform.Microsoft.gradient( startColorstr='#000c1c', endColorstr='#15374f', GradientType=0);
}

body {
  margin: 0;
}

canvas {
  display: block;
  margin: 0;
}