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
364 changes: 29 additions & 335 deletions README.md

Large diffs are not rendered by default.

Binary file added assets/noise.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
273 changes: 273 additions & 0 deletions custom_wave.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,273 @@
<html>

<head>
<title>Vertex Wave</title>
<meta charset ="utf-8">
<meta http-equiv="X-UA-Compatible" content="chrome=1"> <!-- Use Chrome Frame in IE -->
</head>

<body>
<div id="message" style="position:absolute;top:100px"></div> <!-- Pixel offset to avoid FPS counter -->
<canvas id="canvas" style="border: none;" width="1024" height="768" tabindex="1"></canvas>
<script src ="js/lib/gl-matrix.js" type ="text/javascript"></script>
<script src ="js/webGLUtility.js" type ="text/javascript"></script>
<script src="js/lib/dat.gui.min.js" type="text/javascript"></script>

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

attribute vec2 position;
vec2 center = vec2( 0.5, 0.5 );

uniform mat4 u_modelViewPerspective;
uniform float u_time;

varying float v_height;

void main( void )
{
float distance_from_center = length( position - center );
float s_contrib = sin( distance_from_center * u_time );
float t_contrib = cos( distance_from_center * u_time );
v_height = s_contrib * t_contrib;

gl_Position = u_modelViewPerspective * vec4( vec3( position, v_height ), 1.0 );
}

</script>

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

precision mediump float;

uniform vec3 u_color_min;
uniform vec3 u_color_max;

varying float v_height;

void main( void )
{
vec3 color = mix( u_color_min, u_color_max, ( v_height / 2.0 + 0.5 ) );
gl_FragColor = vec4( color, 1.0 );
}

</script>

<script>
// Globals
var positionLocation = 0;
var heightLocation = 1;
var u_modelViewPerspectiveLocation;
var u_color;

var heights;
var numberOfIndices;

var eye = [2.0, 1.0, 3.0];
var center = [0.0, 0.0, 0.0];
var up = [0.0, 0.0, 1.0];


var NUM_WIDTH_PTS = 32;
var NUM_HEIGHT_PTS = 32;

var message;
var canvas;
var context;

var persp = mat4.create();
var view = mat4.create();

var wave_colors = {
min: [ 0.0, 0.0, 255.0 ],
max: [ 255.0, 0.0, 0.0 ]
};
var u_color_min_location;
var u_color_max_location;

var u_time_location;
var time_elapsed = 0.0;

var max_time = 8.0;
var time_is_increasing = true;

// Function called when the window is loaded
window.onload = function() {
// Add GUI component
var gui = new dat.GUI();

// Update wave_colors variable when color picker is changed.
gui.addColor( wave_colors, 'min' );
gui.addColor( wave_colors, 'max' );

init();

animate();
};

function init() {
message = document.getElementById("message");
canvas = document.getElementById("canvas");
context = createWebGLContext(canvas, message);

if (!context) {
return;
}

// SET UP WEBGL CONTEXT
context.viewport(0, 0, canvas.width, canvas.height);
context.clearColor(1.0, 1.0, 1.0, 1.0);
context.enable(context.DEPTH_TEST);

mat4.perspective(45.0, 0.5, 0.1, 100.0, persp);

mat4.lookAt(eye, center, up, view);

initializeShader();
initializeGrid();
}


function animate(){
// Update
var model = mat4.create();
mat4.identity(model);
mat4.translate(model, [-0.5, -0.5, 0.0]);
var mv = mat4.create();
mat4.multiply(view, model, mv);
var mvp = mat4.create();
mat4.multiply(persp, mv, mvp);

// Render
context.clear(context.COLOR_BUFFER_BIT | context.DEPTH_BUFFER_BIT);

context.uniformMatrix4fv(u_modelViewPerspectiveLocation, false, mvp);
context.drawElements(context.LINES, numberOfIndices, context.UNSIGNED_SHORT,0);

// Update time_elapsed, which controls wave animation.
if ( time_is_increasing ) {
time_elapsed += 0.01;

if ( time_elapsed > max_time ) {
time_is_increasing = false;
}
}
else {
time_elapsed -= 0.01;

if ( time_elapsed < 0.0 ) {
time_is_increasing = true;
}
}

context.uniform1f( u_time_location, time_elapsed );

// Update uniform color variables in fragment shader.
var c_min = wave_colors.min;
var c_max = wave_colors.max;
context.uniform3f( u_color_min_location, c_min[0] / 255.0, c_min[1] / 255.0, c_min[2] / 255.0 );
context.uniform3f( u_color_max_location, c_max[0] / 255.0, c_max[1] / 255.0, c_max[2] / 255.0 );

window.requestAnimFrame(animate);
}

