aboutsummaryrefslogtreecommitdiff
path: root/index.html
blob: b9095cbb178acee236a969344c869532f432d974 (plain)
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
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <title>Raytracer</title>
    <link rel="stylesheet" href="https://unpkg.com/spectre.css/dist/spectre.min.css">
    <link rel="stylesheet" href="css/style.css">
  </head>
  <body>

    <div class="container">

      <div class="columns">
        <div class="column col-xl-12">
          <div id="output-wrapper" class="p-centered">
            <canvas id="render-output"></canvas>
          </div>
        </div>
      </div>

      <div class="container grid-xl">

        <div class="columns">
          <div class="column">
            <ul class="tab">
              <li id="demo-tab" class="tab-item active">
                <a href="#">Raytracing demo</a>
              </li>
              <li id="benchmark-tab" class="tab-item">
                <a href="#">CPU Benchmark</a>
              </li>
            </ul>
          </div>
        </div>

        <div id="demo-mode"  class="columns controls">
          <div class="column">
            <div class="columns">
              <div class="column col-3">
                <p>A minimal ray tracing engine written from scratch in JS. No graphics APIs or libraries are used, only a single HTML5 canvas call to draw the generated bitmap image.</p>
                <p>Various effects are supported, including recursive optical reflections and refractions, and <a href="https://en.wikipedia.org/wiki/Phong_reflection_model">Phong shading</a>. Basic multi-threading is implemented using the <a href="https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API" target="_blank">Web Workers API</a>.</p>
                <p>The raytracer can also produce CPU performance benchmarks.</p>
                <p>The source is on <a href="https://github.com/jamesbarnett91/js-raytracer" target="_blank">GitHub</a>.</p>
              </div>
              <div class="divider-vert"></div>
              <div class="column col-2">
                <span class="render-option-heading">Render options</span>
                <div class="form-group">
                  <label class="form-switch">
                    <input id="diffuse-toggle" type="checkbox" checked>
                    <i class="form-icon"></i> Diffuse lighting
                  </label>
                </div>
                <div class="form-group">
                  <label class="form-switch">
                    <input id="specular-toggle" type="checkbox" checked>
                    <i class="form-icon"></i> Specular lighting
                  </label>
                </div>
                <div class="form-group">
                  <label class="form-switch">
                    <input id="shadows-toggle" type="checkbox" checked>
                    <i class="form-icon"></i> Shadows
                  </label>
                </div>
                <div class="form-group">
                  <label class="form-switch">
                    <input id="reflections-toggle" type="checkbox" checked>
                    <i class="form-icon"></i> Reflections
                  </label>
                </div>
                <div class="form-group">
                  <label class="form-switch">
                    <input id="refractions-toggle" type="checkbox" checked>
                    <i class="form-icon"></i> Refractions
                  </label>
                </div>
              </div>
              <div class="column col-3">
                <span class="render-option-heading">Performance options</span>
                <div class="form-group">
                  <label class="form-switch">
                    <input id="direct-transfer" type="checkbox" checked>
                    <i class="form-icon"></i> Zero-copy array transfer
                  </label>
                </div>
                <div class="form-group">
                  <label class="form-switch">
                    <input id="enable-threads-toggle" type="checkbox" checked>
                    <i class="form-icon"></i> Multi-threaded rendering
                  </label>
                </div>
                <div class="form-group nested-slider">
                  <label class="form-label label-sm" for="threads">Render threads</label>
                  <!-- TODO style -->
                  <div class="input-group">
                    <input id="threads" class="slider" type="range" min="2" max="32" value="4" step="2">
                    <span id="threads-value" class="input-group-addon">4</span>
                  </div>
                </div>
                <div class="form-group">
                  <label class="form-group">
                    <label id="chunk-size-label" class="form-label label-sm" for="res">Chunk size</label>
                    <select id="chunk-size" class="form-select select-sm">
                      <option value="0" selected>Auto</option>
                      <option value="8">8x8</option>
                      <option value="16">16x16</option>
                      <option value="32">32x32</option>
                      <option value="64">64x64</option>
                      <option value="128">128x128</option>
                      <option value="256">256x256</option>
                    </select>
                  </label>
                </div>
                <div class="form-group">
                  <label class="form-group">
                    <label id="chunk-allocation-mode-label" class="form-label label-sm" for="res">Chunk allocation mode</label>
                    <select id="chunk-allocation-mode" class="form-select select-sm">
                      <option value="SEQUENTIAL" selected>Sequential</option>
                      <option value="RANDOM">Random</option>
                      <option value="CENTER_TO_EDGE">Center to edge</option>
                      <option value="EDGE_TO_CENTER">Edge to center</option>
                    </select>
                  </label>
                </div>
              </div>
              <div class="column col-4">
                <div class="form-group">
                  <label id="res-label" class="form-label label-sm" for="res">Resolution</label>
                  <select id="res" class="form-select select-sm">
                    <option value="360p">360p</option>
                    <option value="480p">480p</option>
                    <option value="720p" selected >720p</option>
                    <option value="1080p">1080p</option>
                    <option value="1440p">1440p</option>
                    <option value="4k">4k</option>
                  </select>
                </div>
                <button id="render" class="btn btn-primary btn-lg">Render</button>
                <button id="stop-render" class="btn btn-link d-hide">Stop render</button>
                <button id="view-full" class="btn btn-link d-hide">View full image</button>
                <pre class="code"><code id="console-demo" class="console"></code></pre>
              </div>
            </div>
          </div>
        </div>

        <div id="benchmark-mode" class="columns controls d-hide">
          <div class="column">
            <div class="columns">
              <div class="column col-3" style="width: 20%">
                <p>You can also use the raytracer to run a CPU and JavaScript performance benchmark.</p>
                <p>This will run multiple 1080p renders, with both single and multicore workloads. An overall score will be calculated based on performance, higher is better.</p>
                <p>Compare your results to the reference scores from the various devices I've tested.</p>
              </div>
              <div class="divider-vert"></div>
              <div class="column col-6" style="width: 55%">
                <div id="benchmark-results-graph" style="width: 100%; height: 500px"></div>
              </div>
              <div class="column col-3">
                <div class="columns">
                  <div class="column col-12 d-flex" style="justify-content: center; padding-bottom: 15px">
                    <button id="benchmark" class="btn btn-primary btn-lg">Run benchmark</button>
                  </div>
                </div>
                <div class="columns">
                  <div class="column col-12" >
                    <div class="h4 text-bold">Score</div>
                  </div>
                </div>
                <div class="columns score-col">
                  <div class="column col-6 text-bold">
                    <div>Multi-core</div>
                    <div id="multi-core-score" class="h1 loading-lg">-</div>
                  </div>
                  <div class="column col-6 text-bold">
                    <div>Single core</div>
                    <div id="single-core-score" class="h1 loading-lg">-</div>
                  </div>
                </div>
                <div class="columns">
                  <div class="column col-12" >
                    <pre class="code"><code id="console-benchmark" class="console"></code></pre>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>

      </div>
    </div>
    <script src="./bundle.js"></script>
  </body>
</html>