-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathraytracer.html
executable file
·199 lines (158 loc) · 6.51 KB
/
raytracer.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<!-- read the list of module enabled (for example you can use in your code: "if(ModuleId.B3) { ... }") -->
<script src="./ModuleId.js"></script>
<!-- simple vector and matrix library (see documentation: http://sylvester.jcoglan.com/) -->
<script src="./sylvester.src.js"></script>
<!-- TGA and OBJ loader for exercise 3 -->
<script type="text/javascript">
var waitingForData = 0; // # of asynchronous loading requests in progress (renderer will wait for them to be done)
</script>
<script src="./read_tga.js"></script>
<script src="./read_obj.js"></script>
<!-- DO NOT change the code BEFORE this point unless you know what you are doing -->
<!-- you can include additional script files here if you need -->
<script src="./src/raytracer.js"></script>
<script src="./src/objects/sphere.js"></script>
<script src="./src/objects/hemisphere.js"></script>
<script src="./src/objects/cylinder.js"></script>
<script src="./src/objects/ellipsoid.js"></script>
<script src="./src/objects/plane.js"></script>
<script src="./src/objects/object_intersection.js"></script>
<script src="./src/objects/mesh.js"></script>
<script src="./src/objects/triangle.js"></script>
<script src="./src/objects/octree.js"></script>
<script src="./src/objects/bounding.js"></script>
<script src="./src/scene/scene.js"></script>
<script src="./src/scene/A1.js"></script>
<script src="./src/scene/B3.js"></script>
<script src="./src/scene/B4.js"></script>
<script src="./src/scene/C3.js"></script>
<script src="./src/scene/D1.js"></script>
<script src="./src/scene/X1.js"></script>
<script src="./src/scene/X2.js"></script>
<script src="src/area_light.js"></script>
<script src="src/point_light.js"></script>
<script src="./src/camera.js"></script>
<script src="./src/ray.js"></script>
<script src="./src/intersection.js"></script>
<script src="./src/properties/material.js"></script>
<script src="./src/properties/texture.js"></script>
<script src="./src/properties/normalmap.js"></script>
<script src="./src/properties/color.js"></script>
<script src="./src/helper.js"></script>
<script src="./src/config.js"></script>
<!-- ... -->
<!-- DO NOT change the code AFTER this point unless you know what you are doing -->
<script type="text/javascript">
var width = RayConfig.width, height = RayConfig.height; // image size
var canv, ctx, imgData; // canvas
var imgBuffer; // canvas buffer
var pixBuffer; // color pixel buffer
var curPixelX = 0, curPixelY = 0; // current pixel to render
// initialization when page loads
function load() {
canv = document.getElementById("myCanvas");
ctx = canv.getContext("2d");
imgData = ctx.createImageData(width,height);
imgBuffer = imgData.data;
pixBuffer = new Array();
document.getElementById("mainContent").style.width = RayConfig.width+"px";
document.getElementById("mainContent").style.height = RayConfig.height+"px";
document.getElementById("myCanvasDiv").style.width = RayConfig.width+"px";
document.getElementById("myCanvasDiv").style.height = RayConfig.height+"px";
document.getElementById("myCanvas").width = RayConfig.width;
document.getElementById("myCanvas").height = RayConfig.height;
canv.onclick = function(e) {
debugPixel(e.offsetX,e.offsetY);
}
startRendering(); // render the scene
}
// launch the renderer
function startRendering() {
clearBuffer(); // clear current buffer
curPixelX = 0; curPixelY = 0; // reset next pixel to be rendered
loadScene(); // load the scene
refresh();
setTimeout("render()",0); // render
}
// reset all the pixel to white color
function clearBuffer() {
var curPixel = 0;
for(curPixelY = 0; curPixelY < height; ++curPixelY) {
for(curPixelX = 0; curPixelX < width; ++curPixelX) {
pixBuffer[4*curPixel+0] = 1.0;
pixBuffer[4*curPixel+1] = 1.0;
pixBuffer[4*curPixel+2] = 1.0;
pixBuffer[4*curPixel+3] = 1.0;
curPixel++;
}
}
}
// update the canvas with currently computed colors
function refresh() {
for(var i = 0; i < pixBuffer.length; ++i) {
imgBuffer[i] = (pixBuffer[i]*255.0);
}
ctx.putImageData(imgData,0,0);
}
// render the new 50 lines of pixels
function render() {
if(curPixelY == height) return; // rendering done
if(waitingForData > 0) { // textures are not loaded yet, wait for them
console.log("Some data are not loaded yet, waiting for them before starting to render");
setTimeout("render()",1000);
return;
}
var curPixel = curPixelY*width;
for(var i = 0; i < 50; ++i, ++curPixelY) {
for(curPixelX = 0; curPixelX < width; ++curPixelX) {
// compute the color for the current pixel
var color = trace(curPixelX, curPixelY);
// copy the result in the buffer
pixBuffer[4*curPixel+0] = color.r;
pixBuffer[4*curPixel+1] = color.g;
pixBuffer[4*curPixel+2] = color.b;
pixBuffer[4*curPixel+3] = 1.0;
curPixel++;
}
}
refresh(); // update screen
// call render as soon as possible to compute next pixel values
setTimeout("render()",0);
}
// export the canvas in a PNG file
function exportPNG() {
var data = canv.toDataURL("image/png");
data = data.replace("image/png", "image/octet-stream");
document.getElementById("exportLink").href = data;
document.getElementById("exportLink").download = "cg-exN-ivonussbaumer-moduleid.png";
document.getElementById("exportLink").click();
}
function debugPixel(x,y) {
var color = trace(x, y);
console.log("Pixel ("+x+","+y+"): RGB -> "+color.r+" "+color.g+" "+color.b);
}
</script>
<style>
body, button {
font-family: 'Verdana', 'Geneva', sans-serif;
font-size: 14pt;
}
</style>
</head>
<body onload="load()">
<div id="mainContent" style="width: 800px; height: 600px; margin-left: auto; margin-right: auto;">
<div id="myUI" style="text-align:center;">
<button onclick="startRendering()" style="width: 396px; height: 40px;">Render</button>
<button onclick="exportPNG()" style="width: 396px; height: 40px;">Export</button>
<!-- hidden link needed to export the image as a PNG -->
<a id="exportLink" download="" href=""></a>
</div>
<div id="myCanvasDiv" style="width: 800px; height: 600px; border: 1px solid black; margin-top: 10px;">
<canvas id="myCanvas" width="800" height="600"></canvas>
</div>
</div>
</body>
</html>