Closed samreid closed 9 years ago
@samreid - lets talk in person Thursday or skype on Friday
Trying to understand the performance of the canvas wave node, I console.logged the number of waveParticles and saw this:
frameStarted 17 17 17 151 151 151 frameCompleted
That is to say, each frame, the canvas node paint loop is hit 504 times, across 6 paint calls.
Something that might be easy to try. 3 gradients with many color stops instead of many gradients each with 3 color stops.
Also, instead of moveTo/lineTo/lineTo/lineTo/close, try a rectangle?
In the Java version, it appears this is just 3 shapes (incoming ray, reflected ray, and transmitted ray) each with a single gradient. In Java you can do a cyclic gradient which is not possible in JavaScript, but in JavaScript, we could add more colorstops.
@ariel-phet it is unclear how much effort we should put into the canvas implementation here. If we leave it as-is, it will likely have good enough performance on laptops and desktops with blacklisted GPUs (and hence no WebGL). The only place it would be slow would be on mobile devices without WebGL. It could be very time consuming to improve performance here. Just guessing about possible strategies: after 20 hours of work, there is a 20% chance we could improve performance by 40%. or so After 50 hours of work, there is a 40% chance we could improve performance by 80% (though all of this would still be orders of magnitude slower than the WebGL implementation). Anyways, these numbers are very fuzzy and mainly intended to give you a map of possibilities. Let me know what you recommend.
@samreid - could we have the wave mode in canvas just be simple lines, no gradient? (corresponding to the peaks of the wave)
This is a very common representation in physics classes. Would that sort of simple rendering be possible in canvas with decent performance?
If not, we could also consider having "wave view" not appear on devices without webgl...but please let me know an answer to the above first.
Using lines is something we could try (could take 20 hours or so, if it works), but I can think of a couple of options that might work to show the full gradient, such as using a pattern fill or a gradient with multiple stops. 504 paint calls per frame (the current approach) leaves open lots of room for improvement.
@samreid Seems worthy of a skype call.
@ariel-phet and I discussed this today. It was approved to send some "couple of hours" investigating each proposed approach to see what seems like it might work.
I'm not sure why @ariel-phet added the bug
label. I'll remove it.
Dividing the number of waveparticles to draw by 20 only gives us a frame rate of 12fps.
Doing everything except the fill call leave us at 20fps. Skipping the entire paintCanvas also leaves us at 20fps.
Leaving the paint commented out and getting rid of the clipping region brings us to 32fps. With the paint but no clipping we are back at 5fps.
Drawing with solids and clipping gives us about 6fps:
Putting the max particles from 150 to 50 in this expression:
var numberOfParticles = Math.min( Math.ceil( distance / gapBetweenSuccessiveParticles ), 50 ) + 1;
and using solid rectangles gives the following results on iPad3: with clipping: 7fps without clipping: 25fps (good enough)
using full gradients and the 50 max particles gives: without clipping: 5fps
If we can't draw gradients fast enough, we could draw the gradient 3 times, one for incoming, transmitted, reflected into a scratch canvas and then drawImage from the scratch canvas.
I can only draw a scratch canvas per particle at about 7-8fps. Drawing rectangles on ipad is fast though, getting 25fps or so for solid rectangles.
I think it will have to be rectangles--when I change to moveTo/lineTo/lineTo/lineTo the performance drops from 25fps to 9fps
So I should try rotating the canvas context to align with the ray, drawing the background for the ray, then drawing rectangles for the wave peaks. That is our best chance for rendering something on the iPad3 with canvas and keeping it at a decent frame rate.
I'm getting 24 fps on the iPad3 using canvas and it looks like this:
Gradients bring the performance back to 5fps, but in my opinion this looks good enough. I still need to patch up a little bit of blank space I see, but I am hopeful about this approach.
Here's a comparison to the WebGL gradient rendering. Somewhat similar!
This is now looking great and running at 24fps on the iPad3, that's 8x faster than before! @ariel-phet can you review this and let me know if you see any issues with this new canvas fallback implementation? To test it, you need webgl=false, which I've included in this URL:
I will take a look when I am campus later today.
@samreid, when I open dev.22 using ?webgl=false and turn on white light, the bottom panel and prisms disappear. While on my Mac, I can still add prisms to the playspace and move the ones already there, but I have trouble doing the same on the iPad 3.
While in monochromatic mode, I am getting 24fps on the iPad 3 while dragging the prisms around, but that's a bit tricky to do in white light mode. I've been able to drag a few prisms, and I think I'm getting a similar frame rate, but it's hard to tell without being sure what actions I'm actually taking.
This issue is about the performance of the wave mode, I'll create a new issue for the problem @arouinfar discovered on the prisms screen.
Also, @arouinfar are you back? Not sure if I should still assign issues like this to @ariel-phet or you.
@samreid, sorry I'm still a bit jetlagged... I'll take a look at the actual issue reported here and get back to you.
@arouinfar welcome back!
Thanks @samreid!
While in wave mode I'm getting 24fps in the iPad 3 while the laser is static. While changing the angle of the laser, the frame rate sometimes dips to 18fps. While changing the index of refraction of the bottom material by moving the slider back and forth, the frame rate was about 12fps. The performance doesn't feel all that laggy, but instead the speed of the wave seems a bit slow (but only when doing a side-by-side comparison with my Mac). The performance seems good to me.
The only issue I notice is that the wave in the bottom material seems a bit more aliased than the canvas desktop version.
Here's what it looks like on my Mac running OSX 10.9.5 and Chrome 44:
iPad 3:
I do not believe we will be able to address the aliasing issue when using canvas, and it doesn't seem too distracting to me. Can this issue be closed?
@samreid, I don't find it that distracting, but I thought I'd bring it up just in case it was relevant. Closing.
During #44 I tried running with ?webgl=false and &profiler I am seeing 4fps. So I'm not sure this canvas fallback is speedy enough. @ariel-phet let's discuss what should be done here, if anything. Some options:
a) require webgl for the wave view for this sim b) create a lower resolution version of the wave view when running in canvas c) something else???