10 ms·
WebAssembly Raytracer
- based2 9y agoa raytracer in JS: ~407.3 ms and in WASM: ~87.4 ms and in GLSL: ~0.17 ms https://www.reddit.com/r/programming/comments/7k4v5t/a_raytracer_in_js_4073_ms_and_in_wasm_874_ms_and/ https://www.reddit.com/r/programming/comments/7k4v5t/a_raytr...
- sniklaus 9y agoThis is where I answered most of the questions. I didn't even see that someone posted it here as well. Thanks!
- Sharlin 9y agoFirefox really benefits from WebASM: the time per frame is ~90ms on my machine whereas the JS version is close to 400ms or so. On the other hand, on Chrome the WebASM performance is ~100ms and JS is just a tiny bit slower at around 120ms!
- malloryerik 9y agoFirefox Quantum?
- Sharlin 9y agoYep, v57.
- Tuna-Fish 9y agoThe first phase of Quantum made styling and layout faster than any browser. The next phase will make rendering faster than anything else. The JS engine is still the old one. (Maybe it's time will come third?)
- azdle 9y agoMozilla people have been working on SpiderMonkey performance already: https://jandemooij.nl/blog/2017/12/06/some-spidermonkey-optimizations-in-firefox-quantum/ https://jandemooij.nl/blog/2017/12/06/some-spidermonkey-opti..., it's just not some wholesale replacement, so it probably never makes the top of the list for what they shout about. It also sounds like it has been a steady progression rather than a big jump, so maybe not quite as noticeable.
- amelius 9y agoPerhaps it was written for Chrome specifically (?)
- Klathmon 9y agoThat's a really interesting observation on so many levels! Firefox (or rather SpiderMonkey) seems to really be focusing on WebASM performance, and it's easy to forget just how goddamn fast V8 has made JavaScript...
- jsheard 9y agoIt's worth noting that this isn't idiomatic Javascript though, the author is jumping through hoops to avoid ever triggering the garbage collector. Javascript can be very fast if you go down that route but the code gets extremely ugly.
- Klathmon 9y agoIsn't most "fast path" code in a GCd language written like this? I've jumped through similar hoops in Go, and even C++ to avoid allocation or GC. The fact that a dynamic language like JavaScript can compile and execute as fast as it does is nothing short of incredible! Even if it's not idiomatic, it's still far from "unreadable".
- pjmlp 9y agoNot if the language supports a mix of value types, off heap allocations or untraced references. There are a few like that.
- imtringued 9y agoCan you name them?
- pjmlp 9y agoYes, surely. - Eiffel - Oberon family (Oberon, Oberon-2, Active Oberon, Component Pascal, Oberon-07) - Mesa/Cedar - Modula-3 - D - Nim - C# (specially now with 7.2 improvements) - Go - Swift (RC is also a form of GC algorithm) These are just the most well known ones, there are others if you feel like having a dive into SIGPLAN papers. I can also provide examples, how to do it in any of them, if you wish.
- JepZ 9y agoBtw. similar numbers are available on the projects github page: https://github.com/sniklaus/experiment-raytracer https://github.com/sniklaus/experiment-raytracer
- BillinghamJ 9y agoGetting 60ms on Safari on macOS for WebASM. The other three don't seem to work though.
- clouddrover 9y agoThe Shader version doesn't work for me in Safari 11.0.1 but the other three did work. I found that I couldn't run any of the others after I had tried the Shader version. I reloaded the page and then I could select between the JavaScript, asm.js, and WebAssembly versions without issue.
- renchap 9y agoThe Shader version needs WebGL 2.0, and works with the latest Safari Technology Preview
- WhitneyLand 9y agoBut would adding antialiasing kill the performance? It’s a small thing, but it’s kind of like a movie where you can totally suspend disbelief and one bad actor or effect jolts you out it.
- Sharlin 9y agoWell, sure, but so would rendering at a more reasonable resolution, or a more realistic scene than five spheres on a plane. And it's not like 10fps is a useful frame rate in the first place. But it's the relative, not absolute, performance figures that are interesting here.
- bartread 9y ago> And it's not like 10fps is a useful frame rate in the first place. How times have changed. I remember running flight sims back in the 16-bit era (Amiga 500, for example) when 10fps would have been considered pretty good, especially if there was a lot going on. But yes, I think nowadays you're right: 60fps or bust. And this is really why ray-tracing isn't used that much in games - it's just so computationally expensive.
- benjamin-fl 9y agoFor ray tracing like this, going the supersampled antialiasing route is pretty much equivalent to rendering the scene at higher resolutions. For example, to get 4 samples per pixel, you need to render at double the resolution in both directions, or 4 times the number of pixels. Of course, techniques like FXAA which are commonly used in rasterization based realtime rendering are possible as well, and would have much lower performance impact. Another thing to think about is that in any monte carlo based rendering algorithm, such as what would be used to render modern movie graphics, antialiasing is basically free. These algorithms already work by running thousands upon thousands of samples per pixel, so distributing these samples inside each pixel has almost no performance impact.
- ajross 9y agoAlternatively, it's pretty amazing that a nearly pure FPU task with small data that should live well in cache is only about 5x slower when written in straightforward JavaScript. This is the kind of code that in previous generations would have expected to see a 20-100x penalty in perl or python.
- heavenlyblue 9y agoAs previous threads have already mentioned: that is not straightforward JavaScript. There’s nothing impressive about stripping down a scripting language by making it’s structure exactly the same as c in the end. What’s the point of JavaScript in the first place? What we had done is we took a microscope and then made sure it’s made of toughened glass and the strengthened steel so that we could nail a few nails with it.
- k__ 9y agothe shader version is the fastest, but looks like modern art on my smartphone. Like someone scribbled the colors over the circles instead of filling them.
- K0nserv 9y agoThat's probably an implementation issues that manifests on your hardware called shadow acne/self intersection. It's explained here[0] 0: https://www.scratchapixel.com/lessons/3d-basic-rendering/introduction-to-shading/ligth-and-shadows https://www.scratchapixel.com/lessons/3d-basic-rendering/int...
- k__ 9y agoMade a screenshot: https://imgur.com/a/7J4Da https://imgur.com/a/7J4Da
- jsheard 9y agoThis is probably the culprit: https://github.com/sniklaus/experiment-raytracer/blob/master/shader.js#L11 https://github.com/sniklaus/experiment-raytracer/blob/master... It declares that floats should only be medium precision by default, but those precision specifiers are only followed on mobile platforms. Desktop WebGL implementations just promote everything to high precision so that kind of bug is invisible until you test on mobile.
- TekMol 9y agoIs there a resource to learn WebAssembly? I don't mean how to use a tool chain to compile higher level languages to WASM. I mean how to write the linear assembly bytecode as seen here on Wikipedia: https://en.wikipedia.org/wiki/WebAssembly#Representation https://en.wikipedia.org/wiki/WebAssembly#Representation
- steveklabnik 9y agoI went straight to the spec personally; it’s quite readable and shorter than I expected.
- pjmlp 9y agoNo linear, but these ones are quite good for the Lisp-like syntax, which I prefer. https://mbebenita.github.io/WasmExplorer/ https://mbebenita.github.io/WasmExplorer/ https://wasdk.github.io/WasmFiddle/ https://wasdk.github.io/WasmFiddle/
- TekMol 9y agoI think these won't let you write WASM. Am I wrong?
- singularity2001 9y agoyou are right I asked them about adding the option to compile WASM or WAST (instead of c), but the answer was that 'there are no use cases'. of cause 'learning' would be just one.
- zurn 9y agoInteresting that there is a 1000x speed difference (0.1 vs 100 ms, in Chrome) between the shader and the JS/WebASM versions even with just Intel integrated graphics.
- Klathmon 9y agoEven after working with them for a while, GPUs still feel like cheating. They are just so goddamn good at what they do. That kind of speed up isn't just a fluke here, it's pretty normal when your work aligns with what a GPU does best.
- pjmlp 9y agoIt is a complete different way of working, but sometimes it just feels like going back to Amiga coding with Blitter and DMA.
- gmueckl 9y agoI've been working with GPUs for many years now and I still get surprised by their performance: some things turn out to be so bloody fast that I initially think that i must do something wrong. Other times, CPU implementations run circles around the GPU for no obvious reason. It's not intuitive and I still have a hard time wrapping my head around how fast these things are when they are at their best.
- roywiggins 9y agoThey're really fast even if you're sort of abusing them. Using fragment shaders to render entire scenes ("two triangle" style) probably wasn't what GPUs were built to do but the technique is awfully effective. I mean: https://www.shadertoy.com/view/Mt2yzK https://www.shadertoy.com/view/Mt2yzK
- andybak 9y agoIt was would interesting to compare a C or Assembly version against a shader version. My hunch is that this is just a use case where a general purpose CPU is left in the dust by a modern GPU.
- igravious 9y agoWow, Chrome is able to run the Shader on my Intel integrated graphics on Wayland in Ubuntu 17.10 Colo(u)r me impressed. I'm getting 0.1 versus 125 for WebAsm versus ASM.js/JS of ~210 – kind of crazy that Chrome can run plain JS as fast as ASM.js (or is it?) Firefox (57) can't run Shader unless there's some under the hood option I have to turn on …
- clouddrover 9y agoI'm using Firefox 58 beta on macOS with Intel graphics and the Shader version works for me. Maybe WebGL is disabled in your set up. Some drivers and driver versions are blocklisted to avoid instability: https://developer.mozilla.org/en-US/docs/Mozilla/QA/Graphics_Blocklisting https://developer.mozilla.org/en-US/docs/Mozilla/QA/Graphics... The graphics section in about:support might tell you your WebGL status.
- bufferoverflow 9y agoShader is broken on both android chrome and ff. These work fine: https://www.shadertoy.com/view/4tyXDR https://www.shadertoy.com/view/4tyXDR https://www.shadertoy.com/view/4sXGDs https://www.shadertoy.com/view/4sXGDs https://www.shadertoy.com/view/4dsGRn https://www.shadertoy.com/view/4dsGRn https://www.shadertoy.com/view/4lB3D1 https://www.shadertoy.com/view/4lB3D1
- Macha 9y agoMight depend on your device, the shader mode worked fine on my nvidia shield, but is broken on my nexus 5x.
- sniklaus 9y agoI unfortunately had a bug in my code that I just fixed. It should work now, unless you encounter the bug that has been discussed here: https://github.com/mrdoob/three.js/issues/9716 https://github.com/mrdoob/three.js/issues/9716
- kowdermeister 9y agoHmmm: JavaScript 106.8 asm.js 140.0 WebAssembly 88.4 Shader 0.1 Just a Dell 13 inspiron laptop with latest Chrome 63.
- vanderZwan 9y agoSeeing the same with Chromium on my Linux machine. In Firefox the JS version is really slow, as you would expect. It's kind of hard to judge this without having a decent enough look at the code, or how it is being benchmarked. For example, asm.js requires quite a bit of set-up to intialise; if it's restarted from scratch every loop for benchmarking purposes that would mess up the timing.
- simooooo 9y agoShader 0.2 - Samsung galaxy s8
- IvanK_net 9y agoI made a Path-tracer (photorealistic algorithm) in pure JS four years ago: http://renderer.ivank.net/ http://renderer.ivank.net/ It rendered this image: http://renderer.ivank.net/balls.jpg http://renderer.ivank.net/balls.jpg :) I also made the "full" 3D game: http://powerstones.ivank.net/ http://powerstones.ivank.net/ (uses a GLSL shader).
- tunnuz 9y agoThat is beautiful, congrats! Advanced Global Illumination is a great book if one is interested in building one.
- otakucode 9y agoWhat's the performance like when compares to WebAssembly? Would that be difficult to determine?
- IvanK_net 9y agoThere was no WASM when I made it in 2013. But I guess WASM would be like 10 - 15 % faster.
- blarg1 9y agoThe 3D game doesn't work for me, when I hit play all I get is a white screen with light pink/teal/yellow coloured pixels/blocks flickering at the top of the screen. I'm on an intel integrated graphics.
- Francute 9y agoOn my desktop: Firefox: JavaScript ~372ms, asm ~121ms, WebAssembly ~91ms, Shader ~0.1ms Chrome: JavaScript ~115ms, asm ~150ms, WebAssembly ~105ms, Shader ~0.1ms Edge: JavaScript ~3340ms , asm ~(230-240)ms, WebAssembly ~(160-180)ms, Shader: Broken IE11: Broken. Interesting values.....
- peterdn 9y agoDoesn't work for me at all in Edge (v41.16299.15.0). Are you on an Insider Preview?
- singularity2001 9y agoI had no idea ray tracers can be written with such concise and clean code. the results are amazing too. lesson learnt: JavaScript is extremely fast on chrome, 6 times slower than WASM in Firefox and GPU shaders are still faster by a factor of 1000!!
- sniklaus 9y agoIf you give up having clean code, you can even fit a raytracer on a business card: http://fabiensanglard.net/rayTracing_back_of_business_card/ http://fabiensanglard.net/rayTracing_back_of_business_card/
- jandem 9y agoThe JS version is slow in Firefox because of a silly perf cliff, I filed a bug [0]. A quick fix for that improves the JS version from ~400 ms to ~180 ms for me locally. ~140 ms if I disable the Nightly-only GC poisoning. edit: the JS code is a bit buggy: it does |if (Math.abs(dblDiscriminant) < 0.01)| in the |intersection| function, but dblDiscriminant is a var set in the next loop! Math.abs(undefined) is something we can easily optimize in the JIT, but really the JS code is broken. Folding this in our JIT [1] improves this to < 130 ms for me. Please let us know if you run into JS perf problems, these bugs are usually easy to fix. [0] https://bugzilla.mozilla.org/show_bug.cgi?id=1425687 https://bugzilla.mozilla.org/show_bug.cgi?id=1425687 [1] https://pastebin.com/CzfP5vQj https://pastebin.com/CzfP5vQj
- sniklaus 9y agoThank you for your evaluation! It should have been dblDenominator instead of dblDiscriminant and I fixed it accordingly. However, this change does not seem to significantly affect performance.
- radarsat1 9y agoA little beside the point, but I love the real-time distribution visualisation with the boxplot.
- sniklaus 9y agoThank you for your kind words. I borrowed the idea from a previous project in which curious students could evaluate the computational performance of their various implementation using a similar plot: https://github.com/sniklaus/teaching-minichess https://github.com/sniklaus/teaching-minichess
- z3t4 9y agoWhen WASM only give's a 10% increase in performance, is it really worth it ? While at the same time using "hardware" shaders gives 1000% increase in performance. If the goal of WASM is not performance, what is the reasoning behind it ? That you would be able to compile any!? program to be run in the browser !?
- akmittal 9y agoThis might not be best way measure wasm performance. WebAssembly can be 2-5x fater than JavaScript. Not to forget wasm is in very early stage, once we get threading support(https://github.com/WebAssembly/threads https://github.com/WebAssembly/threads) we can get much better results.