Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
379 changes: 77 additions & 302 deletions README.md

Large diffs are not rendered by default.

154 changes: 147 additions & 7 deletions frag_globe.html
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@
</script>

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


precision highp float;

//View-Space directional light
Expand Down Expand Up @@ -68,30 +70,75 @@
varying vec2 v_Texcoord;
varying vec3 v_Position; // position in camera coordinates
varying vec3 v_positionMC; // position in model coordinates

uniform int u_cloudDisplay;
uniform int u_movingCloudDisplay;
uniform int u_movingOceanDisplay;
uniform int u_bumpDisplay;

mat3 eastNorthUpToEyeCoordinates(vec3 positionMC, vec3 normalEC);

//float perlinNoise(vec3 v);
float snoise(vec3 v);

void main(void)
{
// surface normal - normalized after rasterization
vec3 normal = normalize(v_Normal);
vec3 normalOrg = normalize(v_Normal);

// normalized eye-to-position vector in camera coordinates
vec3 eyeToPosition = normalize(v_Position);

vec2 texel = vec2(1.0/1024.0, 1.0/512.0);
float center = texture2D(u_Bump, v_Texcoord).r;
float right = texture2D(u_Bump, v_Texcoord + vec2(texel.x, 0.0)).r;
float top = texture2D(u_Bump, v_Texcoord + vec2(0.0, texel.y)).r;

float diffuse = clamp(dot(u_CameraSpaceDirLight, normal), 0.0, 1.0);
vec3 normal = normalize(vec3(center - right, center - top, 0.2));
normal = normalize( eastNorthUpToEyeCoordinates(eyeToPosition, normalOrg) * normal );
normal = (u_bumpDisplay == 1) ? normal : normalOrg;

float diffuse = dot(u_CameraSpaceDirLight, normal);
float diffuseClamp = clamp(dot(u_CameraSpaceDirLight, normal), 0.0, 1.0);

float oceamTerm = texture2D(u_EarthSpec, v_Texcoord).r;

vec3 toReflectedLight = reflect(-u_CameraSpaceDirLight, normal);
float specular = max(dot(toReflectedLight, -eyeToPosition), 0.0);
specular = pow(specular, 20.0);

float gammaCorrect = 1.0/1.2; //gamma correct by 1/1.2

specular = (oceamTerm > 0.0) ? specular : 0.0;

vec3 dayColor = texture2D(u_DayDiffuse, v_Texcoord).rgb;
if (u_movingOceanDisplay == 1 && oceamTerm > 0.5) {
float noise = snoise(v_Position+u_time);
float offsetOceanTerm = texture2D(u_EarthSpec, v_Texcoord+vec2(noise, 0.0)).r;
vec3 offsetColor = texture2D(u_DayDiffuse, v_Texcoord+vec2(noise, 0.0)).rgb;
dayColor = (offsetOceanTerm > 0.5) ? offsetColor : dayColor;
}

vec3 nightColor = texture2D(u_Night, v_Texcoord).rgb;

float gammaCorrect = 1.1/1.2; //gamma correct by 1/1.2
//apply gamma correction to nighttime texture
nightColor = pow(nightColor,vec3(gammaCorrect));

vec3 color = ((0.6 * diffuse) + (0.4 * specular)) * dayColor;
vec2 v_cloudCoord = v_Texcoord;
v_cloudCoord = (u_movingCloudDisplay == 1) ? (v_cloudCoord - vec2(0.08*u_time, 0.0)) : v_cloudCoord;
v_cloudCoord.x = v_cloudCoord.x > 1.0 ? 0.0 : v_cloudCoord.x;

vec3 cloudColor = texture2D(u_Cloud, v_cloudCoord).rgb;
float cloudTrans = texture2D(u_CloudTrans, v_cloudCoord).r;
cloudTrans = (u_cloudDisplay == 1) ? cloudTrans : 1.0;

nightColor = mix(nightColor, vec3(0.0, 0.0, 0.0), 1.0-cloudTrans);
dayColor = mix((0.8 * diffuseClamp + 0.4 * specular) * dayColor, cloudColor, 1.0-cloudTrans);
vec3 color = mix(nightColor, dayColor, (1.0+diffuse)/2.0);

float rim = dot(v_Position, v_Normal) + 1.0;
if (rim > 0.0)
color += vec3(rim/4.0, rim/2.0, rim/2.0);

color = clamp(color, 0.0, 1.0);
gl_FragColor = vec4(color, 1.0);
}

