You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
dummy/js/shader/shader-active.js

257 lines
7.4 KiB

6 months ago
var flatSurface = $('#surface-shader');
if (flatSurface.length) {
var MESH = {
width: 1.2,
height: 1.2,
depth: 0,
segments: 16,
slices: 8,
xRange: 0.8,
yRange: 0.1,
zRange: 1.0,
ambient: '#555555',
diffuse: '#ffffff',
speed: 0.002
};
var LIGHT = {
count: 2,
xyScalar: 1,
zOffset: 100,
ambient: flatSurface.data('ambient-color'),
diffuse: flatSurface.data('diffuse-color'),
speed: 0.002,
gravity: 500,
dampening: 0.95,
minLimit: 10,
maxLimit: null,
minDistance: 20,
maxDistance: 800,
autopilot: true,
draw: false,
bounds: FSS.Vector3.create(),
step: FSS.Vector3.create(
Math.randomInRange(0.2, 1.0),
Math.randomInRange(0.2, 1.0),
Math.randomInRange(0.2, 1.0)
)
};
var RENDER = {
renderer: 'canvas'
};
var now, start = Date.now();
var center = FSS.Vector3.create();
var attractor = FSS.Vector3.create();
var containerFSS = flatSurface[0];
var output = flatSurface[0];
var rendererFSS, sceneFSS, mesh, geometry, material;
var canvasRenderer;
}
function initialise() {
createRenderer();
createScene();
createMesh();
createLights();
addEventListeners();
resize(containerFSS.offsetWidth, containerFSS.offsetHeight);
animateFSS();
}
function createRenderer() {
canvasRenderer = new FSS.CanvasRenderer();
setRenderer(RENDER.renderer);
}
function setRenderer() {
if (rendererFSS) {
output.removeChild(rendererFSS.element);
}
rendererFSS = canvasRenderer;
rendererFSS.setSize(containerFSS.offsetWidth, containerFSS.offsetHeight);
output.appendChild(rendererFSS.element);
}
function createScene() {
sceneFSS = new FSS.Scene();
}
function createMesh() {
sceneFSS.remove(mesh);
rendererFSS.clear();
geometry = new FSS.Plane(MESH.width * rendererFSS.width, MESH.height * rendererFSS.height, MESH.segments, MESH.slices);
material = new FSS.Material(MESH.ambient, MESH.diffuse);
mesh = new FSS.Mesh(geometry, material);
sceneFSS.add(mesh);
// Augment vertices for animation
var v, vertex;
for (v = geometry.vertices.length - 1; v >= 0; v--) {
vertex = geometry.vertices[v];
vertex.anchor = FSS.Vector3.clone(vertex.position);
vertex.step = FSS.Vector3.create(
Math.randomInRange(0.2, 1.0),
Math.randomInRange(0.2, 1.0),
Math.randomInRange(0.2, 1.0)
);
vertex.time = Math.randomInRange(0, Math.PIM2);
}
}
function createLights() {
var l, light;
for (l = sceneFSS.lights.length - 1; l >= 0; l--) {
light = sceneFSS.lights[l];
sceneFSS.remove(light);
}
rendererFSS.clear();
for (l = 0; l < LIGHT.count; l++) {
light = new FSS.Light(LIGHT.ambient, LIGHT.diffuse);
light.ambientHex = light.ambient.format();
light.diffuseHex = light.diffuse.format();
sceneFSS.add(light);
// Augment light for animation
light.mass = Math.randomInRange(0.5, 1);
light.velocity = FSS.Vector3.create();
light.acceleration = FSS.Vector3.create();
light.force = FSS.Vector3.create();
// Ring SVG Circle
light.ring = document.createElementNS(FSS.SVGNS, 'circle');
light.ring.setAttributeNS(null, 'stroke', light.ambientHex);
light.ring.setAttributeNS(null, 'stroke-width', '0.5');
light.ring.setAttributeNS(null, 'fill', 'none');
light.ring.setAttributeNS(null, 'r', '10');
// Core SVG Circle
light.core = document.createElementNS(FSS.SVGNS, 'circle');
light.core.setAttributeNS(null, 'fill', light.diffuseHex);
light.core.setAttributeNS(null, 'r', '4');
}
}
function resize(width, height) {
rendererFSS.setSize(width, height);
FSS.Vector3.set(center, rendererFSS.halfWidth, rendererFSS.halfHeight);
createMesh();
}
function animateFSS() {
now = Date.now() - start;
update();
renderFSS();
requestAnimationFrame(animateFSS);
}
function update() {
var ox, oy, oz, l, light, v, vertex, offset = MESH.depth / 2;
// Update Bounds
FSS.Vector3.copy(LIGHT.bounds, center);
FSS.Vector3.multiplyScalar(LIGHT.bounds, LIGHT.xyScalar);
// Update Attractor
FSS.Vector3.setZ(attractor, LIGHT.zOffset);
// Overwrite the Attractor position
if (LIGHT.autopilot) {
ox = Math.sin(LIGHT.step[0] * now * LIGHT.speed);
oy = Math.cos(LIGHT.step[1] * now * LIGHT.speed);
FSS.Vector3.set(attractor,
LIGHT.bounds[0] * ox,
LIGHT.bounds[1] * oy,
LIGHT.zOffset);
}
// Animate Lights
for (l = sceneFSS.lights.length - 1; l >= 0; l--) {
light = sceneFSS.lights[l];
// Reset the z position of the light
FSS.Vector3.setZ(light.position, LIGHT.zOffset);
// Calculate the force Luke!
var D = Math.clamp(FSS.Vector3.distanceSquared(light.position, attractor), LIGHT.minDistance, LIGHT.maxDistance);
var F = LIGHT.gravity * light.mass / D;
FSS.Vector3.subtractVectors(light.force, attractor, light.position);
FSS.Vector3.normalise(light.force);
FSS.Vector3.multiplyScalar(light.force, F);
// Update the light position
FSS.Vector3.set(light.acceleration);
FSS.Vector3.add(light.acceleration, light.force);
FSS.Vector3.add(light.velocity, light.acceleration);
FSS.Vector3.multiplyScalar(light.velocity, LIGHT.dampening);
FSS.Vector3.limit(light.velocity, LIGHT.minLimit, LIGHT.maxLimit);
FSS.Vector3.add(light.position, light.velocity);
}
// Animate Vertices
for (v = geometry.vertices.length - 1; v >= 0; v--) {
vertex = geometry.vertices[v];
ox = Math.sin(vertex.time + vertex.step[0] * now * MESH.speed);
oy = Math.cos(vertex.time + vertex.step[1] * now * MESH.speed);
oz = Math.sin(vertex.time + vertex.step[2] * now * MESH.speed);
FSS.Vector3.set(vertex.position,
MESH.xRange * geometry.segmentWidth * ox,
MESH.yRange * geometry.sliceHeight * oy,
MESH.zRange * offset * oz - offset);
FSS.Vector3.add(vertex.position, vertex.anchor);
}
// Set the Geometry to dirty
geometry.dirty = true;
}
function renderFSS() {
rendererFSS.render(sceneFSS);
// Draw Lights
if (LIGHT.draw) {
var l, lx, ly, light;
for (l = sceneFSS.lights.length - 1; l >= 0; l--) {
light = sceneFSS.lights[l];
lx = light.position[0];
ly = light.position[1];
rendererFSS.context.lineWidth = 0.5;
rendererFSS.context.beginPath();
rendererFSS.context.arc(lx, ly, 10, 0, Math.PIM2);
rendererFSS.context.strokeStyle = light.ambientHex;
rendererFSS.context.stroke();
rendererFSS.context.beginPath();
rendererFSS.context.arc(lx, ly, 4, 0, Math.PIM2);
rendererFSS.context.fillStyle = light.diffuseHex;
rendererFSS.context.fill();
}
}
}
function addEventListeners() {
window.addEventListener('resize', onWindowResizFSS);
}
// Callbacks
function onWindowResizFSS() {
resize(containerFSS.offsetWidth, containerFSS.offsetHeight);
renderFSS();
}
// Init
if (flatSurface.length) {
initialise();
}