Add param panel to control lighting

This commit is contained in:
Paul Mathieu 2021-12-12 11:36:47 -08:00
parent 5175232b6d
commit 9a859ac6c2
2 changed files with 94 additions and 4 deletions

View File

@ -3,11 +3,68 @@
<head> <head>
<title>WebMinecraft</title> <title>WebMinecraft</title>
<script src="app.js"></script> <script src="app.js"></script>
<style>
body {
font-family: "Google Sans Text", Arial, Helvetica, sans-serif;
}
.params {
background-color: cadetblue;
width: fit-content;
}
.collapsible {
padding: 8px;
cursor: pointer;
border: none;
text-align: left;
width: 100%;
font-size: medium;
}
.paramContent {
display: flex;
overflow-y: hidden;
height: 0px;
}
.paramPanel {
padding: 10px;
background-color: #eeeeee;
}
</style>
</head> </head>
<body> <body>
<canvas id="game" width="1024" height="768"></canvas> <canvas id="game" width="1024" height="768"></canvas>
<div id="fps"></div> <div id="fps"></div>
<div class="params">
<button class="collapsible">Parameters</button>
<div class="paramContent">
<div class="paramPanel">
<h3>Light direction</h3>
<p>
x:
<input type="range" min="-100" max="100" value="50" class="slider" id="lightx" />
</p>
<p>
y:
<input type="range" min="-100" max="100" value="50" class="slider" id="lighty" />
</p>
<p>
z:
<input type="range" min="-100" max="100" value="50" class="slider" id="lightz" />
</p>
<p>
<div id="lightDirVec"></div>
</p>
</div>
<div class="paramPanel">
<h3>Ambiant light</h3>
<p>
<input type="range" min="0" max="100" value="50" class="slider" id="ambiant" />
</p>
</div>
</div>
</div>
</body> </body>
</html> </html>

View File

@ -10,6 +10,8 @@ attribute vec2 aTextureCoord;
uniform mat4 uProjection; uniform mat4 uProjection;
uniform mat4 uModel; uniform mat4 uModel;
uniform mat4 uView; uniform mat4 uView;
uniform vec3 uLightDirection;
uniform float uAmbiantLight;
varying highp vec2 vTextureCoord; varying highp vec2 vTextureCoord;
varying lowp vec3 vLighting; varying lowp vec3 vLighting;
@ -20,10 +22,9 @@ void main() {
gl_Position = uProjection * modelview * vec4(aPosition, 1.0); gl_Position = uProjection * modelview * vec4(aPosition, 1.0);
lowp vec3 normal = mat3(modelview) * aNormal; lowp vec3 normal = mat3(uModel) * aNormal;
lowp vec3 lightDirection = - normalize(mat3(uView) * vec3(1.0, -0.3, -0.8)); lowp float diffuseAmount = max(dot(-uLightDirection, normal), 0.0);
lowp float diffuseAmount = max(dot(lightDirection, normal), 0.0); lowp vec3 ambiant = uAmbiantLight * vec3(1.0, 1.0, 0.9);
lowp vec3 ambiant = 0.4 * vec3(1.0, 1.0, 0.9);
vLighting = ambiant + vec3(1.0, 1.0, 1.0) * diffuseAmount; vLighting = ambiant + vec3(1.0, 1.0, 1.0) * diffuseAmount;
vTextureCoord = aTextureCoord; vTextureCoord = aTextureCoord;
@ -76,6 +77,8 @@ function draw(gl, params, objects) {
const projLoc = gl.getUniformLocation(program, 'uProjection'); const projLoc = gl.getUniformLocation(program, 'uProjection');
const samplerLoc = gl.getUniformLocation(program, 'uSampler'); const samplerLoc = gl.getUniformLocation(program, 'uSampler');
const fogColorLoc = gl.getUniformLocation(program, 'uFogColor'); const fogColorLoc = gl.getUniformLocation(program, 'uFogColor');
const lightDirectionLoc = gl.getUniformLocation(program, 'uLightDirection');
const ambiantLoc = gl.getUniformLocation(program, 'uAmbiantLight');
const positionLoc = gl.getAttribLocation(program, 'aPosition'); const positionLoc = gl.getAttribLocation(program, 'aPosition');
const normalLoc = gl.getAttribLocation(program, 'aNormal'); const normalLoc = gl.getAttribLocation(program, 'aNormal');
@ -90,6 +93,8 @@ function draw(gl, params, objects) {
gl.uniformMatrix4fv(modelLoc, false, new Float32Array(mvMatrix)); gl.uniformMatrix4fv(modelLoc, false, new Float32Array(mvMatrix));
gl.uniformMatrix4fv(projLoc, false, new Float32Array(params.projMatrix)); gl.uniformMatrix4fv(projLoc, false, new Float32Array(params.projMatrix));
gl.uniform3f(fogColorLoc, 0.6, 0.8, 1.0); gl.uniform3f(fogColorLoc, 0.6, 0.8, 1.0);
gl.uniform3f(lightDirectionLoc, ...params.lightDirection);
gl.uniform1f(ambiantLoc, params.ambiantLight);
gl.bindBuffer(gl.ARRAY_BUFFER, geometry.glBuffer); gl.bindBuffer(gl.ARRAY_BUFFER, geometry.glBuffer);
@ -199,6 +204,7 @@ function tick(time, gl, params) {
stuff.lastFrameTime = time; stuff.lastFrameTime = time;
document.querySelector('#fps').textContent = `${1.0 / dt} fps`; document.querySelector('#fps').textContent = `${1.0 / dt} fps`;
document.querySelector('#lightDirVec').textContent = JSON.stringify(params.lightDirection);
requestAnimationFrame(time => tick(time, gl, params)); requestAnimationFrame(time => tick(time, gl, params));
} }
@ -518,6 +524,33 @@ async function main() {
world: makeWorld(), world: makeWorld(),
texture, texture,
program, program,
lightDirection: [-0.2, -0.5, 0.4],
ambiantLight: 0.7,
}
document.querySelector('#lightx').oninput = e => {
params.lightDirection[0] = e.target.value / 100;
};
document.querySelector('#lighty').oninput = e => {
params.lightDirection[1] = e.target.value / 100;
};
document.querySelector('#lightz').oninput = e => {
params.lightDirection[2] = e.target.value / 100;
};
document.querySelector('#ambiant').oninput = e => {
params.ambiantLight = e.target.value / 100;
};
const collapsibles = document.getElementsByClassName("collapsible");
for (const collapsible of collapsibles) {
collapsible.onclick = e => {
const content = collapsible.nextElementSibling;
if (content.style.height === 'fit-content') {
content.style.height = '0px';
} else {
content.style.height = 'fit-content';
}
};
} }
canvas.onclick = e => { canvas.onclick = e => {