Commit db51ec78 authored by Spencer Brown's avatar Spencer Brown
Browse files

Add mathematically robust normal map combination blending mode.

This approach uses quaternions to rotate the normal vector of the destination
layer so that it deforms correctly from the base layer. The algorithm is
called reoriented normal mapping and is detailed at
http://blog.selfshadow.com/publications/blending-in-detail/.

Differential: https://phabricator.kde.org/D210
parent 7aab7307
......@@ -85,6 +85,7 @@ KoCompositeOpRegistry::KoCompositeOpRegistry()
m_map.insert(m_categories[4], KoID(COMPOSITE_GEOMETRIC_MEAN, i18n("Geometric Mean")));
m_map.insert(m_categories[5], KoID(COMPOSITE_BUMPMAP , i18n("Bumpmap")));
m_map.insert(m_categories[5], KoID(COMPOSITE_COMBINE_NORMAL, i18n("Combine Normal Map")));
m_map.insert(m_categories[5], KoID(COMPOSITE_DISSOLVE , i18n("Dissolve")));
m_map.insert(m_categories[5], KoID(COMPOSITE_COPY_RED , i18n("Copy Red")));
m_map.insert(m_categories[5], KoID(COMPOSITE_COPY_GREEN, i18n("Copy Green")));
......
......@@ -120,6 +120,7 @@ const QString COMPOSITE_COPY_BLUE = "copy_blue";
const QString COMPOSITE_COLORIZE = "colorize";
const QString COMPOSITE_BUMPMAP = "bumpmap";
const QString COMPOSITE_COMBINE_NORMAL = "combine_normal";
const QString COMPOSITE_CLEAR = "clear";
const QString COMPOSITE_DISSOLVE = "dissolve";
const QString COMPOSITE_DISPLACE = "displace";
......
......@@ -22,6 +22,29 @@
#include <KoColorSpaceMaths.h>
template<class HSXType, class TReal>
inline void cfReorientedNormalMapCombine(TReal srcR, TReal srcG, TReal srcB, TReal& dstR, TReal& dstG, TReal& dstB)
{
// see http://blog.selfshadow.com/publications/blending-in-detail/ by Barre-Brisebois and Hill
TReal tx = 2*srcR-1;
TReal ty = 2*srcG-1;
TReal tz = 2*srcB;
TReal ux = -2*dstR+1;
TReal uy = -2*dstG+1;
TReal uz = 2*dstB-1;
TReal k = (tx*ux+ty*uy+tz*uz)/tz; // dot(t,u)/t.z
TReal rx = tx*k-ux;
TReal ry = ty*k-uy;
TReal rz = tz*k-uz;
k = 1/sqrt(rx*rx+ry*ry+rz*rz); // normalize result
rx *= k;
ry *= k;
rz *= k;
dstR = rx*0.5+0.5;
dstG = ry*0.5+0.5;
dstB = rz*0.5+0.5;
}
template<class HSXType, class TReal>
inline void cfColor(TReal sr, TReal sg, TReal sb, TReal& dr, TReal& dg, TReal& db) {
TReal lum = getLightness<HSXType>(dr, dg, db);
......
......@@ -165,6 +165,7 @@ struct AddRGBOps<Traits, true>
cs->addCompositeOp(new KoCompositeOpCopyChannel<Traits,red_pos >(cs, COMPOSITE_COPY_RED , i18n("Copy Red") , KoCompositeOp::categoryMisc()));
cs->addCompositeOp(new KoCompositeOpCopyChannel<Traits,green_pos>(cs, COMPOSITE_COPY_GREEN, i18n("Copy Green"), KoCompositeOp::categoryMisc()));
cs->addCompositeOp(new KoCompositeOpCopyChannel<Traits,blue_pos >(cs, COMPOSITE_COPY_BLUE , i18n("Copy Blue") , KoCompositeOp::categoryMisc()));
add<&cfReorientedNormalMapCombine <HSYType, Arg> >(cs, COMPOSITE_COMBINE_NORMAL, i18n("Combine Normal Maps"), KoCompositeOp::categoryMisc());
add<&cfColor <HSYType,Arg> >(cs, COMPOSITE_COLOR , i18n("Color") , KoCompositeOp::categoryHSY());
add<&cfHue <HSYType,Arg> >(cs, COMPOSITE_HUE , i18n("Hue") , KoCompositeOp::categoryHSY());
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment