<h5 dir="auto">Description of the problem</h5>
<p dir="auto">Given 2D geometry like</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="var vertices = new Float32Array( [-1,0, 0,1, 1,0, 0,-1, -1,0] );
var geometry = new THREE.BufferGeometry();
geometry.addAttribute( &quot;position&quot;, new THREE.BufferAttribute( vertices, 2 ) );"><pre class="notranslate"><code class="notranslate">var vertices = new Float32Array( [-1,0, 0,1, 1,0, 0,-1, -1,0] );
var geometry = new THREE.BufferGeometry();
geometry.addAttribute( "position", new THREE.BufferAttribute( vertices, 2 ) );
</code></pre></div>
<p dir="auto">I get the following console error (via <code class="notranslate">render</code> -&gt; <code class="notranslate">projectObject</code> -&gt; <code class="notranslate">intersectsObject</code>):</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="THREE.BufferGeometry.computeBoundingSphere(): Computed radius is NaN. The &quot;position&quot; attribute is likely to have NaN values."><pre class="notranslate"><code class="notranslate">THREE.BufferGeometry.computeBoundingSphere(): Computed radius is NaN. The "position" attribute is likely to have NaN values.
</code></pre></div>
<p dir="auto">I've only started playing with three.js today so I may be doing something derpy, but it looks like the problem is that <code class="notranslate">computeBoundingSphere</code> assumes 3 components per vertex and so unconditionally calls</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="position.getZ( i )"><pre class="notranslate"><code class="notranslate">position.getZ( i )
</code></pre></div>
<p dir="auto">and that method returns</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="this.array[ index * this.itemSize + 2 ];"><pre class="notranslate"><code class="notranslate">this.array[ index * this.itemSize + 2 ];
</code></pre></div>
<p dir="auto">So each 2-component primitive uses a spurious <code class="notranslate">z</code> from the following primitive's <code class="notranslate">x</code>, and the last one falls off the end and gets <code class="notranslate">NaN</code>.</p>
<p dir="auto">It doesn't seem to affect rendering and could presumably be avoided by setting the bounding sphere manually, but I'm guessing this wasn't intentional.</p>
<p dir="auto"><a href="http://jsfiddle.net/jeu0th6p/1/" rel="nofollow">Fiddle demonstrating console error</a>, dev  is the same.</p>
<h5 dir="auto">Three.js version</h5>
<ul class="contains-task-list">
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> Dev</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> r87</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox"> ...</li>
</ul>
<h5 dir="auto">Browser</h5>
<ul class="contains-task-list">
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox"> All of them</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> Chrome</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> Firefox</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox"> Internet Explorer</li>
</ul>
<h5 dir="auto">OS</h5>
<ul class="contains-task-list">
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox"> All of them</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> Windows</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox"> macOS</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox"> Linux</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox"> Android</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox"> iOS</li>
</ul>
<h5 dir="auto">Hardware (graphics card, VR Device, ...)</h5>
<p dir="auto">Intel HD Graphics 3000</p>
<p dir="auto">So, apparently many WebGL samples including three.js samples are broken on Safari and Chrome on the new iMacs with 5k displays.</p>
<p dir="auto">The issue is the apps request a fullscreen canvas which is 5120x2880 but Chrome and Safari often return a 4096x2880 canvas. <a href="https://code.google.com/p/chromium/issues/detail?id=445542" rel="nofollow">See bug report</a>. So what happens is because the app asked for 5120x2880 it sets the <code class="notranslate">gl.viewport</code> to that but because the drawingBuffer is actually 4096x2880 it's the wrong viewport setting (and the wrong aspect ratio given the way most of the examples are not using clientWidth/clientHeight) and so the samples don't work.</p>
<p dir="auto">As it says in the bug this is spec compliant. Basically you can ask for a canvas of any size and WebGL will do its best but the size you actually get is in <code class="notranslate">gl.drawingBufferWidth</code> and <code class="notranslate">gl.drawingBufferHeight</code>.</p>
<p dir="auto"><strong>The question is, should three.js and the examples change to handle that?</strong></p>
<p dir="auto">Basically after you call <code class="notranslate">renderer.setSize</code> you need to check what size you actually got by checking <code class="notranslate">gl.drawingBufferWidth</code> and <code class="notranslate">gl.drawingBufferHeight</code> (could be some func like <code class="notranslate">renderer.getSize</code>) and then use those values in your code where appropriate. At the same time you should use <code class="notranslate">gl.canvas.clientWidth</code> and <code class="notranslate">gl.canvas.clientHeight</code> for your aspect ratio because the two won't match</p>
<p dir="auto">NOTE: If you're curious why it's this way imagine you have a machine with 3 monitors side-by-side. Take any three.js sample and resize the window until it crosses and fills all 3 monitors. Let's assume the monitors are 1920x1080. You'll now have a window that's 5760x1080. The code will ask for a canvas 5760x1080 but the driver likely has a limit of 4096. So, rather than crash the spec says the canvas will have its width set to 5760 (so it fills the area of the page it's supposed to fill) but WebGL will make drawingbuffer whatever size it can. In this case probably 4096x1080.</p>
<p dir="auto">Apparently they will look into the issue and see if they can make it return the fullsize on iMac 5k more often but (a) I went into the Apple store to test. It's not a hard coded limit AFAICT. Sometimes the samples work. Other times they don't. That suggests is a memory issue. 5120*2880 is 56meg. Antialiased that's at least 112meg, it's double buffered so that's 168meg, and then there's all the compositing tiles (b) even if they fix it so it happens less often it can still happen if your system is low on memory or if you have multiple monitors so it's still worth considering.</p>
<p dir="auto">Thoughts?</p>