obj loading, lighting
This commit is contained in:
parent
e842eb3d66
commit
2525f321ee
|
@ -6,10 +6,12 @@
|
|||
<title>CG1 MDI</title>
|
||||
<script src="matrix-math.js"></script>
|
||||
<script src="shader.js"></script>
|
||||
<script src="wavefront.js"></script>
|
||||
<script src="script.js"></script>
|
||||
<style>
|
||||
:root {
|
||||
font-size: 20px;
|
||||
--padding: 10px;
|
||||
}
|
||||
|
||||
html, body {
|
||||
|
@ -44,10 +46,10 @@
|
|||
display: block;
|
||||
background-color: #181825;
|
||||
}
|
||||
#stats, #controls {
|
||||
#stats {
|
||||
position: absolute;
|
||||
top: 20px;
|
||||
padding: 20px;
|
||||
top: var(--padding);
|
||||
padding: var(--padding);
|
||||
display: block;
|
||||
border: solid 2px #11111b;
|
||||
background-color: #313244;
|
||||
|
@ -55,11 +57,7 @@
|
|||
}
|
||||
|
||||
#stats {
|
||||
right: 20px;
|
||||
}
|
||||
|
||||
#controls {
|
||||
left: 20px;
|
||||
right: var(--padding);
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
@ -69,28 +67,6 @@
|
|||
<div id="stats">
|
||||
FPS: <span id="fps"></span> - <span id="ms"></span>
|
||||
</div>
|
||||
|
||||
<div id="controls">
|
||||
<div>
|
||||
Click & Drag to move camera
|
||||
</div>
|
||||
<div>
|
||||
Scroll to zoom
|
||||
</div>
|
||||
<div>
|
||||
LookAt Matrix: <input type="range" min=0 max=1 step=0.01 value=0 id="interpolateLookAt" autocomplete="off">
|
||||
</div>
|
||||
<div>
|
||||
Projection Matrix: <input type="range" min=0 max=1 step=0.01 value=0 id="interpolateProjection" autocomplete="off" disabled="yes">
|
||||
<div style="margin-left: 20px;">Invert Z-Axis: <input type="checkbox" id="invertZAxis" checked autocomplete="off"></div>
|
||||
</div>
|
||||
<div>
|
||||
Use virtual camera: <input type="checkbox" id="displayMatricesVirtually" checked autocomplete="off">
|
||||
</div>
|
||||
<div>
|
||||
Backface Culling: <input type="checkbox" id="backfaceCulling" autocomplete="off">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -369,6 +369,18 @@ function mat4Inverse(out, m) {
|
|||
return;
|
||||
}
|
||||
|
||||
function mat4vec4Multiply(out, inMat, inVec) {
|
||||
let result = [0, 0, 0, 0];
|
||||
for (let i = 0; i < 4; i++) {
|
||||
for (let j = 0; j < 4; j++) {
|
||||
result[i] += inMat[i + j * 4] * inVec[j];
|
||||
}
|
||||
}
|
||||
out[0] = result[0];
|
||||
out[1] = result[1];
|
||||
out[2] = result[2];
|
||||
out[3] = result[3];
|
||||
}
|
||||
|
||||
/**
|
||||
* subtracts b from a, storing the result in out
|
||||
|
@ -507,4 +519,12 @@ function mat3Inverse(out, inm) {
|
|||
mat3Adjoint(result, inm);
|
||||
mat3MultiplyScalar(result, result, 1 / mat3Determinant(inm));
|
||||
mat3Copy(result, out);
|
||||
}
|
||||
|
||||
function mat3MakeNormal(out, inm) {
|
||||
let result = [];
|
||||
mat3From4(result, inm);
|
||||
mat3Inverse(result, result);
|
||||
mat3Transpose(result, result);
|
||||
mat3Copy(result, out);
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
# Blender 4.4.3
|
||||
# www.blender.org
|
||||
o Cube
|
||||
v 1.000000 1.000000 -1.000000
|
||||
v 1.000000 -1.000000 -1.000000
|
||||
v 1.000000 1.000000 1.000000
|
||||
v 1.000000 -1.000000 1.000000
|
||||
v -1.000000 1.000000 -1.000000
|
||||
v -1.000000 -1.000000 -1.000000
|
||||
v -1.000000 1.000000 1.000000
|
||||
v -1.000000 -1.000000 1.000000
|
||||
vn -0.0000 1.0000 -0.0000
|
||||
vn -0.0000 -0.0000 1.0000
|
||||
vn -1.0000 -0.0000 -0.0000
|
||||
vn -0.0000 -1.0000 -0.0000
|
||||
vn 1.0000 -0.0000 -0.0000
|
||||
vn -0.0000 -0.0000 -1.0000
|
||||
vt 1.000000 0.000000
|
||||
vt 0.000000 1.000000
|
||||
vt 0.000000 0.000000
|
||||
vt 1.000000 1.000000
|
||||
s 0
|
||||
f 5/1/1 3/2/1 1/3/1
|
||||
f 3/1/2 8/2/2 4/3/2
|
||||
f 7/1/3 6/2/3 8/3/3
|
||||
f 2/1/4 8/2/4 6/3/4
|
||||
f 1/1/5 4/2/5 2/3/5
|
||||
f 5/1/6 2/2/6 6/3/6
|
||||
f 5/1/1 7/4/1 3/2/1
|
||||
f 3/1/2 7/4/2 8/2/2
|
||||
f 7/1/3 5/4/3 6/2/3
|
||||
f 2/1/4 4/4/4 8/2/4
|
||||
f 1/1/5 3/4/5 4/2/5
|
||||
f 5/1/6 1/4/6 2/2/6
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
546
src/script.js
546
src/script.js
|
@ -3,36 +3,16 @@
|
|||
let cv, gl;
|
||||
|
||||
let program;
|
||||
let floorProgram;
|
||||
|
||||
let hVertices;
|
||||
let hVertexBuffer;
|
||||
class Object {
|
||||
vertexBuffer;
|
||||
numVertices;
|
||||
}
|
||||
|
||||
let cubeVertices;
|
||||
let cubeVertexBuffer;
|
||||
|
||||
let lineCubeVertices;
|
||||
let lineCubeVertexBuffer;
|
||||
|
||||
let originVertices;
|
||||
let originVertexBuffer;
|
||||
|
||||
let floorVertices;
|
||||
let floorVertexBuffer;
|
||||
|
||||
let cameraVertices;
|
||||
let cameraVertexBuffer;
|
||||
let o = new Object();
|
||||
|
||||
let lastFrame = Date.now();
|
||||
|
||||
let interpolateProjection = 0;
|
||||
let interpolateLookAt = 0;
|
||||
|
||||
let displayMatricesVirtually = true;
|
||||
let virtualRealInterpolation = 1;
|
||||
|
||||
let invertZAxis = true;
|
||||
|
||||
let cameraPitch = 0.565;
|
||||
let cameraYaw = 0.375;
|
||||
let cameraDistance = 4;
|
||||
|
@ -64,43 +44,6 @@ async function init() {
|
|||
|
||||
|
||||
// input handling
|
||||
document.getElementById("interpolateProjection").addEventListener("input", (e) => {
|
||||
interpolateProjection = e.target.value;
|
||||
if (interpolateProjection <= 0) {
|
||||
document.getElementById("interpolateLookAt").disabled = "";
|
||||
} else {
|
||||
document.getElementById("interpolateLookAt").disabled = "yes";
|
||||
}
|
||||
});
|
||||
document.getElementById("invertZAxis").addEventListener("input", (e) => {
|
||||
invertZAxis = e.target.checked;
|
||||
});
|
||||
document.getElementById("interpolateLookAt").addEventListener("input", (e) => {
|
||||
interpolateLookAt = e.target.value;
|
||||
if (interpolateLookAt >= 1) {
|
||||
document.getElementById("interpolateProjection").disabled = "";
|
||||
} else {
|
||||
document.getElementById("interpolateProjection").disabled = "yes";
|
||||
}
|
||||
});
|
||||
document.getElementById("displayMatricesVirtually").addEventListener("input", (e) => {
|
||||
displayMatricesVirtually = e.target.checked;
|
||||
if (!displayMatricesVirtually) {
|
||||
document.getElementById("invertZAxis").checked = true;
|
||||
document.getElementById("invertZAxis").disabled = true;
|
||||
} else {
|
||||
document.getElementById("invertZAxis").checked = invertZAxis;
|
||||
document.getElementById("invertZAxis").disabled = false;
|
||||
}
|
||||
});
|
||||
document.getElementById("backfaceCulling").addEventListener("input", (e) => {
|
||||
if (e.target.checked) {
|
||||
gl.enable(gl.CULL_FACE);
|
||||
} else {
|
||||
gl.disable(gl.CULL_FACE);
|
||||
}
|
||||
});
|
||||
|
||||
cv.addEventListener("mousedown", (e) => {
|
||||
if (e.button == 0) {
|
||||
mouseDragging = true;
|
||||
|
@ -116,7 +59,7 @@ async function init() {
|
|||
});
|
||||
|
||||
document.addEventListener("mousemove", (e) => {
|
||||
if (mouseDragging && displayMatricesVirtually) {
|
||||
if (mouseDragging) {
|
||||
cameraYaw += e.movementX / 100;
|
||||
cameraPitch += e.movementY / 100;
|
||||
|
||||
|
@ -130,303 +73,49 @@ async function init() {
|
|||
if (cameraDistance > 15) cameraDistance = 15;
|
||||
e.preventDefault();
|
||||
});
|
||||
|
||||
|
||||
// end input handling
|
||||
|
||||
console.log("compiling shaders...");
|
||||
program = await buildShaderProgram(gl, "shaders/vertex.glsl", "shaders/fragment.glsl");
|
||||
floorProgram = await buildShaderProgram(gl, "shaders/floor-vertex.glsl", "shaders/floor-fragment.glsl");
|
||||
|
||||
console.log("creating vertex buffer");
|
||||
|
||||
hVertices = [
|
||||
// X // Y
|
||||
|
||||
// left vertical bar
|
||||
-0.35, 0.6, 0.0, 1.0, 0.3, 0.3,
|
||||
-0.35, -0.6, 0.0, 1.0, 0.3, 0.3,
|
||||
-0.2, 0.6, 0.0, 1.0, 0.3, 0.3,
|
||||
let f = await readObjFile("obj/smooth_monkey.obj");
|
||||
o = new Object();
|
||||
|
||||
-0.2, 0.6, 0.0, 1.0, 0.3, 0.3,
|
||||
-0.35, -0.6, 0.0, 1.0, 0.3, 0.3,
|
||||
-0.2, -0.6, 0.0, 1.0, 0.3, 0.3,
|
||||
|
||||
// right vertical bar
|
||||
0.35, -0.6, 0.0, 1.0, 0.3, 0.3,
|
||||
0.35, 0.6, 0.0, 1.0, 0.3, 0.3,
|
||||
0.2, 0.6, 0.0, 1.0, 0.3, 0.3,
|
||||
|
||||
0.35, -0.6, 0.0, 1.0, 0.3, 0.3,
|
||||
0.2, 0.6, 0.0, 1.0, 0.3, 0.3,
|
||||
0.2, -0.6, 0.0, 1.0, 0.3, 0.3,
|
||||
|
||||
// middle bar
|
||||
-0.2, 0.1, 0.0, 1.0, 0.3, 0.3,
|
||||
-0.2, -0.1, 0.0, 1.0, 0.3, 0.3,
|
||||
0.2, 0.1, 0.0, 1.0, 0.3, 0.3,
|
||||
|
||||
0.2, 0.1, 0.0, 1.0, 0.3, 0.3,
|
||||
-0.2, -0.1, 0.0, 1.0, 0.3, 0.3,
|
||||
0.2, -0.1, 0.0, 1.0, 0.3, 0.3,
|
||||
|
||||
// bottom bar
|
||||
-0.35, -0.7, 0.0, 1.0, 0.3, 0.3,
|
||||
-0.35, -0.9, 0.0, 1.0, 0.3, 0.3,
|
||||
0.35, -0.9, 0.0, 1.0, 0.3, 0.3,
|
||||
|
||||
-0.35, -0.7, 0.0, 1.0, 0.3, 0.3,
|
||||
0.35, -0.9, 0.0, 1.0, 0.3, 0.3,
|
||||
0.35, -0.7, 0.0, 1.0, 0.3, 0.3,
|
||||
];
|
||||
|
||||
cubeVertices = [
|
||||
// Back face (red)
|
||||
-1, -1, -1, 1, 0.5, 0.5,
|
||||
-1, 1, -1, 1, 0.5, 0.5,
|
||||
1, 1, -1, 1, 0.5, 0.5,
|
||||
-1, -1, -1, 1, 0.5, 0.5,
|
||||
1, 1, -1, 1, 0.5, 0.5,
|
||||
1, -1, -1, 1, 0.5, 0.5,
|
||||
|
||||
// Front face (green)
|
||||
-1, -1, 1, 0.5, 1, 0.5,
|
||||
1, -1, 1, 0.5, 1, 0.5,
|
||||
1, 1, 1, 0.5, 1, 0.5,
|
||||
-1, -1, 1, 0.5, 1, 0.5,
|
||||
1, 1, 1, 0.5, 1, 0.5,
|
||||
-1, 1, 1, 0.5, 1, 0.5,
|
||||
|
||||
// Left face (blue)
|
||||
-1, 1, -1, 0.5, 0.5, 1,
|
||||
-1, -1, -1, 0.5, 0.5, 1,
|
||||
-1, 1, 1, 0.5, 0.5, 1,
|
||||
-1, 1, 1, 0.5, 0.5, 1,
|
||||
-1, -1, -1, 0.5, 0.5, 1,
|
||||
-1, -1, 1, 0.5, 0.5, 1,
|
||||
|
||||
// Right face (yellow)
|
||||
1, -1, -1, 1, 1, 0.5,
|
||||
1, 1, -1, 1, 1, 0.5,
|
||||
1, 1, 1, 1, 1, 0.5,
|
||||
1, -1, -1, 1, 1, 0.5,
|
||||
1, 1, 1, 1, 1, 0.5,
|
||||
1, -1, 1, 1, 1, 0.5,
|
||||
|
||||
// Top face (magenta)
|
||||
-1, 1, -1, 1, 0.5, 1,
|
||||
-1, 1, 1, 1, 0.5, 1,
|
||||
1, 1, 1, 1, 0.5, 1,
|
||||
-1, 1, -1, 1, 0.5, 1,
|
||||
1, 1, 1, 1, 0.5, 1,
|
||||
1, 1, -1, 1, 0.5, 1,
|
||||
|
||||
// Bottom face (cyan)
|
||||
-1, -1, 1, 0.5, 1, 1,
|
||||
-1, -1, -1, 0.5, 1, 1,
|
||||
1, -1, 1, 0.5, 1, 1,
|
||||
1, -1, 1, 0.5, 1, 1,
|
||||
-1, -1, -1, 0.5, 1, 1,
|
||||
1, -1, -1, 0.5, 1, 1
|
||||
];
|
||||
|
||||
lineCubeVertices = [
|
||||
1, 1, 1, 1, 0, 0,
|
||||
1, 1, -1, 1, 0, 0,
|
||||
1, 1, 1, 1, 0, 0,
|
||||
1, -1, 1, 1, 0, 0,
|
||||
1, 1, 1, 1, 0, 0,
|
||||
-1, 1, 1, 1, 0, 0,
|
||||
1, 1, -1, 1, 0, 0,
|
||||
1, -1, -1, 1, 0, 0,
|
||||
1, 1, -1, 1, 0, 0,
|
||||
-1, 1, -1, 1, 0, 0,
|
||||
1, -1, 1, 1, 0, 0,
|
||||
1, -1, -1, 1, 0, 0,
|
||||
1, -1, 1, 1, 0, 0,
|
||||
-1, -1, 1, 1, 0, 0,
|
||||
-1, 1, 1, 1, 0, 0,
|
||||
-1, 1, -1, 1, 0, 0,
|
||||
-1, 1, 1, 1, 0, 0,
|
||||
-1, -1, 1, 1, 0, 0,
|
||||
1, -1, -1, 1, 0, 0,
|
||||
-1, -1, -1, 1, 0, 0,
|
||||
-1, -1, 1, 1, 0, 0,
|
||||
-1, -1, -1, 1, 0, 0,
|
||||
-1, 1, -1, 1, 0, 0,
|
||||
-1, -1, -1, 1, 0, 0,
|
||||
];
|
||||
|
||||
originVertices = [
|
||||
0, 0, 0, 1, 0, 0,
|
||||
1, 0, 0, 1, 0, 0,
|
||||
0, 0, 0, 0, 1, 0,
|
||||
0, 1, 0, 0, 1, 0,
|
||||
0, 0, 0, 0, 0, 1,
|
||||
0, 0, 1, 0, 0, 1,
|
||||
];
|
||||
|
||||
floorVertices = [
|
||||
1, 0, 1, 0, 0, 0,
|
||||
-1, 0, -1, 0, 0, 0,
|
||||
-1, 0, 1, 0, 0, 0,
|
||||
-1, 0, -1, 0, 0, 0,
|
||||
1, 0, 1, 0, 0, 0,
|
||||
1, 0, -1, 0, 0, 0,
|
||||
];
|
||||
|
||||
cameraVertices = [
|
||||
// Cube Body (dark gray)
|
||||
// Front face
|
||||
-1, -1, 1, 0.196, 0.196, 0.196,
|
||||
1, -1, 1, 0.196, 0.196, 0.196,
|
||||
1, 1, 1, 0.196, 0.196, 0.196,
|
||||
-1, -1, 1, 0.196, 0.196, 0.196,
|
||||
1, 1, 1, 0.196, 0.196, 0.196,
|
||||
-1, 1, 1, 0.196, 0.196, 0.196,
|
||||
|
||||
// Back face
|
||||
-1, -1, -1, 0.196, 0.196, 0.196,
|
||||
1, 1, -1, 0.196, 0.196, 0.196,
|
||||
1, -1, -1, 0.196, 0.196, 0.196,
|
||||
-1, -1, -1, 0.196, 0.196, 0.196,
|
||||
-1, 1, -1, 0.196, 0.196, 0.196,
|
||||
1, 1, -1, 0.196, 0.196, 0.196,
|
||||
|
||||
// Left face
|
||||
-1, -1, -1, 0.196, 0.196, 0.196,
|
||||
-1, -1, 1, 0.196, 0.196, 0.196,
|
||||
-1, 1, 1, 0.196, 0.196, 0.196,
|
||||
-1, -1, -1, 0.196, 0.196, 0.196,
|
||||
-1, 1, 1, 0.196, 0.196, 0.196,
|
||||
-1, 1, -1, 0.196, 0.196, 0.196,
|
||||
|
||||
// Right face
|
||||
1, -1, -1, 0.196, 0.196, 0.196,
|
||||
1, 1, 1, 0.196, 0.196, 0.196,
|
||||
1, -1, 1, 0.196, 0.196, 0.196,
|
||||
1, -1, -1, 0.196, 0.196, 0.196,
|
||||
1, 1, -1, 0.196, 0.196, 0.196,
|
||||
1, 1, 1, 0.196, 0.196, 0.196,
|
||||
|
||||
// Top face
|
||||
-1, 1, -1, 0.196, 0.196, 0.196,
|
||||
-1, 1, 1, 0.196, 0.196, 0.196,
|
||||
1, 1, 1, 0.196, 0.196, 0.196,
|
||||
-1, 1, -1, 0.196, 0.196, 0.196,
|
||||
1, 1, 1, 0.196, 0.196, 0.196,
|
||||
1, 1, -1, 0.196, 0.196, 0.196,
|
||||
|
||||
// Bottom face
|
||||
-1, -1, -1, 0.196, 0.196, 0.196,
|
||||
1, -1, 1, 0.196, 0.196, 0.196,
|
||||
-1, -1, 1, 0.196, 0.196, 0.196,
|
||||
-1, -1, -1, 0.196, 0.196, 0.196,
|
||||
1, -1, -1, 0.196, 0.196, 0.196,
|
||||
1, -1, 1, 0.196, 0.196, 0.196,
|
||||
|
||||
// Lens (light gray)
|
||||
// Front face
|
||||
-0.5, -0.5, -1.6, 0.706, 0.706, 0.706,
|
||||
0.5, 0.5, -1.6, 0.706, 0.706, 0.706,
|
||||
0.5, -0.5, -1.6, 0.706, 0.706, 0.706,
|
||||
-0.5, -0.5, -1.6, 0.706, 0.706, 0.706,
|
||||
-0.5, 0.5, -1.6, 0.706, 0.706, 0.706,
|
||||
0.5, 0.5, -1.6, 0.706, 0.706, 0.706,
|
||||
|
||||
// Back face
|
||||
-0.5, -0.5, -1.0, 0.706, 0.706, 0.706,
|
||||
0.5, -0.5, -1.0, 0.706, 0.706, 0.706,
|
||||
0.5, 0.5, -1.0, 0.706, 0.706, 0.706,
|
||||
-0.5, -0.5, -1.0, 0.706, 0.706, 0.706,
|
||||
0.5, 0.5, -1.0, 0.706, 0.706, 0.706,
|
||||
-0.5, 0.5, -1.0, 0.706, 0.706, 0.706,
|
||||
|
||||
// Left face
|
||||
-0.5, 0.5, -1.6, 0.706, 0.706, 0.706,
|
||||
-0.5, -0.5, -1.0, 0.706, 0.706, 0.706,
|
||||
-0.5, 0.5, -1.0, 0.706, 0.706, 0.706,
|
||||
-0.5, -0.5, -1.6, 0.706, 0.706, 0.706,
|
||||
-0.5, -0.5, -1.0, 0.706, 0.706, 0.706,
|
||||
-0.5, 0.5, -1.6, 0.706, 0.706, 0.706,
|
||||
|
||||
// Right face
|
||||
0.5, 0.5, -1.0, 0.706, 0.706, 0.706,
|
||||
0.5, -0.5, -1.0, 0.706, 0.706, 0.706,
|
||||
0.5, 0.5, -1.6, 0.706, 0.706, 0.706,
|
||||
0.5, 0.5, -1.6, 0.706, 0.706, 0.706,
|
||||
0.5, -0.5, -1.0, 0.706, 0.706, 0.706,
|
||||
0.5, -0.5, -1.6, 0.706, 0.706, 0.706,
|
||||
|
||||
// Top face
|
||||
0.5, 0.5, -1.6, 0.706, 0.706, 0.706,
|
||||
-0.5, 0.5, -1.0, 0.706, 0.706, 0.706,
|
||||
0.5, 0.5, -1.0, 0.706, 0.706, 0.706,
|
||||
-0.5, 0.5, -1.6, 0.706, 0.706, 0.706,
|
||||
-0.5, 0.5, -1.0, 0.706, 0.706, 0.706,
|
||||
0.5, 0.5, -1.6, 0.706, 0.706, 0.706,
|
||||
|
||||
// Bottom face
|
||||
-0.5, -0.5, -1.0, 0.706, 0.706, 0.706,
|
||||
0.5, -0.5, -1.0, 0.706, 0.706, 0.706,
|
||||
0.5, -0.5, -1.6, 0.706, 0.706, 0.706,
|
||||
-0.5, -0.5, -1.0, 0.706, 0.706, 0.706,
|
||||
0.5, -0.5, -1.6, 0.706, 0.706, 0.706,
|
||||
-0.5, -0.5, -1.6, 0.706, 0.706, 0.706
|
||||
];
|
||||
|
||||
hVertexBuffer = gl.createBuffer();
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, hVertexBuffer);
|
||||
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(hVertices), gl.STATIC_DRAW);
|
||||
|
||||
cubeVertexBuffer = gl.createBuffer();
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexBuffer);
|
||||
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(cubeVertices), gl.STATIC_DRAW);
|
||||
|
||||
lineCubeVertexBuffer = gl.createBuffer();
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, lineCubeVertexBuffer);
|
||||
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(lineCubeVertices), gl.STATIC_DRAW);
|
||||
|
||||
originVertexBuffer = gl.createBuffer();
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, originVertexBuffer);
|
||||
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(originVertices), gl.STATIC_DRAW);
|
||||
|
||||
floorVertexBuffer = gl.createBuffer();
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, floorVertexBuffer);
|
||||
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(floorVertices), gl.STATIC_DRAW);
|
||||
|
||||
cameraVertexBuffer = gl.createBuffer();
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, cameraVertexBuffer);
|
||||
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(cameraVertices), gl.STATIC_DRAW);
|
||||
|
||||
// unbind buffer
|
||||
o.vertexBuffer = gl.createBuffer();
|
||||
o.numVertices = f.length / 8;
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, o.vertexBuffer);
|
||||
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(f), gl.STATIC_DRAW);
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, null);
|
||||
|
||||
|
||||
// set clear colour
|
||||
gl.clearColor(...hexToRgb("181825"), 1.0);
|
||||
|
||||
gl.enable(gl.DEPTH_TEST);
|
||||
gl.enable(gl.BLEND);
|
||||
gl.enable(gl.CULL_FACE);
|
||||
gl.frontFace(gl.CCW);
|
||||
gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
gl.enable( gl.LINE_SMOOTH );
|
||||
gl.enable( gl.POLYGON_SMOOTH );
|
||||
gl.hint( gl.LINE_SMOOTH_HINT, gl.NICEST );
|
||||
gl.hint( gl.POLYGON_SMOOTH_HINT, gl.NICEST )
|
||||
|
||||
// start drawing
|
||||
requestAnimationFrame(draw);
|
||||
}
|
||||
|
||||
function setAttribPointers() {
|
||||
let positionAttribLocation = gl.getAttribLocation(program, "vertPosition");
|
||||
let colorAttribLocation = gl.getAttribLocation(program, "vertColor");
|
||||
let normalAttribLocation = gl.getAttribLocation(program, "vertNormal");
|
||||
let textureAttribLocation = gl.getAttribLocation(program, "vertTexture");
|
||||
|
||||
gl.vertexAttribPointer(positionAttribLocation, 3, gl.FLOAT, gl.FALSE, 6 * Float32Array.BYTES_PER_ELEMENT, 0);
|
||||
gl.vertexAttribPointer(colorAttribLocation, 3, gl.FLOAT, gl.FALSE, 6 * Float32Array.BYTES_PER_ELEMENT, 3 * Float32Array.BYTES_PER_ELEMENT);
|
||||
gl.vertexAttribPointer(positionAttribLocation, 3, gl.FLOAT, gl.FALSE, 8 * Float32Array.BYTES_PER_ELEMENT, 0);
|
||||
gl.vertexAttribPointer(textureAttribLocation, 2, gl.FLOAT, gl.FALSE, 8 * Float32Array.BYTES_PER_ELEMENT, 3 * Float32Array.BYTES_PER_ELEMENT);
|
||||
gl.vertexAttribPointer(normalAttribLocation, 3, gl.FLOAT, gl.FALSE, 8 * Float32Array.BYTES_PER_ELEMENT, 5 * Float32Array.BYTES_PER_ELEMENT);
|
||||
|
||||
gl.enableVertexAttribArray(positionAttribLocation);
|
||||
gl.enableVertexAttribArray(colorAttribLocation);
|
||||
gl.enableVertexAttribArray(textureAttribLocation);
|
||||
gl.enableVertexAttribArray(normalAttribLocation);
|
||||
}
|
||||
|
||||
let frameCount = 0;
|
||||
|
@ -464,193 +153,48 @@ async function draw() {
|
|||
hue += deltaTime / 5;
|
||||
if (hue > 1) hue = 0;
|
||||
|
||||
if (displayMatricesVirtually) {
|
||||
virtualRealInterpolation = Math.min(virtualRealInterpolation + deltaTime * 2, 1);
|
||||
} else {
|
||||
virtualRealInterpolation = Math.max(virtualRealInterpolation - deltaTime * 2, 0);
|
||||
}
|
||||
|
||||
smoothCameraDistance += (cameraDistance - smoothCameraDistance) / 8;
|
||||
|
||||
updateStats(deltaTime);
|
||||
|
||||
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
|
||||
|
||||
|
||||
|
||||
let identity = [];
|
||||
mat4Identity(identity);
|
||||
|
||||
// Real Matrices
|
||||
let realProjectionMatrix = [];
|
||||
mat4BuildPerspective(realProjectionMatrix, 90.0 / 180.0 * Math.PI, cv.width / cv.height, 0.1, 30);
|
||||
let projectionMatrix = [];
|
||||
mat4BuildPerspective(projectionMatrix, 90.0 / 180.0 * Math.PI, cv.width / cv.height, 0.1, 30);
|
||||
|
||||
let realViewMatrix = [];
|
||||
let realCameraPosition = [Math.cos(cameraYaw) * smoothCameraDistance * Math.cos(cameraPitch), Math.sin(cameraPitch) * smoothCameraDistance, Math.sin(cameraYaw) * smoothCameraDistance * Math.cos(cameraPitch)];
|
||||
let realCameraLookAt = [0, 0, 0];
|
||||
let realCameraUp = [0, 1, 0];
|
||||
mat4BuildLookAt(realViewMatrix, realCameraPosition, realCameraLookAt, realCameraUp);
|
||||
let viewMatrix = [];
|
||||
let cameraPosition = [Math.cos(cameraYaw) * smoothCameraDistance * Math.cos(cameraPitch), Math.sin(cameraPitch) * smoothCameraDistance, Math.sin(cameraYaw) * smoothCameraDistance * Math.cos(cameraPitch)];
|
||||
let cameraLookAt = [0, 0, 0];
|
||||
let cameraUp = [0, 1, 0];
|
||||
mat4BuildLookAt(viewMatrix, cameraPosition, cameraLookAt, cameraUp);
|
||||
|
||||
mat4Interpolate(realProjectionMatrix, identity, realProjectionMatrix, virtualRealInterpolation * virtualRealInterpolation);
|
||||
mat4Interpolate(realViewMatrix, identity, realViewMatrix, virtualRealInterpolation);
|
||||
let normalMatrix = [];
|
||||
mat3MakeNormal(normalMatrix, viewMatrix);
|
||||
|
||||
gl.useProgram(program);
|
||||
gl.uniformMatrix4fv(gl.getUniformLocation(program, "realProjectionMatrix"), gl.FALSE, new Float32Array(realProjectionMatrix));
|
||||
gl.uniformMatrix4fv(gl.getUniformLocation(program, "realViewMatrix"), gl.FALSE, new Float32Array(realViewMatrix));
|
||||
gl.uniformMatrix4fv(gl.getUniformLocation(program, "projectionMatrix"), gl.FALSE, new Float32Array(projectionMatrix));
|
||||
gl.uniformMatrix4fv(gl.getUniformLocation(program, "modelViewMatrix"), gl.FALSE, new Float32Array(viewMatrix));
|
||||
gl.uniformMatrix3fv(gl.getUniformLocation(program, "normalMatrix"), gl.FALSE, new Float32Array(normalMatrix));
|
||||
|
||||
gl.useProgram(floorProgram);
|
||||
gl.uniformMatrix4fv(gl.getUniformLocation(floorProgram, "realProjectionMatrix"), gl.FALSE, new Float32Array(realProjectionMatrix));
|
||||
let lightPosition = [Math.cos(hue * Math.PI * 2) * 3, 2.0, Math.sin(hue * Math.PI * 2) * 3, 1.0];
|
||||
mat4vec4Multiply(lightPosition, viewMatrix, lightPosition);
|
||||
|
||||
// Virtual Matrices
|
||||
gl.useProgram(program);
|
||||
let virtualModelViewLocation = gl.getUniformLocation(program, "virtualModelViewMatrix");
|
||||
let virtualProjectionLocation = gl.getUniformLocation(program, "virtualProjectionMatrix");
|
||||
let colorOverrideLocation = gl.getUniformLocation(program, "colorOverride");
|
||||
gl.uniform3f(gl.getUniformLocation(program, "Light.position"), ...lightPosition.slice(0, 3));
|
||||
gl.uniform3f(gl.getUniformLocation(program, "Light.color"), 1, 1, 1);
|
||||
|
||||
gl.uniform3f(gl.getUniformLocation(program, "Material.ambientColor"), 0.1, 0.1, 0.1);
|
||||
gl.uniform3f(gl.getUniformLocation(program, "Material.emitColor"), 0.05, 0.05, 0.0);
|
||||
gl.uniform3f(gl.getUniformLocation(program, "Material.diffColor"), 0.7, 0.8, 0.1);
|
||||
gl.uniform3f(gl.getUniformLocation(program, "Material.specColor"), 1, 1, 0.8);
|
||||
gl.uniform1f(gl.getUniformLocation(program, "Material.shininess"), 10);
|
||||
|
||||
let virtualProjectionMatrix = [];
|
||||
mat4BuildPerspective(virtualProjectionMatrix, 90.0 / 180.0 * Math.PI, cv.width / cv.height, 0.9, 5);
|
||||
|
||||
if (!invertZAxis) {
|
||||
let zAxisFlipMatrix = [];
|
||||
mat4Identity(zAxisFlipMatrix);
|
||||
zAxisFlipMatrix[10] = -1;
|
||||
mat4Interpolate(zAxisFlipMatrix, identity, zAxisFlipMatrix, virtualRealInterpolation);
|
||||
mat4Multiply(virtualProjectionMatrix, zAxisFlipMatrix, virtualProjectionMatrix);
|
||||
}
|
||||
|
||||
let inverseVirtualProjectionMatrix = [];
|
||||
mat4Inverse(inverseVirtualProjectionMatrix, virtualProjectionMatrix);
|
||||
|
||||
let virtualViewMatrix = [];
|
||||
let virtualCameraPosition = [1.2, 1.2, 2];
|
||||
let virtualCameraLookAt = [0, 0, -1];
|
||||
let virtualCameraUp = [0, 1, 0];
|
||||
mat4BuildLookAt(virtualViewMatrix, virtualCameraPosition, virtualCameraLookAt, virtualCameraUp);
|
||||
|
||||
let inverseVirtualViewMatrix = [];
|
||||
mat4Inverse(inverseVirtualViewMatrix, virtualViewMatrix);
|
||||
|
||||
mat4Interpolate(virtualProjectionMatrix, identity, virtualProjectionMatrix, interpolateProjection);
|
||||
mat4Interpolate(virtualViewMatrix, identity, virtualViewMatrix, interpolateLookAt);
|
||||
|
||||
gl.uniformMatrix4fv(virtualProjectionLocation, gl.FALSE, new Float32Array(virtualProjectionMatrix));
|
||||
|
||||
|
||||
let modelMatrix = [];
|
||||
mat4Identity(modelMatrix);
|
||||
|
||||
let modelViewMatrix = [];
|
||||
mat4Multiply(modelViewMatrix, virtualViewMatrix, modelMatrix);
|
||||
|
||||
gl.uniformMatrix4fv(virtualModelViewLocation, gl.FALSE, new Float32Array(modelViewMatrix));
|
||||
|
||||
|
||||
// draw scene
|
||||
|
||||
// draw H
|
||||
gl.useProgram(program);
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, hVertexBuffer);
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, o.vertexBuffer);
|
||||
setAttribPointers();
|
||||
gl.drawArrays(gl.TRIANGLES, 0, hVertices.length / 6);
|
||||
|
||||
// draw line cube
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, lineCubeVertexBuffer);
|
||||
setAttribPointers();
|
||||
gl.uniform3fv(colorOverrideLocation, [1, 1, 0.5]);
|
||||
gl.drawArrays(gl.LINES, 0, lineCubeVertices.length / 6);
|
||||
gl.uniform3fv(colorOverrideLocation, [0, 0, 0]);
|
||||
|
||||
// draw solid cube 1
|
||||
let cube1ModelView = [];
|
||||
mat4Identity(cube1ModelView);
|
||||
mat4Scale(cube1ModelView, cube1ModelView, [0.3, 0.3, 0.3]);
|
||||
mat4RotateY(cube1ModelView, cube1ModelView, 0.3);
|
||||
mat4Translate(cube1ModelView, cube1ModelView, [-0.5, 0.3, -0.7]);
|
||||
mat4Multiply(cube1ModelView, virtualViewMatrix, cube1ModelView);
|
||||
|
||||
gl.uniformMatrix4fv(virtualModelViewLocation, gl.FALSE, new Float32Array(cube1ModelView));
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexBuffer);
|
||||
setAttribPointers();
|
||||
gl.drawArrays(gl.TRIANGLES, 0, cubeVertices.length / 6);
|
||||
|
||||
// draw solid cube 2
|
||||
let cube2ModelView = [];
|
||||
mat4Identity(cube2ModelView);
|
||||
mat4Scale(cube2ModelView, cube2ModelView, [0.4, 0.4, 0.4]);
|
||||
mat4RotateY(cube2ModelView, cube2ModelView, 2.6);
|
||||
mat4Translate(cube2ModelView, cube2ModelView, [1.6, 0.3, -1]);
|
||||
mat4Multiply(cube2ModelView, virtualViewMatrix, cube2ModelView);
|
||||
|
||||
gl.uniformMatrix4fv(virtualModelViewLocation, gl.FALSE, new Float32Array(cube2ModelView));
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexBuffer);
|
||||
setAttribPointers();
|
||||
gl.drawArrays(gl.TRIANGLES, 0, cubeVertices.length / 6);
|
||||
|
||||
// draw virtual camera
|
||||
let virtualCameraModelView = [];
|
||||
mat4Identity(virtualCameraModelView);
|
||||
mat4Scale(virtualCameraModelView, virtualCameraModelView, [0.1, 0.1, 0.1]);
|
||||
mat4Translate(virtualCameraModelView, virtualCameraModelView, [0, 0, 0.16]);
|
||||
|
||||
mat4Multiply(virtualCameraModelView, inverseVirtualViewMatrix, virtualCameraModelView);
|
||||
mat4Multiply(virtualCameraModelView, virtualViewMatrix, virtualCameraModelView);
|
||||
|
||||
gl.uniformMatrix4fv(virtualModelViewLocation, gl.FALSE, new Float32Array(virtualCameraModelView));
|
||||
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, cameraVertexBuffer);
|
||||
setAttribPointers();
|
||||
if (displayMatricesVirtually && interpolateProjection <= 0) {
|
||||
gl.drawArrays(gl.TRIANGLES, 0, cameraVertices.length / 6);
|
||||
}
|
||||
|
||||
let frustomModelMatrix = [];
|
||||
mat4Multiply(frustomModelMatrix, inverseVirtualViewMatrix, inverseVirtualProjectionMatrix);
|
||||
mat4Multiply(frustomModelMatrix, virtualViewMatrix, frustomModelMatrix);
|
||||
// mat4Copy(inverseVirtualProjectionMatrix, frustomModelMatrix);
|
||||
|
||||
gl.uniformMatrix4fv(virtualModelViewLocation, gl.FALSE, new Float32Array(frustomModelMatrix));
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, lineCubeVertexBuffer);
|
||||
setAttribPointers();
|
||||
gl.uniform3fv(colorOverrideLocation, [1, 0, 1]);
|
||||
gl.drawArrays(gl.LINES, 0, lineCubeVertices.length / 6);
|
||||
gl.uniform3fv(colorOverrideLocation, [0, 0, 0]);
|
||||
|
||||
|
||||
|
||||
// draw origin
|
||||
|
||||
gl.uniformMatrix4fv(virtualModelViewLocation, gl.FALSE, new Float32Array(identity));
|
||||
gl.uniformMatrix4fv(virtualProjectionLocation, gl.FALSE, new Float32Array(identity));
|
||||
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, originVertexBuffer);
|
||||
setAttribPointers();
|
||||
gl.drawArrays(gl.LINES, 0, originVertices.length / 6);
|
||||
|
||||
// draw origin cube
|
||||
|
||||
if (interpolateProjection < 1 && interpolateLookAt > 0) {
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, lineCubeVertexBuffer);
|
||||
setAttribPointers();
|
||||
gl.uniform3fv(colorOverrideLocation, [1, 0, 0]);
|
||||
gl.drawArrays(gl.LINES, 0, lineCubeVertices.length / 6);
|
||||
gl.uniform3fv(colorOverrideLocation, [0, 0, 0]);
|
||||
}
|
||||
|
||||
// draw floor
|
||||
|
||||
gl.useProgram(floorProgram);
|
||||
|
||||
let floorModelView = [];
|
||||
mat4Identity(floorModelView);
|
||||
mat4Scale(floorModelView, floorModelView, [10, 0, 10]);
|
||||
mat4Multiply(floorModelView, realViewMatrix, floorModelView);
|
||||
gl.uniformMatrix4fv(gl.getUniformLocation(floorProgram, "realModelViewMatrix"), gl.FALSE, new Float32Array(floorModelView));
|
||||
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, floorVertexBuffer);
|
||||
setAttribPointers();
|
||||
gl.drawArrays(gl.TRIANGLES, 0, floorVertices.length / 6);
|
||||
|
||||
gl.drawArrays(gl.TRIANGLES, 0, o.numVertices);
|
||||
|
||||
frameTimes.push(performance.now() - frameStart);
|
||||
lastFrame = now;
|
||||
|
|
|
@ -1,6 +0,0 @@
|
|||
precision mediump float;
|
||||
varying vec3 vPosition;
|
||||
|
||||
void main() {
|
||||
gl_FragColor = mix(vec4(1,1,1,0.5), vec4(0.8,0.8,0.8,0.5), step(0.0, sin(vPosition.x * 3.14159 * 20.0) * sin(vPosition.z * 3.14159 * 20.0)));
|
||||
}
|
|
@ -1,14 +0,0 @@
|
|||
precision mediump float;
|
||||
|
||||
attribute vec3 vertPosition;
|
||||
attribute vec3 vertColor;
|
||||
|
||||
uniform mat4 realModelViewMatrix;
|
||||
uniform mat4 realProjectionMatrix;
|
||||
|
||||
varying vec3 vPosition;
|
||||
|
||||
void main() {
|
||||
vPosition = vertPosition;
|
||||
gl_Position = realProjectionMatrix * realModelViewMatrix * vec4(vertPosition, 1.0);
|
||||
}
|
|
@ -1,6 +1,33 @@
|
|||
precision mediump float;
|
||||
varying vec3 fragColor;
|
||||
|
||||
uniform struct {
|
||||
vec3 position;
|
||||
vec3 color;
|
||||
} Light;
|
||||
|
||||
uniform struct {
|
||||
vec3 ambientColor;
|
||||
vec3 emitColor;
|
||||
vec3 diffColor;
|
||||
vec3 specColor;
|
||||
float shininess;
|
||||
} Material;
|
||||
|
||||
varying vec3 vNormal;
|
||||
varying vec2 vTexture;
|
||||
varying vec3 vPosition;
|
||||
|
||||
void main() {
|
||||
gl_FragColor = vec4(fragColor, 1.0);
|
||||
vec3 pleaseDontDeleteMe = vec3(vTexture, 0.0);
|
||||
|
||||
vec3 eyeDir = normalize(-vPosition);
|
||||
vec3 lightDir = normalize(Light.position - vPosition);
|
||||
vec3 r = reflect(-lightDir, vNormal);
|
||||
|
||||
vec3 ambient = Material.ambientColor;
|
||||
vec3 emit = Material.emitColor;
|
||||
vec3 diff = max(dot(lightDir, vNormal), 0.0) * Material.diffColor * Light.color;
|
||||
vec3 spec = pow(max(dot(r, eyeDir), 0.0), Material.shininess) * Material.specColor * Light.color;
|
||||
|
||||
gl_FragColor = vec4(ambient + emit + diff + spec, 1);
|
||||
}
|
|
@ -1,21 +1,21 @@
|
|||
precision mediump float;
|
||||
|
||||
attribute vec3 vertPosition;
|
||||
attribute vec3 vertColor;
|
||||
attribute vec3 vertNormal;
|
||||
attribute vec2 vertTexture;
|
||||
|
||||
uniform mat4 virtualModelViewMatrix;
|
||||
uniform mat4 virtualProjectionMatrix;
|
||||
uniform mat4 modelViewMatrix;
|
||||
uniform mat4 projectionMatrix;
|
||||
uniform mat3 normalMatrix;
|
||||
|
||||
uniform mat4 realViewMatrix;
|
||||
uniform mat4 realProjectionMatrix;
|
||||
|
||||
uniform vec3 colorOverride;
|
||||
|
||||
varying vec3 fragColor;
|
||||
varying vec3 vNormal;
|
||||
varying vec2 vTexture;
|
||||
varying vec3 vPosition;
|
||||
|
||||
void main() {
|
||||
float colorOverrideActive = step(0.001, length(colorOverride));
|
||||
fragColor = colorOverride * colorOverrideActive + vertColor * (1.0 - colorOverrideActive);
|
||||
vNormal = normalize(normalMatrix * vertNormal);
|
||||
vTexture = vertTexture;
|
||||
vPosition = (modelViewMatrix * vec4(vertPosition, 1.0)).xyz;
|
||||
|
||||
gl_Position = realProjectionMatrix * realViewMatrix * virtualProjectionMatrix * virtualModelViewMatrix * vec4(vertPosition, 1.0);
|
||||
gl_Position = projectionMatrix * modelViewMatrix * vec4(vertPosition, 1.0);
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
async function readObjFile(path) {
|
||||
const res = await fetch(path);
|
||||
const text = await res.text();
|
||||
|
||||
let vertices = [];
|
||||
let textures = [];
|
||||
let normals = [];
|
||||
|
||||
let result = [];
|
||||
|
||||
const lines = text.replace("\r","").split("\n");
|
||||
|
||||
for (let line of lines) {
|
||||
const parts = line.split(/\s+/);
|
||||
|
||||
switch (parts[0]) {
|
||||
case "v":
|
||||
vertices.push(parts.slice(1, 4).map(parseFloat));
|
||||
break;
|
||||
case "vt":
|
||||
textures.push(parts.slice(1, 3).map(parseFloat));
|
||||
break;
|
||||
case "vn":
|
||||
normals.push(parts.slice(1, 4).map(parseFloat));
|
||||
break;
|
||||
case "f":
|
||||
for (const part of parts.slice(1, 4)) {
|
||||
const [v, vt, vn] = part.split("/").map((i) => parseInt(i) - 1);
|
||||
result.push(...vertices[v], ...textures[vt], ...normals[vn]);
|
||||
}
|
||||
|
||||
// support for quads:
|
||||
if (parts.length > 4) {
|
||||
for (let i of [1, 3, 4]) {
|
||||
const part = parts[i];
|
||||
const [v, vt, vn] = part.split("/").map((i) => parseInt(i) - 1);
|
||||
result.push(...vertices[v], ...textures[vt], ...normals[vn]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
Loading…
Reference in New Issue