<p dir="auto"><strong>Describe the bug</strong></p>
<p dir="auto">The recent transmission framebuffer is awesome 🎉 but I ran into a couple issues:</p>
<ul dir="auto">
<li>The aspect ratio of the transmission framebuffer is uncoupled from the current render target, creating x / y warping dependent on viewing dimensions</li>
<li>Nearest sampling is used for magnification which creates visual artefacts but there's no obvious motivation for Nearest over Linear here</li>
</ul>
<p dir="auto"><a href="https://github.com/mrdoob/three.js/blob/431baa0a0e808637df959aa547c98e0b2380bdbe/src/renderers/WebGLRenderer.js#L1189">Relevant part of three.js source</a></p>
<div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="_transmissionRenderTarget = new renderTargetType( 1024, 1024, {
	generateMipmaps: true,
	type: utils.convert( HalfFloatType ) !== null ? HalfFloatType : UnsignedByteType,
	minFilter: LinearMipmapLinearFilter,
	magFilter: NearestFilter,
	wrapS: ClampToEdgeWrapping,
	wrapT: ClampToEdgeWrapping
} );"><pre class="notranslate"><span class="pl-s1">_transmissionRenderTarget</span> <span class="pl-c1">=</span> <span class="pl-k">new</span> <span class="pl-s1">renderTargetType</span><span class="pl-kos">(</span> <span class="pl-c1">1024</span><span class="pl-kos">,</span> <span class="pl-c1">1024</span><span class="pl-kos">,</span> <span class="pl-kos">{</span>
	<span class="pl-c1">generateMipmaps</span>: <span class="pl-c1">true</span><span class="pl-kos">,</span>
	<span class="pl-c1">type</span>: <span class="pl-s1">utils</span><span class="pl-kos">.</span><span class="pl-en">convert</span><span class="pl-kos">(</span> <span class="pl-v">HalfFloatType</span> <span class="pl-kos">)</span> <span class="pl-c1">!==</span> <span class="pl-c1">null</span> ? <span class="pl-v">HalfFloatType</span> : <span class="pl-v">UnsignedByteType</span><span class="pl-kos">,</span>
	<span class="pl-c1">minFilter</span>: <span class="pl-v">LinearMipmapLinearFilter</span><span class="pl-kos">,</span>
	<span class="pl-c1">magFilter</span>: <span class="pl-v">NearestFilter</span><span class="pl-kos">,</span>
	<span class="pl-c1">wrapS</span>: <span class="pl-v">ClampToEdgeWrapping</span><span class="pl-kos">,</span>
	<span class="pl-c1">wrapT</span>: <span class="pl-v">ClampToEdgeWrapping</span>
