Blender V2.61 - r43446

svm_fresnel.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 CCL_NAMESPACE_BEGIN
00020 
00021 /* Fresnel Node */
00022 
00023 __device void svm_node_fresnel(ShaderData *sd, float *stack, uint ior_offset, uint ior_value, uint out_offset)
00024 {
00025     float eta = (stack_valid(ior_offset))? stack_load_float(stack, ior_offset): __int_as_float(ior_value);
00026     eta = fmaxf(eta, 1.0f + 1e-5f);
00027     eta = (sd->flag & SD_BACKFACING)? 1.0f/eta: eta;
00028 
00029     float f = fresnel_dielectric_cos(dot(sd->I, sd->N), eta);
00030 
00031     stack_store_float(stack, out_offset, f);
00032 }
00033 
00034 /* Blend Weight Node */
00035 
00036 __device void svm_node_layer_weight(ShaderData *sd, float *stack, uint4 node)
00037 {
00038     uint blend_offset = node.y;
00039     uint blend_value = node.z;
00040     float blend = (stack_valid(blend_offset))? stack_load_float(stack, blend_offset): __int_as_float(blend_value);
00041 
00042     uint type, out_offset;
00043     decode_node_uchar4(node.w, &type, &out_offset, NULL, NULL);
00044 
00045     float f;
00046 
00047     if(type == NODE_LAYER_WEIGHT_FRESNEL) {
00048         float eta = fmaxf(1.0f - blend, 1e-5f);
00049         eta = (sd->flag & SD_BACKFACING)? eta: 1.0f/eta;
00050 
00051         f = fresnel_dielectric_cos(dot(sd->I, sd->N), eta);
00052     }
00053     else {
00054         f = fabsf(dot(sd->I, sd->N));
00055 
00056         if(blend != 0.5f) {
00057             blend = clamp(blend, 0.0f, 1.0f);
00058             blend = (blend < 0.5f)? 2.0f*blend: 0.5f/(1.0f - blend);
00059 
00060             f = powf(f, blend);
00061         }
00062 
00063         f = 1.0f - f;
00064     }
00065 
00066     stack_store_float(stack, out_offset, f);
00067 }
00068 
00069 CCL_NAMESPACE_END
00070