title: Need help understanding how this shader code works
body: <p>source: <a href="https://github.com/microsoft/Win2D-Samples/blob/master/ExampleGallery/Shaders/Mandelbrot.hlsl" rel="nofollow noreferrer">https://github.com/microsoft/Win2D-Samples/blob/master/ExampleGallery/Shaders/Mandelbrot.hlsl</a></p>
  <p>line 50:</p>
  <pre><code>float4 vectorResult = isfinite(distanceSquared) ? saturate(1 - distanceSquared) : 0;
  </code></pre>
  <p>What is the purpose of <code>saturate</code> here? I understand that it clamps the vector between 0 and 1, so only small values of <code>distanceSquared</code> will be non-zero after this. With the standard escape time algorithm the distance is compared against a cutoff radius during each iteration to determine if the current iteration of 'z' has escaped the set's boundaries, but this is obviously something different. How does this work to determine if a given point is contained in the mandelbrot set?</p>
  <p><strong>Edit:</strong> See edit below. If <code>distanceSquared</code> contains finite floating point values that are relatively close to the origin in terms of magnitude then we consider it to be inside the set.</p>
  <p>line 52:</p>
  <pre><code>// Resolve the supersampling to produce a single scalar result.
  float result = dot(vectorResult, 0.25);
  </code></pre>
  <p>What is <code>result</code> supposed to be representing? Is it significant that 0.25 is the same as the offset of each inner pixel sample? How does the squared magnitude affect this value?</p>
  <p><strong>Edit:</strong> <code>result</code> is essentially the &quot;average&quot; of all 4 values in <code>vectorResult</code>. Those values will be in the range of 0 &lt;= value &lt; 1, where a higher value represents a smaller magnitude (result of 1 - distanceSquared). I understand this piece now.</p>
  <p>line 55:</p>
  <pre><code>if (result &lt; 1.0 / 256)
      return 0;
  else
      return float4(result, result, result, 1);
  </code></pre>
  <p>What is the significance of checking &lt; 1.0 / 256? Seems like any outliers would definitely be 0 and the check could be simplified to == 0. Not sure though. Might be missing something here as well.</p>
  <p><strong>Edit:</strong> Still not sure about this part. I haven't noticed a visual difference using == 0 instead of this check. Wondering if it needs to be there and if so why.</p>
  <p><strong>Edit:</strong> For example, I'm beginning to modify it, and this version without branching seems to produce the same result</p>
  <pre><code>float4 cr = (pos.x - center.x + samplesX) * scale;
  float4 ci = (pos.y - center.y + samplesY) * scale;
  
  float4 zr = 0;
  float4 zi = 0;
  
  [unroll(iterations)] for (int i = 0; i &lt; iterations; i++)
  {
      float4 z2r = zr * zr - zi * zi;
      float4 z2i = zr * zi * 2;
  
      zr = z2r + cr;
      zi = z2i + ci;
  }
  
  // Adjust our four parallel results to range 0:1.
  float4 distanceSquared = zr * zr + zi * zi;
  
  float4 vectorResult = saturate(1 - distanceSquared);
  
  // Resolve the supersampling to produce a single scalar result.
  float result = dot(vectorResult, 0.25);
  
  return float4(result, result, result, 1);
  </code></pre>