<h5 dir="auto">TLDR</h5>
<p dir="auto">If you render to a <code class="notranslate">CubeCamera</code> and</p>
<ul dir="auto">
<li>
<p dir="auto">have <code class="notranslate">renderer.outputEncoding != renderTarget.texture.encoding</code>, at each render, for each material a <code class="notranslate">.acuireProgram()</code> will be called, which is slow. (<a href="https://jsfiddle.net/ebvr4xmw/" rel="nofollow">Example</a>) (covered by <a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="595236749" data-permission-text="Title is private" data-url="https://github.com/mrdoob/three.js/issues/19056" data-hovercard-type="issue" data-hovercard-url="/mrdoob/three.js/issues/19056/hovercard" href="https://github.com/mrdoob/three.js/issues/19056">#19056</a>)</p>
</li>
<li>
<p dir="auto">have light-based materials, at each render for each material a new <code class="notranslate">.initMaterial()</code> will be called, which is slow due to <code class="notranslate">.cloneUniforms()</code>(<a href="https://jsfiddle.net/1muvze3k/" rel="nofollow">Example</a>) (covered by <a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="307373360" data-permission-text="Title is private" data-url="https://github.com/mrdoob/three.js/issues/13656" data-hovercard-type="issue" data-hovercard-url="/mrdoob/three.js/issues/13656/hovercard" href="https://github.com/mrdoob/three.js/issues/13656">#13656</a>, <a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="325721720" data-permission-text="Title is private" data-url="https://github.com/mrdoob/three.js/issues/14121" data-hovercard-type="issue" data-hovercard-url="/mrdoob/three.js/issues/14121/hovercard" href="https://github.com/mrdoob/three.js/issues/14121">#14121</a> and now <a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="639509793" data-permission-text="Title is private" data-url="https://github.com/mrdoob/three.js/issues/19673" data-hovercard-type="pull_request" data-hovercard-url="/mrdoob/three.js/pull/19673/hovercard" href="https://github.com/mrdoob/three.js/pull/19673">#19673</a>)</p>
</li>
</ul>
<h5 dir="auto">Description of the problem</h5>
<p dir="auto">I noticed a severe performance regression when updating to latest THREE version (r117), causing my rendering times to increase from ~3ms to ~200ms. My scenes heavily rely on CubeCamera's, and I noticed an unusually high amount of material recompiles.</p>
<p dir="auto">It appears that if you render a <code class="notranslate">CubeCamera</code> and you either</p>
<ul dir="auto">
<li>have <code class="notranslate">renderer.outputEncoding != renderTarget.texture.encoding</code> <strong>or</strong></li>
<li>have a light based material in your scene</li>
</ul>
<p dir="auto">that <code class="notranslate">lightsStateVersion</code> property will flip/flop between the CubeCamera and main cameras renderStates, causing unnecessary calls to <code class="notranslate">initMaterial</code>. Even if the material does not need to be recompiled, the calculation of <code class="notranslate">programCacheKey</code> takes longer than usual, probably because it now involves cloning of the material's uniforms.</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="
{
lightsStateVersion: 6,
materialProperties.lightsStateVersion: 5,
//^^^^^this causes the recompile^^^^^^

parameters.shaderID: &quot;basic&quot;,
program: WebGLProgram {name: &quot;MeshBasicMaterial&quot;, id: 81, getUniforms: ƒ, getAttributes: ƒ, destroy: ƒ, …},
program.cacheKey: &quot;basic,highp,false,true,3000,false,false,3000,false,3000,false,,3000,false,false,3000,false,false,3000,false,false,false,false,false,false,false,false,false,false,false,false,false,0,false,,false,false,false,true,,false,,false,false,0,true,false,,8,4,false,0,0,0,0,0,0,0,0,false,1,0,false,0,false,false,0,0,false,false,false,3001,2,...&quot;,
programCacheKey: &quot;basic,highp,false,true,3001,false,false,3000,false,3000,false,,3000,false,false,3000,false,false,3000,false,false,false,false,false,false,false,false,false,false,false,false,false,0,false,,false,false,false,true,,false,,false,false,0,true,false,,8,4,false,0,0,0,0,0,0,0,0,false,1,0,false,0,false,false,0,0,false,false,false,3001,2,...&quot;,
programChange: true
}"><pre class="notranslate"><code class="notranslate">
{
lightsStateVersion: 6,
materialProperties.lightsStateVersion: 5,
//^^^^^this causes the recompile^^^^^^

parameters.shaderID: "basic",
program: WebGLProgram {name: "MeshBasicMaterial", id: 81, getUniforms: ƒ, getAttributes: ƒ, destroy: ƒ, …},
program.cacheKey: "basic,highp,false,true,3000,false,false,3000,false,3000,false,,3000,false,false,3000,false,false,3000,false,false,false,false,false,false,false,false,false,false,false,false,false,0,false,,false,false,false,true,,false,,false,false,0,true,false,,8,4,false,0,0,0,0,0,0,0,0,false,1,0,false,0,false,false,0,0,false,false,false,3001,2,...",
programCacheKey: "basic,highp,false,true,3001,false,false,3000,false,3000,false,,3000,false,false,3000,false,false,3000,false,false,false,false,false,false,false,false,false,false,false,false,false,0,false,,false,false,false,true,,false,,false,false,0,true,false,,8,4,false,0,0,0,0,0,0,0,0,false,1,0,false,0,false,false,0,0,false,false,false,3001,2,...",
programChange: true
}
</code></pre></div>
<p dir="auto">You can find an example here:</p>
<ul dir="auto">
<li><a href="https://jsfiddle.net/ebvr4xmw/" rel="nofollow">TextureEncodings</a></li>
<li><a href="https://jsfiddle.net/1muvze3k/" rel="nofollow">Light-based material</a></li>
</ul>
<p dir="auto">I didn't bisect the commit in question, but it appears to have happened between [r112,r115].</p>
<p dir="auto"><strong>TextureEncoding</strong><br>
I don't expect all involved renderTargets to have the same encodings, but if that should be the case, I would recommend a corresponding warning message. On the other hand, IMHO the encoding of the renderTarget should not affect caching of the object's material at all? Although if it does, it might make sense to cache the material multiple times for each different encoding instead of flip/flopping between both encoding and causing a recompilation every time.</p>
<p dir="auto">Thanks for investigating, please let me know if I can supply additional information.</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=""> r117</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> r116</li>
<li>[?] ....</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox"> r111</li>
</ul>
<h5 dir="auto">Browser</h5>
<ul class="contains-task-list">
<li>[?] 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>[?] Internet Explorer</li>
</ul>
<h5 dir="auto">OS</h5>
<ul class="contains-task-list">
<li>[?] All of them</li>
<li>[?] Windows</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> macOS</li>
<li>[?] Linux</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> Android</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> iOS</li>
</ul>
<h5 dir="auto">Description of the problem</h5>
<p dir="auto">Hi there,</p>
<p dir="auto">I'm working on an application that renders the same scene twice in a single frame, once without post processing and once using EffectsComposer. The use case is basically an editor with a thumbnail preview of the scene with postfx.</p>
<p dir="auto">This seems to trigger a shader recompilation, as has been discovered in a few other issues*. The advice so far has been to only use EffectsComposer and apply gamma correction as a pass in the effects chain, but this is pretty problematic for our use case as we use line rendering quite a bit for e.g. reference grids so losing hardware AA when using RTT results in unacceptable image quality.</p>
<p dir="auto">A potential work around is setting the encoding of all render targets in the EffectComposer chain to use sRGB encoding, but I'm not certain what problems this might produce and feels brittle since there is no way to <em>force</em> every pass to use the correct encoding as far as I know. But results should still be correct, since my understanding of using sRGB encoding for a texture is that hardware then performs the appropriate conversions on reads/writes, so shaders can still run code as if the data was linear.</p>
<p dir="auto">It seems that the necessary conditions to reproduce are:</p>
<ul dir="auto">
<li>sRGB encoding for <code class="notranslate">renderer.outputEncoding</code></li>
<li>using two different cameras</li>
<li>RTT (EffectsComposer in this case)</li>
</ul>
<p dir="auto">Stepping through the code it seems specifically to do with the <a href="https://github.com/mrdoob/three.js/issues/14121" data-hovercard-type="issue" data-hovercard-url="/mrdoob/three.js/issues/14121/hovercard"><code class="notranslate">renderContext.state.lights</code> version</a> being different for each camera, which then triggers a check of the various properties against those when the program was created, which in will fail due to the different renderTargets and their encoding.</p>
<p dir="auto"><a href="https://jsfiddle.net/BruOps/qy6o74pn/9/" rel="nofollow">https://jsfiddle.net/BruOps/qy6o74pn/9/</a></p>
<ul dir="auto">
<li>Related:<br>
<a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="580514624" data-permission-text="Title is private" data-url="https://github.com/mrdoob/three.js/issues/18893" data-hovercard-type="issue" data-hovercard-url="/mrdoob/three.js/issues/18893/hovercard" href="https://github.com/mrdoob/three.js/issues/18893">#18893</a><br>
<a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="568974772" data-permission-text="Title is private" data-url="https://github.com/mrdoob/three.js/issues/18699" data-hovercard-type="issue" data-hovercard-url="/mrdoob/three.js/issues/18699/hovercard" href="https://github.com/mrdoob/three.js/issues/18699">#18699</a><br>
<a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="547689143" data-permission-text="Title is private" data-url="https://github.com/mrdoob/three.js/issues/18355" data-hovercard-type="issue" data-hovercard-url="/mrdoob/three.js/issues/18355/hovercard" href="https://github.com/mrdoob/three.js/issues/18355">#18355</a><br>
<del><a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="325721720" data-permission-text="Title is private" data-url="https://github.com/mrdoob/three.js/issues/14121" data-hovercard-type="issue" data-hovercard-url="/mrdoob/three.js/issues/14121/hovercard" href="https://github.com/mrdoob/three.js/issues/14121">#14121</a></del></li>
</ul>
<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=""> r115</li>
</ul>
<p dir="auto">Introduced in r112</p>
<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" checked=""> All of them</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox"> Chrome</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox"> 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" checked=""> All of them</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox"> 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 Requirements (graphics card, VR Device, ...)</h5>
<p dir="auto">None</p>