twgl.js/examples/textures.html

409 lines
12 KiB
HTML

<!DOCTYPE html>
<html>
<head>
<meta charset="utf8">
<!--
@license twgl.js Copyright (c) 2015, Gregg Tavares All Rights Reserved.
Available via the MIT license.
see: http://github.com/greggman/twgl.js for details
-->
<meta name="viewport" content="width=device-width, target-densitydpi=160dpi, initial-scale=1.0, user-scalable=yes">
<meta property="og:title" content="TWGL.js - textures" />
<meta property="og:type" content="website" />
<meta property="og:image" content="http://twgljs.org/examples/screenshots/textures.png" />
<meta property="og:description" content="TWGL.js - textures" />
<meta property="og:url" content="http://twgljs.org" />
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:site" content="@greggman">
<meta name="twitter:creator" content="@greggman">
<meta name="twitter:domain" content="twgljs.org">
<meta name="twitter:title" content="TWGL.js - textures">
<meta name="twitter:url" content="http://twgljs.org/examples/textures.html">
<meta name="twitter:description" content="TWGL.js - textures">
<meta name="twitter:image:src" content="http://twgljs.org/examples/screenshots/textures.png">
<link href="/resources/images/twgljs-icon.png" rel="shortcut icon" type="image/png">
<title>twgl.js - textures</title>
<style>
html, body {
margin: 0px;
width: 100%;
height: 100%;
overflow: hidden;
font-family: monospace;
}
canvas {
width: 100%;
height: 100%;
}
#b {
position: absolute;
top: 10px;
width: 100%;
text-align: center;
z-index: 2;
}
</style>
</head>
<body>
<canvas id="c"></canvas>
<div id="b"><a href="http://twgljs.org">twgl.js</a> - textures</div>
</body>
<script id="one-point-vs" type="notjs">
uniform mat4 u_worldViewProjection;
uniform vec3 u_lightWorldPos;
uniform mat4 u_world;
uniform mat4 u_viewInverse;
uniform mat4 u_worldInverseTranspose;
attribute vec4 a_position;
attribute vec3 a_normal;
attribute vec2 a_texcoord;
varying vec4 v_position;
varying vec2 v_texCoord;
varying vec3 v_normal;
varying vec3 v_surfaceToLight;
varying vec3 v_surfaceToView;
void main() {
v_texCoord = a_texcoord;
v_position = (u_worldViewProjection * a_position);
v_normal = (u_worldInverseTranspose * vec4(a_normal, 0)).xyz;
v_surfaceToLight = u_lightWorldPos - (u_world * a_position).xyz;
v_surfaceToView = (u_viewInverse[3] - (u_world * a_position)).xyz;
gl_Position = v_position;
}
</script>
<script id="one-point-fs" type="notjs">
precision mediump float;
varying vec4 v_position;
varying vec2 v_texCoord;
varying vec3 v_normal;
varying vec3 v_surfaceToLight;
varying vec3 v_surfaceToView;
uniform vec4 u_lightColor;
uniform vec4 u_diffuseMult;
uniform sampler2D u_diffuse;
uniform vec4 u_specular;
uniform float u_shininess;
uniform float u_specularFactor;
vec4 lit(float l ,float h, float m) {
return vec4(1.0,
abs(l),//max(l, 0.0),
(l > 0.0) ? pow(max(0.0, h), m) : 0.0,
1.0);
}
void main() {
vec4 diffuseColor = texture2D(u_diffuse, v_texCoord) * u_diffuseMult;
if (diffuseColor.a < 0.1) {
discard;
}
vec3 a_normal = normalize(v_normal);
vec3 surfaceToLight = normalize(v_surfaceToLight);
vec3 surfaceToView = normalize(v_surfaceToView);
vec3 halfVector = normalize(surfaceToLight + surfaceToView);
vec4 litR = lit(dot(a_normal, surfaceToLight),
dot(a_normal, halfVector), u_shininess);
vec4 outColor = vec4((
u_lightColor * (diffuseColor * litR.y +
u_specular * litR.z * u_specularFactor)).rgb,
diffuseColor.a);
gl_FragColor = outColor;
}
</script>
<script id="env-map-vs" type="notjs">
uniform mat4 u_viewInverse;
uniform mat4 u_world;
uniform mat4 u_worldViewProjection;
uniform mat4 u_worldInverseTranspose;
attribute vec4 a_position;
attribute vec3 a_normal;
varying vec3 v_normal;
varying vec3 v_surfaceToView;
void main() {
v_normal = (u_worldInverseTranspose * vec4(a_normal, 0)).xyz;
v_surfaceToView = (u_viewInverse[3] - (u_world * a_position)).xyz;
gl_Position = u_worldViewProjection * a_position;
}
</script>
<script id="env-map-fs" type="notjs">
precision mediump float;
uniform samplerCube u_texture;
varying vec3 v_surfaceToView;
varying vec3 v_normal;
void main() {
vec3 normal = normalize(v_normal);
vec3 surfaceToView = normalize(v_surfaceToView);
vec4 color = textureCube(u_texture, -reflect(surfaceToView, normal));
gl_FragColor = color;
}
</script>
<script src="../dist/twgl-full.min.js"></script>
<script src="../3rdparty/chroma.min.js"></script>
<script>
"use strict";
twgl.setAttributePrefix("a_");
var m4 = twgl.m4;
var gl = twgl.getWebGLContext(document.getElementById("c"));
var onePointProgramInfo = twgl.createProgramInfo(gl, ["one-point-vs", "one-point-fs"]);
var envMapProgramInfo = twgl.createProgramInfo(gl, ["env-map-vs", "env-map-fs"]);
var shapes = [
twgl.primitives.createCubeBufferInfo(gl, 2),
twgl.primitives.createSphereBufferInfo(gl, 1, 24, 12),
twgl.primitives.createPlaneBufferInfo(gl, 2, 2),
twgl.primitives.createTruncatedConeBufferInfo(gl, 1, 0, 2, 24, 1),
];
function rand(min, max) {
if (max === undefined) {
max = min;
min = 0;
}
return min + Math.random() * (max - min);
}
// Shared values
var baseHue = rand(360);
var lightWorldPosition = [1, 8, -10];
var lightColor = [1, 1, 1, 1];
var camera = m4.identity();
var view = m4.identity();
var viewProjection = m4.identity();
// A circle on a canvas
var ctx = document.createElement("canvas").getContext("2d");
ctx.canvas.width = 64;
ctx.canvas.height = 64;
function updateCanvas(time) {
ctx.fillStyle = "#00f";
ctx.strokeStyle = "#ff0";
ctx.lineWidth = "10";
ctx.fillRect(0, 0, ctx.canvas.width, ctx.canvas.height);
ctx.beginPath();
ctx.arc(ctx.canvas.width / 2, ctx.canvas.height / 2, ctx.canvas.width / 2.2 * Math.abs(Math.cos(time)), 0, Math.PI * 2);
ctx.stroke();
}
updateCanvas(0);
// A cubemap drawn to a canvas with a circle on each face.
var cubemapCtx = document.createElement("canvas").getContext("2d");
var size = 40;
cubemapCtx.canvas.width = size * 6;
cubemapCtx.canvas.height = size;
cubemapCtx.fillStyle = "#888";
for (var ff = 0; ff < 6; ++ff) {
var color = chroma.hsv((baseHue + ff * 10) % 360, 1 - ff / 6, 1);
cubemapCtx.fillStyle = color.darken().hex();
cubemapCtx.fillRect(size * ff, 0, size, size);
cubemapCtx.save();
cubemapCtx.translate(size * (ff + 0.5), size * 0.5);
cubemapCtx.beginPath();
cubemapCtx.arc(0, 0, size * 0.3, 0, Math.PI * 2);
cubemapCtx.fillStyle = color.hex();
cubemapCtx.fill();
cubemapCtx.restore();
}
var textures = twgl.createTextures(gl, {
// a power of 2 image
hftIcon: { src: "images/hft-icon-16.png", mag: gl.NEAREST },
// a non-power of 2 image
clover: { src: "images/clover.jpg" },
// From a canvas
fromCanvas: { src: ctx.canvas },
// A cubemap from 6 images
yokohama: {
target: gl.TEXTURE_CUBE_MAP,
src: [
'images/yokohama/posx.jpg',
'images/yokohama/negx.jpg',
'images/yokohama/posy.jpg',
'images/yokohama/negy.jpg',
'images/yokohama/posz.jpg',
'images/yokohama/negz.jpg',
],
},
// A cubemap from 1 image (can be 1x6, 2x3, 3x2, 6x1)
goldengate: {
target: gl.TEXTURE_CUBE_MAP,
src: 'images/goldengate.jpg',
},
// A 2x2 pixel texture from a JavaScript array
checker: {
mag: gl.NEAREST,
min: gl.LINEAR,
src: [
255, 255, 255, 255,
192, 192, 192, 255,
192, 192, 192, 255,
255, 255, 255, 255,
],
},
// a 1x8 pixel texture from a typed array.
stripe: {
mag: gl.NEAREST,
min: gl.LINEAR,
format: gl.LUMINANCE,
src: new Uint8Array([
255,
128,
255,
128,
255,
128,
255,
128,
]),
width: 1,
},
// a cubemap from array
cubemapFromArray: {
target: gl.TEXTURE_CUBE_MAP,
format: gl.LUMINANCE,
src: [
0xF0,
0xE0,
0xD0,
0xC0,
0xB0,
0xA0,
],
},
cubemapFromCanvas: { target: gl.TEXTURE_CUBE_MAP, src: cubemapCtx.canvas },
});
// This is soley to make it easy to pick textures at random
var twoDTextures = [
textures.checker,
textures.stripe,
textures.hftIcon,
textures.clover,
textures.fromCanvas,
];
var cubeTextures = [
textures.yokohama,
textures.goldengate,
textures.cubemapFromCanvas,
textures.cubemapFromArray,
];
var objects = [];
var drawObjects = [];
var numObjects = 100;
for (var ii = 0; ii < numObjects; ++ii) {
var uniforms;
var programInfo;
var shape;
var renderType = rand(0, 2) | 0;
switch (renderType) {
case 0: // checker
shape = shapes[ii % shapes.length];
programInfo = onePointProgramInfo;
uniforms = {
u_lightWorldPos: lightWorldPosition,
u_lightColor: lightColor,
u_diffuseMult: chroma.hsv((baseHue + rand(0, 60)) % 360, 0.4, 0.8).gl(),
u_specular: [1, 1, 1, 1],
u_shininess: 50,
u_specularFactor: 1,
u_diffuse: twoDTextures[rand(0, twoDTextures.length) | 0],
u_viewInverse: camera,
u_world: m4.identity(),
u_worldInverseTranspose: m4.identity(),
u_worldViewProjection: m4.identity(),
};
break;
case 1: // yokohama
shape = rand(0, 2) < 1 ? shapes[1] : shapes[3];
programInfo = envMapProgramInfo;
uniforms = {
u_texture: cubeTextures[rand(0, cubeTextures.length) | 0],
u_viewInverse: camera,
u_world: m4.identity(),
u_worldInverseTranspose: m4.identity(),
u_worldViewProjection: m4.identity(),
};
break;
default:
throw "wAT!";
}
drawObjects.push({
programInfo: programInfo,
bufferInfo: shape,
uniforms: uniforms,
});
objects.push({
translation: [rand(-10, 10), rand(-10, 10), rand(-10, 10)],
ySpeed: rand(0.1, 0.3),
zSpeed: rand(0.1, 0.3),
uniforms: uniforms,
});
}
function render(time) {
time *= 0.001;
twgl.resizeCanvasToDisplaySize(gl.canvas);
gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);
gl.enable(gl.DEPTH_TEST);
gl.enable(gl.BLEND);
gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
var radius = 20;
var orbitSpeed = time * 0.1;
var projection = m4.perspective(30 * Math.PI / 180, gl.canvas.clientWidth / gl.canvas.clientHeight, 0.5, 100);
var eye = [Math.cos(orbitSpeed) * radius, 4, Math.sin(orbitSpeed) * radius];
var target = [0, 0, 0];
var up = [0, 1, 0];
m4.lookAt(eye, target, up, camera);
m4.inverse(camera, view);
m4.multiply(view, projection, viewProjection);
updateCanvas(time);
twgl.setTextureFromElement(gl, textures.fromCanvas, ctx.canvas);
objects.forEach(function(obj) {
var uni = obj.uniforms;
var world = uni.u_world;
m4.identity(world);
m4.rotateY(world, time * obj.ySpeed, world);
m4.rotateZ(world, time * obj.zSpeed, world);
m4.translate(world, obj.translation, world);
m4.rotateX(world, time, world);
m4.transpose(m4.inverse(world, uni.u_worldInverseTranspose), uni.u_worldInverseTranspose);
m4.multiply(uni.u_world, viewProjection, uni.u_worldViewProjection);
});
twgl.drawObjectList(gl, drawObjects);
requestAnimationFrame(render);
}
requestAnimationFrame(render);
</script>
</html>