mirror of
https://github.com/wahyd4/three.js.git
synced 2026-08-08 20:46:21 +10:00
Added dynamic terrain example.
This commit is contained in:
@@ -0,0 +1,308 @@
|
||||
/**
|
||||
* @author alteredq / http://alteredqualia.com/
|
||||
*
|
||||
*/
|
||||
|
||||
THREE.ShaderTerrain = {
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
// Dynamic terrain shader
|
||||
// - Blinn-Phong
|
||||
// - height + normal + diffuse1 + diffuse2 + specular + detail maps
|
||||
// - point and directional lights (use with "lights: true" material option)
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
'terrain' : {
|
||||
|
||||
uniforms: THREE.UniformsUtils.merge( [
|
||||
|
||||
THREE.UniformsLib[ "fog" ],
|
||||
THREE.UniformsLib[ "lights" ],
|
||||
|
||||
{
|
||||
|
||||
"enableDiffuse1" : { type: "i", value: 0 },
|
||||
"enableDiffuse2" : { type: "i", value: 0 },
|
||||
"enableSpecular" : { type: "i", value: 0 },
|
||||
"enableReflection": { type: "i", value: 0 },
|
||||
|
||||
"tDiffuse1" : { type: "t", value: 0, texture: null },
|
||||
"tDiffuse2" : { type: "t", value: 1, texture: null },
|
||||
"tDetail" : { type: "t", value: 2, texture: null },
|
||||
"tNormal" : { type: "t", value: 3, texture: null },
|
||||
"tSpecular" : { type: "t", value: 4, texture: null },
|
||||
"tDisplacement": { type: "t", value: 5, texture: null },
|
||||
|
||||
"uNormalScale": { type: "f", value: 1.0 },
|
||||
|
||||
"uDisplacementBias": { type: "f", value: 0.0 },
|
||||
"uDisplacementScale": { type: "f", value: 1.0 },
|
||||
|
||||
"uDiffuseColor": { type: "c", value: new THREE.Color( 0xeeeeee ) },
|
||||
"uSpecularColor": { type: "c", value: new THREE.Color( 0x111111 ) },
|
||||
"uAmbientColor": { type: "c", value: new THREE.Color( 0x050505 ) },
|
||||
"uShininess": { type: "f", value: 30 },
|
||||
"uOpacity": { type: "f", value: 1 },
|
||||
|
||||
"uRepeatBase" : { type: "v2", value: new THREE.Vector2( 1, 1 ) },
|
||||
"uRepeatOverlay" : { type: "v2", value: new THREE.Vector2( 1, 1 ) },
|
||||
|
||||
"uOffset" : { type: "v2", value: new THREE.Vector2( 0, 0 ) }
|
||||
|
||||
}
|
||||
|
||||
] ),
|
||||
|
||||
fragmentShader: [
|
||||
|
||||
"uniform vec3 uAmbientColor;",
|
||||
"uniform vec3 uDiffuseColor;",
|
||||
"uniform vec3 uSpecularColor;",
|
||||
"uniform float uShininess;",
|
||||
"uniform float uOpacity;",
|
||||
|
||||
"uniform bool enableDiffuse1;",
|
||||
"uniform bool enableDiffuse2;",
|
||||
"uniform bool enableSpecular;",
|
||||
|
||||
"uniform sampler2D tDiffuse1;",
|
||||
"uniform sampler2D tDiffuse2;",
|
||||
"uniform sampler2D tDetail;",
|
||||
"uniform sampler2D tNormal;",
|
||||
"uniform sampler2D tSpecular;",
|
||||
"uniform sampler2D tDisplacement;",
|
||||
|
||||
"uniform float uNormalScale;",
|
||||
|
||||
"uniform vec2 uRepeatOverlay;",
|
||||
"uniform vec2 uRepeatBase;",
|
||||
|
||||
"uniform vec2 uOffset;",
|
||||
|
||||
"varying vec3 vTangent;",
|
||||
"varying vec3 vBinormal;",
|
||||
"varying vec3 vNormal;",
|
||||
"varying vec2 vUv;",
|
||||
|
||||
"uniform vec3 ambientLightColor;",
|
||||
|
||||
"#if MAX_DIR_LIGHTS > 0",
|
||||
"uniform vec3 directionalLightColor[ MAX_DIR_LIGHTS ];",
|
||||
"uniform vec3 directionalLightDirection[ MAX_DIR_LIGHTS ];",
|
||||
"#endif",
|
||||
|
||||
"#if MAX_POINT_LIGHTS > 0",
|
||||
"uniform vec3 pointLightColor[ MAX_POINT_LIGHTS ];",
|
||||
"uniform vec3 pointLightPosition[ MAX_POINT_LIGHTS ];",
|
||||
"uniform float pointLightDistance[ MAX_POINT_LIGHTS ];",
|
||||
"#endif",
|
||||
|
||||
"varying vec3 vViewPosition;",
|
||||
|
||||
THREE.ShaderChunk[ "fog_pars_fragment" ],
|
||||
|
||||
"void main() {",
|
||||
|
||||
"gl_FragColor = vec4( vec3( 1.0 ), uOpacity );",
|
||||
|
||||
"vec3 specularTex = vec3( 1.0 );",
|
||||
|
||||
"vec2 uvOverlay = uRepeatOverlay * vUv + uOffset;",
|
||||
"vec2 uvBase = uRepeatBase * vUv;",
|
||||
|
||||
"vec3 normalTex = texture2D( tDetail, uvOverlay ).xyz * 2.0 - 1.0;",
|
||||
"normalTex.xy *= uNormalScale;",
|
||||
"normalTex = normalize( normalTex );",
|
||||
|
||||
"if( enableDiffuse1 && enableDiffuse2 ) {",
|
||||
|
||||
"vec4 colDiffuse1 = texture2D( tDiffuse1, uvOverlay );",
|
||||
"vec4 colDiffuse2 = texture2D( tDiffuse2, uvOverlay );",
|
||||
|
||||
"#ifdef GAMMA_INPUT",
|
||||
|
||||
"colDiffuse1.xyz *= colDiffuse1.xyz;",
|
||||
"colDiffuse2.xyz *= colDiffuse2.xyz;",
|
||||
|
||||
"#endif",
|
||||
|
||||
"gl_FragColor = gl_FragColor * mix ( colDiffuse1, colDiffuse2, 1.0 - texture2D( tDisplacement, uvBase ) );",
|
||||
|
||||
" } else if( enableDiffuse1 ) {",
|
||||
|
||||
"gl_FragColor = gl_FragColor * texture2D( tDiffuse1, uvOverlay );",
|
||||
|
||||
"} else if( enableDiffuse2 ) {",
|
||||
|
||||
"gl_FragColor = gl_FragColor * texture2D( tDiffuse2, uvOverlay );",
|
||||
|
||||
"}",
|
||||
|
||||
"if( enableSpecular )",
|
||||
"specularTex = texture2D( tSpecular, uvOverlay ).xyz;",
|
||||
|
||||
"mat3 tsb = mat3( vTangent, vBinormal, vNormal );",
|
||||
"vec3 finalNormal = tsb * normalTex;",
|
||||
|
||||
"vec3 normal = normalize( finalNormal );",
|
||||
"vec3 viewPosition = normalize( vViewPosition );",
|
||||
|
||||
// point lights
|
||||
|
||||
"#if MAX_POINT_LIGHTS > 0",
|
||||
|
||||
"vec3 pointDiffuse = vec3( 0.0 );",
|
||||
"vec3 pointSpecular = vec3( 0.0 );",
|
||||
|
||||
"for ( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) {",
|
||||
|
||||
"vec4 lPosition = viewMatrix * vec4( pointLightPosition[ i ], 1.0 );",
|
||||
|
||||
"vec3 lVector = lPosition.xyz + vViewPosition.xyz;",
|
||||
|
||||
"float lDistance = 1.0;",
|
||||
|
||||
"if ( pointLightDistance[ i ] > 0.0 )",
|
||||
"lDistance = 1.0 - min( ( length( lVector ) / pointLightDistance[ i ] ), 1.0 );",
|
||||
|
||||
"lVector = normalize( lVector );",
|
||||
|
||||
"vec3 pointHalfVector = normalize( lVector + viewPosition );",
|
||||
"float pointDistance = lDistance;",
|
||||
|
||||
"float pointDotNormalHalf = max( dot( normal, pointHalfVector ), 0.0 );",
|
||||
"float pointDiffuseWeight = max( dot( normal, lVector ), 0.0 );",
|
||||
|
||||
"float pointSpecularWeight = specularTex.r * pow( pointDotNormalHalf, uShininess );",
|
||||
|
||||
"pointDiffuse += pointDistance * pointLightColor[ i ] * uDiffuseColor * pointDiffuseWeight;",
|
||||
"pointSpecular += pointDistance * pointLightColor[ i ] * uSpecularColor * pointSpecularWeight * pointDiffuseWeight;",
|
||||
|
||||
"}",
|
||||
|
||||
"#endif",
|
||||
|
||||
// directional lights
|
||||
|
||||
"#if MAX_DIR_LIGHTS > 0",
|
||||
|
||||
"vec3 dirDiffuse = vec3( 0.0 );",
|
||||
"vec3 dirSpecular = vec3( 0.0 );",
|
||||
|
||||
"for( int i = 0; i < MAX_DIR_LIGHTS; i++ ) {",
|
||||
|
||||
"vec4 lDirection = viewMatrix * vec4( directionalLightDirection[ i ], 0.0 );",
|
||||
|
||||
"vec3 dirVector = normalize( lDirection.xyz );",
|
||||
"vec3 dirHalfVector = normalize( lDirection.xyz + viewPosition );",
|
||||
|
||||
"float dirDotNormalHalf = max( dot( normal, dirHalfVector ), 0.0 );",
|
||||
"float dirDiffuseWeight = max( dot( normal, dirVector ), 0.0 );",
|
||||
|
||||
"float dirSpecularWeight = specularTex.r * pow( dirDotNormalHalf, uShininess );",
|
||||
|
||||
"dirDiffuse += directionalLightColor[ i ] * uDiffuseColor * dirDiffuseWeight;",
|
||||
"dirSpecular += directionalLightColor[ i ] * uSpecularColor * dirSpecularWeight * dirDiffuseWeight;",
|
||||
|
||||
"}",
|
||||
|
||||
"#endif",
|
||||
|
||||
// all lights contribution summation
|
||||
|
||||
"vec3 totalDiffuse = vec3( 0.0 );",
|
||||
"vec3 totalSpecular = vec3( 0.0 );",
|
||||
|
||||
"#if MAX_DIR_LIGHTS > 0",
|
||||
|
||||
"totalDiffuse += dirDiffuse;",
|
||||
"totalSpecular += dirSpecular;",
|
||||
|
||||
"#endif",
|
||||
|
||||
"#if MAX_POINT_LIGHTS > 0",
|
||||
|
||||
"totalDiffuse += pointDiffuse;",
|
||||
"totalSpecular += pointSpecular;",
|
||||
|
||||
"#endif",
|
||||
|
||||
//"gl_FragColor.xyz = gl_FragColor.xyz * ( totalDiffuse + ambientLightColor * uAmbientColor) + totalSpecular;",
|
||||
"gl_FragColor.xyz = gl_FragColor.xyz * ( totalDiffuse + ambientLightColor * uAmbientColor + totalSpecular );",
|
||||
|
||||
THREE.ShaderChunk[ "linear_to_gamma_fragment" ],
|
||||
THREE.ShaderChunk[ "fog_fragment" ],
|
||||
|
||||
"}"
|
||||
|
||||
].join("\n"),
|
||||
|
||||
vertexShader: [
|
||||
|
||||
"attribute vec4 tangent;",
|
||||
|
||||
"uniform vec2 uRepeatBase;",
|
||||
|
||||
"uniform sampler2D tNormal;",
|
||||
|
||||
"#ifdef VERTEX_TEXTURES",
|
||||
|
||||
"uniform sampler2D tDisplacement;",
|
||||
"uniform float uDisplacementScale;",
|
||||
"uniform float uDisplacementBias;",
|
||||
|
||||
"#endif",
|
||||
|
||||
"varying vec3 vTangent;",
|
||||
"varying vec3 vBinormal;",
|
||||
"varying vec3 vNormal;",
|
||||
"varying vec2 vUv;",
|
||||
|
||||
"varying vec3 vViewPosition;",
|
||||
|
||||
"void main() {",
|
||||
|
||||
"vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );",
|
||||
|
||||
"vViewPosition = -mvPosition.xyz;",
|
||||
|
||||
"vNormal = normalize( normalMatrix * normal );",
|
||||
|
||||
// tangent and binormal vectors
|
||||
|
||||
"vTangent = normalize( normalMatrix * tangent.xyz );",
|
||||
|
||||
"vBinormal = cross( vNormal, vTangent ) * tangent.w;",
|
||||
"vBinormal = normalize( vBinormal );",
|
||||
|
||||
// texture coordinates
|
||||
|
||||
"vUv = uv;",
|
||||
|
||||
"vec2 uvBase = uv * uRepeatBase;",
|
||||
|
||||
// displacement mapping
|
||||
|
||||
"#ifdef VERTEX_TEXTURES",
|
||||
|
||||
"vec3 dv = texture2D( tDisplacement, uvBase ).xyz;",
|
||||
"float df = uDisplacementScale * dv.x + uDisplacementBias;",
|
||||
"vec4 displacedPosition = vec4( vNormal.xyz * df, 0.0 ) + mvPosition;",
|
||||
"gl_Position = projectionMatrix * displacedPosition;",
|
||||
|
||||
"#else",
|
||||
|
||||
"gl_Position = projectionMatrix * mvPosition;",
|
||||
|
||||
"#endif",
|
||||
|
||||
"vec3 normalTex = texture2D( tNormal, uvBase ).xyz * 2.0 - 1.0;",
|
||||
"vNormal = normalMatrix * normalTex;",
|
||||
|
||||
"}"
|
||||
|
||||
].join("\n")
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Binary file not shown.
|
After Width: | Height: | Size: 77 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 2.7 MiB |
Binary file not shown.
|
After Width: | Height: | Size: 2.2 MiB |
Binary file not shown.
|
After Width: | Height: | Size: 2.5 MiB |
@@ -0,0 +1,9 @@
|
||||
Textures from http://opengameart.org/
|
||||
|
||||
http://opengameart.org/content/dark-grass
|
||||
http://opengameart.org/content/backgrounds-topdown-games
|
||||
|
||||
Slightly modified to have more GPU friendly sizes.
|
||||
|
||||
Licensed under a Creative Commons Attribution 3.0 Unported License:
|
||||
http://creativecommons.org/licenses/by/3.0/
|
||||
@@ -0,0 +1,762 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>three.js webgl - dynamic procedural terrain</title>
|
||||
<meta charset="utf-8">
|
||||
<style type="text/css">
|
||||
body {
|
||||
background: #000;
|
||||
color: #999;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
overflow: hidden;
|
||||
font-family: georgia;
|
||||
font-size:1em;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#info { margin-top: 2em }
|
||||
|
||||
a { color: #fb0; }
|
||||
|
||||
#footer { width: 100%; margin: 2em auto; text-align: center; position: absolute; bottom: 0 }
|
||||
.h { color: #fb0 }
|
||||
.c { display: inline; margin-left: 1em }
|
||||
|
||||
#loading { width: 100%; margin: 2em auto; text-align: center; position: absolute; top: 25em }
|
||||
|
||||
#oldie a { color:#da0 }
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="container"></div>
|
||||
|
||||
<div id="info">
|
||||
<a href="http://github.com/mrdoob/three.js" target="_blank">three.js</a> - dynamic procedural terrain using
|
||||
<a href="https://github.com/ashima/webgl-noise" target="_blank">3d simplex noise</a><br/>
|
||||
birds by <a href="http://mirada.com/">mirada</a> from <a href="http://ro.me">ro.me</a> -
|
||||
textures by <a href="http://opengameart.org/content/dark-grass">qubodup</a> and
|
||||
<a href="http://opengameart.org/content/backgrounds-topdown-games">davis123</a> -
|
||||
music by <a href="http://incompetech.com/m/c/royalty-free/index.html?keywords=00875">Kevin MacLeod</a>
|
||||
</div>
|
||||
|
||||
<div id="loading">Loading...</div>
|
||||
|
||||
<div id="footer">
|
||||
<div class="c">
|
||||
day / night: <span class="h">n</span>
|
||||
</div>
|
||||
|
||||
<div class="c">
|
||||
animate terrain: <span class="h">m</span>
|
||||
</div>
|
||||
|
||||
<div class="c">
|
||||
toggle soundtrack: <span class="h">b</span>
|
||||
</div>
|
||||
</div>
|
||||
<!--
|
||||
<audio id="soundtrack" autoplay loop style="display:none">
|
||||
<source src="sounds/Five_Armies.mp3" type='audio/mp3'>
|
||||
<source src="sounds/Five_Armies.ogg" type='audio/ogg'>
|
||||
</audio>
|
||||
-->
|
||||
<script src="../build/Three.js"></script>
|
||||
|
||||
<script src="js/Detector.js"></script>
|
||||
<script src="js/RequestAnimationFrame.js"></script>
|
||||
<script src="js/Stats.js"></script>
|
||||
|
||||
<script src="js/ShaderTerrain.js"></script>
|
||||
<script src="js/ShaderExtras.js"></script>
|
||||
|
||||
<script src="js/postprocessing/EffectComposer.js"></script>
|
||||
<script src="js/postprocessing/RenderPass.js"></script>
|
||||
<script src="js/postprocessing/BloomPass.js"></script>
|
||||
<script src="js/postprocessing/ShaderPass.js"></script>
|
||||
<script src="js/postprocessing/MaskPass.js"></script>
|
||||
<script src="js/postprocessing/SavePass.js"></script>
|
||||
|
||||
<script id="fragmentShaderNormal" type="x-shader/x-fragment">
|
||||
|
||||
uniform float height;
|
||||
uniform vec2 resolution;
|
||||
uniform sampler2D heightMap;
|
||||
|
||||
varying vec2 vUv;
|
||||
|
||||
void main( void ) {
|
||||
|
||||
float val = texture2D( heightMap, vUv ).x;
|
||||
|
||||
float valU = texture2D( heightMap, vUv + vec2( 1.0 / resolution.x, 0.0 ) ).x;
|
||||
float valV = texture2D( heightMap, vUv + vec2( 0.0, 1.0 / resolution.y ) ).x;
|
||||
|
||||
gl_FragColor = vec4( ( 0.5 * normalize( vec3( val - valU, val - valV, height ) ) + 0.5 ), 1.0 );
|
||||
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<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>
|
||||
|
||||
<script id="vertexShaderFlip" type="x-shader/x-vertex">
|
||||
|
||||
varying vec2 vUv;
|
||||
uniform vec2 scale;
|
||||
|
||||
void main( void ) {
|
||||
|
||||
vUv = vec2( uv.x, 1.0 - uv.y ) * scale;
|
||||
gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
|
||||
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<script>
|
||||
|
||||
if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
|
||||
|
||||
var MARGIN = 100;
|
||||
|
||||
var SCREEN_WIDTH = window.innerWidth;
|
||||
var SCREEN_HEIGHT = window.innerHeight - 2 * MARGIN;
|
||||
|
||||
var renderer, container, stats;
|
||||
|
||||
var camera, scene;
|
||||
var cameraOrtho, sceneRenderTarget;
|
||||
|
||||
var uniformsNoise, uniformsNormal,
|
||||
heightMap, normalMap,
|
||||
quadTarget;
|
||||
|
||||
var spotLight, pointLight;
|
||||
|
||||
var terrain;
|
||||
|
||||
var textureCounter = 0;
|
||||
|
||||
var animDelta = 0, animDeltaDir = -1;
|
||||
var lightVal = 0, lightDir = 1;
|
||||
var soundVal = 0, oldSoundVal = 0, soundDir = 1;
|
||||
|
||||
var clock = new THREE.Clock();
|
||||
|
||||
var morph, morphs = [];
|
||||
|
||||
var updateNoise = true;
|
||||
|
||||
var animateTerrain = false;
|
||||
|
||||
var textMesh1;
|
||||
|
||||
var mlib = {};
|
||||
|
||||
init();
|
||||
animate();
|
||||
|
||||
function init() {
|
||||
|
||||
container = document.getElementById( 'container' );
|
||||
|
||||
soundtrack = document.getElementById( "soundtrack" );
|
||||
|
||||
// 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 );
|
||||
|
||||
// SCENE (FINAL)
|
||||
|
||||
scene = new THREE.Scene();
|
||||
|
||||
scene.fog = new THREE.Fog( 0x050505, 2000, 4000 );
|
||||
scene.fog.color.setHSV( 0.102, 0.9, 0.825 );
|
||||
|
||||
camera = new THREE.PerspectiveCamera( 40, SCREEN_WIDTH / SCREEN_HEIGHT, 2, 4000 );
|
||||
camera.position.set( -1200, 800, 1200 );
|
||||
|
||||
scene.add( camera );
|
||||
|
||||
controls = new THREE.TrackballControls( camera );
|
||||
controls.target.set( 0, 0, 0 );
|
||||
|
||||
controls.rotateSpeed = 1.0;
|
||||
controls.zoomSpeed = 1.2;
|
||||
controls.panSpeed = 0.8;
|
||||
|
||||
controls.noZoom = false;
|
||||
controls.noPan = false;
|
||||
|
||||
controls.staticMoving = false;
|
||||
controls.dynamicDampingFactor = 0.15;
|
||||
|
||||
controls.keys = [ 65, 83, 68 ];
|
||||
|
||||
// LIGHTS
|
||||
|
||||
scene.add( new THREE.AmbientLight( 0x111111 ) );
|
||||
|
||||
spotLight = new THREE.SpotLight( 0xffffff, 1.15 );
|
||||
spotLight.position.set( 500, 2000, 0 );
|
||||
spotLight.castShadow = true;
|
||||
scene.add( spotLight );
|
||||
|
||||
pointLight = new THREE.PointLight( 0xff4400, 1.5 );
|
||||
pointLight.position.set( 0, 0, 0 );
|
||||
scene.add( pointLight );
|
||||
|
||||
|
||||
// HEIGHT + NORMAL MAPS
|
||||
|
||||
var rx = 256, ry = 256;
|
||||
var pars = { minFilter: THREE.LinearMipmapLinearFilter, magFilter: THREE.LinearFilter, format: THREE.RGBFormat };
|
||||
|
||||
heightMap = new THREE.WebGLRenderTarget( rx, ry, pars );
|
||||
normalMap = new THREE.WebGLRenderTarget( rx, ry, pars );
|
||||
|
||||
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 = {
|
||||
|
||||
height: { type: "f", value: 0.05 },
|
||||
resolution: { type: "v2", value: new THREE.Vector2( rx, ry ) },
|
||||
scale: { type: "v2", value: new THREE.Vector2( 1, 1 ) },
|
||||
heightMap: { type: "t", value: 1, texture: heightMap }
|
||||
|
||||
};
|
||||
|
||||
var vertexShader = document.getElementById( 'vertexShader' ).textContent;
|
||||
var vertexShaderFlip = document.getElementById( 'vertexShaderFlip' ).textContent;
|
||||
|
||||
var normalShader = THREE.ShaderTerrain[ "terrain" ];
|
||||
|
||||
uniformsNormalMap = THREE.UniformsUtils.clone( normalShader.uniforms );
|
||||
|
||||
uniformsNormalMap[ "tNormal" ].texture = normalMap;
|
||||
uniformsNormalMap[ "uNormalScale" ].value = 3.5;
|
||||
|
||||
uniformsNormalMap[ "tDisplacement" ].texture = heightMap;
|
||||
|
||||
uniformsNormalMap[ "tDiffuse1" ].texture = THREE.ImageUtils.loadTexture( "textures/terrain/grasslight-big.jpg", null, loadTextures );
|
||||
uniformsNormalMap[ "tDiffuse2" ].texture = THREE.ImageUtils.loadTexture( "textures/terrain/backgrounddetailed6.jpg", null, loadTextures );
|
||||
uniformsNormalMap[ "tSpecular" ].texture = THREE.ImageUtils.loadTexture( "textures/terrain/grasslight-big-specular.jpg", null, loadTextures );
|
||||
uniformsNormalMap[ "tDetail" ].texture = THREE.ImageUtils.loadTexture( "textures/terrain/grasslight-big-nm.jpg", null, loadTextures );
|
||||
|
||||
uniformsNormalMap[ "enableDiffuse1" ].value = true;
|
||||
uniformsNormalMap[ "enableDiffuse2" ].value = true;
|
||||
uniformsNormalMap[ "enableSpecular" ].value = true;
|
||||
|
||||
uniformsNormalMap[ "uDiffuseColor" ].value.setHex( 0xffffff );
|
||||
uniformsNormalMap[ "uSpecularColor" ].value.setHex( 0xffffff );
|
||||
uniformsNormalMap[ "uAmbientColor" ].value.setHex( 0x111111 );
|
||||
|
||||
uniformsNormalMap[ "uShininess" ].value = 30;
|
||||
|
||||
uniformsNormalMap[ "uDisplacementScale" ].value = 375;
|
||||
|
||||
uniformsNormalMap[ "tDiffuse1" ].texture.wrapS = uniformsNormalMap[ "tDiffuse1" ].texture.wrapT = THREE.RepeatWrapping;
|
||||
uniformsNormalMap[ "tDiffuse2" ].texture.wrapS = uniformsNormalMap[ "tDiffuse2" ].texture.wrapT = THREE.RepeatWrapping;
|
||||
uniformsNormalMap[ "tDetail" ].texture.wrapS = uniformsNormalMap[ "tDetail" ].texture.wrapT = THREE.RepeatWrapping;
|
||||
uniformsNormalMap[ "tSpecular" ].texture.wrapS = uniformsNormalMap[ "tDetail" ].texture.wrapT = THREE.RepeatWrapping;
|
||||
uniformsNormalMap[ "uRepeatOverlay" ].value.set( 6, 6 );
|
||||
|
||||
var params = [
|
||||
[ 'heightmap', document.getElementById( 'fragmentShaderNoise' ).textContent, vertexShader, uniformsNoise, false ],
|
||||
[ 'normal', document.getElementById( 'fragmentShaderNormal' ).textContent, vertexShaderFlip, uniformsNormal, false ],
|
||||
[ 'terrain', normalShader.fragmentShader, normalShader.vertexShader, uniformsNormalMap, true ]
|
||||
];
|
||||
|
||||
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.PlaneGeometry( SCREEN_WIDTH, SCREEN_HEIGHT );
|
||||
|
||||
quadTarget = new THREE.Mesh( plane, new THREE.MeshBasicMaterial( { color: 0xff0000 } ) );
|
||||
quadTarget.position.z = -500;
|
||||
sceneRenderTarget.addObject( quadTarget );
|
||||
|
||||
// TERRAIN MESH
|
||||
|
||||
var geometryTerrain = new THREE.PlaneGeometry( 6000, 6000, 256, 256 );
|
||||
geometryTerrain.computeFaceNormals();
|
||||
geometryTerrain.computeVertexNormals();
|
||||
geometryTerrain.computeTangents();
|
||||
|
||||
terrain = new THREE.Mesh( geometryTerrain, mlib[ "terrain" ] );
|
||||
terrain.rotation.set( -Math.PI/2, 0, 0 );
|
||||
terrain.position.set( 0, -125, 0 );
|
||||
terrain.visible = false;
|
||||
scene.add( terrain );
|
||||
|
||||
// RENDERER
|
||||
|
||||
renderer = new THREE.WebGLRenderer();
|
||||
renderer.setSize( SCREEN_WIDTH, SCREEN_HEIGHT );
|
||||
renderer.setClearColor( scene.fog.color, 1 );
|
||||
|
||||
renderer.domElement.style.position = "absolute";
|
||||
renderer.domElement.style.top = MARGIN + "px";
|
||||
renderer.domElement.style.left = "0px";
|
||||
|
||||
container.appendChild( renderer.domElement );
|
||||
|
||||
//
|
||||
|
||||
renderer.gammaInput = true;
|
||||
renderer.gammaOutput = true;
|
||||
|
||||
|
||||
// STATS
|
||||
|
||||
stats = new Stats();
|
||||
stats.domElement.style.position = 'absolute';
|
||||
stats.domElement.style.top = '0px';
|
||||
container.appendChild( stats.domElement );
|
||||
|
||||
stats.domElement.children[ 0 ].children[ 0 ].style.color = "#aaa";
|
||||
stats.domElement.children[ 0 ].style.background = "transparent";
|
||||
stats.domElement.children[ 0 ].children[ 1 ].style.display = "none";
|
||||
|
||||
// EVENTS
|
||||
|
||||
onWindowResize();
|
||||
|
||||
window.addEventListener( 'resize', onWindowResize, false );
|
||||
|
||||
document.addEventListener( 'keydown', onKeyDown, false );
|
||||
document.addEventListener( 'keyup', onKeyUp, false );
|
||||
|
||||
// COMPOSER
|
||||
|
||||
renderer.autoClear = false;
|
||||
|
||||
renderTargetParameters = { minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter, format: THREE.RGBFormat, stencilBufer: false };
|
||||
renderTarget = new THREE.WebGLRenderTarget( SCREEN_WIDTH, SCREEN_HEIGHT, renderTargetParameters );
|
||||
|
||||
effectBloom = new THREE.BloomPass( 0.6 );
|
||||
var effectBleach = new THREE.ShaderPass( THREE.ShaderExtras[ "bleachbypass" ] );
|
||||
|
||||
hblur = new THREE.ShaderPass( THREE.ShaderExtras[ "horizontalTiltShift" ] );
|
||||
vblur = new THREE.ShaderPass( THREE.ShaderExtras[ "verticalTiltShift" ] );
|
||||
|
||||
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 );
|
||||
|
||||
// MORPHS
|
||||
|
||||
function addMorph( geometry, speed, duration, x, y, z ) {
|
||||
|
||||
var material = new THREE.MeshLambertMaterial( { color: 0xffaa55, morphTargets: true, vertexColors: THREE.FaceColors } );
|
||||
|
||||
var meshAnim = new THREE.MorphAnimMesh( geometry, material );
|
||||
|
||||
meshAnim.speed = speed;
|
||||
meshAnim.duration = duration;
|
||||
meshAnim.time = 600 * Math.random();
|
||||
|
||||
meshAnim.position.set( x, y, z );
|
||||
meshAnim.rotation.y = Math.PI/2;
|
||||
|
||||
meshAnim.castShadow = true;
|
||||
meshAnim.receiveShadow = false;
|
||||
|
||||
scene.add( meshAnim );
|
||||
|
||||
morphs.push( meshAnim );
|
||||
|
||||
renderer.initWebGLObjects( scene );
|
||||
renderer.initMaterial( material, scene.lights, scene.fog, meshAnim );
|
||||
|
||||
}
|
||||
|
||||
function morphColorsToFaceColors( geometry ) {
|
||||
|
||||
if ( geometry.morphColors && geometry.morphColors.length ) {
|
||||
|
||||
var colorMap = geometry.morphColors[ 0 ];
|
||||
|
||||
for ( var i = 0; i < colorMap.colors.length; i ++ ) {
|
||||
|
||||
geometry.faces[ i ].color = colorMap.colors[ i ];
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
var loader = new THREE.JSONLoader();
|
||||
|
||||
var startX = -3000;
|
||||
|
||||
loader.load( "models/animated/parrot.js", function( geometry ) {
|
||||
|
||||
morphColorsToFaceColors( geometry );
|
||||
addMorph( geometry, 250, 500, startX -500, 500, 700 );
|
||||
addMorph( geometry, 250, 500, startX - Math.random() * 500, 500, -200 );
|
||||
addMorph( geometry, 250, 500, startX - Math.random() * 500, 500, 200 );
|
||||
addMorph( geometry, 250, 500, startX - Math.random() * 500, 500, 1000 );
|
||||
|
||||
} );
|
||||
|
||||
loader.load( "models/animated/flamingo.js", function( geometry ) {
|
||||
|
||||
morphColorsToFaceColors( geometry );
|
||||
addMorph( geometry, 500, 1000, startX - Math.random() * 500, 350, 40 );
|
||||
|
||||
} );
|
||||
|
||||
loader.load( "models/animated/stork.js", function( geometry ) {
|
||||
|
||||
morphColorsToFaceColors( geometry );
|
||||
addMorph( geometry, 350, 1000, startX - Math.random() * 500, 350, 340 );
|
||||
|
||||
} );
|
||||
|
||||
// PRE-INIT
|
||||
|
||||
renderer.initWebGLObjects( scene );
|
||||
renderer.initMaterial( mlib[ "terrain" ], scene.lights, scene.fog, terrain );
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
function onWindowResize( event ) {
|
||||
|
||||
SCREEN_WIDTH = window.innerWidth;
|
||||
SCREEN_HEIGHT = window.innerHeight - 2 * MARGIN;
|
||||
|
||||
renderer.setSize( SCREEN_WIDTH, SCREEN_HEIGHT );
|
||||
|
||||
camera.aspect = SCREEN_WIDTH / SCREEN_HEIGHT;
|
||||
camera.updateProjectionMatrix();
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
function onKeyDown ( event ) {
|
||||
|
||||
switch( event.keyCode ) {
|
||||
|
||||
case 78: /*N*/ lightDir *= -1; break;
|
||||
case 77: /*M*/ animDeltaDir *= -1; break;
|
||||
case 66: /*B*/ soundDir *= -1; break;
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
function onKeyUp ( event ) {
|
||||
|
||||
switch( event.keyCode ) {
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
//
|
||||
|
||||
function loadTextures() {
|
||||
|
||||
textureCounter += 1;
|
||||
|
||||
if ( textureCounter == 4 ) {
|
||||
|
||||
terrain.visible = true;
|
||||
|
||||
document.getElementById( "loading" ).style.display = "none";
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
function animate() {
|
||||
|
||||
requestAnimationFrame( animate );
|
||||
|
||||
render();
|
||||
stats.update();
|
||||
|
||||
}
|
||||
|
||||
function render() {
|
||||
|
||||
var delta = clock.getDelta();
|
||||
|
||||
soundVal = THREE.Math.clamp( soundVal + delta * soundDir, 0, 1 );
|
||||
|
||||
if ( soundVal !== oldSoundVal ) {
|
||||
|
||||
if ( soundtrack ) {
|
||||
|
||||
soundtrack.volume = soundVal;
|
||||
oldSoundVal = soundVal;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if ( terrain.visible ) {
|
||||
|
||||
controls.update();
|
||||
|
||||
var time = Date.now() * 0.001;
|
||||
|
||||
var fLow = 0.4, fHigh = 0.825;
|
||||
|
||||
lightVal = THREE.Math.clamp( lightVal + 0.5 * delta * lightDir, fLow, fHigh );
|
||||
|
||||
var valNorm = ( lightVal - fLow ) / ( fHigh - fLow );
|
||||
|
||||
var sat = THREE.Math.mapLinear( valNorm, 0, 1, 0.95, 0.25 );
|
||||
scene.fog.color.setHSV( 0.1, sat, lightVal );
|
||||
|
||||
renderer.setClearColor( scene.fog.color, 1 );
|
||||
|
||||
spotLight.intensity = THREE.Math.mapLinear( valNorm, 0, 1, 0.1, 1.15 );
|
||||
pointLight.intensity = THREE.Math.mapLinear( valNorm, 0, 1, 0.9, 1.5 );
|
||||
|
||||
uniformsNormalMap[ "uNormalScale" ].value = THREE.Math.mapLinear( valNorm, 0, 1, 0.6, 3.5 );
|
||||
|
||||
if ( updateNoise ) {
|
||||
|
||||
animDelta = THREE.Math.clamp( animDelta + 0.00075 * animDeltaDir, 0, 0.05 );
|
||||
uniformsNoise.time.value += delta * animDelta;
|
||||
|
||||
uniformsNoise.offset.value.x += delta * 0.05;
|
||||
|
||||
uniformsNormalMap.uOffset.value.x = 4 * uniformsNoise.offset.value.x;
|
||||
|
||||
quadTarget.material = mlib[ "heightmap" ];
|
||||
renderer.render( sceneRenderTarget, cameraOrtho, heightMap, true );
|
||||
|
||||
quadTarget.material = mlib[ "normal" ];
|
||||
renderer.render( sceneRenderTarget, cameraOrtho, normalMap, true );
|
||||
|
||||
//updateNoise = false;
|
||||
|
||||
}
|
||||
|
||||
|
||||
for ( var i = 0; i < morphs.length; i ++ ) {
|
||||
|
||||
morph = morphs[ i ];
|
||||
|
||||
morph.updateAnimation( 1000 * delta );
|
||||
|
||||
morph.position.x += morph.speed * delta;
|
||||
|
||||
if ( morph.position.x > 2000 ) {
|
||||
|
||||
morph.position.x = -1500 - Math.random() * 500;
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
//renderer.render( scene, camera );
|
||||
composer.render( 0.1 );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user