function initializeShader() {
var program;
var vs = getShaderSource(document.getElementById("vs"));
var fs = getShaderSource(document.getElementById("fs"));

var program = createProgram(context, vs, fs, message);
context.bindAttribLocation(program, positionLocation, "position");
u_modelViewPerspectiveLocation = context.getUniformLocation(program,"u_modelViewPerspective");
u_colorLocation = context.getUniformLocation(program, "u_color");

// Locate uniform variables.
u_color_min_location = context.getUniformLocation( program,"u_color_min" );
u_color_max_location = context.getUniformLocation( program,"u_color_max" );

// Locate uniform variables.
u_time_location = context.getUniformLocation( program,"u_time" );

context.useProgram(program);
}

function initializeGrid() {
function uploadMesh(positions, heights, indices) {
// Positions
var positionsName = context.createBuffer();
context.bindBuffer(context.ARRAY_BUFFER, positionsName);
context.bufferData(context.ARRAY_BUFFER, positions, context.STREAM_DRAW);
context.vertexAttribPointer(positionLocation, 2, context.FLOAT, false, 0, 0);
context.enableVertexAttribArray(positionLocation);

if (heights){
// Heights
var heightsName = context.createBuffer();
context.bindBuffer(context.ARRAY_BUFFER, heightsName);
context.bufferData(context.ARRAY_BUFFER, heights.length *
heights.BYTES_PER_ELEMENT, context.STATIC_DRAW);
context.vertexAttribPointer(heightLocation, 1, context.FLOAT, false, 0, 0);
context.enableVertexAttribArray(heightLocation);
}

// Indices
var indicesName = context.createBuffer();
context.bindBuffer(context.ELEMENT_ARRAY_BUFFER, indicesName);
context.bufferData(context.ELEMENT_ARRAY_BUFFER, indices, context.STATIC_DRAW);
}

var WIDTH_DIVISIONS = NUM_WIDTH_PTS - 1;
var HEIGHT_DIVISIONS = NUM_HEIGHT_PTS - 1;

var numberOfPositions = NUM_WIDTH_PTS * NUM_HEIGHT_PTS;

var positions = new Float32Array(2 * numberOfPositions);
var indices = new Uint16Array(2 * ((NUM_HEIGHT_PTS * (NUM_WIDTH_PTS - 1)) +
(NUM_WIDTH_PTS * (NUM_HEIGHT_PTS - 1))));

var positionsIndex = 0;
var indicesIndex = 0;
var length;

for (var j = 0; j < NUM_WIDTH_PTS; ++j){
positions[positionsIndex++] = j /(NUM_WIDTH_PTS - 1);
positions[positionsIndex++] = 0.0;

if (j>=1){
length = positionsIndex / 2;
indices[indicesIndex++] = length - 2;
indices[indicesIndex++] = length - 1;
}
}

for (var i = 0; i < HEIGHT_DIVISIONS; ++i){
var v = (i + 1) / (NUM_HEIGHT_PTS - 1);
positions[positionsIndex++] = 0.0;
positions[positionsIndex++] = v;

length = (positionsIndex / 2);
indices[indicesIndex++] = length - 1;
indices[indicesIndex++] = length - 1 - NUM_WIDTH_PTS;

for (var k = 0; k < WIDTH_DIVISIONS; ++k){
positions[positionsIndex++] = (k + 1) / (NUM_WIDTH_PTS - 1);
positions[positionsIndex++] = v;

length = positionsIndex / 2;
var new_pt = length - 1;
indices[indicesIndex++] = new_pt - 1; // Previous side
indices[indicesIndex++] = new_pt;

indices[indicesIndex++] = new_pt - NUM_WIDTH_PTS; // Previous bottom
indices[indicesIndex++] = new_pt;
}
}

uploadMesh(positions, heights, indices);
numberOfIndices = indices.length;
}

</script>

</body>

</html>
65 changes: 58 additions & 7 deletions frag_globe.html
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@
//Bump map
uniform sampler2D u_Bump;

uniform sampler2D u_noise;

uniform float u_time;
uniform mat4 u_InvTrans;

