/* * Copyright 2011-2013 Blender Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "node_noise.h" #include "stdcycles.h" #include "vector2.h" #include "vector4.h" #define vector3 point /* The following offset functions generate random offsets to be added to texture * coordinates to act as a seed since the noise functions don't have seed values. * A seed value is needed for generating distortion textures and color outputs. * The offset's components are in the range [100, 200], not too high to cause * bad precision and not to small to be noticeable. We use float seed because * OSL only support float hashes. */ float random_float_offset(float seed) { return 100.0 + noise("hash", seed) * 100.0; } vector2 random_vector2_offset(float seed) { return vector2(100.0 + noise("hash", seed, 0.0) * 100.0, 100.0 + noise("hash", seed, 1.0) * 100.0); } vector3 random_vector3_offset(float seed) { return vector3(100.0 + noise("hash", seed, 0.0) * 100.0, 100.0 + noise("hash", seed, 1.0) * 100.0, 100.0 + noise("hash", seed, 2.0) * 100.0); } vector4 random_vector4_offset(float seed) { return vector4(100.0 + noise("hash", seed, 0.0) * 100.0, 100.0 + noise("hash", seed, 1.0) * 100.0, 100.0 + noise("hash", seed, 2.0) * 100.0, 100.0 + noise("hash", seed, 3.0) * 100.0); } float noise_texture(float co, float detail, float distortion, output color Color) { float p = co; if (distortion != 0.0) { p += safe_snoise(p + random_float_offset(0.0)) * distortion; } float value = fractal_noise(p, detail); Color = color(value, fractal_noise(p + random_float_offset(1.0), detail), fractal_noise(p + random_float_offset(2.0), detail)); return value; } float noise_texture(vector2 co, float detail, float distortion, output color Color) { vector2 p = co; if (distortion != 0.0) { p += vector2(safe_snoise(p + random_vector2_offset(0.0)) * distortion, safe_snoise(p + random_vector2_offset(1.0)) * distortion); } float value = fractal_noise(p, detail); Color = color(value, fractal_noise(p + random_vector2_offset(2.0), detail), fractal_noise(p + random_vector2_offset(3.0), detail)); return value; } float noise_texture(vector3 co, float detail, float distortion, output color Color) { vector3 p = co; if (distortion != 0.0) { p += vector3(safe_snoise(p + random_vector3_offset(0.0)) * distortion, safe_snoise(p + random_vector3_offset(1.0)) * distortion, safe_snoise(p + random_vector3_offset(2.0)) * distortion); } float value = fractal_noise(p, detail); Color = color(value, fractal_noise(p + random_vector3_offset(3.0), detail), fractal_noise(p + random_vector3_offset(4.0), detail)); return value; } float noise_texture(vector4 co, float detail, float distortion, output color Color) { vector4 p = co; if (distortion != 0.0) { p += vector4(safe_snoise(p + random_vector4_offset(0.0)) * distortion, safe_snoise(p + random_vector4_offset(1.0)) * distortion, safe_snoise(p + random_vector4_offset(2.0)) * distortion, safe_snoise(p + random_vector4_offset(3.0)) * distortion); } float value = fractal_noise(p, detail); Color = color(value, fractal_noise(p + random_vector4_offset(4.0), detail), fractal_noise(p + random_vector4_offset(5.0), detail)); return value; } shader node_noise_texture(int use_mapping = 0, matrix mapping = matrix(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), string dimensions = "3D", vector3 Vector = vector3(0, 0, 0), float W = 0.0, float Scale = 5.0, float Detail = 2.0, float Distortion = 0.0, output float Fac = 0.0, output color Color = 0.0) { vector3 p = Vector; if (use_mapping) p = transform(mapping, p); p *= Scale; float w = W * Scale; if (dimensions == "1D") Fac = noise_texture(w, Detail, Distortion, Color); else if (dimensions == "2D") Fac = noise_texture(vector2(p[0], p[1]), Detail, Distortion, Color); else if (dimensions == "3D") Fac = noise_texture(p, Detail, Distortion, Color); else if (dimensions == "4D") Fac = noise_texture(vector4(p[0], p[1], p[2], w), Detail, Distortion, Color); else error("Unknown dimension!"); }