Blender V2.61 - r43446

svm_mix.h

Go to the documentation of this file.
00001 /*
00002  * Copyright 2011, Blender Foundation.
00003  *
00004  * This program is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU General Public License
00006  * as published by the Free Software Foundation; either version 2
00007  * of the License, or (at your option) any later version.
00008  *
00009  * This program is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  * GNU General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU General Public License
00015  * along with this program; if not, write to the Free Software Foundation,
00016  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00017  */
00018 
00019 #include "svm_hsv.h"
00020 
00021 CCL_NAMESPACE_BEGIN
00022 
00023 __device float3 svm_lerp(const float3 a, const float3 b, float t)
00024 {
00025     return (a * (1.0f - t) + b * t);
00026 }
00027 
00028 __device float3 svm_mix_blend(float t, float3 col1, float3 col2)
00029 {
00030     return svm_lerp(col1, col2, t);
00031 }
00032 
00033 __device float3 svm_mix_add(float t, float3 col1, float3 col2)
00034 {
00035     return svm_lerp(col1, col1 + col2, t);
00036 }
00037 
00038 __device float3 svm_mix_mul(float t, float3 col1, float3 col2)
00039 {
00040     return svm_lerp(col1, col1 * col2, t);
00041 }
00042 
00043 __device float3 svm_mix_screen(float t, float3 col1, float3 col2)
00044 {
00045     float tm = 1.0f - t;
00046     float3 one = make_float3(1.0f, 1.0f, 1.0f);
00047     float3 tm3 = make_float3(tm, tm, tm);
00048 
00049     return one - (tm3 + t*(one - col2))*(one - col1);
00050 }
00051 
00052 __device float3 svm_mix_overlay(float t, float3 col1, float3 col2)
00053 {
00054     float tm = 1.0f - t;
00055 
00056     float3 outcol = col1;
00057 
00058     if(outcol.x < 0.5f)
00059         outcol.x *= tm + 2.0f*t*col2.x;
00060     else
00061         outcol.x = 1.0f - (tm + 2.0f*t*(1.0f - col2.x))*(1.0f - outcol.x);
00062 
00063     if(outcol.y < 0.5f)
00064         outcol.y *= tm + 2.0f*t*col2.y;
00065     else
00066         outcol.y = 1.0f - (tm + 2.0f*t*(1.0f - col2.y))*(1.0f - outcol.y);
00067 
00068     if(outcol.z < 0.5f)
00069         outcol.z *= tm + 2.0f*t*col2.z;
00070     else
00071         outcol.z = 1.0f - (tm + 2.0f*t*(1.0f - col2.z))*(1.0f - outcol.z);
00072     
00073     return outcol;
00074 }
00075 
00076 __device float3 svm_mix_sub(float t, float3 col1, float3 col2)
00077 {
00078     return svm_lerp(col1, col1 - col2, t);
00079 }
00080 
00081 __device float3 svm_mix_div(float t, float3 col1, float3 col2)
00082 {
00083     float tm = 1.0f - t;
00084 
00085     float3 outcol = col1;
00086 
00087     if(col2.x != 0.0f) outcol.x = tm*outcol.x + t*outcol.x/col2.x;
00088     if(col2.y != 0.0f) outcol.y = tm*outcol.y + t*outcol.y/col2.y;
00089     if(col2.z != 0.0f) outcol.z = tm*outcol.z + t*outcol.z/col2.z;
00090 
00091     return outcol;
00092 }
00093 
00094 __device float3 svm_mix_diff(float t, float3 col1, float3 col2)
00095 {
00096     return svm_lerp(col1, fabs(col1 - col2), t);
00097 }
00098 
00099 __device float3 svm_mix_dark(float t, float3 col1, float3 col2)
00100 {
00101     return min(col1, col2*t);
00102 }
00103 
00104 __device float3 svm_mix_light(float t, float3 col1, float3 col2)
00105 {
00106     return max(col1, col2*t);
00107 }
00108 
00109 __device float3 svm_mix_dodge(float t, float3 col1, float3 col2)
00110 {
00111     float3 outcol = col1;
00112 
00113     if(outcol.x != 0.0f) {
00114         float tmp = 1.0f - t*col2.x;
00115         if(tmp <= 0.0f)
00116             outcol.x = 1.0f;
00117         else if((tmp = outcol.x/tmp) > 1.0f)
00118             outcol.x = 1.0f;
00119         else
00120             outcol.x = tmp;
00121     }
00122     if(outcol.y != 0.0f) {
00123         float tmp = 1.0f - t*col2.y;
00124         if(tmp <= 0.0f)
00125             outcol.y = 1.0f;
00126         else if((tmp = outcol.y/tmp) > 1.0f)
00127             outcol.y = 1.0f;
00128         else
00129             outcol.y = tmp;
00130     }
00131     if(outcol.z != 0.0f) {
00132         float tmp = 1.0f - t*col2.z;
00133         if(tmp <= 0.0f)
00134             outcol.z = 1.0f;
00135         else if((tmp = outcol.z/tmp) > 1.0f)
00136             outcol.z = 1.0f;
00137         else
00138             outcol.z = tmp;
00139     }
00140 
00141     return outcol;
00142 }
00143 
00144 __device float3 svm_mix_burn(float t, float3 col1, float3 col2)
00145 {
00146     float tmp, tm = 1.0f - t;
00147 
00148     float3 outcol = col1;
00149 
00150     tmp = tm + t*col2.x;
00151     if(tmp <= 0.0f)
00152         outcol.x = 0.0f;
00153     else if((tmp = (1.0f - (1.0f - outcol.x)/tmp)) < 0.0f)
00154         outcol.x = 0.0f;
00155     else if(tmp > 1.0f)
00156         outcol.x = 1.0f;
00157     else
00158         outcol.x = tmp;
00159 
00160     tmp = tm + t*col2.y;
00161     if(tmp <= 0.0f)
00162         outcol.y = 0.0f;
00163     else if((tmp = (1.0f - (1.0f - outcol.y)/tmp)) < 0.0f)
00164         outcol.y = 0.0f;
00165     else if(tmp > 1.0f)
00166         outcol.y = 1.0f;
00167     else
00168         outcol.y = tmp;
00169 
00170     tmp = tm + t*col2.z;
00171     if(tmp <= 0.0f)
00172         outcol.z = 0.0f;
00173     else if((tmp = (1.0f - (1.0f - outcol.z)/tmp)) < 0.0f)
00174         outcol.z = 0.0f;
00175     else if(tmp > 1.0f)
00176         outcol.z = 1.0f;
00177     else
00178         outcol.z = tmp;
00179     
00180     return outcol;
00181 }
00182 
00183 __device float3 svm_mix_hue(float t, float3 col1, float3 col2)
00184 {
00185     float3 outcol = col1;
00186 
00187     float3 hsv2 = rgb_to_hsv(col2);
00188 
00189     if(hsv2.y != 0.0f) {
00190         float3 hsv = rgb_to_hsv(outcol);
00191         hsv.x = hsv2.x;
00192         float3 tmp = hsv_to_rgb(hsv); 
00193 
00194         outcol = svm_lerp(outcol, tmp, t);
00195     }
00196 
00197     return outcol;
00198 }
00199 
00200 __device float3 svm_mix_sat(float t, float3 col1, float3 col2)
00201 {
00202     float tm = 1.0f - t;
00203 
00204     float3 outcol = col1;
00205 
00206     float3 hsv = rgb_to_hsv(outcol);
00207 
00208     if(hsv.y != 0.0f) {
00209         float3 hsv2 = rgb_to_hsv(col2);
00210 
00211         hsv.y = tm*hsv.y + t*hsv2.y;
00212         outcol = hsv_to_rgb(hsv);
00213     }
00214 
00215     return outcol;
00216 }
00217 
00218 __device float3 svm_mix_val(float t, float3 col1, float3 col2)
00219 {
00220     float tm = 1.0f - t;
00221 
00222     float3 hsv = rgb_to_hsv(col1);
00223     float3 hsv2 = rgb_to_hsv(col2);
00224 
00225     hsv.z = tm*hsv.z + t*hsv2.z;
00226 
00227     return hsv_to_rgb(hsv);
00228 }
00229 
00230 __device float3 svm_mix_color(float t, float3 col1, float3 col2)
00231 {
00232     float3 outcol = col1;
00233     float3 hsv2 = rgb_to_hsv(col2);
00234 
00235     if(hsv2.y != 0.0f) {
00236         float3 hsv = rgb_to_hsv(outcol);
00237         hsv.x = hsv2.x;
00238         hsv.y = hsv2.y;
00239         float3 tmp = hsv_to_rgb(hsv); 
00240 
00241         outcol = svm_lerp(outcol, tmp, t);
00242     }
00243 
00244     return outcol;
00245 }
00246 
00247 __device float3 svm_mix_soft(float t, float3 col1, float3 col2)
00248 {
00249     float tm = 1.0f - t;
00250 
00251     float3 one= make_float3(1.0f, 1.0f, 1.0f);
00252     float3 scr= one - (one - col2)*(one - col1);
00253 
00254     return tm*col1 + t*((one - col1)*col2*col1 + col1*scr);
00255 }
00256 
00257 __device float3 svm_mix_linear(float t, float3 col1, float3 col2)
00258 {
00259     float3 outcol = col1;
00260 
00261     if(col2.x > 0.5f)
00262         outcol.x= col1.x + t*(2.0f*(col2.x - 0.5f));
00263     else
00264         outcol.x= col1.x + t*(2.0f*(col2.x) - 1.0f);
00265 
00266     if(col2.y > 0.5f)
00267         outcol.y= col1.y + t*(2.0f*(col2.y - 0.5f));
00268     else
00269         outcol.y= col1.y + t*(2.0f*(col2.y) - 1.0f);
00270 
00271     if(col2.z > 0.5f)
00272         outcol.z= col1.z + t*(2.0f*(col2.z - 0.5f));
00273     else
00274         outcol.z= col1.z + t*(2.0f*(col2.z) - 1.0f);
00275     
00276     return outcol;
00277 }
00278 
00279 __device float3 svm_mix(NodeMix type, float fac, float3 c1, float3 c2)
00280 {
00281     float t = clamp(fac, 0.0f, 1.0f);
00282 
00283     switch(type) {
00284         case NODE_MIX_BLEND: return svm_mix_blend(t, c1, c2);
00285         case NODE_MIX_ADD: return svm_mix_add(t, c1, c2);
00286         case NODE_MIX_MUL: return svm_mix_mul(t, c1, c2);
00287         case NODE_MIX_SCREEN: return svm_mix_screen(t, c1, c2);
00288         case NODE_MIX_OVERLAY: return svm_mix_overlay(t, c1, c2);
00289         case NODE_MIX_SUB: return svm_mix_sub(t, c1, c2);
00290         case NODE_MIX_DIV: return svm_mix_div(t, c1, c2);
00291         case NODE_MIX_DIFF: return svm_mix_diff(t, c1, c2);
00292         case NODE_MIX_DARK: return svm_mix_dark(t, c1, c2);
00293         case NODE_MIX_LIGHT: return svm_mix_light(t, c1, c2);
00294         case NODE_MIX_DODGE: return svm_mix_dodge(t, c1, c2);
00295         case NODE_MIX_BURN: return svm_mix_burn(t, c1, c2);
00296         case NODE_MIX_HUE: return svm_mix_hue(t, c1, c2);
00297         case NODE_MIX_SAT: return svm_mix_sat(t, c1, c2);
00298         case NODE_MIX_VAL: return svm_mix_val (t, c1, c2);
00299         case NODE_MIX_COLOR: return svm_mix_color(t, c1, c2);
00300         case NODE_MIX_SOFT: return svm_mix_soft(t, c1, c2);
00301         case NODE_MIX_LINEAR: return svm_mix_linear(t, c1, c2);
00302     }
00303 
00304     return make_float3(0.0f, 0.0f, 0.0f);
00305 }
00306 
00307 /* Node */
00308 
00309 __device void svm_node_mix(KernelGlobals *kg, ShaderData *sd, float *stack, uint fac_offset, uint c1_offset, uint c2_offset, int *offset)
00310 {
00311     /* read extra data */
00312     uint4 node1 = read_node(kg, offset);
00313 
00314     float fac = stack_load_float(stack, fac_offset);
00315     float3 c1 = stack_load_float3(stack, c1_offset);
00316     float3 c2 = stack_load_float3(stack, c2_offset);
00317     float3 result = svm_mix((NodeMix)node1.y, fac, c1, c2);
00318 
00319     stack_store_float3(stack, node1.z, result);
00320 }
00321 
00322 CCL_NAMESPACE_END
00323