Expand All @@ -69,30 +71,78 @@
varying vec3 v_Position; // position in camera coordinates
varying vec3 v_positionMC; // position in model coordinates

float HORIZONTAL_STEP = 1.0 / 1024.0;
float VERTICAL_STEP = 1.0 / 512.0;

mat3 eastNorthUpToEyeCoordinates(vec3 positionMC, vec3 normalEC);
float water(float t, vec2 tc);
float snoise(vec2 v);

void main(void)
{
// surface normal - normalized after rasterization
vec3 normal = normalize(v_Normal);
// normalized eye-to-position vector in camera coordinates
vec3 eyeToPosition = normalize(v_Position);

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

vec3 dayColor = texture2D(u_DayDiffuse, v_Texcoord).rgb;
vec3 nightColor = texture2D(u_Night, v_Texcoord).rgb;
vec3 spec_map = texture2D( u_EarthSpec, v_Texcoord ).rgb;
vec3 bump_map = texture2D( u_Bump, v_Texcoord ).rgb;

// Bump mapping.
float bump_center, bump_right, bump_top;

// Land.
if ( spec_map.r == 0.0 ) {
bump_center = texture2D( u_Bump, v_Texcoord ).r;
bump_right = texture2D( u_Bump, vec2( v_Texcoord.s + HORIZONTAL_STEP, v_Texcoord.t ) ).r;
bump_top = texture2D( u_Bump, vec2( v_Texcoord.s, v_Texcoord.t + VERTICAL_STEP ) ).r;
}
// Water.
else {
vec2 base_pos = vec2( v_Texcoord.s - u_time / 40.0, v_Texcoord.t - u_time / 60.0 );
bump_center = texture2D( u_noise, base_pos ).r * 4.0;
bump_right = texture2D( u_noise, vec2( base_pos.s + HORIZONTAL_STEP, base_pos.t ) ).r * 4.0;
bump_top = texture2D( u_noise, vec2( base_pos.s, base_pos.t + VERTICAL_STEP ) ).r * 4.0;
}

vec3 perturbed_normal = normalize( vec3( bump_center - bump_right, bump_center - bump_top, 0.2 ) );
mat3 normal_transform = eastNorthUpToEyeCoordinates( v_positionMC, v_Normal );
vec3 bump_normal = normalize( normal_transform * perturbed_normal );

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

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

vec3 dayColor = texture2D(u_DayDiffuse, v_Texcoord).rgb;
vec3 nightColor = texture2D(u_Night, v_Texcoord).rgb;
//apply gamma correction to nighttime texture
vec2 cloud_texture_coordinates = vec2( v_Texcoord.s - ( u_time / 10.0 ), v_Texcoord.t );
vec3 cloud_color = texture2D( u_Cloud, cloud_texture_coordinates ).rgb;
vec3 cloud_map = texture2D( u_CloudTrans, cloud_texture_coordinates ).rgb;

// Apply gamma correction to nighttime texture.
nightColor = pow(nightColor,vec3(gammaCorrect));

vec3 color = ((0.6 * diffuse) + (0.4 * specular)) * dayColor;
gl_FragColor = vec4(color, 1.0);
// spec_map.r will be 0 if no specularity should be applied, and 1 otherwise.
dayColor = ((0.6 * diffuse) + (0.4 * specular * spec_map.r )) * dayColor;

// Update colors based on cloud coverage.
dayColor = mix( cloud_color, dayColor, cloud_map.r );
nightColor = mix( vec3( 0.0 ), nightColor, cloud_map.r );

// Blend day and night textures.
vec3 color = mix( nightColor, dayColor, clamp( ( diffuse - ( diffuse / 2.0 ) ) * 4.0, 0.0, 1.0 ) );

// Rim lighting.
float rim_factor = dot( v_Normal, v_Position ) + 1.0;
if ( rim_factor > 0.0 ) {
color += vec3( rim_factor / 4.0, rim_factor / 2.0, rim_factor / 2.0 );
}

gl_FragColor = vec4( color, 1.0 );
}

mat3 eastNorthUpToEyeCoordinates(vec3 positionMC, vec3 normalEC)
Expand All @@ -109,6 +159,7 @@
bitangentEC.x, bitangentEC.y, bitangentEC.z,
normalEC.x, normalEC.y, normalEC.z);
}

</script>

<script src ="js/lib/gl-matrix.js" type ="text/javascript"></script>
Expand Down
Loading