<span class="pl-kos">}</span> <span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
<p dir="auto"><strong>Current three.js</strong><br>
Here we render scattered Points within a refractive sphere, notice the asymmetrical refraction pattern in the lower image and hard pixel edges in both<br>
<a target="_blank" rel="noopener noreferrer nofollow" href="https://user-images.githubusercontent.com/3742992/138747728-e81cc880-2fae-40c7-9823-2ed2f7e7987a.jpg"><img src="https://user-images.githubusercontent.com/3742992/138747728-e81cc880-2fae-40c7-9823-2ed2f7e7987a.jpg" alt="Screenshot 2021-10-25 at 19 00 13" style="max-width: 100%;"></a><br>
<a target="_blank" rel="noopener noreferrer nofollow" href="https://user-images.githubusercontent.com/3742992/138747735-529ed6ea-30ab-4e4a-a932-be391c1267fb.jpg"><img src="https://user-images.githubusercontent.com/3742992/138747735-529ed6ea-30ab-4e4a-a932-be391c1267fb.jpg" alt="Screenshot 2021-10-25 at 19 00 20" style="max-width: 100%;"></a></p>
<p dir="auto"><strong>After correcting</strong><br>
Here we use Linear sample and couple the transmission framebuffer's resolution to the viewing resolution. Refraction patterns are now symmetrical and the hard pixel edges are resolved</p>
<p dir="auto"><a target="_blank" rel="noopener noreferrer nofollow" href="https://user-images.githubusercontent.com/3742992/138748059-d924b62b-c52c-493a-a780-3a2797ee6c64.jpg"><img src="https://user-images.githubusercontent.com/3742992/138748059-d924b62b-c52c-493a-a780-3a2797ee6c64.jpg" alt="Screenshot 2021-10-25 at 19 01 45" style="max-width: 100%;"></a><br>
<a target="_blank" rel="noopener noreferrer nofollow" href="https://user-images.githubusercontent.com/3742992/138748069-3b863319-27f8-4bec-86c2-767a4c114eac.jpg"><img src="https://user-images.githubusercontent.com/3742992/138748069-3b863319-27f8-4bec-86c2-767a4c114eac.jpg" alt="Screenshot 2021-10-25 at 19 02 18" style="max-width: 100%;"></a></p>
<p dir="auto"><strong>To Reproduce</strong></p>
<ul dir="auto">
<li>Use a refracting material with roughness set to 0 (or close 0) and IOR greater than 1</li>
<li>Notice the refraction effect has dimension dependence</li>
<li>Notice hard pixel edges where refraction scales up</li>
</ul>
<p dir="auto"><em><strong>Code</strong></em><br>
Example material</p>
<div class="highlight highlight-source-hx notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="new MeshPhysicalMaterial({
	roughness: 0.0,
	color: 0xffffff,
	transmission: 0.9,
	attenuationTint: new Color(0x59ff),
	attenuationDistance: 1.7,
	clearcoat: 0.9
})"><pre class="notranslate"><span class="pl-k">new</span> <span class="pl-en">MeshPhysicalMaterial</span>({
	<span class="pl-smi">roughness</span>: <span class="pl-c1">0.0</span>,
	<span class="pl-smi">color</span>: <span class="pl-c1">0xffffff</span>,
	<span class="pl-smi">transmission</span>: <span class="pl-c1">0.9</span>,
	<span class="pl-smi">attenuationTint</span>: <span class="pl-k">new</span> <span class="pl-en">Color</span>(<span class="pl-c1">0x59ff</span>),
	<span class="pl-smi">attenuationDistance</span>: <span class="pl-c1">1.7</span>,
	<span class="pl-smi">clearcoat</span>: <span class="pl-c1">0.9</span>
})</pre></div>
<p dir="auto"><em><strong>Live example</strong></em></p>
<p dir="auto">Example above, click "Fix Transmission" to toggle my fix<br>
<a href="https://threejs-issue-22729.netlify.app" rel="nofollow">https://threejs-issue-22729.netlify.app</a></p>
<p dir="auto"><strong>Expected behavior</strong></p>
<p dir="auto">Transmission should be independent of viewing dimensions and use Linear filtering for magnification</p>
<p dir="auto"><strong>Suggested fix</strong></p>
<p dir="auto">The dimension issue has 2 complexities</p>
<ul dir="auto">
<li>WebGL1 requires power-of-two dimensions for mipmapping</li>
<li>Different passes may require different transmission texture dimensions, requiring some level of texture management</li>
</ul>
<p dir="auto">Both these issues can be solved fully but introduce complexity to the three.js codebase. Instead, if we expose creation of transmission textures to the user, they can handle this to suit their needs</p>
<p dir="auto">For example: <a href="https://github.com/haxiomic/three.js-refraction/blob/f90ec8e27b61f0be4974c0da2f15f8789dc5336f/src/Main.hx#L60">https://github.com/haxiomic/three.js-refraction/blob/f90ec8e27b61f0be4974c0da2f15f8789dc5336f/src/Main.hx#L60</a></p>
<p dir="auto"><strong>Platform:</strong></p>
<ul dir="auto">
<li>Device: All</li>
<li>OS: All</li>
<li>Browser: All</li>
<li>Three.js version: [dev, r133.1]</li>
</ul>
<p dir="auto">Reposting <a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="778246160" data-permission-text="Title is private" data-url="https://github.com/mrdoob/three.js/issues/21000" data-hovercard-type="issue" data-hovercard-url="/mrdoob/three.js/issues/21000/hovercard?comment_id=862597968&amp;comment_type=issue_comment" href="https://github.com/mrdoob/three.js/issues/21000#issuecomment-862597968">#21000 (comment)</a> so as to consolidate some remaining issues.</p>
<ol dir="auto">
<li>
<p dir="auto"><code class="notranslate">webgl_loader_gltf_transmission</code> has the <code class="notranslate">transparent</code> property of each sphere to set to <code class="notranslate">false</code>. Is that what the loader should be doing? What should <code class="notranslate">transparent</code> be set to when <code class="notranslate">transmission</code> is non-zero?</p>
</li>
<li>
<p dir="auto">After setting <code class="notranslate">transparent</code> to <code class="notranslate">true</code>, only front-faces show the hot-spot. (This may be a known limitation, but <a class="user-mention notranslate" data-hovercard-type="user" data-hovercard-url="/users/mrdoob/hovercard" data-octo-click="hovercard-link-click" data-octo-dimensions="link_type:self" href="https://github.com/mrdoob">@mrdoob</a> just added support for properly rendering back-faces of double-sided meshes.) There should be two hot-spots.</p>
</li>
</ol>
<p dir="auto"><a target="_blank" rel="noopener noreferrer nofollow" href="https://user-images.githubusercontent.com/1000017/122269153-e4018880-ceaa-11eb-8e14-65e9c56f8866.png"><img width="123" alt="Screen Shot 2021-06-16 at 1 53 43 PM" src="https://user-images.githubusercontent.com/1000017/122269153-e4018880-ceaa-11eb-8e14-65e9c56f8866.png" style="max-width: 100%;"></a></p>
<ol start="3" dir="auto">
<li><del>FIXED: This is caused by issue 7. below.</del></li>
</ol>
<p dir="auto"><a target="_blank" rel="noopener noreferrer nofollow" href="https://user-images.githubusercontent.com/1000017/122269137-e06e0180-ceaa-11eb-991e-6d51fd134415.png"><img width="113" alt="Screen Shot 2021-06-16 at 1 51 42 PM" src="https://user-images.githubusercontent.com/1000017/122269137-e06e0180-ceaa-11eb-991e-6d51fd134415.png" style="max-width: 100%;"></a></p>
<ol start="4" dir="auto">
<li><del>FIXED Also, in Chrome and Firefox (not Safari)</del></li>
</ol>
<blockquote>
<p dir="auto"><del>THREE.WebGLProgram: gl.getProgramInfoLog() WARNING: Output of vertex shader 'vUv' not read by fragment shader</del></p>
</blockquote>
<p dir="auto"><del>Transmission always sets the <code class="notranslate">USE_UV</code> flag.</del></p>
<ol start="5" dir="auto">
<li><del>FIXED: If performant, I think the dimensions of the "transmission render target" should match the dimensions of the "current render target".</del> Doing so will prevent artifacts like the following:</li>
</ol>
<p dir="auto"><a target="_blank" rel="noopener noreferrer nofollow" href="https://user-images.githubusercontent.com/1000017/123011145-ddcd4980-d38d-11eb-9a14-6284ed3ed306.png"><img width="555" alt="Screen Shot 2021-06-21 at 9 04 34 PM" src="https://user-images.githubusercontent.com/1000017/123011145-ddcd4980-d38d-11eb-9a14-6284ed3ed306.png" style="max-width: 100%;"></a></p>
<ol start="6" dir="auto">
<li><del>FIXED In the following code snippet, <code class="notranslate">transmissionFactor</code> is applied to <code class="notranslate">getIBLVolumeRefraction()</code> twice. I expect that is a physical modeling error.</del></li>
</ol>
<p dir="auto"></p><div class="Box Box--condensed my-2">
  <div class="Box-header f6">
    <p class="mb-0 text-bold">
      <a href="https://github.com/mrdoob/three.js/blob/dd6ab3cf310f78a8375b8b2037db12ce8e31e82c/src/renderers/shaders/ShaderChunk/transmission_fragment.glsl.js#L23-L28">three.js/src/renderers/shaders/ShaderChunk/transmission_fragment.glsl.js</a>
    </p>
    <p class="mb-0 color-fg-muted">
        Lines 23 to 28
      in
      <a data-pjax="true" class="commit-tease-sha" href="/mrdoob/three.js/commit/dd6ab3cf310f78a8375b8b2037db12ce8e31e82c">dd6ab3c</a>
    </p>
  </div>
  <div itemprop="text" class="Box-body p-0 blob-wrapper blob-wrapper-embedded data">
    <table class="highlight tab-size mb-0 js-file-line-container" data-tab-size="8" data-paste-markdown-skip="">

        <tbody><tr class="border-0">
          <td id="L23" class="blob-num border-0 px-3 py-0 color-bg-default" data-line-number="23"></td>
          <td id="LC23" class="blob-code border-0 px-3 py-0 color-bg-default blob-code-inner js-file-line"> <span class="pl-s">	vec3 transmission = transmissionFactor * getIBLVolumeRefraction(</span> </td>
        </tr>

        <tr class="border-0">
          <td id="L24" class="blob-num border-0 px-3 py-0 color-bg-default" data-line-number="24"></td>
          <td id="LC24" class="blob-code border-0 px-3 py-0 color-bg-default blob-code-inner js-file-line"> <span class="pl-s">		normal, v, roughnessFactor, material.diffuseColor, totalSpecular,</span> </td>
        </tr>

        <tr class="border-0">
          <td id="L25" class="blob-num border-0 px-3 py-0 color-bg-default" data-line-number="25"></td>
          <td id="LC25" class="blob-code border-0 px-3 py-0 color-bg-default blob-code-inner js-file-line"> <span class="pl-s">		pos, modelMatrix, viewMatrix, projectionMatrix, ior, thicknessFactor,</span> </td>
        </tr>

        <tr class="border-0">
          <td id="L26" class="blob-num border-0 px-3 py-0 color-bg-default" data-line-number="26"></td>
          <td id="LC26" class="blob-code border-0 px-3 py-0 color-bg-default blob-code-inner js-file-line"> <span class="pl-s">		attenuationColor, attenuationDistance );</span> </td>
        </tr>

        <tr class="border-0">
          <td id="L27" class="blob-num border-0 px-3 py-0 color-bg-default" data-line-number="27"></td>
          <td id="LC27" class="blob-code border-0 px-3 py-0 color-bg-default blob-code-inner js-file-line"> <span class="pl-s"></span> </td>
        </tr>

        <tr class="border-0">
          <td id="L28" class="blob-num border-0 px-3 py-0 color-bg-default" data-line-number="28"></td>
          <td id="LC28" class="blob-code border-0 px-3 py-0 color-bg-default blob-code-inner js-file-line"> <span class="pl-s">	totalDiffuse = mix( totalDiffuse, transmission, transmissionFactor );</span> </td>
        </tr>
    </tbody></table>
  </div>
</div>
<p></p>
<ol start="7" dir="auto">
<li><del>FIXED Also in the above snippet, <code class="notranslate">totalSpecular</code> has units of radiance, and therefore cannot be the correct argument because the function expects a unit-less quantity. A reasonable guess would be <code class="notranslate">material.specularColor</code>, instead.</del></li>
</ol>
<ul dir="auto">
<li>Device: Desktop</li>
<li>OS: macOS 11.4</li>
<li>Browser: Chrome, Firefox, Safari</li>
<li>Three.js version: r130dev</li>
</ul>
<p dir="auto">/ping <a class="user-mention notranslate" data-hovercard-type="user" data-hovercard-url="/users/takahirox/hovercard" data-octo-click="hovercard-link-click" data-octo-dimensions="link_type:self" href="https://github.com/takahirox">@takahirox</a> <a class="user-mention notranslate" data-hovercard-type="user" data-hovercard-url="/users/donmccurdy/hovercard" data-octo-click="hovercard-link-click" data-octo-dimensions="link_type:self" href="https://github.com/donmccurdy">@donmccurdy</a></p>