<?xml version="1.0"?>
<?xml-stylesheet type="text/css" href="http://wiki.polycount.com/w/skins/common/feed.css?303"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
		<id>http://wiki.polycount.com/w/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Millennium</id>
		<title>polycount - User contributions [en]</title>
		<link rel="self" type="application/atom+xml" href="http://wiki.polycount.com/w/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Millennium"/>
		<link rel="alternate" type="text/html" href="http://wiki.polycount.com/wiki/Special:Contributions/Millennium"/>
		<updated>2026-05-29T21:52:24Z</updated>
		<subtitle>User contributions</subtitle>
		<generator>MediaWiki 1.23.2</generator>

	<entry>
		<id>http://wiki.polycount.com/wiki/Blending_functions</id>
		<title>Blending functions</title>
		<link rel="alternate" type="text/html" href="http://wiki.polycount.com/wiki/Blending_functions"/>
				<updated>2015-10-14T12:03:33Z</updated>
		
		<summary type="html">&lt;p&gt;Millennium: /* Category 3 (Complex) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Here are all the Photoshop Blending Modes, in easy to use functions for various languages.&lt;br /&gt;
&lt;br /&gt;
==HLSL==&lt;br /&gt;
===Category 1 (Darker)===&lt;br /&gt;
&amp;lt;pre&amp;gt;float4 Darken (float4 cBase, float4 cBlend)&lt;br /&gt;
{&lt;br /&gt;
	float4 cNew;&lt;br /&gt;
	cNew.rgb = min(cBase.rgb, cBlend.rgb);&lt;br /&gt;
	cNew.a = 1.0;&lt;br /&gt;
	return cNew;&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;float4 Multiply (float4 cBase, float4 cBlend)&lt;br /&gt;
{&lt;br /&gt;
	return (cBase * cBlend);&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;float4 ColorBurn (float4 cBase, float4 cBlend)&lt;br /&gt;
{&lt;br /&gt;
	return (1 - (1 - cBase) / cBlend);&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;float4 LinearBurn (float4 cBase, float4 CBlend)&lt;br /&gt;
{&lt;br /&gt;
	return (cBase + cBlend - 1);&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Category 2 (Lighter)===&lt;br /&gt;
&amp;lt;pre&amp;gt;float4 Lighten (float4 cBase, float4 cBlend)&lt;br /&gt;
{&lt;br /&gt;
	float4 cNew;&lt;br /&gt;
	cNew.rgb = max(cBase.rgb, cBlend.rgb);&lt;br /&gt;
	cNew.a = 1.0;&lt;br /&gt;
	return cNew;&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;float4 Screen (float4 cBase, float4 cBlend)&lt;br /&gt;
{&lt;br /&gt;
	return (1 - (1 - cBase) * (1 - cBlend));&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;float4 ColorDodge (float4 cBase, float4 cBlend)&lt;br /&gt;
{&lt;br /&gt;
	return (cBase / (1 - cBlend));&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;float4 LinearDodge (float4 cBase, float4 cBlend)&lt;br /&gt;
{&lt;br /&gt;
	return (cBase + cBlend);&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Category 3 (Complex)===&lt;br /&gt;
&lt;br /&gt;
==== Condintional statements in shaders ====&lt;br /&gt;
[http://http.developer.nvidia.com/GPUGems2/gpugems2_chapter34.html GPUs hate branching], so it's better to avoid '''if..else''' in your shaders. The promblem here is that GPU will execute both blocks of code anyway - for then and else respectively - eventually a part of calculations will be thrown away (the more unnecessary instructions executed, the lower shader performance will be). In most of the cases conditional statements could be substituted with a help of [https://msdn.microsoft.com/en-us/library/windows/desktop/ff471376(v=vs.85).aspx HLSL's intrinsic functions].&lt;br /&gt;
&lt;br /&gt;
Let's optimize the following piece of code:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
	float4 cNew;&lt;br /&gt;
	if (cBase.r &amp;gt; .5) { cNew.r = 1 - (1 - 2 * (cBase.r - .5)) * (1 - cBlend.r); }&lt;br /&gt;
	else { cNew.r = (2 * cBase.r) * cBlend.r; }&lt;br /&gt;
	&lt;br /&gt;
	if (cBase.g &amp;gt; .5) { cNew.g = 1 - (1 - 2 * (cBase.g - .5)) * (1 - cBlend.g); }&lt;br /&gt;
	else { cNew.g = (2 * cBase.g) * cBlend.g; }&lt;br /&gt;
	&lt;br /&gt;
	if (cBase.b &amp;gt; .5) { cNew.b = 1 - (1 - 2 * (cBase.b - .5)) * (1 - cBlend.b); }&lt;br /&gt;
	else { cNew.b = (2 * cBase.b) * cBlend.b; }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As we see the result values of R, G and B components (except for alpha) for this blending mode depend on it's base layer initial values&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
	if (baseColor &amp;gt; .5) then {&lt;br /&gt;
	    resultColor = A; &lt;br /&gt;
	} else {&lt;br /&gt;
	    resultColor = B;&lt;br /&gt;
	}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Using of [https://msdn.microsoft.com/en-us/library/windows/desktop/bb509618(v=vs.85).aspx lerp(A, B, interpolation_value)] - linear interpolation - function makes it simpler to switch between two branches.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
	float4 newColor = lerp(A, B, interpolation_value); // = A*(1 - interpolation_value) + B*interpolation_value&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Actually we don't want newColor to gradually change between A and B, but only switch A &amp;lt;-&amp;gt; B, so interpolation_value must be strictly equal to 0 or 1. And here is where the [https://msdn.microsoft.com/en-us/library/windows/desktop/bb509665(v=vs.85).aspx step(x, y)] function comes in. The equivalent for '''step''' functionality is:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
	float step(x, y) {&lt;br /&gt;
	    if (x &amp;gt; y) then {&lt;br /&gt;
	        return 0;&lt;br /&gt;
	    } else {&lt;br /&gt;
	        return 1;&lt;br /&gt;
	    }&lt;br /&gt;
	}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Apparently, if it's required to invert output values, we just should change the order of '''step''' input arguments. Let's assembly all the information we've found out and re-write our shader:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
	float isLessOrEq = step(cBase, 0.5);&lt;br /&gt;
	float4 cNew = lerp(1. - (1. - 2.*(cBase - .5))*(1. - cBlend), 2*cBase*cBlend, isLessOrEq);	// get rid of per component calculations and using vectorization&lt;br /&gt;
													// for performance optimization sake&lt;br /&gt;
	cNew.a = 1.;	// restore alpha&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
P.S. In a special case, when one of the possible values of '''cNew''' is 0, there is no more need in '''lerp''' &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
	float isLessOrEq = step(cBase, 0.5);&lt;br /&gt;
	float4 cNew = isLessOrEq * 2*cBase*cBlend;	// = (x &amp;lt;= 0.5) ? 2*cBase*cBlend : 0;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
P.P.S. Although compiler will do this work for you at the optimization stage, keep in mind that explicit variables declaration as '''float''' (1.0, 1. or 1.f insted of 1) is more preferable then writing expressions with variables of different types and, in result, mixing '''float''' with '''int'''. It causes implicit type conversion, which sometimes leads to [http://media.moddb.com/images/members/1/691/690410/G-Mans_Ghost.jpg unforeseen consequences].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Shaders implementation ====&lt;br /&gt;
&amp;lt;pre&amp;gt;float4 Overlay (float4 cBase, float4 cBlend)&lt;br /&gt;
{&lt;br /&gt;
	float isLessOrEq = step(cBase, .5);&lt;br /&gt;
	float4 cNew = lerp(2*cBlend*cBase, 1 - (1 - 2*(Base - .5))*(1 - Blend), isLessOrEq);&lt;br /&gt;
	cNew.a = 1.0;&lt;br /&gt;
	return cNew;&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;float4 SoftLight (float4 cBase, float4 cBlend)&lt;br /&gt;
{&lt;br /&gt;
	float isLessOrEq = step(cBlend, .5);&lt;br /&gt;
	float4 cNew = lerp(1 - (1 - cBase)*(1 - 2*cBlend*cBase), cBase*(1 - (1 - cBase)*(1 - 2*cBlend)), isLessOrEq);&lt;br /&gt;
	cNew.a = 1.0;&lt;br /&gt;
	return cNew;&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;float4 HardLight (float4 cBase, float4 cBlend)&lt;br /&gt;
{&lt;br /&gt;
	float isLessOrEq = step(cBlend, .5);&lt;br /&gt;
	float4 cNew = lerp(1 - (1 - cBase)*(1 - 2*cBlend), 2*cBlend*cBase, isLessOrEq);&lt;br /&gt;
	cNew.a = 1.0;&lt;br /&gt;
	return cNew;&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;float4 VividLight (float4 cBase, float4 cBlend)&lt;br /&gt;
{&lt;br /&gt;
	float isLessOrEq = step(cBlend, .5);&lt;br /&gt;
	float4 cNew = lerp(1 - (1 - cBase)/(2*(cBlend - .5)), cBase/(1 - 2*cBlend), isGreaterThen);&lt;br /&gt;
	cNew.a = 1.0;&lt;br /&gt;
	return cNew;&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;float4 LinearLight (float4 cBase, float4 cBlend)&lt;br /&gt;
{&lt;br /&gt;
	float isLessOrEq = step(cBlend, .5);&lt;br /&gt;
	float4 cNew = lerp(cBase + 2*(cBlend - .5), cBase + 2*cBlend - 1., isLessOrEq);&lt;br /&gt;
	cNew.a = 1.0;&lt;br /&gt;
	return cNew;&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;float4 PinLight (float4 cBase, float4 cBlend)&lt;br /&gt;
{&lt;br /&gt;
	float isLessOrEq = step(cBlend, .5);&lt;br /&gt;
	float4 cNew = lerp(max(cBase, 2*(cBlend - .5)), min(cBase, 2*cBlend), isLessOrEq);&lt;br /&gt;
	cNew.a = 1.0;&lt;br /&gt;
	return cNew;&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Category 4 (Comparison)===&lt;br /&gt;
&amp;lt;pre&amp;gt;float4 Difference (float4 cBase, float4 cBlend)&lt;br /&gt;
{&lt;br /&gt;
	return (abs(cBase - cBlend));&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;float4 Exclusion (float4 cBase, float4 cBlend)&lt;br /&gt;
{&lt;br /&gt;
	return (.5 - 2 * (cBase - .5) * (cBlend - .5));&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:HLSL]][[Category:Shaders]][[Category:Rendering]][[Category:Code]][[Category:Functions]]&lt;/div&gt;</summary>
		<author><name>Millennium</name></author>	</entry>

	<entry>
		<id>http://wiki.polycount.com/wiki/Blending_functions</id>
		<title>Blending functions</title>
		<link rel="alternate" type="text/html" href="http://wiki.polycount.com/wiki/Blending_functions"/>
				<updated>2015-09-10T18:22:22Z</updated>
		
		<summary type="html">&lt;p&gt;Millennium: /* Category 3 (Complex) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Here are all the Photoshop Blending Modes, in easy to use functions for various languages.&lt;br /&gt;
&lt;br /&gt;
==HLSL==&lt;br /&gt;
===Category 1 (Darker)===&lt;br /&gt;
&amp;lt;pre&amp;gt;float4 Darken (float4 cBase, float4 cBlend)&lt;br /&gt;
{&lt;br /&gt;
	float4 cNew;&lt;br /&gt;
	cNew.rgb = min(cBase.rgb, cBlend.rgb);&lt;br /&gt;
	cNew.a = 1.0;&lt;br /&gt;
	return cNew;&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;float4 Multiply (float4 cBase, float4 cBlend)&lt;br /&gt;
{&lt;br /&gt;
	return (cBase * cBlend);&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;float4 ColorBurn (float4 cBase, float4 cBlend)&lt;br /&gt;
{&lt;br /&gt;
	return (1 - (1 - cBase) / cBlend);&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;float4 LinearBurn (float4 cBase, float4 CBlend)&lt;br /&gt;
{&lt;br /&gt;
	return (cBase + cBlend - 1);&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Category 2 (Lighter)===&lt;br /&gt;
&amp;lt;pre&amp;gt;float4 Lighten (float4 cBase, float4 cBlend)&lt;br /&gt;
{&lt;br /&gt;
	float4 cNew;&lt;br /&gt;
	cNew.rgb = max(cBase.rgb, cBlend.rgb);&lt;br /&gt;
	cNew.a = 1.0;&lt;br /&gt;
	return cNew;&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;float4 Screen (float4 cBase, float4 cBlend)&lt;br /&gt;
{&lt;br /&gt;
	return (1 - (1 - cBase) * (1 - cBlend));&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;float4 ColorDodge (float4 cBase, float4 cBlend)&lt;br /&gt;
{&lt;br /&gt;
	return (cBase / (1 - cBlend));&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;float4 LinearDodge (float4 cBase, float4 cBlend)&lt;br /&gt;
{&lt;br /&gt;
	return (cBase + cBlend);&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Category 3 (Complex)===&lt;br /&gt;
&lt;br /&gt;
==== Condintional statements in shaders ====&lt;br /&gt;
[http://http.developer.nvidia.com/GPUGems2/gpugems2_chapter34.html GPUs hate branching], so it's better to avoid '''if..else''' in your shaders. The promblem here is that GPU will execute both blocks of code anyway - for then and else respectively - eventually a part of calculations will be thrown away (the more unnecessary instructions executed, the lower shader performance will be). In most of the cases conditional statements could be substituted with a help of [https://msdn.microsoft.com/en-us/library/windows/desktop/ff471376(v=vs.85).aspx HLSL's intrinsic functions].&lt;br /&gt;
&lt;br /&gt;
Let's optimize the following piece of code:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
	float4 cNew;&lt;br /&gt;
	if (cBase.r &amp;gt; .5) { cNew.r = 1 - (1 - 2 * (cBase.r - .5)) * (1 - cBlend.r); }&lt;br /&gt;
	else { cNew.r = (2 * cBase.r) * cBlend.r; }&lt;br /&gt;
	&lt;br /&gt;
	if (cBase.g &amp;gt; .5) { cNew.g = 1 - (1 - 2 * (cBase.g - .5)) * (1 - cBlend.g); }&lt;br /&gt;
	else { cNew.g = (2 * cBase.g) * cBlend.g; }&lt;br /&gt;
	&lt;br /&gt;
	if (cBase.b &amp;gt; .5) { cNew.b = 1 - (1 - 2 * (cBase.b - .5)) * (1 - cBlend.b); }&lt;br /&gt;
	else { cNew.b = (2 * cBase.b) * cBlend.b; }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As we see the result values of R, G and B components (except for alpha) for this blending mode depends on it's base layer initial values&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
	if (baseColor &amp;gt; .5) then {&lt;br /&gt;
	    resultColor = A; &lt;br /&gt;
	} else {&lt;br /&gt;
	    resultColor = B;&lt;br /&gt;
	}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Using of [https://msdn.microsoft.com/en-us/library/windows/desktop/bb509618(v=vs.85).aspx lerp(A, B, interpolation_value)] - linear interpolation - function makes it simpler to switch between two branches.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
	float4 newColor = lerp(A, B, interpolation_value); // = A*(1 - interpolation_value) + B*interpolation_value&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Actually we don't want newColor to gradually change between A and B, but only switch A &amp;lt;-&amp;gt; B, so interpolation_value should be strictly equal to 0 or 1. And here is where the [https://msdn.microsoft.com/en-us/library/windows/desktop/bb509665(v=vs.85).aspx step(x, y)] function come in. The equivalent for '''step''' functionality is:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
	float step(x, y) {&lt;br /&gt;
	    if (x &amp;gt; y) then {&lt;br /&gt;
	        return 0;&lt;br /&gt;
	    } else {&lt;br /&gt;
	        return 1;&lt;br /&gt;
	    }&lt;br /&gt;
	}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Apparently, if it's required to invert output values, just change the order of '''step''' input arguments. Let's assembly all the information we've found out and re-write our shader:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
	float isLessOrEq = step(cBase, 0.5);&lt;br /&gt;
	float4 cNew = lerp(1. - (1. - 2.*(cBase - .5))*(1. - cBlend), 2*cBase*cBlend, isLessOrEq);	// get rid of per component calculations and using vectorization&lt;br /&gt;
													// for performance optimization sake&lt;br /&gt;
	cNew.a = 1.;	// restore alpha&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
P.S. In a special case, when one of the possible values of '''cNew''' is 0, there is no more need in '''lerp''' &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
	float isLessOrEq = step(cBase, 0.5);&lt;br /&gt;
	float4 cNew = isLessOrEq * 2*cBase*cBlend;	// = (x &amp;lt;= 0.5) ? 2*cBase*cBlend : 0;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
P.P.S. Although compiler will do this work for you at the optimization stage, keep in mind that explicit declaration variables as '''float''' (1.0, 1. or 1.f insted of 1) is more preferable then writing expressions with variables of different types and, in result, mixing '''float''' with '''int'''. It causes implicit type conversion, which sometimes leads to [http://media.moddb.com/images/members/1/691/690410/G-Mans_Ghost.jpg unforeseen consequences].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Shaders implementation ====&lt;br /&gt;
&amp;lt;pre&amp;gt;float4 Overlay (float4 cBase, float4 cBlend)&lt;br /&gt;
{&lt;br /&gt;
	float isLessOrEq = step(cBase, .5);&lt;br /&gt;
	float4 cNew = lerp(2*cBlend*cBase, 1 - (1 - 2*(Base - .5))*(1 - Blend), isLessOrEq);&lt;br /&gt;
	cNew.a = 1.0;&lt;br /&gt;
	return cNew;&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;float4 SoftLight (float4 cBase, float4 cBlend)&lt;br /&gt;
{&lt;br /&gt;
	float isLessOrEq = step(cBlend, .5);&lt;br /&gt;
	float4 cNew = lerp(1 - (1 - cBase)*(1 - 2*cBlend*cBase), cBase*(1 - (1 - cBase)*(1 - 2*cBlend)), isLessOrEq);&lt;br /&gt;
	cNew.a = 1.0;&lt;br /&gt;
	return cNew;&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;float4 HardLight (float4 cBase, float4 cBlend)&lt;br /&gt;
{&lt;br /&gt;
	float isLessOrEq = step(cBlend, .5);&lt;br /&gt;
	float4 cNew = lerp(1 - (1 - cBase)*(1 - 2*cBlend), 2*cBlend*cBase, isLessOrEq);&lt;br /&gt;
	cNew.a = 1.0;&lt;br /&gt;
	return cNew;&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;float4 VividLight (float4 cBase, float4 cBlend)&lt;br /&gt;
{&lt;br /&gt;
	float isLessOrEq = step(cBlend, .5);&lt;br /&gt;
	float4 cNew = lerp(1 - (1 - cBase)/(2*(cBlend - .5)), cBase/(1 - 2*cBlend), isGreaterThen);&lt;br /&gt;
	cNew.a = 1.0;&lt;br /&gt;
	return cNew;&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;float4 LinearLight (float4 cBase, float4 cBlend)&lt;br /&gt;
{&lt;br /&gt;
	float isLessOrEq = step(cBlend, .5);&lt;br /&gt;
	float4 cNew = lerp(cBase + 2*(cBlend - .5), cBase + 2*cBlend - 1., isLessOrEq);&lt;br /&gt;
	cNew.a = 1.0;&lt;br /&gt;
	return cNew;&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;float4 PinLight (float4 cBase, float4 cBlend)&lt;br /&gt;
{&lt;br /&gt;
	float isLessOrEq = step(cBlend, .5);&lt;br /&gt;
	float4 cNew = lerp(max(cBase, 2*(cBlend - .5)), min(cBase, 2*cBlend), isLessOrEq);&lt;br /&gt;
	cNew.a = 1.0;&lt;br /&gt;
	return cNew;&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Category 4 (Comparison)===&lt;br /&gt;
&amp;lt;pre&amp;gt;float4 Difference (float4 cBase, float4 cBlend)&lt;br /&gt;
{&lt;br /&gt;
	return (abs(cBase - cBlend));&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;float4 Exclusion (float4 cBase, float4 cBlend)&lt;br /&gt;
{&lt;br /&gt;
	return (.5 - 2 * (cBase - .5) * (cBlend - .5));&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:HLSL]][[Category:Shaders]][[Category:Rendering]][[Category:Code]][[Category:Functions]]&lt;/div&gt;</summary>
		<author><name>Millennium</name></author>	</entry>

	</feed>