phetsims / bending-light

"Bending Light" is an educational simulation in HTML5, by PhET Interactive Simulations.
http://phet.colorado.edu/en/simulation/bending-light
GNU General Public License v3.0
8 stars 8 forks source link

Wave mode with webgl=false is 4fps on iPad3 #154

Closed samreid closed 9 years ago

samreid commented 9 years ago

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???

ariel-phet commented 9 years ago

@samreid - lets talk in person Thursday or skype on Friday

samreid commented 9 years ago

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.

samreid commented 9 years ago

Something that might be easy to try. 3 gradients with many color stops instead of many gradients each with 3 color stops.

samreid commented 9 years ago

Also, instead of moveTo/lineTo/lineTo/lineTo/close, try a rectangle?

samreid commented 9 years ago

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.

samreid commented 9 years ago

@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.

ariel-phet commented 9 years ago

@samreid - could we have the wave mode in canvas just be simple lines, no gradient? (corresponding to the peaks of the wave)

refraction-water-waves

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.

samreid commented 9 years ago

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.

ariel-phet commented 9 years ago

@samreid Seems worthy of a skype call.

samreid commented 9 years ago

@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.

samreid commented 9 years ago

I'm not sure why @ariel-phet added the bug label. I'll remove it.

samreid commented 9 years ago

Dividing the number of waveparticles to draw by 20 only gives us a frame rate of 12fps.

samreid commented 9 years ago

Doing everything except the fill call leave us at 20fps. Skipping the entire paintCanvas also leaves us at 20fps.

samreid commented 9 years ago

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.

samreid commented 9 years ago

Drawing with solids and clipping gives us about 6fps:

image

samreid commented 9 years ago

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

samreid commented 9 years ago

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.

samreid commented 9 years ago

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.

samreid commented 9 years ago

I think it will have to be rectangles--when I change to moveTo/lineTo/lineTo/lineTo the performance drops from 25fps to 9fps

samreid commented 9 years ago

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.

samreid commented 9 years ago

I'm getting 24 fps on the iPad3 using canvas and it looks like this: image

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.

samreid commented 9 years ago

Here's a comparison to the WebGL gradient rendering. Somewhat similar!

image

samreid commented 9 years ago

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:

http://www.colorado.edu/physics/phet/dev/html/bending-light/1.0.0-dev.22/bending-light_en.html?webgl=false

ariel-phet commented 9 years ago

I will take a look when I am campus later today.

arouinfar commented 9 years ago

@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. image

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.

samreid commented 9 years ago

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.

samreid commented 9 years ago

Also, @arouinfar are you back? Not sure if I should still assign issues like this to @ariel-phet or you.

arouinfar commented 9 years ago

@samreid, sorry I'm still a bit jetlagged... I'll take a look at the actual issue reported here and get back to you.

samreid commented 9 years ago

@arouinfar welcome back!

arouinfar commented 9 years ago

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: image

iPad 3: img_0069

samreid commented 9 years ago

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?

arouinfar commented 9 years ago

@samreid, I don't find it that distracting, but I thought I'd bring it up just in case it was relevant. Closing.