1/* 2 * Copyright 2011-2013 Blender Foundation 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#include "stdcycles.h" 18 19shader node_normal_map(normal NormalIn = N, 20 float Strength = 1.0, 21 color Color = color(0.5, 0.5, 1.0), 22 string space = "tangent", 23 string attr_name = "geom:tangent", 24 string attr_sign_name = "geom:tangent_sign", 25 output normal Normal = NormalIn) 26{ 27 color mcolor = 2.0 * color(Color[0] - 0.5, Color[1] - 0.5, Color[2] - 0.5); 28 int is_backfacing = backfacing(); 29 30 if (space == "tangent") { 31 vector tangent; 32 vector ninterp; 33 float tangent_sign; 34 float is_smooth; 35 36 getattribute("geom:is_smooth", is_smooth); 37 if (!is_smooth) { 38 ninterp = normalize(transform("world", "object", Ng)); 39 40 /* the normal is already inverted, which is too soon for the math here */ 41 if (is_backfacing) { 42 ninterp = -ninterp; 43 } 44 } 45 46 // get _unnormalized_ interpolated normal and tangent 47 if (getattribute(attr_name, tangent) && getattribute(attr_sign_name, tangent_sign) && 48 (!is_smooth || getattribute("geom:N", ninterp))) { 49 // apply normal map 50 vector B = tangent_sign * cross(ninterp, tangent); 51 Normal = normalize(mcolor[0] * tangent + mcolor[1] * B + mcolor[2] * ninterp); 52 53 // transform to world space 54 Normal = normalize(transform("object", "world", Normal)); 55 } 56 else { 57 Normal = normal(0, 0, 0); 58 } 59 } 60 else if (space == "object") { 61 Normal = normalize(transform("object", "world", vector(mcolor))); 62 } 63 else if (space == "world") { 64 Normal = normalize(vector(mcolor)); 65 } 66 else if (space == "blender_object") { 67 /* strange blender convention */ 68 mcolor[1] = -mcolor[1]; 69 mcolor[2] = -mcolor[2]; 70 71 Normal = normalize(transform("object", "world", vector(mcolor))); 72 } 73 else if (space == "blender_world") { 74 /* strange blender convention */ 75 mcolor[1] = -mcolor[1]; 76 mcolor[2] = -mcolor[2]; 77 78 Normal = normalize(vector(mcolor)); 79 } 80 81 /* invert normal for backfacing polygons */ 82 if (is_backfacing) { 83 Normal = -Normal; 84 } 85 86 if (Strength != 1.0) 87 Normal = normalize(NormalIn + (Normal - NormalIn) * max(Strength, 0.0)); 88 89 Normal = ensure_valid_reflection(Ng, I, Normal); 90} 91