Added interaction, more descriptions.

But fixes.
This commit is contained in:
bill
2021-02-24 22:43:53 +08:00
parent 603603993a
commit dffef6657c
6 changed files with 392 additions and 41 deletions
+148 -26
View File
@@ -21,6 +21,7 @@
</style>
<body bgcolor=white text=black link=black alink=blue vlink=blue>
<center>
<!!--- SUPER SAMPLING THE W/H PARAMS FOR CANVAS ARE RENDER SIZE, IN THE CSS IS ACTUAL(DISPLAY) SIZE.--->
<canvas id='canvas1' style="width: 600px; height:600px;" width=1200 height=1200></canvas>
</center>
</body>
@@ -56,7 +57,19 @@ Solar RTX
<p style="font-size:30px; ">In this homework, I implemented Global illumination w/
Realtime Recursive Ray Tracing!
<p>
<i style="font-size:25px;">Here is how it works:</i>
<i style="font-size:25px;">Usage: </i>
<ul>
<li>Ctrl+Alt/Option+T: Toggle Texture.</li>
<li>Ctrl+S: Download fragment shader.</li>
<li>Ctrl+Alt/Option+R: Toggle Recursive Ray Tracing.</li>
<li>Ctrl+Alt/Option+N: Reset ViewPoint.</li>
<li>Ctrl+Alt/Option+P: Toggle Pause/Resume.</li>
<li style="color:red;">Please unfocus the Editing area (click somewhere else on the page) to use hotkeys.</li>
<li>Click on canvas (WITHOUT key modifiers): Toggle Pause/Resume.</li>
<li>SHIFT+Alt/Option+MOUSE DRAG/WHEEL ZOOM: Changing Viewing point.</li>
</ul>
<i style="font-size:25px;">How it works:</i>
<ul>
<li>First, I started with what I've already done in homework 1. Which already included complete Phong shading with
Specular light and much more (spherical texture mapping, simple interactions, improved UI/shader editor).
@@ -65,10 +78,19 @@ Solar RTX
<li> I modified the ray tracing algorithm so that when hitting an object, instead of returning color calculated from
Phong model:<br>
<ul>
<li>I recursively traced the light reflected and refract from the object.</li>
<li></li>
<li>It recursively bounces and/or refract(NOT IMPLEMENTED YET) itself spawning new rays.</li>
<li>The color of this pixel equals to Ambient + Diffuse + ks*color[Reflected] + kt*color[Refracted].
(<a href="https://www.cs.drexel.edu/~david/Classes/Papers/p343-whitted.pdf">Turner Whitted Model</a>)</li>
<li>The tracing will stop when a ray was reflected/refracted n_ref times. </li>
<li>The color of the final light is computed via specular component from the Phong model.</li>
<li>You may increase n_ref for more iterations, but please proceed with caution, because it may halt the computer.
</li>
</ul>
<li></li>
<li>I added more interactions, you can now change the viewpoint by
holding shift and alt key while dragging on canvas to rotate,
or holding shift and alt while scrolling on canvas to change focal length.
This is implemented by applying a transformation matrix to the viewpoint and projection surface.
</li>
<li>Finally, I used super sampling via doubling the render dimensions of the canvas to reduce aliasing.</li>
<li>Repo on <a href="https://github.com/sunyinqi0508/graphics_hw1">Github</a>.</li>
</li>
@@ -104,6 +126,9 @@ let vs = my_vertex_shader.innerHTML;
client.send();
document.body.innerHTML = [''
,'<font size=7 color=#909090>' + my_title.innerHTML
,'<img id="rtx" style="float:right;" src="./RTXon.svg" type="image/svg+xml"'
,' alt="Turn Ray Tracing On/OFF" title="Turn Ray Tracing On/OFF" height=60px /img>'
,'<div id="fps" style="font-size:25;float:right;margin-right:18px;"></div>'
,'<TABLE cellspacing=0 cellpadding=0><TR>'
,'<td><font color=red size=5><div id=errorMessage></div></font></td>'
,'</TR><TR>'
@@ -111,7 +136,8 @@ document.body.innerHTML = [''
,'<tr>'
,'<td valign=top>'
,'<div id="ace" style="width:800px;height:1780px;"></div>'
,'</td><td valign=top>' + document.body.innerHTML + '<div style=\'font-size:25px\'>' + my_instructions.innerHTML + '</div>' + '</td>'
,'</td><td valign=top>' + document.body.innerHTML
,'<div style=\'font-size:25px\'>' + my_instructions.innerHTML + '</div>' + '</td>'
,'</tr></table>'
,'</TR></TABLE>'
].join('');
@@ -137,52 +163,148 @@ editor.setAutoScrollEditorIntoView(true);
delete editor.KeyBinding;
let lastTime = Date.now();
let animating = true;
let ctrl = false;
canvas1.addEventListener('click',function(ev){
let ctrl = false, alt = false, shift = false, fpson = true, moving = false;
let mousedx = 0, mousedy = 0, mousedz = 0;
let mouselastX, mouselastY;
let pause_resume = function(){
if(animating)
lastTime = Date.now();
else
startTime += Date.now() - lastTime;
animating = !animating;
lastTime = Date.now();
else
startTime += Date.now() - lastTime;
animating = !animating;
};
canvas1.addEventListener('click',function(ev){
if(!(shift && alt))
pause_resume();
//moving = false;
});
document.addEventListener('keydown',(e)=>{
if(e.code.startsWith('Control'))
{
ctrl = true;
canvas1.addEventListener('mousedown', function(e){
if(shift && alt){
moving = true
mouselastX = mouselastY = undefined;
}
else if(ctrl && e.code == 'KeyT')
{
mask = 0x1;
else
moving = false;
});
canvas1.addEventListener('mousemove', function(e){
if(shift && alt && moving){
if(!(mouselastX==undefined || mouselastY == undefined)){
mousedx += (mouselastX - e.offsetX)/60;
mousedy += (mouselastY - e.offsetY)/60;
setUniform('4f', 'rot', Math.cos(mousedx), Math.sin(mousedx), Math.cos(mousedy), Math.sin(mousedy));
}
mouselastX = e.offsetX;
mouselastY = e.offsetY;
}
else
moving = false;
});
canvas1.addEventListener('mouseup', function(e){
// if(ctrl && alt && moving){
// }
moving = false;
});
canvas1.addEventListener('mouseout', function(e){
// if(ctrl && alt && moving){
// }
moving = false;
});
canvas1.addEventListener('wheel', function(e){
if(shift && alt){
mousedz += e.wheelDelta/600;
setUniform('1f', 'dFL', mousedz);
}
});
rtx.style.cursor="pointer";
let rtswitch = function(){
const mask = 0x2;
let rtstatus = !(flags&mask);
if (rtstatus)
rtx.src='./RTXoff.svg';
else
rtx.src='./RTXon.svg';
flags = flags&!mask | (rtstatus?mask:0);
setUniform('1i', 'flags', flags);
}
rtx.addEventListener('click', rtswitch);
var requestAnimationFrame = window.requestAnimationFrame ||
window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame;
let fpscounter = function(time){
if (start === undefined)
start = time;
else
fps.innerHTML = Math.round(10000/(time-start))/10 + ' fps';
start = time;
if(fpson)
requestAnimationFrame(fpscounter);
else{
start = undefined;
fps.innerHTML = '';
}
};
document.addEventListener('keydown',(e)=>{
if(e.code.startsWith('Shift'))
shift = true;
if(e.code.startsWith('Control'))
ctrl = true;
if(e.code.startsWith('Alt'))
alt = true;
else if(ctrl && alt && e.code == 'KeyT'){
const mask = 0x1;
flags = flags&!mask | (!(flags&mask)?mask:0);
setUniform('1i', 'flags', flags);
}
else if (ctrl && e.code == 'KeyS')
{
else if (ctrl &&e.code == 'KeyS'){
let a = document.createElement('a');
a.href = "data:text/plain,"+encodeURIComponent(editor.getSession().getValue());
a.download = 'shader.frag';
a.click();
}
else if(ctrl && alt&&e.code == 'KeyR')
rtswitch();
else if(ctrl && alt&&e.code == 'KeyN')
{
flags = 0;
moving = false;
mousedx = mousedy = mousedz = 0;
setUniform('4f', 'rot', Math.cos(mousedx), Math.sin(mousedx), Math.cos(mousedy), Math.sin(mousedy));
setUniform('1f', 'dFL', mousedz);
setUniform('1i', 'flags', flags);
}
else if(ctrl && alt&&e.code == 'KeyP')
pause_resume();
else if(ctrl && alt&&e.code == 'KeyF')
if(!fpson)
{
fpson = true;
requestAnimationFrame(fpscounter);
}
else
fpson = false;
// else if(e.code =='KeyV')
// alert(' '+ mousedx+ ' ' + mousedy + ' '+mousedz)
});
document.addEventListener('keyup',(e)=>{
if(e.code.startsWith('Control'))
{
ctrl = false;
}
if(e.code.startsWith('Alt'))
alt = false;
if(e.code.startsWith('Shift'))
shift = false;
});
// SET THE CURRENT TIME IN SECONDS BEFORE RENDERING EACH FRAME.
let startTime = Date.now();
let lastFrameTime = 0;
function animate(gl) {
if(animating)
setUniform('1f', 'uTime', (Date.now() - startTime) / 1000);
else
setUniform('1f', 'uTime', (lastTime - startTime) / 1000);
}
let start;
requestAnimationFrame(fpscounter);
</script>