xxxxxxxxxx
405
let defaultColor;
let defaultNormal;
let defaultAOSD;
let depthTestNoShine;
let depthTestFullShine;
let shineTest;
let block0;
let block0AOSD;
let block1;
let normalSphere;
let swordAndShieldColor;
let swordAndShieldNormal;
let swordAndShieldAOSD;
let swordAndShieldLorgeColor;
let swordAndShieldLorgeNormal;
let tetrisColor;
let tetrisNormal;
let tetrisAOSD;
let phong;
let canvasW;
let canvasH;
let halfW;
let halfH;
let drawDot = false;
let objX = 0;
let objY = 0;
let objZ = 0;
let scaleX = 1;
let scaleY = 1;
let currentColor;
let currentNormal;
let currentAOSD;
let defaultZoom = 8;
let zoom = defaultZoom;
let minZoom = 0.25;
let maxZoom = 64.0;
let zoomChange = 0.025;
let useDirectionalLight = true;
let directionalLightX = 11;
let directionalLightY = 121;
let directionalLightZ = -100;
class LightInputData
{
constructor(x, y, z, r, g, b, fa, fb, fc)
{
this.x = x; this.y = y; this.z = z;
this.r = r; this.g = g; this.b = b;
this.fa = fa; this.fb = fb; this.fc = fc;
}
get WorldPosArray() { return [this.x, this.y, this.z]; }
get ColorArray() { return [this.r, this.g, this.b]; }
get FalloffArray() { return [this.fa, this.fb, this.fc]; }
SetWorldPos(x, y, z) { this.x = x; this.y = y; this.z = z; }
SetColor(r, g, b) { this.r = r; this.g = g; this.b = b; }
SetFalloff(fa, fb, fc) { this.fa = fa; this.fb = fb; this.fc = fc; }
}
let pointLights = [];
let mainBuffer;
let post;
let eightBitSquare;
let useTextify = false;
let usePointLightRotation = true;
let usePointLights = true;
let useColor = true;
let useNormal = true;
let useAO = true;
let useSpecular = true;
let useDepth = true;
let useInterpolation = true;
let linear;
let nearestNeighbor;
let objW;
let objH;
function preload()
{
defaultColor = loadImage("defaultColor.png");
defaultNormal = loadImage("defaultNormal.png");
defaultAOSD = loadImage("defaultAOSD.png");
depthTestNoShine = loadImage("depthTestNoShine.png");
depthTestFullShine = loadImage("depthTestFullShine.png");
shineTest = loadImage("shineTest.png");
block0 = loadImage("block0.png");
block0AOSD = loadImage("block0AOSD.png");
block1 = loadImage("block1.png");
normalSphere = loadImage("normalSphere.png");
swordAndShieldColor = loadImage("SwordAndShieldColor.png");
swordAndShieldNormal = loadImage("SwordAndShieldNormal.png");
swordAndShieldAOSD = loadImage("SwordAndShieldAOSD.png");
swordAndShieldLorgeColor = loadImage("SwordAndShieldLorgeColor.png");
swordAndShieldLorgeNormal = loadImage("SwordAndShieldLorgeNormal.png");
tetrisColor = loadImage("TetrisColor.png");
tetrisNormal = loadImage("TetrisNormal.png");
tetrisAOSD = loadImage("TetrisAOSD.png");
phong = loadShader("Basic.vert", "Phong.frag");
post = loadShader("FullQuad.vert", "Textify.frag");
eightBitSquare = loadImage("EightBitSquare.png");
currentColor = swordAndShieldColor;
currentNormal = swordAndShieldNormal;
currentAOSD = swordAndShieldAOSD;
}
function setup()
{
canvasW = windowWidth;
canvasH = windowHeight;
halfW = canvasW / 2;
halfH = canvasH / 2;
createCanvas(canvasW, canvasH, WEBGL);
objW = currentColor.width;
objH = currentColor.height;
mainBuffer = createGraphics(canvasW, canvasH, WEBGL);
mainBuffer.fill(255);
mainBuffer.noStroke();
mainBuffer.rectMode(CENTER);
let lightCount = 8;
let radius = 200;
angleMode(DEGREES);
colorMode(HSB, 1.0);
let dAngle = 360 / lightCount;
let initialAngle = 0;
for (let i = 0; i < lightCount; ++i)
{
let angle = initialAngle + i * dAngle;
let x = radius * cos(angle);
let y = radius * sin(angle);
let z = 10;
let h = angle / 360.0;
let s = 0.8;
let v = 0.6;
let c = color(h, s, v, 1.0);
let r = red(c) / 255.0;
let g = green(c) / 255.0;
let b = blue(c) / 255.0;
let pl = new LightInputData();
pl.SetWorldPos(x, y, z);
pl.SetColor(r, g, b);
pl.SetFalloff(1, 0, 0);
pointLights.push(pl);
}
colorMode(RGB, 255);
}
function draw()
{
background(0);
mainBuffer.clear();
mainBuffer.push();
let change = 0.0;
if (keyIsDown(88))
change += zoomChange;
if (keyIsDown(90))
change -= zoomChange;
zoom = constrain(zoom * (1 + change), minZoom, maxZoom);
let dX = 0;
let dY = 0;
if (keyIsDown(RIGHT_ARROW))
dX += 1;
if (keyIsDown(LEFT_ARROW))
dX -= 1;
if (keyIsDown(DOWN_ARROW))
dY += 1;
if (keyIsDown(UP_ARROW))
dY -= 1;
objX += dX * (((zoom - 1) * 0.1) + 1);
objY += dY * (((zoom - 1) * 0.1) + 1);
if (keyIsDown(SHIFT) && mouseIsPressed && mouseButton === LEFT)
{
directionalLightX = halfW - mouseX;
directionalLightY = halfH - mouseY;
}
mainBuffer.shader(phong);
let totalWidth = objW * zoom * scaleX;
let totalHeight = objH * zoom * scaleY;
phong.setUniform("uSourceSize", [objW, objH]);
phong.setUniform("uLightingSize", [totalWidth, totalHeight]);
phong.setUniform("uColorMap", currentColor);
phong.setUniform("uNormalMap", currentNormal);
phong.setUniform("uAOSDMap", currentAOSD);
phong.setUniform("uEmissionColor", [0.0, 0.0, 0.0]);
phong.setUniform("uAmbiemtColor", [0.2, 0.15, 0.6]);
phong.setUniform("uUseDirectionalLight", useDirectionalLight);
phong.setUniform("uDirectionalLightDirection", [directionalLightX, directionalLightY, directionalLightZ]);
phong.setUniform("uDirectionalLightColor", [1.0, 1.0, 1.0]);
phong.setUniform("uUseColor", useColor);
phong.setUniform("uUseNormal", useNormal);
phong.setUniform("uUseAO", useAO);
phong.setUniform("uUseSpecular", useSpecular);
phong.setUniform("uUseDepth", useDepth);
phong.setUniform("uUseInterpolation", useInterpolation);
let pointLightCount = pointLights.length;
if (!usePointLights)
pointLightCount = 0;
phong.setUniform("uPoimtLightCount", pointLightCount);
for (let i = 0; i < pointLightCount; ++i)
{
let pointLight = pointLights[i];
phong.setUniform(`uPointLights[${i}].worldPos`, pointLight.WorldPosArray);
phong.setUniform(`uPointLights[${i}].color`, pointLight.ColorArray);
phong.setUniform(`uPointLights[${i}].falloff`, pointLight.FalloffArray);
}
phong.setUniform("uKA", 0.3);
phong.setUniform("uKD", 1.0);
phong.setUniform("uKS", 1.0);
phong.setUniform("uDepthScale", 10.0);
phong.setUniform("uObjectWorldPos", [objX, objY, objZ]);
mainBuffer.rect(objX, objY, totalWidth, totalHeight);
if (useTextify)
shader(post);
post.setUniform("uSource", mainBuffer);
post.setUniform("uTileAtlas", eightBitSquare);
post.setUniform("uSourceSize", [canvasW, canvasH]);
post.setUniform("uAtlasSize", [eightBitSquare.width, eightBitSquare.height]);
post.setUniform("uTileSize", [8, 8]);
post.setUniform("uTileIndexMin", 7);
post.setUniform("uBackgroundColor", [0, 0, 0]);
if (useTextify)
rect(0, 0, 0, 0);
else
image(mainBuffer, -canvasW / 2, -canvasH / 2);
if (usePointLightRotation)
RotatePointLights();
mainBuffer.pop();
}
function keyPressed()
{
switch (keyCode)
{
case 77: // M
PrintDirectionalLightData();
break;
case 32: // Spacebar
ToggleDirectionalLight();
break;
case 84: // T for textify
ToggleTextify();
break;
case 82: // R for rotate
TogglePointLightRotation();
break;
case 81: // Q for quit? Not really clear :(
ResetZoom();
break;
case 80: // P for point lights
TogglePointLights();
break;
case 67: // C for Catwoman
ToggleColor();
break;
case 78: // N for normal
ToggleNormal();
break;
case 65: // A for ambient occlusion
ToggleAO();
break;
case 83: // S for specular
ToggleSpecular();
break;
case 68: // D for depth
ToggleDepth();
break;
case 73: // I for interpolation
ToggleInterpolation();
break;
}
}
function RotatePointLights()
{
let rotationSpeed = 30;
let dAngle = rotationSpeed * deltaTime / 1000;
for (const pl of pointLights)
{
let x = pl.x;
let y = pl.y;
let r = sqrt(x * x + y * y);
let angle = atan2(y, x) + dAngle;
pl.x = r * cos(angle);
pl.y = r * sin(angle);
}
}
function PrintDirectionalLightData()
{
print(directionalLightX, directionalLightY, directionalLightZ);
}
function ResetZoom()
{
zoom = defaultZoom;
}
function ToggleDirectionalLight()
{
useDirectionalLight = !useDirectionalLight;
print(`Directional light ${useDirectionalLight ? "en" : "dis"}abled`);
}
function ToggleTextify()
{
useTextify = !useTextify;
print(`Textify ${useTextify ? "en" : "dis"}abled`);
}
function TogglePointLightRotation()
{
usePointLightRotation = !usePointLightRotation;
print(`Point light rotation ${usePointLightRotation ? "en" : "dis"}abled`);
}
function TogglePointLights()
{
usePointLights = !usePointLights;
print(`Point lights ${usePointLights ? "en" : "dis"}abled`);
}
function ToggleColor()
{
useColor = !useColor;
print(`Color mapping ${useColor ? "en" : "dis"}abled`);
}
function ToggleNormal()
{
useNormal = !useNormal;
print(`Normal mapping ${useNormal ? "en" : "dis"}abled`);
}
function ToggleAO()
{
useAO = !useAO;
print(`Ambient occlusion mapping ${useAO ? "en" : "dis"}abled`);
}
function ToggleSpecular()
{
useSpecular = !useSpecular;
print(`Specular mapping ${useSpecular ? "en" : "dis"}abled`);
}
function ToggleDepth()
{
useDepth = !useDepth;
print(`Depth mapping ${useDepth ? "en" : "dis"}abled`);
}
function ToggleInterpolation()
{
useInterpolation = !useInterpolation;
print(`Interpolation ${useInterpolation ? "en" : "dis"}abled`);
}