jsl-prism.PaintTextureSecondPassLCD.jsl Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of openjfx-78-backport-native Show documentation
Show all versions of openjfx-78-backport-native Show documentation
This contains the native files for the backport of OpenJFX 8 to run on Java 7.
The newest version!
/*
* Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
param sampler dstColor;
param sampler glyphColor;
param float3 gamma; // gamma.x := gamma and gamma.y := 1/gamma
// gamma.z := unitXCoord
//This is the beef of the LCD Algorithm
//must inverse gamma each
float4 paint(float2 texCoord, float2 texCoord2, float4 jslVertexColor)
{
// Sub-pixel positioning
float unitXCoord = gamma.z;
float2 dTexCoord = texCoord;
float4 glyphClr;
// Negative unitXCoord can be used for BGR sub pixel structure
dTexCoord.x = texCoord.x - unitXCoord; // Left sub-pixel of center
glyphClr.r = sample(glyphColor, dTexCoord).a;
glyphClr.g = sample(glyphColor, texCoord).a;
dTexCoord.x = texCoord.x + unitXCoord; // Right sub-pixel of center
glyphClr.b = sample(glyphColor, dTexCoord).a;
// glyphClr.a defined as average texel coverage of glyph
const float third = 1.0/3.0;
glyphClr.a = dot(glyphClr.rgb, float3(third, third, third));
if (glyphClr.a == 0.0) {
discard;
}
float4 dstClr = sample(dstColor, texCoord2);
/*
* Sub-pixel blending with non-opaque destination
*
* Sub-pixel/LCD blending can only occur over opaque colors in the
* destination.
*
* Grayscale texel can be defined as an average texel coverage of glyph.
* avg(g.rgb) := (g.r + g.g + r.b)/3.0
* Grayscale SRC_OVER blend equation is given by:
* (1) grayScaleResult = d * (1.0 - s.a * avg(g.rgb)) + s * avg(g.rgb);
* where we define variables:
* - g := glyph color
* - s := source color
* - d := destination color
*
* The SRC_OVER result of LCD blending to opaque destination can be obtained
* via equation:
* (2) LCDResult = d*(1 - g*s.a) + g*s
* provided d.a == 1
* If we ignore transparent part of destination equation (2) becomes:
* (3) LCDOpaqueDstResult = (d/d.a) * (1 - g*s.a) + g*s
*
* Now we can derive an equation, which can handle non-opaque destination.
* Let f(d.a) be a function, which depends on destination alpha (d.a) and
* satisfies the conditions:
* 1. For opaque destination we want LCD result by using blend equation (3)
* 2. For fully transparent destination we should get grayscale results via
* blend equation (1)
* 3. Must satisfy pre-multiplication condition.
* Mathematically these conditions can be expressed:
* 1. f(1) = LCDOpaqueDstResult = (d/d.a)*(1 - g*s.a) + g*s
*
* 2. f(0) = d * (1 - avg(g) * s.a) + avg(g) * s
* = avg(g) * s
* Since d == <0,0,0,0>
* 3. It can be shown that (f(0).rgb <= f(0).a) && (f(1).rgb <= f(1)) is true
*
* Finally we can derive f(d.a), as a linear distribution from f(0) to f(1),
* and which satisfies the above conditions:
* f(d.a) = f(0) * (1 - d.a) + f(1) * d.a
* = avg(g) * s * (1-d.a) + ((d/d.a)*(1 - g*s) + g*s) * d.a
* = d*(1-g*s) + s *(avg(g) * (1-d.a) + g * d.a)
* which simplifies to:
* f(d.a) = d*(1-g*s) + s * mix(avg(g), g, d.a)
*/
dstClr = pow(dstClr, float4(gamma.y, gamma.y, gamma.y, gamma.y));
float4 c = jslVertexColor;
// Source over LCD blend equation, which handles transparency.
// REMIND this does not work with default alpha blending:
// D3DRS_SRCBLEND, D3DBLEND_ONE no change to source color
// D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA or (1 - src.a)
// Requires that alpha channel composite is turned off (SRC composite mode).
float4 glyphMix;
glyphMix.a = glyphClr.a;
glyphMix.rgb = mix(float3(glyphClr.a, glyphClr.a, glyphClr.a), glyphClr.rgb, dstClr.a);
c = dstClr * (1.0 - glyphClr * c.a) + c * glyphMix;
c = pow(c, float4(gamma.x, gamma.x, gamma.x, gamma.x));
return c;
}