title: Gamma correct treatment of sRGB textures in THREE.js
body: <p>I can't get three.js to treat my sRGB texture correctly.  What am I supposed to do?</p>
  
  <p>Here is the sRGB test image that should appear uniformly 50% gray:</p>
  
  <p><a href="https://i.stack.imgur.com/j8c7H.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/j8c7H.png" alt="An sRGB test image that should appear completely 50% gray."></a></p>
  
  <p>It consists primarily of alternating black and white pixels in a checkerboard pattern.  black = (0,0,0)  white = (255,255,255)
  This should result in an average linear intensity of 50%.
  There are three patches of a 50% intensity grey color in the middle, which is encoded in sRGB as (188,188,188)  (explained below).</p>
  
  <blockquote>
    <p>explaination: (see Wikipedia article for <a href="https://en.wikipedia.org/wiki/SRGB" rel="nofollow noreferrer">sRGB</a>
    which says that a normalized 50% intensity should get an sRGB value of (1.055*0.5^(1/2.4))-0.055 =
    0.735358, which is about 187.516 in 8-bit sRGB, hence the logic of encoding it as 188.</p>
  </blockquote>
  
  <p>Visually, the texture is clearly correct when viewed natively on any suitably calibrated monitor, and likely looks OK in this posting unless your browser has scaled the image down.  (Browsers tend to fail on gamma-correct downsampling too, so please view the image at its native resolution if you can easily see the three bars already.)</p>
  
  <p>When scaling down this image, most naive software will simply average the sRGB encodings and arrive at bogus intensities that are too dark.  The black and white pixels will be naively averaged as (0+255)/2, to get a color of (128,128,128), which is only about 22% intensity (((128/255)+0.055)/(1.055)^2.4) =~ 0.215861.  This is considerably darker than the desired intensity of 50% that would be the average intensity of equal contributions of 0% and 100%.  And intuitively, "half brightness" is 50%.</p>
  
  <p>In OpenGL, this is easy.  You simply treat the texture as sRGB and use an sRGB frame buffer.  Texture samples are converted from the sRGB encoding to linear when sampled, and linear values are encoded as sRGB when written to the frame buffer and all is well.</p>
  
  <p>I'm at a complete loss for how to achieve this within the three.js framework though.  Can someone help?</p>
  
  <p>I've tried setting...</p>
  
  <pre><code>renderer.gammaFactor = 2.2;
  renderer.gammaInput = true;
  renderer.gammaOutput = true;`
  </code></pre>
  
  <p>...but it really appears that the mipmap generation does not treat the texture as sRGB properly.  I didn't do anything special when loading the texture -- just used THREE.TextureLoader.</p>
  
  <pre><code>var texture = textureLoader.load( 'images/gamma_srgb.png' );
  </code></pre>
  
  <p>But here is the poor quality result where the checkerboard part of the image gets too dark, but the solid color areas of the image are much brighter.  <a href="https://i.stack.imgur.com/qMs2l.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/qMs2l.png" alt="Example output with bad gamma treatment"></a></p>
  
  <p>FYI, I did create the WebGLRenderer with <code>{antialias: true}</code> and I did set <code>maxAnisotropy</code> on the texture to the renderer's max anisotropy value.</p>
  
  <p><strong>EDIT:</strong>  Added a repro in jsfiddle.  <a href="https://jsfiddle.net/fvusxp1g/" rel="nofollow noreferrer">https://jsfiddle.net/fvusxp1g/</a></p>