Expand All @@ -109,10 +156,103 @@
bitangentEC.x, bitangentEC.y, bitangentEC.z,
normalEC.x, normalEC.y, normalEC.z);
}
</script>

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;
}

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 );

// x0 = x0 - 0.0 + 0.0 * C.xxx;
// x1 = x0 - i1 + 1.0 * C.xxx;
// x2 = x0 - i2 + 2.0 * C.xxx;
// x3 = x0 - 1.0 + 3.0 * C.xxx;
vec3 x1 = x0 - i1 + C.xxx;
vec3 x2 = x0 - i2 + C.yyy; // 2.0*C.x = 1/3 = C.y
vec3 x3 = x0 - D.yyy; // -1.0+3.0*C.x = -0.5 = -D.y

// Permutations
i = mod289(i);
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: 7x7 points over a square, mapped onto an octahedron.
// The ring size 17*17 = 289 is close to a multiple of 49 (49*6 = 294)
float n_ = 0.142857142857; // 1.0/7.0
vec3 ns = n_ * D.wyz - D.xzx;

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

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 = vec4(lessThan(b0,0.0))*2.0 - 1.0;
//vec4 s1 = vec4(lessThan(b1,0.0))*2.0 - 1.0;
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) ) );
}
</script>
<script src ="js/lib/dat.gui.min.js" type ="text/javascript"></script>
<script src ="js/lib/gl-matrix.js" type ="text/javascript"></script>
<script src ="js/webGLUtility.js" type ="text/javascript"></script>
<script src ="js/lib/stats.js" type="text/javascript"></script>
<script src ="js/frag_globe.js" type ="text/javascript"></script>
</body>

Expand Down
99 changes: 96 additions & 3 deletions js/frag_globe.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,27 @@
var u_EarthSpecLocation;
var u_BumpLocation;
var u_timeLocation;


var cloudDisplay = true;
var u_cloudDisLocation;
var movingCloudDisplay = true;
var u_mvCloudDisLocation;
var movingOceanDisplay = true;
var u_mvOceanDisLocation;
var bumpDisplay = true;
var u_bumpDisLocation;

//stas.js
var statsInitShader = new Stats();
statsInitShader.setMode(1); // 0: fps, 1: ms
statsInitShader.domElement.style.position = 'absolute';
statsInitShader.domElement.style.right = '0px';
statsInitShader.domElement.style.top = '160px';
document.body.appendChild(statsInitShader.domElement );
var initS = document.createElement('div');
initS.innerHTML = 'init shader';
statsInitShader.domElement.appendChild(initS);
statsInitShader.begin();
(function initializeShader() {
var vs = getShaderSource(document.getElementById("vs"));
var fs = getShaderSource(document.getElementById("fs"));
Expand All @@ -76,9 +96,15 @@
u_BumpLocation = gl.getUniformLocation(program,"u_Bump");
u_timeLocation = gl.getUniformLocation(program,"u_time");
u_CameraSpaceDirLightLocation = gl.getUniformLocation(program,"u_CameraSpaceDirLight");

u_cloudDisLocation = gl.getUniformLocation(program, "u_cloudDisplay");
u_mvCloudDisLocation = gl.getUniformLocation(program, "u_movingCloudDisplay");
u_mvOceanDisLocation = gl.getUniformLocation(program, "u_movingOceanDisplay");
u_bumpDisLocation = gl.getUniformLocation(program, "u_bumpDisplay");

gl.useProgram(program);
})();
statsInitShader.end();

var dayTex = gl.createTexture();
var bumpTex = gl.createTexture();
Expand All @@ -87,6 +113,17 @@
var lightTex = gl.createTexture();
var specTex = gl.createTexture();

