<div dir="ltr">
<p><span lang="EN-GB" style="font-size:10.0pt;font-family:"Arial",sans-serif;
color:black;mso-ansi-language:EN-GB">Hello Robert,</span></p>
<p><span lang="EN-GB" style="font-size:10.0pt;font-family:"Arial",sans-serif;
color:black;mso-ansi-language:EN-GB"> </span></p>
<p><span lang="EN-GB" style="font-size:10.0pt;font-family:"Arial",sans-serif;
color:black;mso-ansi-language:EN-GB">I toyed around with SDF and discovered some problems in the fragment shader that I managed to solve.</span></p>
<p><span lang="EN-GB" style="font-size:10.0pt;font-family:"Arial",sans-serif;
color:black;mso-ansi-language:EN-GB"> </span></p>
<p><span lang="EN-GB" style="font-size:10.0pt;font-family:"Arial",sans-serif;
color:black;mso-ansi-language:EN-GB">There seems to be a bug in the multisampling/blending
code. Affected are semi-transparent texts. It’s most obvious for glyphs with a
big fill area, like e.g. for the bullet character.<font color="#004000" face=""Arial","Helvetica",sans-serif"> </font></span><span lang="EN-GB" style="font-size:10.0pt;font-family:"Arial",sans-serif;
color:black;mso-ansi-language:EN-GB">In the attached picture, the upper bullet
character was rendered with the original shader and an alpha value of 0.2. It looks
totally wrong. For comparison, the second line was rendered with an alpha value
of 1 and is fine.</span></p>
<p><span lang="EN-GB" style="font-size:10.0pt;font-family:"Arial",sans-serif;
color:black;mso-ansi-language:EN-GB"><br></span></p><p><span lang="EN-GB" style="font-size:10.0pt;font-family:"Arial",sans-serif;
color:black;mso-ansi-language:EN-GB">In order to find out what’s wrong I
rewrote the code applying the basic blending “trick” – doing linear
combinations of colours with premultiplied alpha only. (Let’s call them colours
in pma format, the transform function being pma[ (r,g,b,a) ] -> (r*a,g*a,b*a,a).)<font color="#004000" face=""Arial","Helvetica",sans-serif"> </font></span><span lang="EN-GB" style="font-size:10.0pt;font-family:"Arial",sans-serif;
color:black;mso-ansi-language:EN-GB">This resolved the issue for me, semi-transparent
characters now render visually correct.</span></p>
<p><span lang="EN-GB" style="font-size:10.0pt;font-family:"Arial",sans-serif;
color:black;mso-ansi-language:EN-GB"><br></span></p><p><span lang="EN-GB" style="font-size:10.0pt;font-family:"Arial",sans-serif;
color:black;mso-ansi-language:EN-GB">So, what I did, is:</span></p>
<ol type="1" style="margin-top:0cm" start="1">
<li style="color: black; font-family:; font-size: 10pt; font-style: normal; font-weight: 400; margin-left: 0cm;"><span lang="EN-GB" style="font-size:10.0pt;font-family:"Arial",sans-serif;
mso-ansi-language:EN-GB">Apply pma transformation to the source colours
(vertex colour, border colour)</span></li>
<li style="color: black; font-family:; font-size: 10pt; font-style: normal; font-weight: 400; margin-left: 0cm;"><span lang="EN-GB" style="font-size:10.0pt;font-family:"Arial",sans-serif;
mso-ansi-language:EN-GB">Do the multisampling. Simply calculate the mean
of the sampled colours. Each sampled colour is a linear combination of the
source colours, so too in pma format.</span></li>
<li style="color: black; font-family:; font-size: 10pt; font-style: normal; font-weight: 400; margin-left: 0cm;"><span lang="EN-GB" style="font-size:10.0pt;font-family:"Arial",sans-serif;
mso-ansi-language:EN-GB">Apply inverse pma transformation for to get the resulting
fragment colour (to be blended with default blend mode (GL_SRC_ALPHA,
GL_ONE_MINUS_SRC_ALPHA)).</span></li>
</ol>
<p style="text-align:justify"><span lang="EN-GB" style="font-size:10.0pt;font-family:"Arial",sans-serif;color:black;mso-ansi-language:
EN-GB">This algorithm can be simplified. Obviously, the resulting fragment
colour too is just a linear combination of the source colours. So, I changed
the multisampling loop to only sample the coefficients for the source colours.(It’s
applying distributive law.) </span><span lang="EN-GB" style="font-size:10.0pt;font-family:"Arial",sans-serif;color:black;mso-ansi-language:
EN-GB">This in turn made me get rid of the pma and inverse pma transformations.</span></p>
<p style="text-align:justify"><span lang="EN-GB" style="font-size:10.0pt;font-family:"Arial",sans-serif;color:black;mso-ansi-language:
EN-GB"> </span></p>
<p style="text-align:justify"><span lang="EN-GB" style="font-size:10.0pt;font-family:"Arial",sans-serif;color:black;mso-ansi-language:
EN-GB">And it also helped resolving the second issue that I had with the shader:
Shadow backdrops were not rendered correctly. The problem was caused but
following lines of code:</span></p>
<p style="text-align:justify"><span lang="EN-GB" style="font-size:10.0pt;font-family:"Arial",sans-serif;color:black;mso-ansi-language:
EN-GB"> </span></p>
<p style="text-align:justify"><span lang="EN-GB" style="font-size:10.0pt;font-family:"Arial",sans-serif;color:black;mso-ansi-language:
EN-GB"><span style="mso-spacerun:yes"> </span>total_color.rgb /=
total_color.a;</span></p>
<p style="text-align:justify"><span lang="EN-GB" style="font-size:10.0pt;font-family:"Arial",sans-serif;color:black;mso-ansi-language:
EN-GB"><span style="mso-spacerun:yes"> </span>total_color.a *= scale;</span></p>
<p style="text-align:justify"><span lang="EN-GB" style="font-size:10.0pt;font-family:"Arial",sans-serif;color:black;mso-ansi-language:
EN-GB"><span style="mso-spacerun:yes"> </span>return total_color;</span></p>
<p style="text-align:justify"><span lang="EN-GB" style="font-size:10.0pt;font-family:"Arial",sans-serif;color:black;mso-ansi-language:
EN-GB"> </span></p>
<p style="text-align:justify"><span lang="EN-GB" style="font-size:10.0pt;font-family:"Arial",sans-serif;color:black;mso-ansi-language:
EN-GB">I think the division could turn out to be 0.0 / 0.0 which may have
produced NaNs or unspecified results.</span></p>
<p style="text-align:justify"><span lang="EN-GB" style="font-size:10.0pt;font-family:"Arial",sans-serif;color:black;mso-ansi-language:
EN-GB"> </span></p>
<p style="text-align:justify"><span lang="EN-GB" style="font-size:10.0pt;font-family:"Arial",sans-serif;color:black;mso-ansi-language:
EN-GB">A minor issue I encountered that prevented the shader to compile on my
GLSL ES 1.0 system. </span></p>
<p style="text-align:justify"><span lang="EN-GB" style="font-size:10.0pt;font-family:"Arial",sans-serif;color:black;mso-ansi-language:
EN-GB">The function texture2DLod is specified by the GLSL ES 1.0, GLSL 1.1,
GLSL 1.2 specifications only for use in vertex shader. It may be available
though. In my case it wasn’t, but the extension texture2DLodEXT was.</span></p>
<p style="text-align:justify"><span lang="EN-GB" style="font-size:10.0pt;font-family:"Arial",sans-serif;color:black;mso-ansi-language:
EN-GB">So I made an extra check to prefer that extension, if available, for
GLSL ES 1.0 only.</span></p>
<p style="text-align:justify"><span lang="EN-GB" style="font-size:10.0pt;font-family:"Arial",sans-serif;color:black;mso-ansi-language:
EN-GB"> </span></p>
<p style="text-align:justify"><span lang="EN-GB" style="font-size:10.0pt;font-family:"Arial",sans-serif;color:black;mso-ansi-language:
EN-GB">I experienced another issue that I wasn’t able to solve so far.</span></p>
<p style="text-align:justify"><span lang="EN-GB" style="font-size:10.0pt;font-family:"Arial",sans-serif;color:black;mso-ansi-language:
EN-GB">On my embedded ES 2.0 system, the GL_OES_standard_derivatives extension is
available but the functions dFdx /</span><span lang="EN-GB" style="mso-ansi-language:
EN-GB"> </span><span lang="EN-GB" style="font-size:10.0pt;font-family:"Arial",sans-serif;
color:black;mso-ansi-language:EN-GB">dFdy just seem to deliver bad results.</span></p>
<p style="text-align:justify"><span lang="EN-GB" style="font-size:10.0pt;font-family:"Arial",sans-serif;color:black;mso-ansi-language:
EN-GB">I don’t know why. Could it be non-conforming usage? A driver or GPU bug? As a
workaround, I’ve switched to using a simpler shader for that system only, which
doesn’t do multisampling. The result seems still fine.</span></p>
<p style="text-align:justify"><span lang="EN-GB" style="font-size:10.0pt;font-family:"Arial",sans-serif;color:black;mso-ansi-language:
EN-GB"> </span></p>
<p style="text-align:justify"><span lang="EN-GB" style="font-size:10.0pt;font-family:"Arial",sans-serif;color:black;mso-ansi-language:
EN-GB">Please check out my changes. I’ll do a pull request. I hope this is
helpful, SDF is really a cool feature.</span></p>
<p style="text-align:justify"><span lang="EN-GB" style="font-size:10.0pt;font-family:"Arial",sans-serif;color:black;mso-ansi-language:
EN-GB">The shader could surely further be simplified when adapting it to blend mode
(GL_ONE, GL_ONE_MINUS_SRC_ALPHA), which would be a bit easier to deal with.</span></p>
<p style="text-align:justify"><span lang="EN-GB" style="font-size:10.0pt;font-family:"Arial",sans-serif;color:black;mso-ansi-language:
EN-GB">I also wondered if the extensive bounds checking for smoothstep when
sampling the colours/coefficients is still adequate for performance.</span></p>
<p style="text-align:justify"><span lang="EN-GB" style="font-size:10.0pt;font-family:"Arial",sans-serif;color:black;mso-ansi-language:
EN-GB"> </span></p>
<p style="text-align:justify"><span lang="EN-GB" style="font-size:10.0pt;font-family:"Arial",sans-serif;color:black;mso-ansi-language:
EN-GB">Regards,</span></p>
<p style="text-align:justify"><span lang="EN-GB" style="font-size:10.0pt;font-family:"Arial",sans-serif;color:black;mso-ansi-language:
EN-GB">Hannes</span></p>
</div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups "OpenSceneGraph Users" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an email to <a href="mailto:osg-users+unsubscribe@googlegroups.com">osg-users+unsubscribe@googlegroups.com</a>.<br />
To view this discussion on the web visit <a href="https://groups.google.com/d/msgid/osg-users/575dbd7a-cac9-418f-86da-a9f14ff1d9f3%40googlegroups.com?utm_medium=email&utm_source=footer">https://groups.google.com/d/msgid/osg-users/575dbd7a-cac9-418f-86da-a9f14ff1d9f3%40googlegroups.com</a>.<br />