//stas.js
var statsInitTexture = new Stats();
statsInitTexture.setMode(1); // 0: fps, 1: ms
statsInitTexture.domElement.style.position = 'absolute';
statsInitTexture.domElement.style.right = '0px';
statsInitTexture.domElement.style.top = '240px';
document.body.appendChild( statsInitTexture.domElement );
var initT = document.createElement('div');
initT.innerHTML = 'init texture';
statsInitTexture.domElement.appendChild(initT);
statsInitTexture.begin();
function initLoadedTexture(texture){
gl.bindTexture(gl.TEXTURE_2D, texture);
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
Expand All @@ -97,9 +134,22 @@
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT);
gl.bindTexture(gl.TEXTURE_2D, null);
}
statsInitTexture.end();

var numberOfIndices;


//stas.js
var statsInitSphere = new Stats();
statsInitSphere.setMode(1); // 0: fps, 1: ms
statsInitSphere.domElement.style.position = 'absolute';
statsInitSphere.domElement.style.right = '0px';
statsInitSphere.domElement.style.top = '320';
document.body.appendChild( statsInitSphere.domElement );
var initSphere = document.createElement('div');
initSphere.innerHTML = 'init sphere';
statsInitSphere.domElement.appendChild(initSphere);
statsInitSphere.begin();

(function initializeSphere() {
function uploadMesh(positions, texCoords, indices) {
// Positions
Expand Down Expand Up @@ -174,6 +224,7 @@
uploadMesh(positions, texCoords, indices);
numberOfIndices = indicesIndex;
})();
statsInitSphere.end();

var time = 0;
var mouseLeftDown = false;
Expand Down Expand Up @@ -233,10 +284,21 @@
document.onmouseup = handleMouseUp;
document.onmousemove = handleMouseMove;


//stas.js
var statsAnimate = new Stats();
statsAnimate.setMode(1); // 0: fps, 1: ms
statsAnimate.domElement.style.position = 'absolute';
statsAnimate.domElement.style.right = '0';
statsAnimate.domElement.style.top = '400px';
document.body.appendChild( statsAnimate.domElement );
var anim = document.createElement('div');
anim.innerHTML = 'animate';
statsAnimate.domElement.appendChild(anim);

function animate() {
///////////////////////////////////////////////////////////////////////////
// Update
statsAnimate.begin();

var model = mat4.create();
mat4.identity(model);
Expand Down Expand Up @@ -289,6 +351,15 @@
gl.drawElements(gl.TRIANGLES, numberOfIndices, gl.UNSIGNED_SHORT,0);

time += 0.001;
gl.uniform1f(u_timeLocation, time);

gl.uniform1i(u_cloudDisLocation, cloudDisplay);
gl.uniform1i(u_mvCloudDisLocation, movingCloudDisplay);
gl.uniform1i(u_mvOceanDisLocation, movingOceanDisplay);
gl.uniform1i(u_bumpDisLocation, bumpDisplay);

statsAnimate.end();

window.requestAnimFrame(animate);
}

Expand All @@ -306,6 +377,28 @@
}
texture.image.src = src;
}


function config() {
this.cloud = cloudDisplay; // RGB array
this.movingCloud = movingCloudDisplay;
this.movingOcean = movingOceanDisplay;
this.bump = bumpDisplay;
}
var gui = new dat.GUI();
var cong = new config();
gui.add(cong, 'cloud').onChange(function () {
cloudDisplay = cong.cloud;
});
gui.add(cong, 'movingCloud').onChange(function () {
movingCloudDisplay = cong.movingCloud;
});
gui.add(cong, 'movingOcean').onChange(function () {
movingOceanDisplay = cong.movingOcean;
});
gui.add(cong, 'bump').onChange(function () {
bumpDisplay = cong.bump;
});

initializeTexture(dayTex, "assets/earthmap1024.png");
initializeTexture(bumpTex, "assets/earthbump1024.png");
Expand Down
Loading