Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'intern/cycles/kernel/osl')
-rw-r--r--intern/cycles/kernel/osl/CMakeLists.txt18
-rw-r--r--intern/cycles/kernel/osl/background.cpp2
-rw-r--r--intern/cycles/kernel/osl/bsdf_diffuse_ramp.cpp5
-rw-r--r--intern/cycles/kernel/osl/bsdf_phong_ramp.cpp4
-rw-r--r--intern/cycles/kernel/osl/bssrdf.cpp (renamed from intern/cycles/kernel/osl/osl_bssrdf.cpp)5
-rw-r--r--intern/cycles/kernel/osl/closures.cpp (renamed from intern/cycles/kernel/osl/osl_closures.cpp)12
-rw-r--r--intern/cycles/kernel/osl/closures.h (renamed from intern/cycles/kernel/osl/osl_closures.h)4
-rw-r--r--intern/cycles/kernel/osl/emissive.cpp4
-rw-r--r--intern/cycles/kernel/osl/globals.h (renamed from intern/cycles/kernel/osl/osl_globals.h)10
-rw-r--r--intern/cycles/kernel/osl/services.cpp (renamed from intern/cycles/kernel/osl/osl_services.cpp)41
-rw-r--r--intern/cycles/kernel/osl/services.h (renamed from intern/cycles/kernel/osl/osl_services.h)0
-rw-r--r--intern/cycles/kernel/osl/shader.cpp (renamed from intern/cycles/kernel/osl/osl_shader.cpp)19
-rw-r--r--intern/cycles/kernel/osl/shader.h (renamed from intern/cycles/kernel/osl/osl_shader.h)2
-rw-r--r--intern/cycles/kernel/osl/shaders/CMakeLists.txt155
-rw-r--r--intern/cycles/kernel/osl/shaders/node_absorption_volume.osl24
-rw-r--r--intern/cycles/kernel/osl/shaders/node_add_closure.osl24
-rw-r--r--intern/cycles/kernel/osl/shaders/node_ambient_occlusion.osl43
-rw-r--r--intern/cycles/kernel/osl/shaders/node_anisotropic_bsdf.osl57
-rw-r--r--intern/cycles/kernel/osl/shaders/node_attribute.osl45
-rw-r--r--intern/cycles/kernel/osl/shaders/node_background.osl24
-rw-r--r--intern/cycles/kernel/osl/shaders/node_bevel.osl29
-rw-r--r--intern/cycles/kernel/osl/shaders/node_blackbody.osl28
-rw-r--r--intern/cycles/kernel/osl/shaders/node_brick_texture.osl119
-rw-r--r--intern/cycles/kernel/osl/shaders/node_brightness.osl30
-rw-r--r--intern/cycles/kernel/osl/shaders/node_bump.osl68
-rw-r--r--intern/cycles/kernel/osl/shaders/node_camera.osl29
-rw-r--r--intern/cycles/kernel/osl/shaders/node_checker_texture.osl62
-rw-r--r--intern/cycles/kernel/osl/shaders/node_clamp.osl27
-rw-r--r--intern/cycles/kernel/osl/shaders/node_color.h163
-rw-r--r--intern/cycles/kernel/osl/shaders/node_combine_hsv.osl22
-rw-r--r--intern/cycles/kernel/osl/shaders/node_combine_rgb.osl22
-rw-r--r--intern/cycles/kernel/osl/shaders/node_combine_xyz.osl22
-rw-r--r--intern/cycles/kernel/osl/shaders/node_convert_from_color.osl32
-rw-r--r--intern/cycles/kernel/osl/shaders/node_convert_from_float.osl32
-rw-r--r--intern/cycles/kernel/osl/shaders/node_convert_from_int.osl33
-rw-r--r--intern/cycles/kernel/osl/shaders/node_convert_from_normal.osl32
-rw-r--r--intern/cycles/kernel/osl/shaders/node_convert_from_point.osl32
-rw-r--r--intern/cycles/kernel/osl/shaders/node_convert_from_string.osl27
-rw-r--r--intern/cycles/kernel/osl/shaders/node_convert_from_vector.osl32
-rw-r--r--intern/cycles/kernel/osl/shaders/node_diffuse_bsdf.osl28
-rw-r--r--intern/cycles/kernel/osl/shaders/node_displacement.osl36
-rw-r--r--intern/cycles/kernel/osl/shaders/node_emission.osl22
-rw-r--r--intern/cycles/kernel/osl/shaders/node_environment_texture.osl85
-rw-r--r--intern/cycles/kernel/osl/shaders/node_float_curve.osl32
-rw-r--r--intern/cycles/kernel/osl/shaders/node_fresnel.h62
-rw-r--r--intern/cycles/kernel/osl/shaders/node_fresnel.osl26
-rw-r--r--intern/cycles/kernel/osl/shaders/node_gamma.osl22
-rw-r--r--intern/cycles/kernel/osl/shaders/node_geometry.osl71
-rw-r--r--intern/cycles/kernel/osl/shaders/node_glass_bsdf.osl43
-rw-r--r--intern/cycles/kernel/osl/shaders/node_glossy_bsdf.osl38
-rw-r--r--intern/cycles/kernel/osl/shaders/node_gradient_texture.osl77
-rw-r--r--intern/cycles/kernel/osl/shaders/node_hair_bsdf.osl57
-rw-r--r--intern/cycles/kernel/osl/shaders/node_hair_info.osl32
-rw-r--r--intern/cycles/kernel/osl/shaders/node_hash.h81
-rw-r--r--intern/cycles/kernel/osl/shaders/node_holdout.osl21
-rw-r--r--intern/cycles/kernel/osl/shaders/node_hsv.osl42
-rw-r--r--intern/cycles/kernel/osl/shaders/node_ies_light.osl40
-rw-r--r--intern/cycles/kernel/osl/shaders/node_image_texture.osl270
-rw-r--r--intern/cycles/kernel/osl/shaders/node_invert.osl23
-rw-r--r--intern/cycles/kernel/osl/shaders/node_layer_weight.osl44
-rw-r--r--intern/cycles/kernel/osl/shaders/node_light_falloff.osl42
-rw-r--r--intern/cycles/kernel/osl/shaders/node_light_path.osl64
-rw-r--r--intern/cycles/kernel/osl/shaders/node_magic_texture.osl108
-rw-r--r--intern/cycles/kernel/osl/shaders/node_map_range.osl58
-rw-r--r--intern/cycles/kernel/osl/shaders/node_mapping.osl73
-rw-r--r--intern/cycles/kernel/osl/shaders/node_math.h117
-rw-r--r--intern/cycles/kernel/osl/shaders/node_math.osl109
-rw-r--r--intern/cycles/kernel/osl/shaders/node_mix.osl330
-rw-r--r--intern/cycles/kernel/osl/shaders/node_mix_closure.osl26
-rw-r--r--intern/cycles/kernel/osl/shaders/node_musgrave_texture.osl803
-rw-r--r--intern/cycles/kernel/osl/shaders/node_noise.h202
-rw-r--r--intern/cycles/kernel/osl/shaders/node_noise_texture.osl152
-rw-r--r--intern/cycles/kernel/osl/shaders/node_normal.osl26
-rw-r--r--intern/cycles/kernel/osl/shaders/node_normal_map.osl90
-rw-r--r--intern/cycles/kernel/osl/shaders/node_object_info.osl30
-rw-r--r--intern/cycles/kernel/osl/shaders/node_output_displacement.osl22
-rw-r--r--intern/cycles/kernel/osl/shaders/node_output_surface.osl22
-rw-r--r--intern/cycles/kernel/osl/shaders/node_output_volume.osl22
-rw-r--r--intern/cycles/kernel/osl/shaders/node_particle_info.osl36
-rw-r--r--intern/cycles/kernel/osl/shaders/node_principled_bsdf.osl157
-rw-r--r--intern/cycles/kernel/osl/shaders/node_principled_hair_bsdf.osl105
-rw-r--r--intern/cycles/kernel/osl/shaders/node_principled_volume.osl93
-rw-r--r--intern/cycles/kernel/osl/shaders/node_ramp_util.h93
-rw-r--r--intern/cycles/kernel/osl/shaders/node_refraction_bsdf.osl36
-rw-r--r--intern/cycles/kernel/osl/shaders/node_rgb_curves.osl39
-rw-r--r--intern/cycles/kernel/osl/shaders/node_rgb_ramp.osl30
-rw-r--r--intern/cycles/kernel/osl/shaders/node_rgb_to_bw.osl22
-rw-r--r--intern/cycles/kernel/osl/shaders/node_scatter_volume.osl25
-rw-r--r--intern/cycles/kernel/osl/shaders/node_separate_hsv.osl30
-rw-r--r--intern/cycles/kernel/osl/shaders/node_separate_rgb.osl27
-rw-r--r--intern/cycles/kernel/osl/shaders/node_separate_xyz.osl27
-rw-r--r--intern/cycles/kernel/osl/shaders/node_set_normal.osl23
-rw-r--r--intern/cycles/kernel/osl/shaders/node_sky_texture.osl237
-rw-r--r--intern/cycles/kernel/osl/shaders/node_subsurface_scattering.osl30
-rw-r--r--intern/cycles/kernel/osl/shaders/node_tangent.osl46
-rw-r--r--intern/cycles/kernel/osl/shaders/node_texture_coordinate.osl99
-rw-r--r--intern/cycles/kernel/osl/shaders/node_toon_bsdf.osl30
-rw-r--r--intern/cycles/kernel/osl/shaders/node_translucent_bsdf.osl22
-rw-r--r--intern/cycles/kernel/osl/shaders/node_transparent_bsdf.osl22
-rw-r--r--intern/cycles/kernel/osl/shaders/node_uv_map.osl44
-rw-r--r--intern/cycles/kernel/osl/shaders/node_value.osl29
-rw-r--r--intern/cycles/kernel/osl/shaders/node_vector_curves.osl39
-rw-r--r--intern/cycles/kernel/osl/shaders/node_vector_displacement.osl58
-rw-r--r--intern/cycles/kernel/osl/shaders/node_vector_math.osl112
-rw-r--r--intern/cycles/kernel/osl/shaders/node_vector_rotate.osl49
-rw-r--r--intern/cycles/kernel/osl/shaders/node_vector_transform.osl34
-rw-r--r--intern/cycles/kernel/osl/shaders/node_velvet_bsdf.osl28
-rw-r--r--intern/cycles/kernel/osl/shaders/node_vertex_color.osl50
-rw-r--r--intern/cycles/kernel/osl/shaders/node_voronoi_texture.osl1031
-rw-r--r--intern/cycles/kernel/osl/shaders/node_voxel_texture.osl45
-rw-r--r--intern/cycles/kernel/osl/shaders/node_wave_texture.osl119
-rw-r--r--intern/cycles/kernel/osl/shaders/node_wavelength.osl22
-rw-r--r--intern/cycles/kernel/osl/shaders/node_white_noise_texture.osl49
-rw-r--r--intern/cycles/kernel/osl/shaders/node_wireframe.osl40
-rw-r--r--intern/cycles/kernel/osl/shaders/stdcycles.h150
115 files changed, 7850 insertions, 65 deletions
diff --git a/intern/cycles/kernel/osl/CMakeLists.txt b/intern/cycles/kernel/osl/CMakeLists.txt
index 6cdc7367fbb..f226c95766f 100644
--- a/intern/cycles/kernel/osl/CMakeLists.txt
+++ b/intern/cycles/kernel/osl/CMakeLists.txt
@@ -25,21 +25,21 @@ set(SRC
bsdf_diffuse_ramp.cpp
bsdf_phong_ramp.cpp
emissive.cpp
- osl_bssrdf.cpp
- osl_closures.cpp
- osl_services.cpp
- osl_shader.cpp
+ bssrdf.cpp
+ closures.cpp
+ services.cpp
+ shader.cpp
)
set(HEADER_SRC
- osl_closures.h
- osl_globals.h
- osl_services.h
- osl_shader.h
+ closures.h
+ globals.h
+ services.h
+ shader.h
)
set(LIB
- cycles_render
+ cycles_scene
${OSL_LIBRARIES}
${OPENIMAGEIO_LIBRARIES}
diff --git a/intern/cycles/kernel/osl/background.cpp b/intern/cycles/kernel/osl/background.cpp
index bb290a5ced2..540180f99e8 100644
--- a/intern/cycles/kernel/osl/background.cpp
+++ b/intern/cycles/kernel/osl/background.cpp
@@ -34,7 +34,7 @@
#include <OSL/genclosure.h>
-#include "kernel/osl/osl_closures.h"
+#include "kernel/osl/closures.h"
// clang-format off
#include "kernel/device/cpu/compat.h"
diff --git a/intern/cycles/kernel/osl/bsdf_diffuse_ramp.cpp b/intern/cycles/kernel/osl/bsdf_diffuse_ramp.cpp
index 45216f4c74d..768531a0bf9 100644
--- a/intern/cycles/kernel/osl/bsdf_diffuse_ramp.cpp
+++ b/intern/cycles/kernel/osl/bsdf_diffuse_ramp.cpp
@@ -35,11 +35,10 @@
#include <OSL/genclosure.h>
#include "kernel/device/cpu/compat.h"
-#include "kernel/osl/osl_closures.h"
+#include "kernel/osl/closures.h"
// clang-format off
-#include "kernel/kernel_types.h"
-#include "kernel/kernel_montecarlo.h"
+#include "kernel/types.h"
#include "kernel/closure/alloc.h"
#include "kernel/closure/bsdf_diffuse_ramp.h"
// clang-format on
diff --git a/intern/cycles/kernel/osl/bsdf_phong_ramp.cpp b/intern/cycles/kernel/osl/bsdf_phong_ramp.cpp
index 90160fba962..d34a33216a0 100644
--- a/intern/cycles/kernel/osl/bsdf_phong_ramp.cpp
+++ b/intern/cycles/kernel/osl/bsdf_phong_ramp.cpp
@@ -35,10 +35,10 @@
#include <OSL/genclosure.h>
#include "kernel/device/cpu/compat.h"
-#include "kernel/osl/osl_closures.h"
+#include "kernel/osl/closures.h"
// clang-format off
-#include "kernel/kernel_types.h"
+#include "kernel/types.h"
#include "kernel/closure/alloc.h"
#include "kernel/closure/bsdf_phong_ramp.h"
// clang-format on
diff --git a/intern/cycles/kernel/osl/osl_bssrdf.cpp b/intern/cycles/kernel/osl/bssrdf.cpp
index 5bf7b604498..7c7f1ce157f 100644
--- a/intern/cycles/kernel/osl/osl_bssrdf.cpp
+++ b/intern/cycles/kernel/osl/bssrdf.cpp
@@ -33,11 +33,10 @@
#include <OSL/genclosure.h>
#include "kernel/device/cpu/compat.h"
-#include "kernel/osl/osl_closures.h"
+#include "kernel/osl/closures.h"
// clang-format off
-#include "kernel/kernel_types.h"
-#include "kernel/kernel_montecarlo.h"
+#include "kernel/types.h"
#include "kernel/closure/alloc.h"
#include "kernel/closure/bsdf_util.h"
diff --git a/intern/cycles/kernel/osl/osl_closures.cpp b/intern/cycles/kernel/osl/closures.cpp
index a2062046ae8..adc0f50aefb 100644
--- a/intern/cycles/kernel/osl/osl_closures.cpp
+++ b/intern/cycles/kernel/osl/closures.cpp
@@ -33,19 +33,17 @@
#include <OSL/genclosure.h>
#include <OSL/oslclosure.h>
-#include "kernel/osl/osl_closures.h"
-#include "kernel/osl/osl_shader.h"
+#include "kernel/osl/closures.h"
+#include "kernel/osl/shader.h"
-#include "util/util_math.h"
-#include "util/util_param.h"
+#include "util/math.h"
+#include "util/param.h"
// clang-format off
#include "kernel/device/cpu/compat.h"
#include "kernel/device/cpu/globals.h"
-#include "kernel/kernel_types.h"
-#include "kernel/kernel_montecarlo.h"
-#include "kernel/kernel_random.h"
+#include "kernel/types.h"
#include "kernel/closure/alloc.h"
#include "kernel/closure/bsdf_util.h"
diff --git a/intern/cycles/kernel/osl/osl_closures.h b/intern/cycles/kernel/osl/closures.h
index 7869d793737..8f573e89734 100644
--- a/intern/cycles/kernel/osl/osl_closures.h
+++ b/intern/cycles/kernel/osl/closures.h
@@ -33,8 +33,8 @@
#ifndef __OSL_CLOSURES_H__
#define __OSL_CLOSURES_H__
-#include "kernel/kernel_types.h"
-#include "util/util_types.h"
+#include "kernel/types.h"
+#include "util/types.h"
#include <OSL/genclosure.h>
#include <OSL/oslclosure.h>
diff --git a/intern/cycles/kernel/osl/emissive.cpp b/intern/cycles/kernel/osl/emissive.cpp
index 5a7fe14b22e..2615e300a92 100644
--- a/intern/cycles/kernel/osl/emissive.cpp
+++ b/intern/cycles/kernel/osl/emissive.cpp
@@ -34,11 +34,11 @@
#include <OSL/genclosure.h>
-#include "kernel/osl/osl_closures.h"
+#include "kernel/osl/closures.h"
// clang-format off
#include "kernel/device/cpu/compat.h"
-#include "kernel/kernel_types.h"
+#include "kernel/types.h"
#include "kernel/closure/alloc.h"
#include "kernel/closure/emissive.h"
// clang-format on
diff --git a/intern/cycles/kernel/osl/osl_globals.h b/intern/cycles/kernel/osl/globals.h
index f1789f0d7eb..126ace0086e 100644
--- a/intern/cycles/kernel/osl/osl_globals.h
+++ b/intern/cycles/kernel/osl/globals.h
@@ -24,11 +24,11 @@
# include <OpenImageIO/refcnt.h>
# include <OpenImageIO/unordered_map_concurrent.h>
-# include "util/util_map.h"
-# include "util/util_param.h"
-# include "util/util_thread.h"
-# include "util/util_unique_ptr.h"
-# include "util/util_vector.h"
+# include "util/map.h"
+# include "util/param.h"
+# include "util/thread.h"
+# include "util/unique_ptr.h"
+# include "util/vector.h"
# ifndef WIN32
using std::isfinite;
diff --git a/intern/cycles/kernel/osl/osl_services.cpp b/intern/cycles/kernel/osl/services.cpp
index cbe1bf1bfc0..ca0a5a068b3 100644
--- a/intern/cycles/kernel/osl/osl_services.cpp
+++ b/intern/cycles/kernel/osl/services.cpp
@@ -25,38 +25,41 @@
#include <string.h>
-#include "render/colorspace.h"
-#include "render/mesh.h"
-#include "render/object.h"
-#include "render/scene.h"
+#include "scene/colorspace.h"
+#include "scene/mesh.h"
+#include "scene/object.h"
+#include "scene/scene.h"
-#include "kernel/osl/osl_closures.h"
-#include "kernel/osl/osl_globals.h"
-#include "kernel/osl/osl_services.h"
-#include "kernel/osl/osl_shader.h"
+#include "kernel/osl/closures.h"
+#include "kernel/osl/globals.h"
+#include "kernel/osl/services.h"
+#include "kernel/osl/shader.h"
-#include "util/util_foreach.h"
-#include "util/util_logging.h"
-#include "util/util_string.h"
+#include "util/foreach.h"
+#include "util/log.h"
+#include "util/string.h"
// clang-format off
#include "kernel/device/cpu/compat.h"
#include "kernel/device/cpu/globals.h"
#include "kernel/device/cpu/image.h"
-#include "kernel/kernel_differential.h"
+#include "kernel/util/differential.h"
-#include "kernel/integrator/integrator_state.h"
-#include "kernel/integrator/integrator_state_flow.h"
+#include "kernel/integrator/state.h"
+#include "kernel/integrator/state_flow.h"
#include "kernel/geom/geom.h"
+
#include "kernel/bvh/bvh.h"
-#include "kernel/kernel_color.h"
-#include "kernel/kernel_camera.h"
-#include "kernel/kernel_path_state.h"
-#include "kernel/kernel_projection.h"
-#include "kernel/kernel_shader.h"
+#include "kernel/camera/camera.h"
+#include "kernel/camera/projection.h"
+
+#include "kernel/integrator/path_state.h"
+#include "kernel/integrator/shader_eval.h"
+
+#include "kernel/util/color.h"
// clang-format on
CCL_NAMESPACE_BEGIN
diff --git a/intern/cycles/kernel/osl/osl_services.h b/intern/cycles/kernel/osl/services.h
index d9f57c642ad..d9f57c642ad 100644
--- a/intern/cycles/kernel/osl/osl_services.h
+++ b/intern/cycles/kernel/osl/services.h
diff --git a/intern/cycles/kernel/osl/osl_shader.cpp b/intern/cycles/kernel/osl/shader.cpp
index fba207e7230..33633c69e29 100644
--- a/intern/cycles/kernel/osl/osl_shader.cpp
+++ b/intern/cycles/kernel/osl/shader.cpp
@@ -20,22 +20,19 @@
#include "kernel/device/cpu/compat.h"
#include "kernel/device/cpu/globals.h"
-#include "kernel/kernel_montecarlo.h"
-#include "kernel/kernel_types.h"
+#include "kernel/types.h"
-#include "kernel/geom/geom_object.h"
+#include "kernel/geom/object.h"
-#include "kernel/integrator/integrator_state.h"
+#include "kernel/integrator/state.h"
-#include "kernel/osl/osl_closures.h"
-#include "kernel/osl/osl_globals.h"
-#include "kernel/osl/osl_services.h"
-#include "kernel/osl/osl_shader.h"
+#include "kernel/osl/closures.h"
+#include "kernel/osl/globals.h"
+#include "kernel/osl/services.h"
+#include "kernel/osl/shader.h"
// clang-format on
-#include "util/util_foreach.h"
-
-#include "render/attribute.h"
+#include "scene/attribute.h"
CCL_NAMESPACE_BEGIN
diff --git a/intern/cycles/kernel/osl/osl_shader.h b/intern/cycles/kernel/osl/shader.h
index 037a18a1f19..7d68d4eae7f 100644
--- a/intern/cycles/kernel/osl/osl_shader.h
+++ b/intern/cycles/kernel/osl/shader.h
@@ -29,7 +29,7 @@
* This means no thread state must be passed along in the kernel itself.
*/
-# include "kernel/kernel_types.h"
+# include "kernel/types.h"
CCL_NAMESPACE_BEGIN
diff --git a/intern/cycles/kernel/osl/shaders/CMakeLists.txt b/intern/cycles/kernel/osl/shaders/CMakeLists.txt
new file mode 100644
index 00000000000..6b62e7bb52f
--- /dev/null
+++ b/intern/cycles/kernel/osl/shaders/CMakeLists.txt
@@ -0,0 +1,155 @@
+# Copyright 2011-2020 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.
+
+# OSL node shaders
+
+set(SRC_OSL
+ node_add_closure.osl
+ node_ambient_occlusion.osl
+ node_anisotropic_bsdf.osl
+ node_attribute.osl
+ node_background.osl
+ node_bevel.osl
+ node_brick_texture.osl
+ node_brightness.osl
+ node_bump.osl
+ node_camera.osl
+ node_checker_texture.osl
+ node_clamp.osl
+ node_combine_rgb.osl
+ node_combine_hsv.osl
+ node_combine_xyz.osl
+ node_convert_from_color.osl
+ node_convert_from_float.osl
+ node_convert_from_int.osl
+ node_convert_from_normal.osl
+ node_convert_from_point.osl
+ node_convert_from_vector.osl
+ node_diffuse_bsdf.osl
+ node_displacement.osl
+ node_vector_displacement.osl
+ node_emission.osl
+ node_environment_texture.osl
+ node_float_curve.osl
+ node_fresnel.osl
+ node_gamma.osl
+ node_geometry.osl
+ node_glass_bsdf.osl
+ node_glossy_bsdf.osl
+ node_gradient_texture.osl
+ node_hair_info.osl
+ node_scatter_volume.osl
+ node_absorption_volume.osl
+ node_principled_volume.osl
+ node_holdout.osl
+ node_hsv.osl
+ node_ies_light.osl
+ node_image_texture.osl
+ node_invert.osl
+ node_layer_weight.osl
+ node_light_falloff.osl
+ node_light_path.osl
+ node_magic_texture.osl
+ node_map_range.osl
+ node_mapping.osl
+ node_math.osl
+ node_mix.osl
+ node_mix_closure.osl
+ node_musgrave_texture.osl
+ node_noise_texture.osl
+ node_normal.osl
+ node_normal_map.osl
+ node_object_info.osl
+ node_output_displacement.osl
+ node_output_surface.osl
+ node_output_volume.osl
+ node_particle_info.osl
+ node_refraction_bsdf.osl
+ node_rgb_curves.osl
+ node_rgb_ramp.osl
+ node_separate_rgb.osl
+ node_separate_hsv.osl
+ node_separate_xyz.osl
+ node_set_normal.osl
+ node_sky_texture.osl
+ node_subsurface_scattering.osl
+ node_tangent.osl
+ node_texture_coordinate.osl
+ node_toon_bsdf.osl
+ node_translucent_bsdf.osl
+ node_transparent_bsdf.osl
+ node_value.osl
+ node_vector_curves.osl
+ node_vector_math.osl
+ node_vector_rotate.osl
+ node_vector_transform.osl
+ node_velvet_bsdf.osl
+ node_vertex_color.osl
+ node_voronoi_texture.osl
+ node_voxel_texture.osl
+ node_wavelength.osl
+ node_blackbody.osl
+ node_wave_texture.osl
+ node_white_noise_texture.osl
+ node_wireframe.osl
+ node_hair_bsdf.osl
+ node_principled_hair_bsdf.osl
+ node_uv_map.osl
+ node_principled_bsdf.osl
+ node_rgb_to_bw.osl
+)
+
+# The headers that OSL ships differs per release so we can not
+# hardcode this.
+file(GLOB SRC_OSL_HEADER_DIST ${OSL_SHADER_DIR}/*.h)
+
+set(SRC_OSL_HEADERS
+ node_color.h
+ node_fresnel.h
+ node_hash.h
+ node_math.h
+ node_noise.h
+ node_ramp_util.h
+ stdcycles.h
+ ${SRC_OSL_HEADER_DIST}
+)
+
+set(SRC_OSO
+
+)
+
+# TODO, add a module to compile OSL
+foreach(_file ${SRC_OSL})
+ set(_OSL_FILE ${CMAKE_CURRENT_SOURCE_DIR}/${_file})
+ set_source_files_properties(${_file} PROPERTIES HEADER_FILE_ONLY TRUE)
+ string(REPLACE ".osl" ".oso" _OSO_FILE ${_OSL_FILE})
+ string(REPLACE ${CMAKE_SOURCE_DIR} ${CMAKE_BINARY_DIR} _OSO_FILE ${_OSO_FILE})
+ add_custom_command(
+ OUTPUT ${_OSO_FILE}
+ COMMAND ${OSL_COMPILER} -q -O2 -I"${CMAKE_CURRENT_SOURCE_DIR}" -I"${OSL_SHADER_DIR}" -o ${_OSO_FILE} ${_OSL_FILE}
+ DEPENDS ${_OSL_FILE} ${SRC_OSL_HEADERS} ${OSL_COMPILER})
+ list(APPEND SRC_OSO
+ ${_OSO_FILE}
+ )
+
+ unset(_OSL_FILE)
+ unset(_OSO_FILE)
+endforeach()
+
+add_custom_target(cycles_osl_shaders ALL DEPENDS ${SRC_OSO} ${SRC_OSL_HEADERS} ${OSL_COMPILER} SOURCES ${SRC_OSL})
+cycles_set_solution_folder(cycles_osl_shaders)
+
+# CMAKE_CURRENT_SOURCE_DIR is already included in OSO paths
+delayed_install("" "${SRC_OSO}" ${CYCLES_INSTALL_PATH}/shader)
+delayed_install("${CMAKE_CURRENT_SOURCE_DIR}" "${SRC_OSL_HEADERS}" ${CYCLES_INSTALL_PATH}/shader)
diff --git a/intern/cycles/kernel/osl/shaders/node_absorption_volume.osl b/intern/cycles/kernel/osl/shaders/node_absorption_volume.osl
new file mode 100644
index 00000000000..37ccc4c969f
--- /dev/null
+++ b/intern/cycles/kernel/osl/shaders/node_absorption_volume.osl
@@ -0,0 +1,24 @@
+/*
+ * 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 "stdcycles.h"
+
+shader node_absorption_volume(color Color = color(0.8, 0.8, 0.8),
+ float Density = 1.0,
+ output closure color Volume = 0)
+{
+ Volume = ((color(1.0, 1.0, 1.0) - Color) * max(Density, 0.0)) * absorption();
+}
diff --git a/intern/cycles/kernel/osl/shaders/node_add_closure.osl b/intern/cycles/kernel/osl/shaders/node_add_closure.osl
new file mode 100644
index 00000000000..27ecc9ef0c2
--- /dev/null
+++ b/intern/cycles/kernel/osl/shaders/node_add_closure.osl
@@ -0,0 +1,24 @@
+/*
+ * 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 "stdcycles.h"
+
+shader node_add_closure(closure color Closure1 = 0,
+ closure color Closure2 = 0,
+ output closure color Closure = 0)
+{
+ Closure = Closure1 + Closure2;
+}
diff --git a/intern/cycles/kernel/osl/shaders/node_ambient_occlusion.osl b/intern/cycles/kernel/osl/shaders/node_ambient_occlusion.osl
new file mode 100644
index 00000000000..22d245d0698
--- /dev/null
+++ b/intern/cycles/kernel/osl/shaders/node_ambient_occlusion.osl
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2011-2018 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 "stdcycles.h"
+
+shader node_ambient_occlusion(color ColorIn = color(1.0, 1.0, 1.0),
+ int samples = 16,
+ float Distance = 1.0,
+ normal Normal = N,
+ int inside = 0,
+ int only_local = 0,
+ output color ColorOut = color(1.0, 1.0, 1.0),
+ output float AO = 1.0)
+{
+ int global_radius = (Distance == 0.0 && !isconnected(Distance));
+
+ /* Abuse texture call with special @ao token. */
+ AO = texture("@ao",
+ samples,
+ Distance,
+ Normal[0],
+ Normal[1],
+ Normal[2],
+ inside,
+ "sblur",
+ only_local,
+ "tblur",
+ global_radius);
+ ColorOut = ColorIn * AO;
+}
diff --git a/intern/cycles/kernel/osl/shaders/node_anisotropic_bsdf.osl b/intern/cycles/kernel/osl/shaders/node_anisotropic_bsdf.osl
new file mode 100644
index 00000000000..739cd375ab2
--- /dev/null
+++ b/intern/cycles/kernel/osl/shaders/node_anisotropic_bsdf.osl
@@ -0,0 +1,57 @@
+/*
+ * 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 "stdcycles.h"
+
+shader node_anisotropic_bsdf(color Color = 0.0,
+ string distribution = "GGX",
+ float Roughness = 0.0,
+ float Anisotropy = 0.0,
+ float Rotation = 0.0,
+ normal Normal = N,
+ normal Tangent = normalize(dPdu),
+ output closure color BSDF = 0)
+{
+ /* rotate tangent around normal */
+ vector T = Tangent;
+
+ if (Rotation != 0.0)
+ T = rotate(T, Rotation * M_2PI, point(0.0, 0.0, 0.0), Normal);
+
+ /* compute roughness */
+ float roughness = Roughness * Roughness;
+ float roughness_u, roughness_v;
+ float aniso = clamp(Anisotropy, -0.99, 0.99);
+
+ if (aniso < 0.0) {
+ roughness_u = roughness / (1.0 + aniso);
+ roughness_v = roughness * (1.0 + aniso);
+ }
+ else {
+ roughness_u = roughness * (1.0 - aniso);
+ roughness_v = roughness / (1.0 - aniso);
+ }
+
+ if (distribution == "sharp")
+ BSDF = Color * reflection(Normal);
+ else if (distribution == "beckmann")
+ BSDF = Color * microfacet_beckmann_aniso(Normal, T, roughness_u, roughness_v);
+ else if (distribution == "GGX")
+ BSDF = Color * microfacet_ggx_aniso(Normal, T, roughness_u, roughness_v);
+ else if (distribution == "Multiscatter GGX")
+ BSDF = Color * microfacet_multi_ggx_aniso(Normal, T, roughness_u, roughness_v, Color);
+ else
+ BSDF = Color * ashikhmin_shirley(Normal, T, roughness_u, roughness_v);
+}
diff --git a/intern/cycles/kernel/osl/shaders/node_attribute.osl b/intern/cycles/kernel/osl/shaders/node_attribute.osl
new file mode 100644
index 00000000000..b7f35956ec7
--- /dev/null
+++ b/intern/cycles/kernel/osl/shaders/node_attribute.osl
@@ -0,0 +1,45 @@
+/*
+ * 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 "stdcycles.h"
+
+shader node_attribute(string bump_offset = "center",
+ string name = "",
+ output point Vector = point(0.0, 0.0, 0.0),
+ output color Color = 0.0,
+ output float Fac = 0.0,
+ output float Alpha = 0.0)
+{
+ float data[4] = {0.0, 0.0, 0.0, 0.0};
+ getattribute(name, data);
+ Color = color(data[0], data[1], data[2]);
+ Vector = point(Color);
+ getattribute(name, Fac);
+ Alpha = data[3];
+
+ if (bump_offset == "dx") {
+ Color += Dx(Color);
+ Vector += Dx(Vector);
+ Fac += Dx(Fac);
+ Alpha += Dx(Alpha);
+ }
+ else if (bump_offset == "dy") {
+ Color += Dy(Color);
+ Vector += Dy(Vector);
+ Fac += Dy(Fac);
+ Alpha += Dy(Alpha);
+ }
+}
diff --git a/intern/cycles/kernel/osl/shaders/node_background.osl b/intern/cycles/kernel/osl/shaders/node_background.osl
new file mode 100644
index 00000000000..3f45db751b3
--- /dev/null
+++ b/intern/cycles/kernel/osl/shaders/node_background.osl
@@ -0,0 +1,24 @@
+/*
+ * 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 "stdcycles.h"
+
+shader node_background(color Color = 0.8,
+ float Strength = 1.0,
+ output closure color Background = 0)
+{
+ Background = Color * Strength * background();
+}
diff --git a/intern/cycles/kernel/osl/shaders/node_bevel.osl b/intern/cycles/kernel/osl/shaders/node_bevel.osl
new file mode 100644
index 00000000000..e87ddab716d
--- /dev/null
+++ b/intern/cycles/kernel/osl/shaders/node_bevel.osl
@@ -0,0 +1,29 @@
+/*
+ * 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 "stdcycles.h"
+
+shader node_bevel(int samples = 4,
+ float Radius = 0.05,
+ normal NormalIn = N,
+ output normal NormalOut = N)
+{
+ /* Abuse texture call with special @bevel token. */
+ vector bevel_N = (normal)(color)texture("@bevel", samples, Radius);
+
+ /* Preserve input normal. */
+ NormalOut = normalize(NormalIn + (bevel_N - N));
+}
diff --git a/intern/cycles/kernel/osl/shaders/node_blackbody.osl b/intern/cycles/kernel/osl/shaders/node_blackbody.osl
new file mode 100644
index 00000000000..741efae755d
--- /dev/null
+++ b/intern/cycles/kernel/osl/shaders/node_blackbody.osl
@@ -0,0 +1,28 @@
+/*
+ * 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 "stdcycles.h"
+
+shader node_blackbody(float Temperature = 1200.0, output color Color = 0.0)
+{
+ color rgb = blackbody(Temperature);
+
+ /* Scale by luminance */
+ float l = luminance(rgb);
+ if (l != 0.0)
+ rgb /= l;
+ Color = rgb;
+}
diff --git a/intern/cycles/kernel/osl/shaders/node_brick_texture.osl b/intern/cycles/kernel/osl/shaders/node_brick_texture.osl
new file mode 100644
index 00000000000..075a324c730
--- /dev/null
+++ b/intern/cycles/kernel/osl/shaders/node_brick_texture.osl
@@ -0,0 +1,119 @@
+/*
+ * 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 "stdcycles.h"
+
+/* Brick */
+
+float brick_noise(int ns) /* fast integer noise */
+{
+ int nn;
+ int n = (ns + 1013) & 2147483647;
+ n = (n >> 13) ^ n;
+ nn = (n * (n * n * 60493 + 19990303) + 1376312589) & 2147483647;
+ return 0.5 * ((float)nn / 1073741824.0);
+}
+
+float brick(point p,
+ float mortar_size,
+ float mortar_smooth,
+ float bias,
+ float BrickWidth,
+ float row_height,
+ float offset_amount,
+ int offset_frequency,
+ float squash_amount,
+ int squash_frequency,
+ output float tint)
+{
+ int bricknum, rownum;
+ float offset = 0.0;
+ float brick_width = BrickWidth;
+ float x, y;
+
+ rownum = (int)floor(p[1] / row_height);
+
+ if (offset_frequency && squash_frequency) {
+ brick_width *= (rownum % squash_frequency) ? 1.0 : squash_amount; /* squash */
+ offset = (rownum % offset_frequency) ? 0.0 : (brick_width * offset_amount); /* offset */
+ }
+
+ bricknum = (int)floor((p[0] + offset) / brick_width);
+
+ x = (p[0] + offset) - brick_width * bricknum;
+ y = p[1] - row_height * rownum;
+
+ tint = clamp((brick_noise((rownum << 16) + (bricknum & 65535)) + bias), 0.0, 1.0);
+
+ float min_dist = min(min(x, y), min(brick_width - x, row_height - y));
+ if (min_dist >= mortar_size) {
+ return 0.0;
+ }
+ else if (mortar_smooth == 0.0) {
+ return 1.0;
+ }
+ else {
+ min_dist = 1.0 - min_dist / mortar_size;
+ return smoothstep(0.0, mortar_smooth, min_dist);
+ }
+}
+
+shader node_brick_texture(int use_mapping = 0,
+ matrix mapping = matrix(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
+ float offset = 0.5,
+ int offset_frequency = 2,
+ float squash = 1.0,
+ int squash_frequency = 1,
+ point Vector = P,
+ color Color1 = 0.2,
+ color Color2 = 0.8,
+ color Mortar = 0.0,
+ float Scale = 5.0,
+ float MortarSize = 0.02,
+ float MortarSmooth = 0.0,
+ float Bias = 0.0,
+ float BrickWidth = 0.5,
+ float RowHeight = 0.25,
+ output float Fac = 0.0,
+ output color Color = 0.2)
+{
+ point p = Vector;
+
+ if (use_mapping)
+ p = transform(mapping, p);
+
+ float tint = 0.0;
+ color Col = Color1;
+
+ Fac = brick(p * Scale,
+ MortarSize,
+ MortarSmooth,
+ Bias,
+ BrickWidth,
+ RowHeight,
+ offset,
+ offset_frequency,
+ squash,
+ squash_frequency,
+ tint);
+
+ if (Fac != 1.0) {
+ float facm = 1.0 - tint;
+ Col = facm * Color1 + tint * Color2;
+ }
+
+ Color = mix(Col, Mortar, Fac);
+}
diff --git a/intern/cycles/kernel/osl/shaders/node_brightness.osl b/intern/cycles/kernel/osl/shaders/node_brightness.osl
new file mode 100644
index 00000000000..019edfb79a3
--- /dev/null
+++ b/intern/cycles/kernel/osl/shaders/node_brightness.osl
@@ -0,0 +1,30 @@
+/*
+ * 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 "stdcycles.h"
+
+shader node_brightness(color ColorIn = 0.8,
+ float Bright = 0.0,
+ float Contrast = 0.0,
+ output color ColorOut = 0.8)
+{
+ float a = 1.0 + Contrast;
+ float b = Bright - Contrast * 0.5;
+
+ ColorOut[0] = max(a * ColorIn[0] + b, 0.0);
+ ColorOut[1] = max(a * ColorIn[1] + b, 0.0);
+ ColorOut[2] = max(a * ColorIn[2] + b, 0.0);
+}
diff --git a/intern/cycles/kernel/osl/shaders/node_bump.osl b/intern/cycles/kernel/osl/shaders/node_bump.osl
new file mode 100644
index 00000000000..811182f40b5
--- /dev/null
+++ b/intern/cycles/kernel/osl/shaders/node_bump.osl
@@ -0,0 +1,68 @@
+/*
+ * 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 "stdcycles.h"
+
+/* "Bump Mapping Unparameterized Surfaces on the GPU"
+ * Morten S. Mikkelsen, 2010 */
+
+surface node_bump(int invert = 0,
+ int use_object_space = 0,
+ normal NormalIn = N,
+ float Strength = 0.1,
+ float Distance = 1.0,
+ float SampleCenter = 0.0,
+ float SampleX = 0.0,
+ float SampleY = 0.0,
+ output normal NormalOut = N)
+{
+ point Ptmp = P;
+ normal Normal = NormalIn;
+
+ if (use_object_space) {
+ Ptmp = transform("object", Ptmp);
+ Normal = normalize(transform("object", Normal));
+ }
+
+ /* get surface tangents from normal */
+ vector dPdx = Dx(Ptmp);
+ vector dPdy = Dy(Ptmp);
+
+ vector Rx = cross(dPdy, Normal);
+ vector Ry = cross(Normal, dPdx);
+
+ /* compute surface gradient and determinant */
+ float det = dot(dPdx, Rx);
+ vector surfgrad = (SampleX - SampleCenter) * Rx + (SampleY - SampleCenter) * Ry;
+
+ float absdet = fabs(det);
+
+ float strength = max(Strength, 0.0);
+ float dist = Distance;
+
+ if (invert)
+ dist *= -1.0;
+
+ /* compute and output perturbed normal */
+ NormalOut = normalize(absdet * Normal - dist * sign(det) * surfgrad);
+ NormalOut = normalize(strength * NormalOut + (1.0 - strength) * Normal);
+
+ if (use_object_space) {
+ NormalOut = normalize(transform("object", "world", NormalOut));
+ }
+
+ NormalOut = ensure_valid_reflection(Ng, I, NormalOut);
+}
diff --git a/intern/cycles/kernel/osl/shaders/node_camera.osl b/intern/cycles/kernel/osl/shaders/node_camera.osl
new file mode 100644
index 00000000000..45ca50c6e1e
--- /dev/null
+++ b/intern/cycles/kernel/osl/shaders/node_camera.osl
@@ -0,0 +1,29 @@
+/*
+ * 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 "stdcycles.h"
+
+shader node_camera(output vector ViewVector = vector(0.0, 0.0, 0.0),
+ output float ViewZDepth = 0.0,
+ output float ViewDistance = 0.0)
+{
+ ViewVector = (vector)transform("world", "camera", P);
+
+ ViewZDepth = fabs(ViewVector[2]);
+ ViewDistance = length(ViewVector);
+
+ ViewVector = normalize(ViewVector);
+}
diff --git a/intern/cycles/kernel/osl/shaders/node_checker_texture.osl b/intern/cycles/kernel/osl/shaders/node_checker_texture.osl
new file mode 100644
index 00000000000..d6a30dbdb40
--- /dev/null
+++ b/intern/cycles/kernel/osl/shaders/node_checker_texture.osl
@@ -0,0 +1,62 @@
+/*
+ * 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 "stdcycles.h"
+
+/* Checker */
+
+float checker(point ip)
+{
+ point p;
+ p[0] = (ip[0] + 0.000001) * 0.999999;
+ p[1] = (ip[1] + 0.000001) * 0.999999;
+ p[2] = (ip[2] + 0.000001) * 0.999999;
+
+ int xi = (int)fabs(floor(p[0]));
+ int yi = (int)fabs(floor(p[1]));
+ int zi = (int)fabs(floor(p[2]));
+
+ if ((xi % 2 == yi % 2) == (zi % 2)) {
+ return 1.0;
+ }
+ else {
+ return 0.0;
+ }
+}
+
+shader node_checker_texture(
+ int use_mapping = 0,
+ matrix mapping = matrix(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
+ float Scale = 5.0,
+ point Vector = P,
+ color Color1 = 0.8,
+ color Color2 = 0.2,
+ output float Fac = 0.0,
+ output color Color = 0.0)
+{
+ point p = Vector;
+
+ if (use_mapping)
+ p = transform(mapping, p);
+
+ Fac = checker(p * Scale);
+ if (Fac == 1.0) {
+ Color = Color1;
+ }
+ else {
+ Color = Color2;
+ }
+}
diff --git a/intern/cycles/kernel/osl/shaders/node_clamp.osl b/intern/cycles/kernel/osl/shaders/node_clamp.osl
new file mode 100644
index 00000000000..b600fb7c455
--- /dev/null
+++ b/intern/cycles/kernel/osl/shaders/node_clamp.osl
@@ -0,0 +1,27 @@
+/*
+ * 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 "stdcycles.h"
+
+shader node_clamp(string clamp_type = "minmax",
+ float Value = 1.0,
+ float Min = 0.0,
+ float Max = 1.0,
+ output float Result = 0.0)
+{
+ Result = (clamp_type == "range" && (Min > Max)) ? clamp(Value, Max, Min) :
+ clamp(Value, Min, Max);
+}
diff --git a/intern/cycles/kernel/osl/shaders/node_color.h b/intern/cycles/kernel/osl/shaders/node_color.h
new file mode 100644
index 00000000000..276c91843e8
--- /dev/null
+++ b/intern/cycles/kernel/osl/shaders/node_color.h
@@ -0,0 +1,163 @@
+/*
+ * 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.
+ */
+
+/* TODO(lukas): Fix colors in OSL. */
+
+float color_srgb_to_scene_linear(float c)
+{
+ if (c < 0.04045)
+ return (c < 0.0) ? 0.0 : c * (1.0 / 12.92);
+ else
+ return pow((c + 0.055) * (1.0 / 1.055), 2.4);
+}
+
+float color_scene_linear_to_srgb(float c)
+{
+ if (c < 0.0031308)
+ return (c < 0.0) ? 0.0 : c * 12.92;
+ else
+ return 1.055 * pow(c, 1.0 / 2.4) - 0.055;
+}
+
+color color_srgb_to_scene_linear(color c)
+{
+ return color(color_srgb_to_scene_linear(c[0]),
+ color_srgb_to_scene_linear(c[1]),
+ color_srgb_to_scene_linear(c[2]));
+}
+
+color color_scene_linear_to_srgb(color c)
+{
+ return color(color_scene_linear_to_srgb(c[0]),
+ color_scene_linear_to_srgb(c[1]),
+ color_scene_linear_to_srgb(c[2]));
+}
+
+color color_unpremultiply(color c, float alpha)
+{
+ if (alpha != 1.0 && alpha != 0.0)
+ return c / alpha;
+
+ return c;
+}
+
+/* Color Operations */
+
+color xyY_to_xyz(float x, float y, float Y)
+{
+ float X, Z;
+
+ if (y != 0.0)
+ X = (x / y) * Y;
+ else
+ X = 0.0;
+
+ if (y != 0.0 && Y != 0.0)
+ Z = ((1.0 - x - y) / y) * Y;
+ else
+ Z = 0.0;
+
+ return color(X, Y, Z);
+}
+
+color xyz_to_rgb(float x, float y, float z)
+{
+ return color(3.240479 * x + -1.537150 * y + -0.498535 * z,
+ -0.969256 * x + 1.875991 * y + 0.041556 * z,
+ 0.055648 * x + -0.204043 * y + 1.057311 * z);
+}
+
+color rgb_to_hsv(color rgb)
+{
+ float cmax, cmin, h, s, v, cdelta;
+ color c;
+
+ cmax = max(rgb[0], max(rgb[1], rgb[2]));
+ cmin = min(rgb[0], min(rgb[1], rgb[2]));
+ cdelta = cmax - cmin;
+
+ v = cmax;
+
+ if (cmax != 0.0) {
+ s = cdelta / cmax;
+ }
+ else {
+ s = 0.0;
+ h = 0.0;
+ }
+
+ if (s == 0.0) {
+ h = 0.0;
+ }
+ else {
+ c = (color(cmax, cmax, cmax) - rgb) / cdelta;
+
+ if (rgb[0] == cmax)
+ h = c[2] - c[1];
+ else if (rgb[1] == cmax)
+ h = 2.0 + c[0] - c[2];
+ else
+ h = 4.0 + c[1] - c[0];
+
+ h /= 6.0;
+
+ if (h < 0.0)
+ h += 1.0;
+ }
+
+ return color(h, s, v);
+}
+
+color hsv_to_rgb(color hsv)
+{
+ float i, f, p, q, t, h, s, v;
+ color rgb;
+
+ h = hsv[0];
+ s = hsv[1];
+ v = hsv[2];
+
+ if (s == 0.0) {
+ rgb = color(v, v, v);
+ }
+ else {
+ if (h == 1.0)
+ h = 0.0;
+
+ h *= 6.0;
+ i = floor(h);
+ f = h - i;
+ rgb = color(f, f, f);
+ p = v * (1.0 - s);
+ q = v * (1.0 - (s * f));
+ t = v * (1.0 - (s * (1.0 - f)));
+
+ if (i == 0.0)
+ rgb = color(v, t, p);
+ else if (i == 1.0)
+ rgb = color(q, v, p);
+ else if (i == 2.0)
+ rgb = color(p, v, t);
+ else if (i == 3.0)
+ rgb = color(p, q, v);
+ else if (i == 4.0)
+ rgb = color(t, p, v);
+ else
+ rgb = color(v, p, q);
+ }
+
+ return rgb;
+}
diff --git a/intern/cycles/kernel/osl/shaders/node_combine_hsv.osl b/intern/cycles/kernel/osl/shaders/node_combine_hsv.osl
new file mode 100644
index 00000000000..05e502b5bc1
--- /dev/null
+++ b/intern/cycles/kernel/osl/shaders/node_combine_hsv.osl
@@ -0,0 +1,22 @@
+/*
+ * 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 "stdcycles.h"
+
+shader node_combine_hsv(float H = 0.0, float S = 0.0, float V = 0.0, output color Color = 0.8)
+{
+ Color = color("hsv", H, S, V);
+}
diff --git a/intern/cycles/kernel/osl/shaders/node_combine_rgb.osl b/intern/cycles/kernel/osl/shaders/node_combine_rgb.osl
new file mode 100644
index 00000000000..036f371eb5c
--- /dev/null
+++ b/intern/cycles/kernel/osl/shaders/node_combine_rgb.osl
@@ -0,0 +1,22 @@
+/*
+ * 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 "stdcycles.h"
+
+shader node_combine_rgb(float R = 0.0, float G = 0.0, float B = 0.0, output color Image = 0.8)
+{
+ Image = color(R, G, B);
+}
diff --git a/intern/cycles/kernel/osl/shaders/node_combine_xyz.osl b/intern/cycles/kernel/osl/shaders/node_combine_xyz.osl
new file mode 100644
index 00000000000..4ebd86b605c
--- /dev/null
+++ b/intern/cycles/kernel/osl/shaders/node_combine_xyz.osl
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2011-2014 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 "stdcycles.h"
+
+shader node_combine_xyz(float X = 0.0, float Y = 0.0, float Z = 0.0, output vector Vector = 0.8)
+{
+ Vector = vector(X, Y, Z);
+}
diff --git a/intern/cycles/kernel/osl/shaders/node_convert_from_color.osl b/intern/cycles/kernel/osl/shaders/node_convert_from_color.osl
new file mode 100644
index 00000000000..c3f0e118844
--- /dev/null
+++ b/intern/cycles/kernel/osl/shaders/node_convert_from_color.osl
@@ -0,0 +1,32 @@
+/*
+ * 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 "stdcycles.h"
+
+shader node_convert_from_color(color value_color = 0.0,
+ output string value_string = "",
+ output float value_float = 0.0,
+ output int value_int = 0,
+ output vector value_vector = vector(0.0, 0.0, 0.0),
+ output point value_point = point(0.0, 0.0, 0.0),
+ output normal value_normal = normal(0.0, 0.0, 0.0))
+{
+ value_float = value_color[0] * 0.2126 + value_color[1] * 0.7152 + value_color[2] * 0.0722;
+ value_int = (int)(value_color[0] * 0.2126 + value_color[1] * 0.7152 + value_color[2] * 0.0722);
+ value_vector = vector(value_color[0], value_color[1], value_color[2]);
+ value_point = point(value_color[0], value_color[1], value_color[2]);
+ value_normal = normal(value_color[0], value_color[1], value_color[2]);
+}
diff --git a/intern/cycles/kernel/osl/shaders/node_convert_from_float.osl b/intern/cycles/kernel/osl/shaders/node_convert_from_float.osl
new file mode 100644
index 00000000000..61a15a1c2b0
--- /dev/null
+++ b/intern/cycles/kernel/osl/shaders/node_convert_from_float.osl
@@ -0,0 +1,32 @@
+/*
+ * 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 "stdcycles.h"
+
+shader node_convert_from_float(float value_float = 0.0,
+ output string value_string = "",
+ output int value_int = 0,
+ output color value_color = 0.0,
+ output vector value_vector = vector(0.0, 0.0, 0.0),
+ output point value_point = point(0.0, 0.0, 0.0),
+ output normal value_normal = normal(0.0, 0.0, 0.0))
+{
+ value_int = (int)value_float;
+ value_color = color(value_float, value_float, value_float);
+ value_vector = vector(value_float, value_float, value_float);
+ value_point = point(value_float, value_float, value_float);
+ value_normal = normal(value_float, value_float, value_float);
+}
diff --git a/intern/cycles/kernel/osl/shaders/node_convert_from_int.osl b/intern/cycles/kernel/osl/shaders/node_convert_from_int.osl
new file mode 100644
index 00000000000..2e6a99b2765
--- /dev/null
+++ b/intern/cycles/kernel/osl/shaders/node_convert_from_int.osl
@@ -0,0 +1,33 @@
+/*
+ * 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 "stdcycles.h"
+
+shader node_convert_from_int(int value_int = 0,
+ output string value_string = "",
+ output float value_float = 0.0,
+ output color value_color = 0.0,
+ output vector value_vector = vector(0.0, 0.0, 0.0),
+ output point value_point = point(0.0, 0.0, 0.0),
+ output normal value_normal = normal(0.0, 0.0, 0.0))
+{
+ float f = (float)value_int;
+ value_float = f;
+ value_color = color(f, f, f);
+ value_vector = vector(f, f, f);
+ value_point = point(f, f, f);
+ value_normal = normal(f, f, f);
+}
diff --git a/intern/cycles/kernel/osl/shaders/node_convert_from_normal.osl b/intern/cycles/kernel/osl/shaders/node_convert_from_normal.osl
new file mode 100644
index 00000000000..64201d63190
--- /dev/null
+++ b/intern/cycles/kernel/osl/shaders/node_convert_from_normal.osl
@@ -0,0 +1,32 @@
+/*
+ * 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 "stdcycles.h"
+
+shader node_convert_from_normal(normal value_normal = normal(0.0, 0.0, 0.0),
+ output string value_string = "",
+ output float value_float = 0.0,
+ output int value_int = 0,
+ output vector value_vector = vector(0.0, 0.0, 0.0),
+ output color value_color = 0.0,
+ output point value_point = point(0.0, 0.0, 0.0))
+{
+ value_float = (value_normal[0] + value_normal[1] + value_normal[2]) * (1.0 / 3.0);
+ value_int = (int)((value_normal[0] + value_normal[1] + value_normal[2]) * (1.0 / 3.0));
+ value_vector = vector(value_normal[0], value_normal[1], value_normal[2]);
+ value_color = color(value_normal[0], value_normal[1], value_normal[2]);
+ value_point = point(value_normal[0], value_normal[1], value_normal[2]);
+}
diff --git a/intern/cycles/kernel/osl/shaders/node_convert_from_point.osl b/intern/cycles/kernel/osl/shaders/node_convert_from_point.osl
new file mode 100644
index 00000000000..11d64f76d6f
--- /dev/null
+++ b/intern/cycles/kernel/osl/shaders/node_convert_from_point.osl
@@ -0,0 +1,32 @@
+/*
+ * 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 "stdcycles.h"
+
+shader node_convert_from_point(point value_point = point(0.0, 0.0, 0.0),
+ output string value_string = "",
+ output float value_float = 0.0,
+ output int value_int = 0,
+ output vector value_vector = vector(0.0, 0.0, 0.0),
+ output color value_color = 0.0,
+ output normal value_normal = normal(0.0, 0.0, 0.0))
+{
+ value_float = (value_point[0] + value_point[1] + value_point[2]) * (1.0 / 3.0);
+ value_int = (int)((value_normal[0] + value_normal[1] + value_normal[2]) * (1.0 / 3.0));
+ value_vector = vector(value_point[0], value_point[1], value_point[2]);
+ value_color = color(value_point[0], value_point[1], value_point[2]);
+ value_normal = normal(value_point[0], value_point[1], value_point[2]);
+}
diff --git a/intern/cycles/kernel/osl/shaders/node_convert_from_string.osl b/intern/cycles/kernel/osl/shaders/node_convert_from_string.osl
new file mode 100644
index 00000000000..b496c4e6d05
--- /dev/null
+++ b/intern/cycles/kernel/osl/shaders/node_convert_from_string.osl
@@ -0,0 +1,27 @@
+/*
+ * 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 "stdcycles.h"
+
+shader node_convert_from_string(string value_string = "",
+ output color value_color = color(0.0, 0.0, 0.0),
+ output float value_float = 0.0,
+ output int value_int = 0,
+ output vector value_vector = vector(0.0, 0.0, 0.0),
+ output point value_point = point(0.0, 0.0, 0.0),
+ output normal value_normal = normal(0.0, 0.0, 0.0))
+{
+}
diff --git a/intern/cycles/kernel/osl/shaders/node_convert_from_vector.osl b/intern/cycles/kernel/osl/shaders/node_convert_from_vector.osl
new file mode 100644
index 00000000000..820faabd32b
--- /dev/null
+++ b/intern/cycles/kernel/osl/shaders/node_convert_from_vector.osl
@@ -0,0 +1,32 @@
+/*
+ * 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 "stdcycles.h"
+
+shader node_convert_from_vector(vector value_vector = vector(0.0, 0.0, 0.0),
+ output string value_string = "",
+ output float value_float = 0.0,
+ output int value_int = 0,
+ output color value_color = color(0.0, 0.0, 0.0),
+ output point value_point = point(0.0, 0.0, 0.0),
+ output normal value_normal = normal(0.0, 0.0, 0.0))
+{
+ value_float = (value_vector[0] + value_vector[1] + value_vector[2]) * (1.0 / 3.0);
+ value_int = (int)((value_normal[0] + value_normal[1] + value_normal[2]) * (1.0 / 3.0));
+ value_color = color(value_vector[0], value_vector[1], value_vector[2]);
+ value_point = point(value_vector[0], value_vector[1], value_vector[2]);
+ value_normal = normal(value_vector[0], value_vector[1], value_vector[2]);
+}
diff --git a/intern/cycles/kernel/osl/shaders/node_diffuse_bsdf.osl b/intern/cycles/kernel/osl/shaders/node_diffuse_bsdf.osl
new file mode 100644
index 00000000000..f5886f534eb
--- /dev/null
+++ b/intern/cycles/kernel/osl/shaders/node_diffuse_bsdf.osl
@@ -0,0 +1,28 @@
+/*
+ * 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 "stdcycles.h"
+
+shader node_diffuse_bsdf(color Color = 0.8,
+ float Roughness = 0.0,
+ normal Normal = N,
+ output closure color BSDF = 0)
+{
+ if (Roughness == 0.0)
+ BSDF = Color * diffuse(Normal);
+ else
+ BSDF = Color * oren_nayar(Normal, Roughness);
+}
diff --git a/intern/cycles/kernel/osl/shaders/node_displacement.osl b/intern/cycles/kernel/osl/shaders/node_displacement.osl
new file mode 100644
index 00000000000..44a4828d511
--- /dev/null
+++ b/intern/cycles/kernel/osl/shaders/node_displacement.osl
@@ -0,0 +1,36 @@
+/*
+ * 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 "stdcycles.h"
+
+shader node_displacement(string space = "object",
+ float Height = 0.0,
+ float Midlevel = 0.5,
+ float Scale = 1.0,
+ normal Normal = N,
+ output vector Displacement = vector(0.0, 0.0, 0.0))
+{
+ Displacement = Normal;
+ if (space == "object") {
+ Displacement = transform("object", Displacement);
+ }
+
+ Displacement = normalize(Displacement) * (Height - Midlevel) * Scale;
+
+ if (space == "object") {
+ Displacement = transform("object", "world", Displacement);
+ }
+}
diff --git a/intern/cycles/kernel/osl/shaders/node_emission.osl b/intern/cycles/kernel/osl/shaders/node_emission.osl
new file mode 100644
index 00000000000..f289a9711d9
--- /dev/null
+++ b/intern/cycles/kernel/osl/shaders/node_emission.osl
@@ -0,0 +1,22 @@
+/*
+ * 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 "stdcycles.h"
+
+shader node_emission(color Color = 0.8, float Strength = 1.0, output closure color Emission = 0)
+{
+ Emission = (Strength * Color) * emission();
+}
diff --git a/intern/cycles/kernel/osl/shaders/node_environment_texture.osl b/intern/cycles/kernel/osl/shaders/node_environment_texture.osl
new file mode 100644
index 00000000000..d04743eb368
--- /dev/null
+++ b/intern/cycles/kernel/osl/shaders/node_environment_texture.osl
@@ -0,0 +1,85 @@
+/*
+ * 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_color.h"
+#include "stdcycles.h"
+
+vector environment_texture_direction_to_equirectangular(vector dir)
+{
+ float u = -atan2(dir[1], dir[0]) / (M_2PI) + 0.5;
+ float v = atan2(dir[2], hypot(dir[0], dir[1])) / M_PI + 0.5;
+
+ return vector(u, v, 0.0);
+}
+
+vector environment_texture_direction_to_mirrorball(vector idir)
+{
+ vector dir = idir;
+ dir[1] -= 1.0;
+
+ float div = 2.0 * sqrt(max(-0.5 * dir[1], 0.0));
+ if (div > 0.0)
+ dir /= div;
+
+ float u = 0.5 * (dir[0] + 1.0);
+ float v = 0.5 * (dir[2] + 1.0);
+
+ return vector(u, v, 0.0);
+}
+
+shader node_environment_texture(
+ int use_mapping = 0,
+ matrix mapping = matrix(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
+ vector Vector = P,
+ string filename = "",
+ string projection = "equirectangular",
+ string interpolation = "linear",
+ int compress_as_srgb = 0,
+ int ignore_alpha = 0,
+ int unassociate_alpha = 0,
+ int is_float = 1,
+ output color Color = 0.0,
+ output float Alpha = 1.0)
+{
+ vector p = Vector;
+
+ if (use_mapping)
+ p = transform(mapping, p);
+
+ p = normalize(p);
+
+ if (projection == "equirectangular")
+ p = environment_texture_direction_to_equirectangular(p);
+ else
+ p = environment_texture_direction_to_mirrorball(p);
+
+ /* todo: use environment for better texture filtering of equirectangular */
+ Color = (color)texture(
+ filename, p[0], 1.0 - p[1], "wrap", "periodic", "interp", interpolation, "alpha", Alpha);
+
+ if (ignore_alpha) {
+ Alpha = 1.0;
+ }
+ else if (unassociate_alpha) {
+ Color = color_unpremultiply(Color, Alpha);
+
+ if (!is_float)
+ Color = min(Color, 1.0);
+ }
+
+ if (compress_as_srgb)
+ Color = color_srgb_to_scene_linear(Color);
+}
diff --git a/intern/cycles/kernel/osl/shaders/node_float_curve.osl b/intern/cycles/kernel/osl/shaders/node_float_curve.osl
new file mode 100644
index 00000000000..f1f05fd88a9
--- /dev/null
+++ b/intern/cycles/kernel/osl/shaders/node_float_curve.osl
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2011-2021 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_ramp_util.h"
+#include "stdcycles.h"
+
+shader node_float_curve(float ramp[] = {0.0},
+ float min_x = 0.0,
+ float max_x = 1.0,
+ float ValueIn = 0.0,
+ float Factor = 0.0,
+ output float ValueOut = 0.0)
+{
+ float c = (ValueIn - min_x) / (max_x - min_x);
+
+ ValueOut = rgb_ramp_lookup(ramp, c, 1, 1);
+
+ ValueOut = mix(ValueIn, ValueOut, Factor);
+}
diff --git a/intern/cycles/kernel/osl/shaders/node_fresnel.h b/intern/cycles/kernel/osl/shaders/node_fresnel.h
new file mode 100644
index 00000000000..ade1d4c6207
--- /dev/null
+++ b/intern/cycles/kernel/osl/shaders/node_fresnel.h
@@ -0,0 +1,62 @@
+/*
+ * Adapted from Open Shading Language with this license:
+ *
+ * Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al.
+ * All Rights Reserved.
+ *
+ * Modifications Copyright 2011, Blender Foundation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Sony Pictures Imageworks nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+float fresnel_dielectric_cos(float cosi, float eta)
+{
+ /* compute fresnel reflectance without explicitly computing
+ * the refracted direction */
+ float c = fabs(cosi);
+ float g = eta * eta - 1 + c * c;
+ float result;
+
+ if (g > 0) {
+ g = sqrt(g);
+ float A = (g - c) / (g + c);
+ float B = (c * (g + c) - 1) / (c * (g - c) + 1);
+ result = 0.5 * A * A * (1 + B * B);
+ }
+ else
+ result = 1.0; /* TIR (no refracted component) */
+
+ return result;
+}
+
+color fresnel_conductor(float cosi, color eta, color k)
+{
+ color cosi2 = color(cosi * cosi);
+ color one = color(1, 1, 1);
+ color tmp_f = eta * eta + k * k;
+ color tmp = tmp_f * cosi2;
+ color Rparl2 = (tmp - (2.0 * eta * cosi) + one) / (tmp + (2.0 * eta * cosi) + one);
+ color Rperp2 = (tmp_f - (2.0 * eta * cosi) + cosi2) / (tmp_f + (2.0 * eta * cosi) + cosi2);
+ return (Rparl2 + Rperp2) * 0.5;
+}
diff --git a/intern/cycles/kernel/osl/shaders/node_fresnel.osl b/intern/cycles/kernel/osl/shaders/node_fresnel.osl
new file mode 100644
index 00000000000..cff084c344d
--- /dev/null
+++ b/intern/cycles/kernel/osl/shaders/node_fresnel.osl
@@ -0,0 +1,26 @@
+/*
+ * 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_fresnel.h"
+#include "stdcycles.h"
+
+shader node_fresnel(float IOR = 1.45, normal Normal = N, output float Fac = 0.0)
+{
+ float f = max(IOR, 1e-5);
+ float eta = backfacing() ? 1.0 / f : f;
+ float cosi = dot(I, Normal);
+ Fac = fresnel_dielectric_cos(cosi, eta);
+}
diff --git a/intern/cycles/kernel/osl/shaders/node_gamma.osl b/intern/cycles/kernel/osl/shaders/node_gamma.osl
new file mode 100644
index 00000000000..0816df64fe8
--- /dev/null
+++ b/intern/cycles/kernel/osl/shaders/node_gamma.osl
@@ -0,0 +1,22 @@
+/*
+ * 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 "stdcycles.h"
+
+shader node_gamma(color ColorIn = 0.8, float Gamma = 1.0, output color ColorOut = 0.0)
+{
+ ColorOut = pow(ColorIn, Gamma);
+}
diff --git a/intern/cycles/kernel/osl/shaders/node_geometry.osl b/intern/cycles/kernel/osl/shaders/node_geometry.osl
new file mode 100644
index 00000000000..55cda71db1b
--- /dev/null
+++ b/intern/cycles/kernel/osl/shaders/node_geometry.osl
@@ -0,0 +1,71 @@
+/*
+ * 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 "stdcycles.h"
+
+shader node_geometry(normal NormalIn = N,
+ string bump_offset = "center",
+
+ output point Position = point(0.0, 0.0, 0.0),
+ output normal Normal = normal(0.0, 0.0, 0.0),
+ output normal Tangent = normal(0.0, 0.0, 0.0),
+ output normal TrueNormal = normal(0.0, 0.0, 0.0),
+ output vector Incoming = vector(0.0, 0.0, 0.0),
+ output point Parametric = point(0.0, 0.0, 0.0),
+ output float Backfacing = 0.0,
+ output float Pointiness = 0.0,
+ output float RandomPerIsland = 0.0)
+{
+ Position = P;
+ Normal = NormalIn;
+ TrueNormal = Ng;
+ Incoming = I;
+ Parametric = point(u, v, 0.0);
+ Backfacing = backfacing();
+
+ if (bump_offset == "dx") {
+ Position += Dx(Position);
+ Parametric += Dx(Parametric);
+ }
+ else if (bump_offset == "dy") {
+ Position += Dy(Position);
+ Parametric += Dy(Parametric);
+ }
+
+ /* first try to get tangent attribute */
+ point generated;
+
+ /* try to create spherical tangent from generated coordinates */
+ if (getattribute("geom:generated", generated)) {
+ normal data = normal(-(generated[1] - 0.5), (generated[0] - 0.5), 0.0);
+ vector T = transform("object", "world", data);
+ Tangent = cross(Normal, normalize(cross(T, Normal)));
+ }
+ else {
+ /* otherwise use surface derivatives */
+ Tangent = normalize(dPdu);
+ }
+
+ getattribute("geom:pointiness", Pointiness);
+ if (bump_offset == "dx") {
+ Pointiness += Dx(Pointiness);
+ }
+ else if (bump_offset == "dy") {
+ Pointiness += Dy(Pointiness);
+ }
+
+ getattribute("geom:random_per_island", RandomPerIsland);
+}
diff --git a/intern/cycles/kernel/osl/shaders/node_glass_bsdf.osl b/intern/cycles/kernel/osl/shaders/node_glass_bsdf.osl
new file mode 100644
index 00000000000..0042d573f8d
--- /dev/null
+++ b/intern/cycles/kernel/osl/shaders/node_glass_bsdf.osl
@@ -0,0 +1,43 @@
+/*
+ * 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_fresnel.h"
+#include "stdcycles.h"
+
+shader node_glass_bsdf(color Color = 0.8,
+ string distribution = "sharp",
+ float Roughness = 0.2,
+ float IOR = 1.45,
+ normal Normal = N,
+ output closure color BSDF = 0)
+{
+ float f = max(IOR, 1e-5);
+ float eta = backfacing() ? 1.0 / f : f;
+ float cosi = dot(I, Normal);
+ float Fr = fresnel_dielectric_cos(cosi, eta);
+ float roughness = Roughness * Roughness;
+
+ if (distribution == "sharp")
+ BSDF = Color * (Fr * reflection(Normal) + (1.0 - Fr) * refraction(Normal, eta));
+ else if (distribution == "beckmann")
+ BSDF = Color * (Fr * microfacet_beckmann(Normal, roughness) +
+ (1.0 - Fr) * microfacet_beckmann_refraction(Normal, roughness, eta));
+ else if (distribution == "Multiscatter GGX")
+ BSDF = Color * microfacet_multi_ggx_glass(Normal, roughness, eta, Color);
+ else if (distribution == "GGX")
+ BSDF = Color * (Fr * microfacet_ggx(Normal, roughness) +
+ (1.0 - Fr) * microfacet_ggx_refraction(Normal, roughness, eta));
+}
diff --git a/intern/cycles/kernel/osl/shaders/node_glossy_bsdf.osl b/intern/cycles/kernel/osl/shaders/node_glossy_bsdf.osl
new file mode 100644
index 00000000000..c73604d3650
--- /dev/null
+++ b/intern/cycles/kernel/osl/shaders/node_glossy_bsdf.osl
@@ -0,0 +1,38 @@
+/*
+ * 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_fresnel.h"
+#include "stdcycles.h"
+
+shader node_glossy_bsdf(color Color = 0.8,
+ string distribution = "GGX",
+ float Roughness = 0.2,
+ normal Normal = N,
+ output closure color BSDF = 0)
+{
+ float roughness = Roughness * Roughness;
+
+ if (distribution == "sharp")
+ BSDF = Color * reflection(Normal);
+ else if (distribution == "beckmann")
+ BSDF = Color * microfacet_beckmann(Normal, roughness);
+ else if (distribution == "GGX")
+ BSDF = Color * microfacet_ggx(Normal, roughness);
+ else if (distribution == "Multiscatter GGX")
+ BSDF = Color * microfacet_multi_ggx(Normal, roughness, Color);
+ else
+ BSDF = Color * ashikhmin_shirley(Normal, vector(0, 0, 0), roughness, roughness);
+}
diff --git a/intern/cycles/kernel/osl/shaders/node_gradient_texture.osl b/intern/cycles/kernel/osl/shaders/node_gradient_texture.osl
new file mode 100644
index 00000000000..c7faee0d022
--- /dev/null
+++ b/intern/cycles/kernel/osl/shaders/node_gradient_texture.osl
@@ -0,0 +1,77 @@
+/*
+ * 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 "stdcycles.h"
+
+/* Gradient */
+
+float gradient(point p, string type)
+{
+ float x, y, z;
+
+ x = p[0];
+ y = p[1];
+ z = p[2];
+
+ float result = 0.0;
+
+ if (type == "linear") {
+ result = x;
+ }
+ else if (type == "quadratic") {
+ float r = max(x, 0.0);
+ result = r * r;
+ }
+ else if (type == "easing") {
+ float r = min(max(x, 0.0), 1.0);
+ float t = r * r;
+
+ result = (3.0 * t - 2.0 * t * r);
+ }
+ else if (type == "diagonal") {
+ result = (x + y) * 0.5;
+ }
+ else if (type == "radial") {
+ result = atan2(y, x) / M_2PI + 0.5;
+ }
+ else {
+ float r = max(1.0 - sqrt(x * x + y * y + z * z), 0.0);
+
+ if (type == "quadratic_sphere")
+ result = r * r;
+ else if (type == "spherical")
+ result = r;
+ }
+
+ return clamp(result, 0.0, 1.0);
+}
+
+shader node_gradient_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 gradient_type = "linear",
+ point Vector = P,
+ output float Fac = 0.0,
+ output color Color = 0.0)
+{
+ point p = Vector;
+
+ if (use_mapping)
+ p = transform(mapping, p);
+
+ Fac = gradient(p, gradient_type);
+ Color = color(Fac, Fac, Fac);
+}
diff --git a/intern/cycles/kernel/osl/shaders/node_hair_bsdf.osl b/intern/cycles/kernel/osl/shaders/node_hair_bsdf.osl
new file mode 100644
index 00000000000..3e0ac7af2e0
--- /dev/null
+++ b/intern/cycles/kernel/osl/shaders/node_hair_bsdf.osl
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2011, Blender Foundation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "stdcycles.h"
+
+shader node_hair_bsdf(color Color = 0.8,
+ string component = "reflection",
+ float Offset = 0.0,
+ float RoughnessU = 0.1,
+ float RoughnessV = 1.0,
+ normal Tangent = normal(0, 0, 0),
+ output closure color BSDF = 0)
+{
+ float roughnessh = clamp(RoughnessU, 0.001, 1.0);
+ float roughnessv = clamp(RoughnessV, 0.001, 1.0);
+ float offset = -Offset;
+
+ normal T;
+ float IsCurve = 0;
+ getattribute("geom:is_curve", IsCurve);
+
+ if (isconnected(Tangent)) {
+ T = Tangent;
+ }
+ else if (!IsCurve) {
+ T = normalize(dPdv);
+ offset = 0.0;
+ }
+ else {
+ T = normalize(dPdu);
+ }
+
+ if (backfacing() && IsCurve) {
+ BSDF = transparent();
+ }
+ else {
+ if (component == "reflection")
+ BSDF = Color * hair_reflection(Ng, roughnessh, roughnessv, T, offset);
+ else
+ BSDF = Color * hair_transmission(Ng, roughnessh, roughnessv, T, offset);
+ }
+}
diff --git a/intern/cycles/kernel/osl/shaders/node_hair_info.osl b/intern/cycles/kernel/osl/shaders/node_hair_info.osl
new file mode 100644
index 00000000000..ddc2e28b83a
--- /dev/null
+++ b/intern/cycles/kernel/osl/shaders/node_hair_info.osl
@@ -0,0 +1,32 @@
+/*
+ * 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 "stdcycles.h"
+
+shader node_hair_info(output float IsStrand = 0.0,
+ output float Intercept = 0.0,
+ output float Length = 0.0,
+ output float Thickness = 0.0,
+ output normal TangentNormal = N,
+ output float Random = 0)
+{
+ getattribute("geom:is_curve", IsStrand);
+ getattribute("geom:curve_intercept", Intercept);
+ getattribute("geom:curve_length", Length);
+ getattribute("geom:curve_thickness", Thickness);
+ getattribute("geom:curve_tangent_normal", TangentNormal);
+ getattribute("geom:curve_random", Random);
+}
diff --git a/intern/cycles/kernel/osl/shaders/node_hash.h b/intern/cycles/kernel/osl/shaders/node_hash.h
new file mode 100644
index 00000000000..b42e42ff910
--- /dev/null
+++ b/intern/cycles/kernel/osl/shaders/node_hash.h
@@ -0,0 +1,81 @@
+#include "stdcycles.h"
+#include "vector2.h"
+#include "vector4.h"
+
+#define vector3 point
+
+/* **** Hash a float or vector[234] into a float [0, 1] **** */
+
+float hash_float_to_float(float k)
+{
+ return hashnoise(k);
+}
+
+float hash_vector2_to_float(vector2 k)
+{
+ return hashnoise(k.x, k.y);
+}
+
+float hash_vector3_to_float(vector3 k)
+{
+ return hashnoise(k);
+}
+
+float hash_vector4_to_float(vector4 k)
+{
+ return hashnoise(vector3(k.x, k.y, k.z), k.w);
+}
+
+/* **** Hash a vector[234] into a vector[234] [0, 1] **** */
+
+vector2 hash_vector2_to_vector2(vector2 k)
+{
+ return vector2(hash_vector2_to_float(k), hash_vector3_to_float(vector3(k.x, k.y, 1.0)));
+}
+
+vector3 hash_vector3_to_vector3(vector3 k)
+{
+ return vector3(hash_vector3_to_float(k),
+ hash_vector4_to_float(vector4(k[0], k[1], k[2], 1.0)),
+ hash_vector4_to_float(vector4(k[0], k[1], k[2], 2.0)));
+}
+
+vector4 hash_vector4_to_vector4(vector4 k)
+{
+ return vector4(hash_vector4_to_float(k),
+ hash_vector4_to_float(vector4(k.w, k.x, k.y, k.z)),
+ hash_vector4_to_float(vector4(k.z, k.w, k.x, k.y)),
+ hash_vector4_to_float(vector4(k.y, k.z, k.w, k.x)));
+}
+
+/* **** Hash a float or a vec[234] into a color [0, 1] **** */
+
+color hash_float_to_color(float k)
+{
+ return color(hash_float_to_float(k),
+ hash_vector2_to_float(vector2(k, 1.0)),
+ hash_vector2_to_float(vector2(k, 2.0)));
+}
+
+color hash_vector2_to_color(vector2 k)
+{
+ return color(hash_vector2_to_float(k),
+ hash_vector3_to_float(vector3(k.x, k.y, 1.0)),
+ hash_vector3_to_float(vector3(k.x, k.y, 2.0)));
+}
+
+color hash_vector3_to_color(vector3 k)
+{
+ return color(hash_vector3_to_float(k),
+ hash_vector4_to_float(vector4(k[0], k[1], k[2], 1.0)),
+ hash_vector4_to_float(vector4(k[0], k[1], k[2], 2.0)));
+}
+
+color hash_vector4_to_color(vector4 k)
+{
+ return color(hash_vector4_to_float(k),
+ hash_vector4_to_float(vector4(k.z, k.x, k.w, k.y)),
+ hash_vector4_to_float(vector4(k.w, k.z, k.y, k.x)));
+}
+
+#undef vector3
diff --git a/intern/cycles/kernel/osl/shaders/node_holdout.osl b/intern/cycles/kernel/osl/shaders/node_holdout.osl
new file mode 100644
index 00000000000..92e41c92f72
--- /dev/null
+++ b/intern/cycles/kernel/osl/shaders/node_holdout.osl
@@ -0,0 +1,21 @@
+/*
+ * 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 "stdcycles.h"
+
+shader node_holdout(output closure color Holdout = holdout())
+{
+}
diff --git a/intern/cycles/kernel/osl/shaders/node_hsv.osl b/intern/cycles/kernel/osl/shaders/node_hsv.osl
new file mode 100644
index 00000000000..4417057b10f
--- /dev/null
+++ b/intern/cycles/kernel/osl/shaders/node_hsv.osl
@@ -0,0 +1,42 @@
+/*
+ * 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_color.h"
+#include "stdcycles.h"
+
+shader node_hsv(float Hue = 0.5,
+ float Saturation = 1.0,
+ float Value = 1.0,
+ float Fac = 0.5,
+ color ColorIn = 0.0,
+ output color ColorOut = 0.0)
+{
+ color Color = rgb_to_hsv(ColorIn);
+
+ // remember: fmod doesn't work for negative numbers
+ Color[0] = fmod(Color[0] + Hue + 0.5, 1.0);
+ Color[1] = clamp(Color[1] * Saturation, 0.0, 1.0);
+ Color[2] *= Value;
+
+ Color = hsv_to_rgb(Color);
+
+ // Clamp color to prevent negative values cauzed by oversaturation.
+ Color[0] = max(Color[0], 0.0);
+ Color[1] = max(Color[1], 0.0);
+ Color[2] = max(Color[2], 0.0);
+
+ ColorOut = mix(ColorIn, Color, Fac);
+}
diff --git a/intern/cycles/kernel/osl/shaders/node_ies_light.osl b/intern/cycles/kernel/osl/shaders/node_ies_light.osl
new file mode 100644
index 00000000000..76348b4d758
--- /dev/null
+++ b/intern/cycles/kernel/osl/shaders/node_ies_light.osl
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2011-2015 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 "stdcycles.h"
+
+/* IES Light */
+
+shader node_ies_light(int use_mapping = 0,
+ matrix mapping = matrix(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
+ string filename = "",
+ float Strength = 1.0,
+ point Vector = I,
+ output float Fac = 0.0)
+{
+ point p = Vector;
+
+ if (use_mapping) {
+ p = transform(mapping, p);
+ }
+
+ p = normalize((vector)p);
+
+ float v_angle = acos(-p[2]);
+ float h_angle = atan2(p[0], p[1]) + M_PI;
+
+ Fac = Strength * texture(filename, h_angle, v_angle);
+}
diff --git a/intern/cycles/kernel/osl/shaders/node_image_texture.osl b/intern/cycles/kernel/osl/shaders/node_image_texture.osl
new file mode 100644
index 00000000000..56fcc47a011
--- /dev/null
+++ b/intern/cycles/kernel/osl/shaders/node_image_texture.osl
@@ -0,0 +1,270 @@
+/*
+ * 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_color.h"
+#include "stdcycles.h"
+
+point texco_remap_square(point co)
+{
+ return (co - point(0.5, 0.5, 0.5)) * 2.0;
+}
+
+point map_to_tube(vector dir)
+{
+ float u, v;
+ v = (dir[2] + 1.0) * 0.5;
+ float len = sqrt(dir[0] * dir[0] + dir[1] * dir[1]);
+ if (len > 0.0) {
+ u = (1.0 - (atan2(dir[0] / len, dir[1] / len) / M_PI)) * 0.5;
+ }
+ else {
+ v = u = 0.0; /* To avoid un-initialized variables. */
+ }
+ return point(u, v, 0.0);
+}
+
+point map_to_sphere(vector dir)
+{
+ float len = length(dir);
+ float v, u;
+ if (len > 0.0) {
+ if (dir[0] == 0.0 && dir[1] == 0.0) {
+ u = 0.0; /* Otherwise domain error. */
+ }
+ else {
+ u = (1.0 - atan2(dir[0], dir[1]) / M_PI) / 2.0;
+ }
+ v = 1.0 - acos(dir[2] / len) / M_PI;
+ }
+ else {
+ v = u = 0.0; /* To avoid un-initialized variables. */
+ }
+ return point(u, v, 0.0);
+}
+
+color image_texture_lookup(string filename,
+ float u,
+ float v,
+ output float Alpha,
+ int compress_as_srgb,
+ int ignore_alpha,
+ int unassociate_alpha,
+ int is_float,
+ int is_tiled,
+ string interpolation,
+ string extension)
+{
+ /* Flip the y coordinate, but preserve UDIM tiles. */
+ float flip_v;
+ if (is_tiled) {
+ float v_i = (int)v;
+ flip_v = v_i + (1.0 - (v - v_i));
+ }
+ else {
+ flip_v = 1.0 - v;
+ }
+ color rgb = (color)texture(
+ filename, u, flip_v, "wrap", extension, "interp", interpolation, "alpha", Alpha);
+
+ if (ignore_alpha) {
+ Alpha = 1.0;
+ }
+ else if (unassociate_alpha) {
+ rgb = color_unpremultiply(rgb, Alpha);
+
+ if (!is_float)
+ rgb = min(rgb, 1.0);
+ }
+
+ if (compress_as_srgb) {
+ rgb = color_srgb_to_scene_linear(rgb);
+ }
+
+ return rgb;
+}
+
+shader node_image_texture(int use_mapping = 0,
+ matrix mapping = matrix(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
+ point Vector = P,
+ string filename = "",
+ string projection = "flat",
+ string interpolation = "smartcubic",
+ string extension = "periodic",
+ float projection_blend = 0.0,
+ int compress_as_srgb = 0,
+ int ignore_alpha = 0,
+ int unassociate_alpha = 0,
+ int is_tiled = 0,
+ int is_float = 1,
+ output color Color = 0.0,
+ output float Alpha = 1.0)
+{
+ point p = Vector;
+
+ if (use_mapping)
+ p = transform(mapping, p);
+
+ if (projection == "flat") {
+ Color = image_texture_lookup(filename,
+ p[0],
+ p[1],
+ Alpha,
+ compress_as_srgb,
+ ignore_alpha,
+ unassociate_alpha,
+ is_float,
+ is_tiled,
+ interpolation,
+ extension);
+ }
+ else if (projection == "box") {
+ /* object space normal */
+ vector Nob = transform("world", "object", N);
+
+ /* project from direction vector to barycentric coordinates in triangles */
+ Nob = vector(fabs(Nob[0]), fabs(Nob[1]), fabs(Nob[2]));
+ Nob /= (Nob[0] + Nob[1] + Nob[2]);
+
+ /* basic idea is to think of this as a triangle, each corner representing
+ * one of the 3 faces of the cube. in the corners we have single textures,
+ * in between we blend between two textures, and in the middle we a blend
+ * between three textures.
+ *
+ * the `Nxyz` values are the barycentric coordinates in an equilateral
+ * triangle, which in case of blending, in the middle has a smaller
+ * equilateral triangle where 3 textures blend. this divides things into
+ * 7 zones, with an if () test for each zone. */
+
+ vector weight = vector(0.0, 0.0, 0.0);
+ float blend = projection_blend;
+ float limit = 0.5 * (1.0 + blend);
+
+ /* first test for corners with single texture */
+ if (Nob[0] > limit * (Nob[0] + Nob[1]) && Nob[0] > limit * (Nob[0] + Nob[2])) {
+ weight[0] = 1.0;
+ }
+ else if (Nob[1] > limit * (Nob[0] + Nob[1]) && Nob[1] > limit * (Nob[1] + Nob[2])) {
+ weight[1] = 1.0;
+ }
+ else if (Nob[2] > limit * (Nob[0] + Nob[2]) && Nob[2] > limit * (Nob[1] + Nob[2])) {
+ weight[2] = 1.0;
+ }
+ else if (blend > 0.0) {
+ /* in case of blending, test for mixes between two textures */
+ if (Nob[2] < (1.0 - limit) * (Nob[1] + Nob[0])) {
+ weight[0] = Nob[0] / (Nob[0] + Nob[1]);
+ weight[0] = clamp((weight[0] - 0.5 * (1.0 - blend)) / blend, 0.0, 1.0);
+ weight[1] = 1.0 - weight[0];
+ }
+ else if (Nob[0] < (1.0 - limit) * (Nob[1] + Nob[2])) {
+ weight[1] = Nob[1] / (Nob[1] + Nob[2]);
+ weight[1] = clamp((weight[1] - 0.5 * (1.0 - blend)) / blend, 0.0, 1.0);
+ weight[2] = 1.0 - weight[1];
+ }
+ else if (Nob[1] < (1.0 - limit) * (Nob[0] + Nob[2])) {
+ weight[0] = Nob[0] / (Nob[0] + Nob[2]);
+ weight[0] = clamp((weight[0] - 0.5 * (1.0 - blend)) / blend, 0.0, 1.0);
+ weight[2] = 1.0 - weight[0];
+ }
+ else {
+ /* last case, we have a mix between three */
+ weight[0] = ((2.0 - limit) * Nob[0] + (limit - 1.0)) / (2.0 * limit - 1.0);
+ weight[1] = ((2.0 - limit) * Nob[1] + (limit - 1.0)) / (2.0 * limit - 1.0);
+ weight[2] = ((2.0 - limit) * Nob[2] + (limit - 1.0)) / (2.0 * limit - 1.0);
+ }
+ }
+ else {
+ /* Desperate mode, no valid choice anyway, fallback to one side.*/
+ weight[0] = 1.0;
+ }
+
+ Color = color(0.0, 0.0, 0.0);
+ Alpha = 0.0;
+
+ float tmp_alpha;
+
+ if (weight[0] > 0.0) {
+ Color += weight[0] * image_texture_lookup(filename,
+ p[1],
+ p[2],
+ tmp_alpha,
+ compress_as_srgb,
+ ignore_alpha,
+ unassociate_alpha,
+ is_float,
+ 0,
+ interpolation,
+ extension);
+ Alpha += weight[0] * tmp_alpha;
+ }
+ if (weight[1] > 0.0) {
+ Color += weight[1] * image_texture_lookup(filename,
+ p[0],
+ p[2],
+ tmp_alpha,
+ compress_as_srgb,
+ ignore_alpha,
+ unassociate_alpha,
+ is_float,
+ 0,
+ interpolation,
+ extension);
+ Alpha += weight[1] * tmp_alpha;
+ }
+ if (weight[2] > 0.0) {
+ Color += weight[2] * image_texture_lookup(filename,
+ p[1],
+ p[0],
+ tmp_alpha,
+ compress_as_srgb,
+ ignore_alpha,
+ unassociate_alpha,
+ is_float,
+ 0,
+ interpolation,
+ extension);
+ Alpha += weight[2] * tmp_alpha;
+ }
+ }
+ else if (projection == "sphere") {
+ point projected = map_to_sphere(texco_remap_square(p));
+ Color = image_texture_lookup(filename,
+ projected[0],
+ projected[1],
+ Alpha,
+ compress_as_srgb,
+ ignore_alpha,
+ unassociate_alpha,
+ is_float,
+ 0,
+ interpolation,
+ extension);
+ }
+ else if (projection == "tube") {
+ point projected = map_to_tube(texco_remap_square(p));
+ Color = image_texture_lookup(filename,
+ projected[0],
+ projected[1],
+ Alpha,
+ compress_as_srgb,
+ ignore_alpha,
+ unassociate_alpha,
+ is_float,
+ 0,
+ interpolation,
+ extension);
+ }
+}
diff --git a/intern/cycles/kernel/osl/shaders/node_invert.osl b/intern/cycles/kernel/osl/shaders/node_invert.osl
new file mode 100644
index 00000000000..23c16935ca1
--- /dev/null
+++ b/intern/cycles/kernel/osl/shaders/node_invert.osl
@@ -0,0 +1,23 @@
+/*
+ * 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 "stdcycles.h"
+
+shader node_invert(float Fac = 1.0, color ColorIn = 0.8, output color ColorOut = 0.8)
+{
+ color ColorInv = color(1.0) - ColorIn;
+ ColorOut = mix(ColorIn, ColorInv, Fac);
+}
diff --git a/intern/cycles/kernel/osl/shaders/node_layer_weight.osl b/intern/cycles/kernel/osl/shaders/node_layer_weight.osl
new file mode 100644
index 00000000000..1662be2cad1
--- /dev/null
+++ b/intern/cycles/kernel/osl/shaders/node_layer_weight.osl
@@ -0,0 +1,44 @@
+/*
+ * 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_fresnel.h"
+#include "stdcycles.h"
+
+shader node_layer_weight(float Blend = 0.5,
+ normal Normal = N,
+ output float Fresnel = 0.0,
+ output float Facing = 0.0)
+{
+ float blend = Blend;
+ float cosi = dot(I, Normal);
+
+ /* Fresnel */
+ float eta = max(1.0 - Blend, 1e-5);
+ eta = backfacing() ? eta : 1.0 / eta;
+ Fresnel = fresnel_dielectric_cos(cosi, eta);
+
+ /* Facing */
+ Facing = fabs(cosi);
+
+ if (blend != 0.5) {
+ blend = clamp(blend, 0.0, 1.0 - 1e-5);
+ blend = (blend < 0.5) ? 2.0 * blend : 0.5 / (1.0 - blend);
+
+ Facing = pow(Facing, blend);
+ }
+
+ Facing = 1.0 - Facing;
+}
diff --git a/intern/cycles/kernel/osl/shaders/node_light_falloff.osl b/intern/cycles/kernel/osl/shaders/node_light_falloff.osl
new file mode 100644
index 00000000000..3f3c9444a5a
--- /dev/null
+++ b/intern/cycles/kernel/osl/shaders/node_light_falloff.osl
@@ -0,0 +1,42 @@
+/*
+ * 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 "stdcycles.h"
+
+shader node_light_falloff(float Strength = 0.0,
+ float Smooth = 0.0,
+ output float Quadratic = 0.0,
+ output float Linear = 0.0,
+ output float Constant = 0.0)
+{
+ float ray_length = 0.0;
+ float strength = Strength;
+ getattribute("path:ray_length", ray_length);
+
+ if (Smooth > 0.0) {
+ float squared = ray_length * ray_length;
+ strength *= squared / (Smooth + squared);
+ }
+
+ /* Quadratic */
+ Quadratic = strength;
+
+ /* Linear */
+ Linear = (strength * ray_length);
+
+ /* Constant */
+ Constant = (strength * ray_length * ray_length);
+}
diff --git a/intern/cycles/kernel/osl/shaders/node_light_path.osl b/intern/cycles/kernel/osl/shaders/node_light_path.osl
new file mode 100644
index 00000000000..ba268db288c
--- /dev/null
+++ b/intern/cycles/kernel/osl/shaders/node_light_path.osl
@@ -0,0 +1,64 @@
+/*
+ * 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 "stdcycles.h"
+
+shader node_light_path(output float IsCameraRay = 0.0,
+ output float IsShadowRay = 0.0,
+ output float IsDiffuseRay = 0.0,
+ output float IsGlossyRay = 0.0,
+ output float IsSingularRay = 0.0,
+ output float IsReflectionRay = 0.0,
+ output float IsTransmissionRay = 0.0,
+ output float IsVolumeScatterRay = 0.0,
+ output float RayLength = 0.0,
+ output float RayDepth = 0.0,
+ output float DiffuseDepth = 0.0,
+ output float GlossyDepth = 0.0,
+ output float TransparentDepth = 0.0,
+ output float TransmissionDepth = 0.0)
+{
+ IsCameraRay = raytype("camera");
+ IsShadowRay = raytype("shadow");
+ IsDiffuseRay = raytype("diffuse");
+ IsGlossyRay = raytype("glossy");
+ IsSingularRay = raytype("singular");
+ IsReflectionRay = raytype("reflection");
+ IsTransmissionRay = raytype("refraction");
+ IsVolumeScatterRay = raytype("volume_scatter");
+
+ getattribute("path:ray_length", RayLength);
+
+ int ray_depth = 0;
+ getattribute("path:ray_depth", ray_depth);
+ RayDepth = (float)ray_depth;
+
+ int diffuse_depth = 0;
+ getattribute("path:diffuse_depth", diffuse_depth);
+ DiffuseDepth = (float)diffuse_depth;
+
+ int glossy_depth = 0;
+ getattribute("path:glossy_depth", glossy_depth);
+ GlossyDepth = (float)glossy_depth;
+
+ int transparent_depth = 0;
+ getattribute("path:transparent_depth", transparent_depth);
+ TransparentDepth = (float)transparent_depth;
+
+ int transmission_depth = 0;
+ getattribute("path:transmission_depth", transmission_depth);
+ TransmissionDepth = (float)transmission_depth;
+}
diff --git a/intern/cycles/kernel/osl/shaders/node_magic_texture.osl b/intern/cycles/kernel/osl/shaders/node_magic_texture.osl
new file mode 100644
index 00000000000..476c6895f05
--- /dev/null
+++ b/intern/cycles/kernel/osl/shaders/node_magic_texture.osl
@@ -0,0 +1,108 @@
+/*
+ * 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 "stdcycles.h"
+
+/* Magic */
+
+color magic(point p, int n, float distortion)
+{
+ float dist = distortion;
+
+ float x = sin((p[0] + p[1] + p[2]) * 5.0);
+ float y = cos((-p[0] + p[1] - p[2]) * 5.0);
+ float z = -cos((-p[0] - p[1] + p[2]) * 5.0);
+
+ if (n > 0) {
+ x *= dist;
+ y *= dist;
+ z *= dist;
+ y = -cos(x - y + z);
+ y *= dist;
+
+ if (n > 1) {
+ x = cos(x - y - z);
+ x *= dist;
+
+ if (n > 2) {
+ z = sin(-x - y - z);
+ z *= dist;
+
+ if (n > 3) {
+ x = -cos(-x + y - z);
+ x *= dist;
+
+ if (n > 4) {
+ y = -sin(-x + y + z);
+ y *= dist;
+
+ if (n > 5) {
+ y = -cos(-x + y + z);
+ y *= dist;
+
+ if (n > 6) {
+ x = cos(x + y + z);
+ x *= dist;
+
+ if (n > 7) {
+ z = sin(x + y - z);
+ z *= dist;
+
+ if (n > 8) {
+ x = -cos(-x - y + z);
+ x *= dist;
+
+ if (n > 9) {
+ y = -sin(x - y + z);
+ y *= dist;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if (dist != 0.0) {
+ dist *= 2.0;
+ x /= dist;
+ y /= dist;
+ z /= dist;
+ }
+
+ return color(0.5 - x, 0.5 - y, 0.5 - z);
+}
+
+shader node_magic_texture(int use_mapping = 0,
+ matrix mapping = matrix(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
+ int depth = 2,
+ float Distortion = 5.0,
+ float Scale = 5.0,
+ point Vector = P,
+ output float Fac = 0.0,
+ output color Color = 0.0)
+{
+ point p = Vector;
+
+ if (use_mapping)
+ p = transform(mapping, p);
+
+ Color = magic(p * Scale, depth, Distortion);
+ Fac = (Color[0] + Color[1] + Color[2]) * (1.0 / 3.0);
+}
diff --git a/intern/cycles/kernel/osl/shaders/node_map_range.osl b/intern/cycles/kernel/osl/shaders/node_map_range.osl
new file mode 100644
index 00000000000..2fcc664a80e
--- /dev/null
+++ b/intern/cycles/kernel/osl/shaders/node_map_range.osl
@@ -0,0 +1,58 @@
+/*
+ * 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 "stdcycles.h"
+
+float safe_divide(float a, float b)
+{
+ return (b != 0.0) ? a / b : 0.0;
+}
+
+float smootherstep(float edge0, float edge1, float x)
+{
+ float t = clamp(safe_divide((x - edge0), (edge1 - edge0)), 0.0, 1.0);
+ return t * t * t * (t * (t * 6.0 - 15.0) + 10.0);
+}
+
+shader node_map_range(string range_type = "linear",
+ float Value = 1.0,
+ float FromMin = 0.0,
+ float FromMax = 1.0,
+ float ToMin = 0.0,
+ float ToMax = 1.0,
+ float Steps = 4.0,
+ output float Result = 0.0)
+{
+ if (FromMax != FromMin) {
+ float Factor = Value;
+ if (range_type == "stepped") {
+ Factor = (Value - FromMin) / (FromMax - FromMin);
+ Factor = (Steps > 0) ? floor(Factor * (Steps + 1.0)) / Steps : 0.0;
+ }
+ else if (range_type == "smoothstep") {
+ Factor = (FromMin > FromMax) ? 1.0 - smoothstep(FromMax, FromMin, Value) :
+ smoothstep(FromMin, FromMax, Value);
+ }
+ else if (range_type == "smootherstep") {
+ Factor = (FromMin > FromMax) ? 1.0 - smootherstep(FromMax, FromMin, Value) :
+ smootherstep(FromMin, FromMax, Value);
+ }
+ else {
+ Factor = (Value - FromMin) / (FromMax - FromMin);
+ }
+ Result = ToMin + Factor * (ToMax - ToMin);
+ }
+}
diff --git a/intern/cycles/kernel/osl/shaders/node_mapping.osl b/intern/cycles/kernel/osl/shaders/node_mapping.osl
new file mode 100644
index 00000000000..131640685bc
--- /dev/null
+++ b/intern/cycles/kernel/osl/shaders/node_mapping.osl
@@ -0,0 +1,73 @@
+/*
+ * 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 "stdcycles.h"
+
+point safe_divide(point a, point b)
+{
+ return point((b[0] != 0.0) ? a[0] / b[0] : 0.0,
+ (b[1] != 0.0) ? a[1] / b[1] : 0.0,
+ (b[2] != 0.0) ? a[2] / b[2] : 0.0);
+}
+
+matrix euler_to_mat(point euler)
+{
+ float cx = cos(euler[0]);
+ float cy = cos(euler[1]);
+ float cz = cos(euler[2]);
+ float sx = sin(euler[0]);
+ float sy = sin(euler[1]);
+ float sz = sin(euler[2]);
+
+ matrix mat = matrix(1.0);
+ mat[0][0] = cy * cz;
+ mat[0][1] = cy * sz;
+ mat[0][2] = -sy;
+
+ mat[1][0] = sy * sx * cz - cx * sz;
+ mat[1][1] = sy * sx * sz + cx * cz;
+ mat[1][2] = cy * sx;
+
+ mat[2][0] = sy * cx * cz + sx * sz;
+ mat[2][1] = sy * cx * sz - sx * cz;
+ mat[2][2] = cy * cx;
+ return mat;
+}
+
+shader node_mapping(string mapping_type = "point",
+ point VectorIn = point(0.0, 0.0, 0.0),
+ point Location = point(0.0, 0.0, 0.0),
+ point Rotation = point(0.0, 0.0, 0.0),
+ point Scale = point(1.0, 1.0, 1.0),
+ output point VectorOut = point(0.0, 0.0, 0.0))
+{
+ if (mapping_type == "point") {
+ VectorOut = transform(euler_to_mat(Rotation), (VectorIn * Scale)) + Location;
+ }
+ else if (mapping_type == "texture") {
+ VectorOut = safe_divide(transform(transpose(euler_to_mat(Rotation)), (VectorIn - Location)),
+ Scale);
+ }
+ else if (mapping_type == "vector") {
+ VectorOut = transform(euler_to_mat(Rotation), (VectorIn * Scale));
+ }
+ else if (mapping_type == "normal") {
+ VectorOut = normalize((vector)transform(euler_to_mat(Rotation), safe_divide(VectorIn, Scale)));
+ }
+ else {
+ warning("%s", "Unknown Mapping vector type!");
+ }
+}
diff --git a/intern/cycles/kernel/osl/shaders/node_math.h b/intern/cycles/kernel/osl/shaders/node_math.h
new file mode 100644
index 00000000000..2da73b94212
--- /dev/null
+++ b/intern/cycles/kernel/osl/shaders/node_math.h
@@ -0,0 +1,117 @@
+/*
+ * Copyright 2011-2020 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.
+ */
+
+float safe_divide(float a, float b)
+{
+ return (b != 0.0) ? a / b : 0.0;
+}
+
+vector safe_divide(vector a, vector b)
+{
+ return vector((b[0] != 0.0) ? a[0] / b[0] : 0.0,
+ (b[1] != 0.0) ? a[1] / b[1] : 0.0,
+ (b[2] != 0.0) ? a[2] / b[2] : 0.0);
+}
+
+float safe_modulo(float a, float b)
+{
+ return (b != 0.0) ? fmod(a, b) : 0.0;
+}
+
+float fract(float a)
+{
+ return a - floor(a);
+}
+
+/* See: https://www.iquilezles.org/www/articles/smin/smin.htm. */
+float smoothmin(float a, float b, float c)
+{
+ if (c != 0.0) {
+ float h = max(c - abs(a - b), 0.0) / c;
+ return min(a, b) - h * h * h * c * (1.0 / 6.0);
+ }
+ else {
+ return min(a, b);
+ }
+}
+
+float pingpong(float a, float b)
+{
+ return (b != 0.0) ? abs(fract((a - b) / (b * 2.0)) * b * 2.0 - b) : 0.0;
+}
+
+float safe_sqrt(float a)
+{
+ return (a > 0.0) ? sqrt(a) : 0.0;
+}
+
+float safe_log(float a, float b)
+{
+ return (a > 0.0 && b > 0.0) ? log(a) / log(b) : 0.0;
+}
+
+vector project(vector v, vector v_proj)
+{
+ float lenSquared = dot(v_proj, v_proj);
+ return (lenSquared != 0.0) ? (dot(v, v_proj) / lenSquared) * v_proj : vector(0.0);
+}
+
+vector snap(vector a, vector b)
+{
+ return floor(safe_divide(a, b)) * b;
+}
+
+/* Adapted from GODOT-engine math_funcs.h. */
+float wrap(float value, float max, float min)
+{
+ float range = max - min;
+ return (range != 0.0) ? value - (range * floor((value - min) / range)) : min;
+}
+
+point wrap(point value, point max, point min)
+{
+ return point(wrap(value[0], max[0], min[0]),
+ wrap(value[1], max[1], min[1]),
+ wrap(value[2], max[2], min[2]));
+}
+
+/* Built in OSL faceforward is `(dot(I, Nref) > 0) ? -N : N;` which is different to
+ * GLSL `dot(Nref, I) < 0 ? N : -N` for zero values. */
+point compatible_faceforward(point vec, point incident, point reference)
+{
+ return dot(reference, incident) < 0.0 ? vec : -vec;
+}
+
+matrix euler_to_mat(point euler)
+{
+ float cx = cos(euler[0]);
+ float cy = cos(euler[1]);
+ float cz = cos(euler[2]);
+ float sx = sin(euler[0]);
+ float sy = sin(euler[1]);
+ float sz = sin(euler[2]);
+ matrix mat = matrix(1.0);
+ mat[0][0] = cy * cz;
+ mat[0][1] = cy * sz;
+ mat[0][2] = -sy;
+ mat[1][0] = sy * sx * cz - cx * sz;
+ mat[1][1] = sy * sx * sz + cx * cz;
+ mat[1][2] = cy * sx;
+ +mat[2][0] = sy * cx * cz + sx * sz;
+ mat[2][1] = sy * cx * sz - sx * cz;
+ mat[2][2] = cy * cx;
+ return mat;
+}
diff --git a/intern/cycles/kernel/osl/shaders/node_math.osl b/intern/cycles/kernel/osl/shaders/node_math.osl
new file mode 100644
index 00000000000..66884610561
--- /dev/null
+++ b/intern/cycles/kernel/osl/shaders/node_math.osl
@@ -0,0 +1,109 @@
+/*
+ * 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_math.h"
+#include "stdcycles.h"
+
+/* OSL asin, acos, and pow functions are safe by default. */
+shader node_math(string math_type = "add",
+ float Value1 = 0.5,
+ float Value2 = 0.5,
+ float Value3 = 0.5,
+ output float Value = 0.0)
+{
+ if (math_type == "add")
+ Value = Value1 + Value2;
+ else if (math_type == "subtract")
+ Value = Value1 - Value2;
+ else if (math_type == "multiply")
+ Value = Value1 * Value2;
+ else if (math_type == "divide")
+ Value = safe_divide(Value1, Value2);
+ else if (math_type == "power")
+ Value = pow(Value1, Value2);
+ else if (math_type == "logarithm")
+ Value = safe_log(Value1, Value2);
+ else if (math_type == "sqrt")
+ Value = safe_sqrt(Value1);
+ else if (math_type == "inversesqrt")
+ Value = inversesqrt(Value1);
+ else if (math_type == "absolute")
+ Value = fabs(Value1);
+ else if (math_type == "radians")
+ Value = radians(Value1);
+ else if (math_type == "degrees")
+ Value = degrees(Value1);
+ else if (math_type == "minimum")
+ Value = min(Value1, Value2);
+ else if (math_type == "maximum")
+ Value = max(Value1, Value2);
+ else if (math_type == "less_than")
+ Value = Value1 < Value2;
+ else if (math_type == "greater_than")
+ Value = Value1 > Value2;
+ else if (math_type == "round")
+ Value = floor(Value1 + 0.5);
+ else if (math_type == "floor")
+ Value = floor(Value1);
+ else if (math_type == "ceil")
+ Value = ceil(Value1);
+ else if (math_type == "fraction")
+ Value = Value1 - floor(Value1);
+ else if (math_type == "modulo")
+ Value = safe_modulo(Value1, Value2);
+ else if (math_type == "trunc")
+ Value = trunc(Value1);
+ else if (math_type == "snap")
+ Value = floor(safe_divide(Value1, Value2)) * Value2;
+ else if (math_type == "wrap")
+ Value = wrap(Value1, Value2, Value3);
+ else if (math_type == "pingpong")
+ Value = pingpong(Value1, Value2);
+ else if (math_type == "sine")
+ Value = sin(Value1);
+ else if (math_type == "cosine")
+ Value = cos(Value1);
+ else if (math_type == "tangent")
+ Value = tan(Value1);
+ else if (math_type == "sinh")
+ Value = sinh(Value1);
+ else if (math_type == "cosh")
+ Value = cosh(Value1);
+ else if (math_type == "tanh")
+ Value = tanh(Value1);
+ else if (math_type == "arcsine")
+ Value = asin(Value1);
+ else if (math_type == "arccosine")
+ Value = acos(Value1);
+ else if (math_type == "arctangent")
+ Value = atan(Value1);
+ else if (math_type == "arctan2")
+ Value = atan2(Value1, Value2);
+ else if (math_type == "sign")
+ Value = sign(Value1);
+ else if (math_type == "exponent")
+ Value = exp(Value1);
+ else if (math_type == "compare")
+ Value = ((Value1 == Value2) || (abs(Value1 - Value2) <= max(Value3, 1e-5))) ? 1.0 : 0.0;
+ else if (math_type == "multiply_add")
+ Value = Value1 * Value2 + Value3;
+ else if (math_type == "smoothmin")
+ Value = smoothmin(Value1, Value2, Value3);
+ else if (math_type == "smoothmax")
+ Value = -(smoothmin(-Value1, -Value2, Value3));
+ else
+ warning("%s", "Unknown math operator!");
+}
diff --git a/intern/cycles/kernel/osl/shaders/node_mix.osl b/intern/cycles/kernel/osl/shaders/node_mix.osl
new file mode 100644
index 00000000000..dcd9f014f3e
--- /dev/null
+++ b/intern/cycles/kernel/osl/shaders/node_mix.osl
@@ -0,0 +1,330 @@
+/*
+ * 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_color.h"
+#include "stdcycles.h"
+
+color node_mix_blend(float t, color col1, color col2)
+{
+ return mix(col1, col2, t);
+}
+
+color node_mix_add(float t, color col1, color col2)
+{
+ return mix(col1, col1 + col2, t);
+}
+
+color node_mix_mul(float t, color col1, color col2)
+{
+ return mix(col1, col1 * col2, t);
+}
+
+color node_mix_screen(float t, color col1, color col2)
+{
+ float tm = 1.0 - t;
+
+ return color(1.0) - (color(tm) + t * (color(1.0) - col2)) * (color(1.0) - col1);
+}
+
+color node_mix_overlay(float t, color col1, color col2)
+{
+ float tm = 1.0 - t;
+
+ color outcol = col1;
+
+ if (outcol[0] < 0.5)
+ outcol[0] *= tm + 2.0 * t * col2[0];
+ else
+ outcol[0] = 1.0 - (tm + 2.0 * t * (1.0 - col2[0])) * (1.0 - outcol[0]);
+
+ if (outcol[1] < 0.5)
+ outcol[1] *= tm + 2.0 * t * col2[1];
+ else
+ outcol[1] = 1.0 - (tm + 2.0 * t * (1.0 - col2[1])) * (1.0 - outcol[1]);
+
+ if (outcol[2] < 0.5)
+ outcol[2] *= tm + 2.0 * t * col2[2];
+ else
+ outcol[2] = 1.0 - (tm + 2.0 * t * (1.0 - col2[2])) * (1.0 - outcol[2]);
+
+ return outcol;
+}
+
+color node_mix_sub(float t, color col1, color col2)
+{
+ return mix(col1, col1 - col2, t);
+}
+
+color node_mix_div(float t, color col1, color col2)
+{
+ float tm = 1.0 - t;
+
+ color outcol = col1;
+
+ if (col2[0] != 0.0)
+ outcol[0] = tm * outcol[0] + t * outcol[0] / col2[0];
+ if (col2[1] != 0.0)
+ outcol[1] = tm * outcol[1] + t * outcol[1] / col2[1];
+ if (col2[2] != 0.0)
+ outcol[2] = tm * outcol[2] + t * outcol[2] / col2[2];
+
+ return outcol;
+}
+
+color node_mix_diff(float t, color col1, color col2)
+{
+ return mix(col1, abs(col1 - col2), t);
+}
+
+color node_mix_dark(float t, color col1, color col2)
+{
+ return mix(col1, min(col1, col2), t);
+}
+
+color node_mix_light(float t, color col1, color col2)
+{
+ return mix(col1, max(col1, col2), t);
+}
+
+color node_mix_dodge(float t, color col1, color col2)
+{
+ color outcol = col1;
+
+ if (outcol[0] != 0.0) {
+ float tmp = 1.0 - t * col2[0];
+ if (tmp <= 0.0)
+ outcol[0] = 1.0;
+ else if ((tmp = outcol[0] / tmp) > 1.0)
+ outcol[0] = 1.0;
+ else
+ outcol[0] = tmp;
+ }
+ if (outcol[1] != 0.0) {
+ float tmp = 1.0 - t * col2[1];
+ if (tmp <= 0.0)
+ outcol[1] = 1.0;
+ else if ((tmp = outcol[1] / tmp) > 1.0)
+ outcol[1] = 1.0;
+ else
+ outcol[1] = tmp;
+ }
+ if (outcol[2] != 0.0) {
+ float tmp = 1.0 - t * col2[2];
+ if (tmp <= 0.0)
+ outcol[2] = 1.0;
+ else if ((tmp = outcol[2] / tmp) > 1.0)
+ outcol[2] = 1.0;
+ else
+ outcol[2] = tmp;
+ }
+
+ return outcol;
+}
+
+color node_mix_burn(float t, color col1, color col2)
+{
+ float tmp, tm = 1.0 - t;
+
+ color outcol = col1;
+
+ tmp = tm + t * col2[0];
+ if (tmp <= 0.0)
+ outcol[0] = 0.0;
+ else if ((tmp = (1.0 - (1.0 - outcol[0]) / tmp)) < 0.0)
+ outcol[0] = 0.0;
+ else if (tmp > 1.0)
+ outcol[0] = 1.0;
+ else
+ outcol[0] = tmp;
+
+ tmp = tm + t * col2[1];
+ if (tmp <= 0.0)
+ outcol[1] = 0.0;
+ else if ((tmp = (1.0 - (1.0 - outcol[1]) / tmp)) < 0.0)
+ outcol[1] = 0.0;
+ else if (tmp > 1.0)
+ outcol[1] = 1.0;
+ else
+ outcol[1] = tmp;
+
+ tmp = tm + t * col2[2];
+ if (tmp <= 0.0)
+ outcol[2] = 0.0;
+ else if ((tmp = (1.0 - (1.0 - outcol[2]) / tmp)) < 0.0)
+ outcol[2] = 0.0;
+ else if (tmp > 1.0)
+ outcol[2] = 1.0;
+ else
+ outcol[2] = tmp;
+
+ return outcol;
+}
+
+color node_mix_hue(float t, color col1, color col2)
+{
+ color outcol = col1;
+ color hsv2 = rgb_to_hsv(col2);
+
+ if (hsv2[1] != 0.0) {
+ color hsv = rgb_to_hsv(outcol);
+ hsv[0] = hsv2[0];
+ color tmp = hsv_to_rgb(hsv);
+
+ outcol = mix(outcol, tmp, t);
+ }
+
+ return outcol;
+}
+
+color node_mix_sat(float t, color col1, color col2)
+{
+ float tm = 1.0 - t;
+
+ color outcol = col1;
+
+ color hsv = rgb_to_hsv(outcol);
+
+ if (hsv[1] != 0.0) {
+ color hsv2 = rgb_to_hsv(col2);
+
+ hsv[1] = tm * hsv[1] + t * hsv2[1];
+ outcol = hsv_to_rgb(hsv);
+ }
+
+ return outcol;
+}
+
+color node_mix_val(float t, color col1, color col2)
+{
+ float tm = 1.0 - t;
+
+ color hsv = rgb_to_hsv(col1);
+ color hsv2 = rgb_to_hsv(col2);
+
+ hsv[2] = tm * hsv[2] + t * hsv2[2];
+
+ return hsv_to_rgb(hsv);
+}
+
+color node_mix_color(float t, color col1, color col2)
+{
+ color outcol = col1;
+ color hsv2 = rgb_to_hsv(col2);
+
+ if (hsv2[1] != 0.0) {
+ color hsv = rgb_to_hsv(outcol);
+ hsv[0] = hsv2[0];
+ hsv[1] = hsv2[1];
+ color tmp = hsv_to_rgb(hsv);
+
+ outcol = mix(outcol, tmp, t);
+ }
+
+ return outcol;
+}
+
+color node_mix_soft(float t, color col1, color col2)
+{
+ float tm = 1.0 - t;
+
+ color one = color(1.0);
+ color scr = one - (one - col2) * (one - col1);
+
+ return tm * col1 + t * ((one - col1) * col2 * col1 + col1 * scr);
+}
+
+color node_mix_linear(float t, color col1, color col2)
+{
+ color outcol = col1;
+
+ if (col2[0] > 0.5)
+ outcol[0] = col1[0] + t * (2.0 * (col2[0] - 0.5));
+ else
+ outcol[0] = col1[0] + t * (2.0 * (col2[0]) - 1.0);
+
+ if (col2[1] > 0.5)
+ outcol[1] = col1[1] + t * (2.0 * (col2[1] - 0.5));
+ else
+ outcol[1] = col1[1] + t * (2.0 * (col2[1]) - 1.0);
+
+ if (col2[2] > 0.5)
+ outcol[2] = col1[2] + t * (2.0 * (col2[2] - 0.5));
+ else
+ outcol[2] = col1[2] + t * (2.0 * (col2[2]) - 1.0);
+
+ return outcol;
+}
+
+color node_mix_clamp(color col)
+{
+ color outcol = col;
+
+ outcol[0] = clamp(col[0], 0.0, 1.0);
+ outcol[1] = clamp(col[1], 0.0, 1.0);
+ outcol[2] = clamp(col[2], 0.0, 1.0);
+
+ return outcol;
+}
+
+shader node_mix(string mix_type = "mix",
+ int use_clamp = 0,
+ float Fac = 0.5,
+ color Color1 = 0.0,
+ color Color2 = 0.0,
+ output color Color = 0.0)
+{
+ float t = clamp(Fac, 0.0, 1.0);
+
+ if (mix_type == "mix")
+ Color = node_mix_blend(t, Color1, Color2);
+ if (mix_type == "add")
+ Color = node_mix_add(t, Color1, Color2);
+ if (mix_type == "multiply")
+ Color = node_mix_mul(t, Color1, Color2);
+ if (mix_type == "screen")
+ Color = node_mix_screen(t, Color1, Color2);
+ if (mix_type == "overlay")
+ Color = node_mix_overlay(t, Color1, Color2);
+ if (mix_type == "subtract")
+ Color = node_mix_sub(t, Color1, Color2);
+ if (mix_type == "divide")
+ Color = node_mix_div(t, Color1, Color2);
+ if (mix_type == "difference")
+ Color = node_mix_diff(t, Color1, Color2);
+ if (mix_type == "darken")
+ Color = node_mix_dark(t, Color1, Color2);
+ if (mix_type == "lighten")
+ Color = node_mix_light(t, Color1, Color2);
+ if (mix_type == "dodge")
+ Color = node_mix_dodge(t, Color1, Color2);
+ if (mix_type == "burn")
+ Color = node_mix_burn(t, Color1, Color2);
+ if (mix_type == "hue")
+ Color = node_mix_hue(t, Color1, Color2);
+ if (mix_type == "saturation")
+ Color = node_mix_sat(t, Color1, Color2);
+ if (mix_type == "value")
+ Color = node_mix_val(t, Color1, Color2);
+ if (mix_type == "color")
+ Color = node_mix_color(t, Color1, Color2);
+ if (mix_type == "soft_light")
+ Color = node_mix_soft(t, Color1, Color2);
+ if (mix_type == "linear_light")
+ Color = node_mix_linear(t, Color1, Color2);
+
+ if (use_clamp)
+ Color = node_mix_clamp(Color);
+}
diff --git a/intern/cycles/kernel/osl/shaders/node_mix_closure.osl b/intern/cycles/kernel/osl/shaders/node_mix_closure.osl
new file mode 100644
index 00000000000..94fc2171c44
--- /dev/null
+++ b/intern/cycles/kernel/osl/shaders/node_mix_closure.osl
@@ -0,0 +1,26 @@
+/*
+ * 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 "stdcycles.h"
+
+shader node_mix_closure(float Fac = 0.5,
+ closure color Closure1 = 0,
+ closure color Closure2 = 0,
+ output closure color Closure = 0)
+{
+ float t = clamp(Fac, 0.0, 1.0);
+ Closure = (1.0 - t) * Closure1 + t * Closure2;
+}
diff --git a/intern/cycles/kernel/osl/shaders/node_musgrave_texture.osl b/intern/cycles/kernel/osl/shaders/node_musgrave_texture.osl
new file mode 100644
index 00000000000..0e71ce74c29
--- /dev/null
+++ b/intern/cycles/kernel/osl/shaders/node_musgrave_texture.osl
@@ -0,0 +1,803 @@
+/*
+ * 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
+
+/* 1D Musgrave fBm
+ *
+ * H: fractal increment parameter
+ * lacunarity: gap between successive frequencies
+ * octaves: number of frequencies in the fBm
+ *
+ * from "Texturing and Modelling: A procedural approach"
+ */
+
+float noise_musgrave_fBm_1d(float co, float H, float lacunarity, float octaves)
+{
+ float p = co;
+ float value = 0.0;
+ float pwr = 1.0;
+ float pwHL = pow(lacunarity, -H);
+
+ for (int i = 0; i < (int)octaves; i++) {
+ value += safe_snoise(p) * pwr;
+ pwr *= pwHL;
+ p *= lacunarity;
+ }
+
+ float rmd = octaves - floor(octaves);
+ if (rmd != 0.0) {
+ value += rmd * safe_snoise(p) * pwr;
+ }
+
+ return value;
+}
+
+/* 1D Musgrave Multifractal
+ *
+ * H: highest fractal dimension
+ * lacunarity: gap between successive frequencies
+ * octaves: number of frequencies in the fBm
+ */
+
+float noise_musgrave_multi_fractal_1d(float co, float H, float lacunarity, float octaves)
+{
+ float p = co;
+ float value = 1.0;
+ float pwr = 1.0;
+ float pwHL = pow(lacunarity, -H);
+
+ for (int i = 0; i < (int)octaves; i++) {
+ value *= (pwr * safe_snoise(p) + 1.0);
+ pwr *= pwHL;
+ p *= lacunarity;
+ }
+
+ float rmd = octaves - floor(octaves);
+ if (rmd != 0.0) {
+ value *= (rmd * pwr * safe_snoise(p) + 1.0); /* correct? */
+ }
+
+ return value;
+}
+
+/* 1D Musgrave Heterogeneous Terrain
+ *
+ * H: fractal dimension of the roughest area
+ * lacunarity: gap between successive frequencies
+ * octaves: number of frequencies in the fBm
+ * offset: raises the terrain from `sea level'
+ */
+
+float noise_musgrave_hetero_terrain_1d(
+ float co, float H, float lacunarity, float octaves, float offset)
+{
+ float p = co;
+ float pwHL = pow(lacunarity, -H);
+ float pwr = pwHL;
+
+ /* first unscaled octave of function; later octaves are scaled */
+ float value = offset + safe_snoise(p);
+ p *= lacunarity;
+
+ for (int i = 1; i < (int)octaves; i++) {
+ float increment = (safe_snoise(p) + offset) * pwr * value;
+ value += increment;
+ pwr *= pwHL;
+ p *= lacunarity;
+ }
+
+ float rmd = octaves - floor(octaves);
+ if (rmd != 0.0) {
+ float increment = (safe_snoise(p) + offset) * pwr * value;
+ value += rmd * increment;
+ }
+
+ return value;
+}
+
+/* 1D Hybrid Additive/Multiplicative Multifractal Terrain
+ *
+ * H: fractal dimension of the roughest area
+ * lacunarity: gap between successive frequencies
+ * octaves: number of frequencies in the fBm
+ * offset: raises the terrain from `sea level'
+ */
+
+float noise_musgrave_hybrid_multi_fractal_1d(
+ float co, float H, float lacunarity, float octaves, float offset, float gain)
+{
+ float p = co;
+ float pwHL = pow(lacunarity, -H);
+ float pwr = pwHL;
+
+ float value = safe_snoise(p) + offset;
+ float weight = gain * value;
+ p *= lacunarity;
+
+ for (int i = 1; (weight > 0.001) && (i < (int)octaves); i++) {
+ if (weight > 1.0) {
+ weight = 1.0;
+ }
+
+ float signal = (safe_snoise(p) + offset) * pwr;
+ pwr *= pwHL;
+ value += weight * signal;
+ weight *= gain * signal;
+ p *= lacunarity;
+ }
+
+ float rmd = octaves - floor(octaves);
+ if (rmd != 0.0) {
+ value += rmd * ((safe_snoise(p) + offset) * pwr);
+ }
+
+ return value;
+}
+
+/* 1D Ridged Multifractal Terrain
+ *
+ * H: fractal dimension of the roughest area
+ * lacunarity: gap between successive frequencies
+ * octaves: number of frequencies in the fBm
+ * offset: raises the terrain from `sea level'
+ */
+
+float noise_musgrave_ridged_multi_fractal_1d(
+ float co, float H, float lacunarity, float octaves, float offset, float gain)
+{
+ float p = co;
+ float pwHL = pow(lacunarity, -H);
+ float pwr = pwHL;
+
+ float signal = offset - fabs(safe_snoise(p));
+ signal *= signal;
+ float value = signal;
+ float weight = 1.0;
+
+ for (int i = 1; i < (int)octaves; i++) {
+ p *= lacunarity;
+ weight = clamp(signal * gain, 0.0, 1.0);
+ signal = offset - fabs(safe_snoise(p));
+ signal *= signal;
+ signal *= weight;
+ value += signal * pwr;
+ pwr *= pwHL;
+ }
+
+ return value;
+}
+
+/* 2D Musgrave fBm
+ *
+ * H: fractal increment parameter
+ * lacunarity: gap between successive frequencies
+ * octaves: number of frequencies in the fBm
+ *
+ * from "Texturing and Modelling: A procedural approach"
+ */
+
+float noise_musgrave_fBm_2d(vector2 co, float H, float lacunarity, float octaves)
+{
+ vector2 p = co;
+ float value = 0.0;
+ float pwr = 1.0;
+ float pwHL = pow(lacunarity, -H);
+
+ for (int i = 0; i < (int)octaves; i++) {
+ value += safe_snoise(p) * pwr;
+ pwr *= pwHL;
+ p *= lacunarity;
+ }
+
+ float rmd = octaves - floor(octaves);
+ if (rmd != 0.0) {
+ value += rmd * safe_snoise(p) * pwr;
+ }
+
+ return value;
+}
+
+/* 2D Musgrave Multifractal
+ *
+ * H: highest fractal dimension
+ * lacunarity: gap between successive frequencies
+ * octaves: number of frequencies in the fBm
+ */
+
+float noise_musgrave_multi_fractal_2d(vector2 co, float H, float lacunarity, float octaves)
+{
+ vector2 p = co;
+ float value = 1.0;
+ float pwr = 1.0;
+ float pwHL = pow(lacunarity, -H);
+
+ for (int i = 0; i < (int)octaves; i++) {
+ value *= (pwr * safe_snoise(p) + 1.0);
+ pwr *= pwHL;
+ p *= lacunarity;
+ }
+
+ float rmd = octaves - floor(octaves);
+ if (rmd != 0.0) {
+ value *= (rmd * pwr * safe_snoise(p) + 1.0); /* correct? */
+ }
+
+ return value;
+}
+
+/* 2D Musgrave Heterogeneous Terrain
+ *
+ * H: fractal dimension of the roughest area
+ * lacunarity: gap between successive frequencies
+ * octaves: number of frequencies in the fBm
+ * offset: raises the terrain from `sea level'
+ */
+
+float noise_musgrave_hetero_terrain_2d(
+ vector2 co, float H, float lacunarity, float octaves, float offset)
+{
+ vector2 p = co;
+ float pwHL = pow(lacunarity, -H);
+ float pwr = pwHL;
+
+ /* first unscaled octave of function; later octaves are scaled */
+ float value = offset + safe_snoise(p);
+ p *= lacunarity;
+
+ for (int i = 1; i < (int)octaves; i++) {
+ float increment = (safe_snoise(p) + offset) * pwr * value;
+ value += increment;
+ pwr *= pwHL;
+ p *= lacunarity;
+ }
+
+ float rmd = octaves - floor(octaves);
+ if (rmd != 0.0) {
+ float increment = (safe_snoise(p) + offset) * pwr * value;
+ value += rmd * increment;
+ }
+
+ return value;
+}
+
+/* 2D Hybrid Additive/Multiplicative Multifractal Terrain
+ *
+ * H: fractal dimension of the roughest area
+ * lacunarity: gap between successive frequencies
+ * octaves: number of frequencies in the fBm
+ * offset: raises the terrain from `sea level'
+ */
+
+float noise_musgrave_hybrid_multi_fractal_2d(
+ vector2 co, float H, float lacunarity, float octaves, float offset, float gain)
+{
+ vector2 p = co;
+ float pwHL = pow(lacunarity, -H);
+ float pwr = pwHL;
+
+ float value = safe_snoise(p) + offset;
+ float weight = gain * value;
+ p *= lacunarity;
+
+ for (int i = 1; (weight > 0.001) && (i < (int)octaves); i++) {
+ if (weight > 1.0) {
+ weight = 1.0;
+ }
+
+ float signal = (safe_snoise(p) + offset) * pwr;
+ pwr *= pwHL;
+ value += weight * signal;
+ weight *= gain * signal;
+ p *= lacunarity;
+ }
+
+ float rmd = octaves - floor(octaves);
+ if (rmd != 0.0) {
+ value += rmd * ((safe_snoise(p) + offset) * pwr);
+ }
+
+ return value;
+}
+
+/* 2D Ridged Multifractal Terrain
+ *
+ * H: fractal dimension of the roughest area
+ * lacunarity: gap between successive frequencies
+ * octaves: number of frequencies in the fBm
+ * offset: raises the terrain from `sea level'
+ */
+
+float noise_musgrave_ridged_multi_fractal_2d(
+ vector2 co, float H, float lacunarity, float octaves, float offset, float gain)
+{
+ vector2 p = co;
+ float pwHL = pow(lacunarity, -H);
+ float pwr = pwHL;
+
+ float signal = offset - fabs(safe_snoise(p));
+ signal *= signal;
+ float value = signal;
+ float weight = 1.0;
+
+ for (int i = 1; i < (int)octaves; i++) {
+ p *= lacunarity;
+ weight = clamp(signal * gain, 0.0, 1.0);
+ signal = offset - fabs(safe_snoise(p));
+ signal *= signal;
+ signal *= weight;
+ value += signal * pwr;
+ pwr *= pwHL;
+ }
+
+ return value;
+}
+
+/* 3D Musgrave fBm
+ *
+ * H: fractal increment parameter
+ * lacunarity: gap between successive frequencies
+ * octaves: number of frequencies in the fBm
+ *
+ * from "Texturing and Modelling: A procedural approach"
+ */
+
+float noise_musgrave_fBm_3d(vector3 co, float H, float lacunarity, float octaves)
+{
+ vector3 p = co;
+ float value = 0.0;
+ float pwr = 1.0;
+ float pwHL = pow(lacunarity, -H);
+
+ for (int i = 0; i < (int)octaves; i++) {
+ value += safe_snoise(p) * pwr;
+ pwr *= pwHL;
+ p *= lacunarity;
+ }
+
+ float rmd = octaves - floor(octaves);
+ if (rmd != 0.0) {
+ value += rmd * safe_snoise(p) * pwr;
+ }
+
+ return value;
+}
+
+/* 3D Musgrave Multifractal
+ *
+ * H: highest fractal dimension
+ * lacunarity: gap between successive frequencies
+ * octaves: number of frequencies in the fBm
+ */
+
+float noise_musgrave_multi_fractal_3d(vector3 co, float H, float lacunarity, float octaves)
+{
+ vector3 p = co;
+ float value = 1.0;
+ float pwr = 1.0;
+ float pwHL = pow(lacunarity, -H);
+
+ for (int i = 0; i < (int)octaves; i++) {
+ value *= (pwr * safe_snoise(p) + 1.0);
+ pwr *= pwHL;
+ p *= lacunarity;
+ }
+
+ float rmd = octaves - floor(octaves);
+ if (rmd != 0.0) {
+ value *= (rmd * pwr * safe_snoise(p) + 1.0); /* correct? */
+ }
+
+ return value;
+}
+
+/* 3D Musgrave Heterogeneous Terrain
+ *
+ * H: fractal dimension of the roughest area
+ * lacunarity: gap between successive frequencies
+ * octaves: number of frequencies in the fBm
+ * offset: raises the terrain from `sea level'
+ */
+
+float noise_musgrave_hetero_terrain_3d(
+ vector3 co, float H, float lacunarity, float octaves, float offset)
+{
+ vector3 p = co;
+ float pwHL = pow(lacunarity, -H);
+ float pwr = pwHL;
+
+ /* first unscaled octave of function; later octaves are scaled */
+ float value = offset + safe_snoise(p);
+ p *= lacunarity;
+
+ for (int i = 1; i < (int)octaves; i++) {
+ float increment = (safe_snoise(p) + offset) * pwr * value;
+ value += increment;
+ pwr *= pwHL;
+ p *= lacunarity;
+ }
+
+ float rmd = octaves - floor(octaves);
+ if (rmd != 0.0) {
+ float increment = (safe_snoise(p) + offset) * pwr * value;
+ value += rmd * increment;
+ }
+
+ return value;
+}
+
+/* 3D Hybrid Additive/Multiplicative Multifractal Terrain
+ *
+ * H: fractal dimension of the roughest area
+ * lacunarity: gap between successive frequencies
+ * octaves: number of frequencies in the fBm
+ * offset: raises the terrain from `sea level'
+ */
+
+float noise_musgrave_hybrid_multi_fractal_3d(
+ vector3 co, float H, float lacunarity, float octaves, float offset, float gain)
+{
+ vector3 p = co;
+ float pwHL = pow(lacunarity, -H);
+ float pwr = pwHL;
+
+ float value = safe_snoise(p) + offset;
+ float weight = gain * value;
+ p *= lacunarity;
+
+ for (int i = 1; (weight > 0.001) && (i < (int)octaves); i++) {
+ if (weight > 1.0) {
+ weight = 1.0;
+ }
+
+ float signal = (safe_snoise(p) + offset) * pwr;
+ pwr *= pwHL;
+ value += weight * signal;
+ weight *= gain * signal;
+ p *= lacunarity;
+ }
+
+ float rmd = octaves - floor(octaves);
+ if (rmd != 0.0) {
+ value += rmd * ((safe_snoise(p) + offset) * pwr);
+ }
+
+ return value;
+}
+
+/* 3D Ridged Multifractal Terrain
+ *
+ * H: fractal dimension of the roughest area
+ * lacunarity: gap between successive frequencies
+ * octaves: number of frequencies in the fBm
+ * offset: raises the terrain from `sea level'
+ */
+
+float noise_musgrave_ridged_multi_fractal_3d(
+ vector3 co, float H, float lacunarity, float octaves, float offset, float gain)
+{
+ vector3 p = co;
+ float pwHL = pow(lacunarity, -H);
+ float pwr = pwHL;
+
+ float signal = offset - fabs(safe_snoise(p));
+ signal *= signal;
+ float value = signal;
+ float weight = 1.0;
+
+ for (int i = 1; i < (int)octaves; i++) {
+ p *= lacunarity;
+ weight = clamp(signal * gain, 0.0, 1.0);
+ signal = offset - fabs(safe_snoise(p));
+ signal *= signal;
+ signal *= weight;
+ value += signal * pwr;
+ pwr *= pwHL;
+ }
+
+ return value;
+}
+
+/* 4D Musgrave fBm
+ *
+ * H: fractal increment parameter
+ * lacunarity: gap between successive frequencies
+ * octaves: number of frequencies in the fBm
+ *
+ * from "Texturing and Modelling: A procedural approach"
+ */
+
+float noise_musgrave_fBm_4d(vector4 co, float H, float lacunarity, float octaves)
+{
+ vector4 p = co;
+ float value = 0.0;
+ float pwr = 1.0;
+ float pwHL = pow(lacunarity, -H);
+
+ for (int i = 0; i < (int)octaves; i++) {
+ value += safe_snoise(p) * pwr;
+ pwr *= pwHL;
+ p *= lacunarity;
+ }
+
+ float rmd = octaves - floor(octaves);
+ if (rmd != 0.0) {
+ value += rmd * safe_snoise(p) * pwr;
+ }
+
+ return value;
+}
+
+/* 4D Musgrave Multifractal
+ *
+ * H: highest fractal dimension
+ * lacunarity: gap between successive frequencies
+ * octaves: number of frequencies in the fBm
+ */
+
+float noise_musgrave_multi_fractal_4d(vector4 co, float H, float lacunarity, float octaves)
+{
+ vector4 p = co;
+ float value = 1.0;
+ float pwr = 1.0;
+ float pwHL = pow(lacunarity, -H);
+
+ for (int i = 0; i < (int)octaves; i++) {
+ value *= (pwr * safe_snoise(p) + 1.0);
+ pwr *= pwHL;
+ p *= lacunarity;
+ }
+
+ float rmd = octaves - floor(octaves);
+ if (rmd != 0.0) {
+ value *= (rmd * pwr * safe_snoise(p) + 1.0); /* correct? */
+ }
+
+ return value;
+}
+
+/* 4D Musgrave Heterogeneous Terrain
+ *
+ * H: fractal dimension of the roughest area
+ * lacunarity: gap between successive frequencies
+ * octaves: number of frequencies in the fBm
+ * offset: raises the terrain from `sea level'
+ */
+
+float noise_musgrave_hetero_terrain_4d(
+ vector4 co, float H, float lacunarity, float octaves, float offset)
+{
+ vector4 p = co;
+ float pwHL = pow(lacunarity, -H);
+ float pwr = pwHL;
+
+ /* first unscaled octave of function; later octaves are scaled */
+ float value = offset + safe_snoise(p);
+ p *= lacunarity;
+
+ for (int i = 1; i < (int)octaves; i++) {
+ float increment = (safe_snoise(p) + offset) * pwr * value;
+ value += increment;
+ pwr *= pwHL;
+ p *= lacunarity;
+ }
+
+ float rmd = octaves - floor(octaves);
+ if (rmd != 0.0) {
+ float increment = (safe_snoise(p) + offset) * pwr * value;
+ value += rmd * increment;
+ }
+
+ return value;
+}
+
+/* 4D Hybrid Additive/Multiplicative Multifractal Terrain
+ *
+ * H: fractal dimension of the roughest area
+ * lacunarity: gap between successive frequencies
+ * octaves: number of frequencies in the fBm
+ * offset: raises the terrain from `sea level'
+ */
+
+float noise_musgrave_hybrid_multi_fractal_4d(
+ vector4 co, float H, float lacunarity, float octaves, float offset, float gain)
+{
+ vector4 p = co;
+ float pwHL = pow(lacunarity, -H);
+ float pwr = pwHL;
+
+ float value = safe_snoise(p) + offset;
+ float weight = gain * value;
+ p *= lacunarity;
+
+ for (int i = 1; (weight > 0.001) && (i < (int)octaves); i++) {
+ if (weight > 1.0) {
+ weight = 1.0;
+ }
+
+ float signal = (safe_snoise(p) + offset) * pwr;
+ pwr *= pwHL;
+ value += weight * signal;
+ weight *= gain * signal;
+ p *= lacunarity;
+ }
+
+ float rmd = octaves - floor(octaves);
+ if (rmd != 0.0) {
+ value += rmd * ((safe_snoise(p) + offset) * pwr);
+ }
+
+ return value;
+}
+
+/* 4D Ridged Multifractal Terrain
+ *
+ * H: fractal dimension of the roughest area
+ * lacunarity: gap between successive frequencies
+ * octaves: number of frequencies in the fBm
+ * offset: raises the terrain from `sea level'
+ */
+
+float noise_musgrave_ridged_multi_fractal_4d(
+ vector4 co, float H, float lacunarity, float octaves, float offset, float gain)
+{
+ vector4 p = co;
+ float pwHL = pow(lacunarity, -H);
+ float pwr = pwHL;
+
+ float signal = offset - fabs(safe_snoise(p));
+ signal *= signal;
+ float value = signal;
+ float weight = 1.0;
+
+ for (int i = 1; i < (int)octaves; i++) {
+ p *= lacunarity;
+ weight = clamp(signal * gain, 0.0, 1.0);
+ signal = offset - fabs(safe_snoise(p));
+ signal *= signal;
+ signal *= weight;
+ value += signal * pwr;
+ pwr *= pwHL;
+ }
+
+ return value;
+}
+
+shader node_musgrave_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 musgrave_type = "fBM",
+ string dimensions = "3D",
+ point Vector = P,
+ float W = 0.0,
+ float Dimension = 2.0,
+ float Scale = 5.0,
+ float Detail = 2.0,
+ float Lacunarity = 2.0,
+ float Offset = 0.0,
+ float Gain = 1.0,
+ output float Fac = 0.0)
+{
+ float dimension = max(Dimension, 1e-5);
+ float octaves = clamp(Detail, 0.0, 16.0);
+ float lacunarity = max(Lacunarity, 1e-5);
+
+ vector3 s = Vector;
+
+ if (use_mapping)
+ s = transform(mapping, s);
+
+ if (dimensions == "1D") {
+ float p = W * Scale;
+ if (musgrave_type == "multifractal") {
+ Fac = noise_musgrave_multi_fractal_1d(p, dimension, lacunarity, octaves);
+ }
+ else if (musgrave_type == "fBM") {
+ Fac = noise_musgrave_fBm_1d(p, dimension, lacunarity, octaves);
+ }
+ else if (musgrave_type == "hybrid_multifractal") {
+ Fac = noise_musgrave_hybrid_multi_fractal_1d(
+ p, dimension, lacunarity, octaves, Offset, Gain);
+ }
+ else if (musgrave_type == "ridged_multifractal") {
+ Fac = noise_musgrave_ridged_multi_fractal_1d(
+ p, dimension, lacunarity, octaves, Offset, Gain);
+ }
+ else if (musgrave_type == "hetero_terrain") {
+ Fac = noise_musgrave_hetero_terrain_1d(p, dimension, lacunarity, octaves, Offset);
+ }
+ else {
+ Fac = 0.0;
+ }
+ }
+ else if (dimensions == "2D") {
+ vector2 p = vector2(s[0], s[1]) * Scale;
+ if (musgrave_type == "multifractal") {
+ Fac = noise_musgrave_multi_fractal_2d(p, dimension, lacunarity, octaves);
+ }
+ else if (musgrave_type == "fBM") {
+ Fac = noise_musgrave_fBm_2d(p, dimension, lacunarity, octaves);
+ }
+ else if (musgrave_type == "hybrid_multifractal") {
+ Fac = noise_musgrave_hybrid_multi_fractal_2d(
+ p, dimension, lacunarity, octaves, Offset, Gain);
+ }
+ else if (musgrave_type == "ridged_multifractal") {
+ Fac = noise_musgrave_ridged_multi_fractal_2d(
+ p, dimension, lacunarity, octaves, Offset, Gain);
+ }
+ else if (musgrave_type == "hetero_terrain") {
+ Fac = noise_musgrave_hetero_terrain_2d(p, dimension, lacunarity, octaves, Offset);
+ }
+ else {
+ Fac = 0.0;
+ }
+ }
+ else if (dimensions == "3D") {
+ vector3 p = s * Scale;
+ if (musgrave_type == "multifractal") {
+ Fac = noise_musgrave_multi_fractal_3d(p, dimension, lacunarity, octaves);
+ }
+ else if (musgrave_type == "fBM") {
+ Fac = noise_musgrave_fBm_3d(p, dimension, lacunarity, octaves);
+ }
+ else if (musgrave_type == "hybrid_multifractal") {
+ Fac = noise_musgrave_hybrid_multi_fractal_3d(
+ p, dimension, lacunarity, octaves, Offset, Gain);
+ }
+ else if (musgrave_type == "ridged_multifractal") {
+ Fac = noise_musgrave_ridged_multi_fractal_3d(
+ p, dimension, lacunarity, octaves, Offset, Gain);
+ }
+ else if (musgrave_type == "hetero_terrain") {
+ Fac = noise_musgrave_hetero_terrain_3d(p, dimension, lacunarity, octaves, Offset);
+ }
+ else {
+ Fac = 0.0;
+ }
+ }
+ else if (dimensions == "4D") {
+ vector4 p = vector4(s[0], s[1], s[2], W) * Scale;
+ if (musgrave_type == "multifractal") {
+ Fac = noise_musgrave_multi_fractal_4d(p, dimension, lacunarity, octaves);
+ }
+ else if (musgrave_type == "fBM") {
+ Fac = noise_musgrave_fBm_4d(p, dimension, lacunarity, octaves);
+ }
+ else if (musgrave_type == "hybrid_multifractal") {
+ Fac = noise_musgrave_hybrid_multi_fractal_4d(
+ p, dimension, lacunarity, octaves, Offset, Gain);
+ }
+ else if (musgrave_type == "ridged_multifractal") {
+ Fac = noise_musgrave_ridged_multi_fractal_4d(
+ p, dimension, lacunarity, octaves, Offset, Gain);
+ }
+ else if (musgrave_type == "hetero_terrain") {
+ Fac = noise_musgrave_hetero_terrain_4d(p, dimension, lacunarity, octaves, Offset);
+ }
+ else {
+ Fac = 0.0;
+ }
+ }
+ else {
+ Fac = 0.0;
+ }
+}
diff --git a/intern/cycles/kernel/osl/shaders/node_noise.h b/intern/cycles/kernel/osl/shaders/node_noise.h
new file mode 100644
index 00000000000..ab4cd7792cc
--- /dev/null
+++ b/intern/cycles/kernel/osl/shaders/node_noise.h
@@ -0,0 +1,202 @@
+/*
+ * 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 "vector2.h"
+#include "vector4.h"
+
+#define vector3 point
+
+float safe_noise(float p)
+{
+ float f = noise("noise", p);
+ if (isinf(f))
+ return 0.5;
+ return f;
+}
+
+float safe_noise(vector2 p)
+{
+ float f = noise("noise", p.x, p.y);
+ if (isinf(f))
+ return 0.5;
+ return f;
+}
+
+float safe_noise(vector3 p)
+{
+ float f = noise("noise", p);
+ if (isinf(f))
+ return 0.5;
+ return f;
+}
+
+float safe_noise(vector4 p)
+{
+ float f = noise("noise", vector3(p.x, p.y, p.z), p.w);
+ if (isinf(f))
+ return 0.5;
+ return f;
+}
+
+float safe_snoise(float p)
+{
+ float f = noise("snoise", p);
+ if (isinf(f))
+ return 0.0;
+ return f;
+}
+
+float safe_snoise(vector2 p)
+{
+ float f = noise("snoise", p.x, p.y);
+ if (isinf(f))
+ return 0.0;
+ return f;
+}
+
+float safe_snoise(vector3 p)
+{
+ float f = noise("snoise", p);
+ if (isinf(f))
+ return 0.0;
+ return f;
+}
+
+float safe_snoise(vector4 p)
+{
+ float f = noise("snoise", vector3(p.x, p.y, p.z), p.w);
+ if (isinf(f))
+ return 0.0;
+ return f;
+}
+
+/* The fractal_noise functions are all exactly the same except for the input type. */
+float fractal_noise(float p, float details, float roughness)
+{
+ float fscale = 1.0;
+ float amp = 1.0;
+ float maxamp = 0.0;
+ float sum = 0.0;
+ float octaves = clamp(details, 0.0, 16.0);
+ int n = (int)octaves;
+ for (int i = 0; i <= n; i++) {
+ float t = safe_noise(fscale * p);
+ sum += t * amp;
+ maxamp += amp;
+ amp *= clamp(roughness, 0.0, 1.0);
+ fscale *= 2.0;
+ }
+ float rmd = octaves - floor(octaves);
+ if (rmd != 0.0) {
+ float t = safe_noise(fscale * p);
+ float sum2 = sum + t * amp;
+ sum /= maxamp;
+ sum2 /= maxamp + amp;
+ return (1.0 - rmd) * sum + rmd * sum2;
+ }
+ else {
+ return sum / maxamp;
+ }
+}
+
+/* The fractal_noise functions are all exactly the same except for the input type. */
+float fractal_noise(vector2 p, float details, float roughness)
+{
+ float fscale = 1.0;
+ float amp = 1.0;
+ float maxamp = 0.0;
+ float sum = 0.0;
+ float octaves = clamp(details, 0.0, 16.0);
+ int n = (int)octaves;
+ for (int i = 0; i <= n; i++) {
+ float t = safe_noise(fscale * p);
+ sum += t * amp;
+ maxamp += amp;
+ amp *= clamp(roughness, 0.0, 1.0);
+ fscale *= 2.0;
+ }
+ float rmd = octaves - floor(octaves);
+ if (rmd != 0.0) {
+ float t = safe_noise(fscale * p);
+ float sum2 = sum + t * amp;
+ sum /= maxamp;
+ sum2 /= maxamp + amp;
+ return (1.0 - rmd) * sum + rmd * sum2;
+ }
+ else {
+ return sum / maxamp;
+ }
+}
+
+/* The fractal_noise functions are all exactly the same except for the input type. */
+float fractal_noise(vector3 p, float details, float roughness)
+{
+ float fscale = 1.0;
+ float amp = 1.0;
+ float maxamp = 0.0;
+ float sum = 0.0;
+ float octaves = clamp(details, 0.0, 16.0);
+ int n = (int)octaves;
+ for (int i = 0; i <= n; i++) {
+ float t = safe_noise(fscale * p);
+ sum += t * amp;
+ maxamp += amp;
+ amp *= clamp(roughness, 0.0, 1.0);
+ fscale *= 2.0;
+ }
+ float rmd = octaves - floor(octaves);
+ if (rmd != 0.0) {
+ float t = safe_noise(fscale * p);
+ float sum2 = sum + t * amp;
+ sum /= maxamp;
+ sum2 /= maxamp + amp;
+ return (1.0 - rmd) * sum + rmd * sum2;
+ }
+ else {
+ return sum / maxamp;
+ }
+}
+
+/* The fractal_noise functions are all exactly the same except for the input type. */
+float fractal_noise(vector4 p, float details, float roughness)
+{
+ float fscale = 1.0;
+ float amp = 1.0;
+ float maxamp = 0.0;
+ float sum = 0.0;
+ float octaves = clamp(details, 0.0, 16.0);
+ int n = (int)octaves;
+ for (int i = 0; i <= n; i++) {
+ float t = safe_noise(fscale * p);
+ sum += t * amp;
+ maxamp += amp;
+ amp *= clamp(roughness, 0.0, 1.0);
+ fscale *= 2.0;
+ }
+ float rmd = octaves - floor(octaves);
+ if (rmd != 0.0) {
+ float t = safe_noise(fscale * p);
+ float sum2 = sum + t * amp;
+ sum /= maxamp;
+ sum2 /= maxamp + amp;
+ return (1.0 - rmd) * sum + rmd * sum2;
+ }
+ else {
+ return sum / maxamp;
+ }
+}
+
+#undef vector3
diff --git a/intern/cycles/kernel/osl/shaders/node_noise_texture.osl b/intern/cycles/kernel/osl/shaders/node_noise_texture.osl
new file mode 100644
index 00000000000..01196ab633a
--- /dev/null
+++ b/intern/cycles/kernel/osl/shaders/node_noise_texture.osl
@@ -0,0 +1,152 @@
+/*
+ * 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 too 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 roughness, 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, roughness);
+ Color = color(value,
+ fractal_noise(p + random_float_offset(1.0), detail, roughness),
+ fractal_noise(p + random_float_offset(2.0), detail, roughness));
+ return value;
+}
+
+float noise_texture(
+ vector2 co, float detail, float roughness, 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, roughness);
+ Color = color(value,
+ fractal_noise(p + random_vector2_offset(2.0), detail, roughness),
+ fractal_noise(p + random_vector2_offset(3.0), detail, roughness));
+ return value;
+}
+
+float noise_texture(
+ vector3 co, float detail, float roughness, 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, roughness);
+ Color = color(value,
+ fractal_noise(p + random_vector3_offset(3.0), detail, roughness),
+ fractal_noise(p + random_vector3_offset(4.0), detail, roughness));
+ return value;
+}
+
+float noise_texture(
+ vector4 co, float detail, float roughness, 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, roughness);
+ Color = color(value,
+ fractal_noise(p + random_vector4_offset(4.0), detail, roughness),
+ fractal_noise(p + random_vector4_offset(5.0), detail, roughness));
+ 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 Roughness = 0.5,
+ 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, Roughness, Distortion, Color);
+ else if (dimensions == "2D")
+ Fac = noise_texture(vector2(p[0], p[1]), Detail, Roughness, Distortion, Color);
+ else if (dimensions == "3D")
+ Fac = noise_texture(p, Detail, Roughness, Distortion, Color);
+ else if (dimensions == "4D")
+ Fac = noise_texture(vector4(p[0], p[1], p[2], w), Detail, Roughness, Distortion, Color);
+ else
+ error("Unknown dimension!");
+}
diff --git a/intern/cycles/kernel/osl/shaders/node_normal.osl b/intern/cycles/kernel/osl/shaders/node_normal.osl
new file mode 100644
index 00000000000..a0a88445427
--- /dev/null
+++ b/intern/cycles/kernel/osl/shaders/node_normal.osl
@@ -0,0 +1,26 @@
+/*
+ * 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 "stdcycles.h"
+
+shader node_normal(normal direction = normal(0.0, 0.0, 0.0),
+ normal NormalIn = normal(0.0, 0.0, 0.0),
+ output normal NormalOut = normal(0.0, 0.0, 0.0),
+ output float Dot = 1.0)
+{
+ NormalOut = normalize(direction);
+ Dot = dot(NormalOut, normalize(NormalIn));
+}
diff --git a/intern/cycles/kernel/osl/shaders/node_normal_map.osl b/intern/cycles/kernel/osl/shaders/node_normal_map.osl
new file mode 100644
index 00000000000..7a94ad8ad1a
--- /dev/null
+++ b/intern/cycles/kernel/osl/shaders/node_normal_map.osl
@@ -0,0 +1,90 @@
+/*
+ * 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 "stdcycles.h"
+
+shader node_normal_map(normal NormalIn = N,
+ float Strength = 1.0,
+ color Color = color(0.5, 0.5, 1.0),
+ string space = "tangent",
+ string attr_name = "geom:tangent",
+ string attr_sign_name = "geom:tangent_sign",
+ output normal Normal = NormalIn)
+{
+ color mcolor = 2.0 * color(Color[0] - 0.5, Color[1] - 0.5, Color[2] - 0.5);
+ int is_backfacing = backfacing();
+
+ if (space == "tangent") {
+ vector tangent;
+ vector ninterp;
+ float tangent_sign;
+ float is_smooth = 0.0;
+
+ getattribute("geom:is_smooth", is_smooth);
+ if (!is_smooth) {
+ ninterp = normalize(transform("world", "object", Ng));
+
+ /* the normal is already inverted, which is too soon for the math here */
+ if (is_backfacing) {
+ ninterp = -ninterp;
+ }
+ }
+
+ // get _unnormalized_ interpolated normal and tangent
+ if (getattribute(attr_name, tangent) && getattribute(attr_sign_name, tangent_sign) &&
+ (!is_smooth || getattribute("geom:normal_map_normal", ninterp))) {
+ // apply normal map
+ vector B = tangent_sign * cross(ninterp, tangent);
+ Normal = normalize(mcolor[0] * tangent + mcolor[1] * B + mcolor[2] * ninterp);
+
+ // transform to world space
+ Normal = normalize(transform("object", "world", Normal));
+ }
+ else {
+ Normal = normal(0, 0, 0);
+ }
+ }
+ else if (space == "object") {
+ Normal = normalize(transform("object", "world", vector(mcolor)));
+ }
+ else if (space == "world") {
+ Normal = normalize(vector(mcolor));
+ }
+ else if (space == "blender_object") {
+ /* strange blender convention */
+ mcolor[1] = -mcolor[1];
+ mcolor[2] = -mcolor[2];
+
+ Normal = normalize(transform("object", "world", vector(mcolor)));
+ }
+ else if (space == "blender_world") {
+ /* strange blender convention */
+ mcolor[1] = -mcolor[1];
+ mcolor[2] = -mcolor[2];
+
+ Normal = normalize(vector(mcolor));
+ }
+
+ /* invert normal for backfacing polygons */
+ if (is_backfacing) {
+ Normal = -Normal;
+ }
+
+ if (Strength != 1.0)
+ Normal = normalize(NormalIn + (Normal - NormalIn) * max(Strength, 0.0));
+
+ Normal = ensure_valid_reflection(Ng, I, Normal);
+}
diff --git a/intern/cycles/kernel/osl/shaders/node_object_info.osl b/intern/cycles/kernel/osl/shaders/node_object_info.osl
new file mode 100644
index 00000000000..44513d9a1ba
--- /dev/null
+++ b/intern/cycles/kernel/osl/shaders/node_object_info.osl
@@ -0,0 +1,30 @@
+/*
+ * 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 "stdcycles.h"
+
+shader node_object_info(output point Location = point(0.0, 0.0, 0.0),
+ output color Color = color(1.0, 1.0, 1.0),
+ output float ObjectIndex = 0.0,
+ output float MaterialIndex = 0.0,
+ output float Random = 0.0)
+{
+ getattribute("object:location", Location);
+ getattribute("object:color", Color);
+ getattribute("object:index", ObjectIndex);
+ getattribute("material:index", MaterialIndex);
+ getattribute("object:random", Random);
+}
diff --git a/intern/cycles/kernel/osl/shaders/node_output_displacement.osl b/intern/cycles/kernel/osl/shaders/node_output_displacement.osl
new file mode 100644
index 00000000000..bd60fc2b7e1
--- /dev/null
+++ b/intern/cycles/kernel/osl/shaders/node_output_displacement.osl
@@ -0,0 +1,22 @@
+/*
+ * 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 "stdcycles.h"
+
+displacement node_output_displacement(vector Displacement = 0.0)
+{
+ P += Displacement;
+}
diff --git a/intern/cycles/kernel/osl/shaders/node_output_surface.osl b/intern/cycles/kernel/osl/shaders/node_output_surface.osl
new file mode 100644
index 00000000000..cd746f79c4a
--- /dev/null
+++ b/intern/cycles/kernel/osl/shaders/node_output_surface.osl
@@ -0,0 +1,22 @@
+/*
+ * 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 "stdcycles.h"
+
+surface node_output_surface(closure color Surface = 0)
+{
+ Ci = Surface;
+}
diff --git a/intern/cycles/kernel/osl/shaders/node_output_volume.osl b/intern/cycles/kernel/osl/shaders/node_output_volume.osl
new file mode 100644
index 00000000000..4cc14cd6699
--- /dev/null
+++ b/intern/cycles/kernel/osl/shaders/node_output_volume.osl
@@ -0,0 +1,22 @@
+/*
+ * 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 "stdcycles.h"
+
+volume node_output_volume(closure color Volume = 0)
+{
+ Ci = Volume;
+}
diff --git a/intern/cycles/kernel/osl/shaders/node_particle_info.osl b/intern/cycles/kernel/osl/shaders/node_particle_info.osl
new file mode 100644
index 00000000000..2dcdf3d0f3c
--- /dev/null
+++ b/intern/cycles/kernel/osl/shaders/node_particle_info.osl
@@ -0,0 +1,36 @@
+/*
+ * 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 "stdcycles.h"
+
+shader node_particle_info(output float Index = 0.0,
+ output float Random = 0.0,
+ output float Age = 0.0,
+ output float Lifetime = 0.0,
+ output point Location = point(0.0, 0.0, 0.0),
+ output float Size = 0.0,
+ output vector Velocity = point(0.0, 0.0, 0.0),
+ output vector AngularVelocity = point(0.0, 0.0, 0.0))
+{
+ getattribute("particle:index", Index);
+ getattribute("particle:random", Random);
+ getattribute("particle:age", Age);
+ getattribute("particle:lifetime", Lifetime);
+ getattribute("particle:location", Location);
+ getattribute("particle:size", Size);
+ getattribute("particle:velocity", Velocity);
+ getattribute("particle:angular_velocity", AngularVelocity);
+}
diff --git a/intern/cycles/kernel/osl/shaders/node_principled_bsdf.osl b/intern/cycles/kernel/osl/shaders/node_principled_bsdf.osl
new file mode 100644
index 00000000000..55afb892d36
--- /dev/null
+++ b/intern/cycles/kernel/osl/shaders/node_principled_bsdf.osl
@@ -0,0 +1,157 @@
+/*
+ * Copyright 2011-2017 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_fresnel.h"
+#include "stdcycles.h"
+
+shader node_principled_bsdf(string distribution = "Multiscatter GGX",
+ string subsurface_method = "random_walk",
+ color BaseColor = color(0.8, 0.8, 0.8),
+ float Subsurface = 0.0,
+ vector SubsurfaceRadius = vector(1.0, 1.0, 1.0),
+ color SubsurfaceColor = color(0.7, 0.1, 0.1),
+ float SubsurfaceIOR = 1.4,
+ float SubsurfaceAnisotropy = 0.0,
+ float Metallic = 0.0,
+ float Specular = 0.5,
+ float SpecularTint = 0.0,
+ float Roughness = 0.5,
+ float Anisotropic = 0.0,
+ float AnisotropicRotation = 0.0,
+ float Sheen = 0.0,
+ float SheenTint = 0.5,
+ float Clearcoat = 0.0,
+ float ClearcoatRoughness = 0.03,
+ float IOR = 1.45,
+ float Transmission = 0.0,
+ float TransmissionRoughness = 0.0,
+ normal Normal = N,
+ normal ClearcoatNormal = N,
+ normal Tangent = normalize(dPdu),
+ output closure color BSDF = 0)
+{
+ float f = max(IOR, 1e-5);
+ float diffuse_weight = (1.0 - clamp(Metallic, 0.0, 1.0)) * (1.0 - clamp(Transmission, 0.0, 1.0));
+ float final_transmission = clamp(Transmission, 0.0, 1.0) * (1.0 - clamp(Metallic, 0.0, 1.0));
+ float specular_weight = (1.0 - final_transmission);
+
+ vector T = Tangent;
+
+ float m_cdlum = luminance(BaseColor);
+ color m_ctint = m_cdlum > 0.0 ? BaseColor / m_cdlum :
+ color(1.0, 1.0, 1.0); // normalize lum. to isolate hue+sat
+
+ /* rotate tangent */
+ if (AnisotropicRotation != 0.0)
+ T = rotate(T, AnisotropicRotation * M_2PI, point(0.0, 0.0, 0.0), Normal);
+
+ if (diffuse_weight > 1e-5) {
+ if (Subsurface > 1e-5) {
+ color mixed_ss_base_color = SubsurfaceColor * Subsurface + BaseColor * (1.0 - Subsurface);
+
+ BSDF = mixed_ss_base_color * bssrdf(subsurface_method,
+ Normal,
+ Subsurface * SubsurfaceRadius,
+ mixed_ss_base_color,
+ "roughness",
+ Roughness,
+ "ior",
+ SubsurfaceIOR,
+ "anisotropy",
+ SubsurfaceAnisotropy);
+ }
+ else {
+ BSDF = BaseColor * principled_diffuse(Normal, Roughness);
+ }
+
+ if (Sheen > 1e-5) {
+ color sheen_color = color(1.0, 1.0, 1.0) * (1.0 - SheenTint) + m_ctint * SheenTint;
+
+ BSDF = BSDF + sheen_color * Sheen * principled_sheen(Normal);
+ }
+
+ BSDF = BSDF * diffuse_weight;
+ }
+
+ if (specular_weight > 1e-5) {
+ float aspect = sqrt(1.0 - Anisotropic * 0.9);
+ float r2 = Roughness * Roughness;
+
+ float alpha_x = r2 / aspect;
+ float alpha_y = r2 * aspect;
+
+ color tmp_col = color(1.0, 1.0, 1.0) * (1.0 - SpecularTint) + m_ctint * SpecularTint;
+
+ color Cspec0 = (Specular * 0.08 * tmp_col) * (1.0 - Metallic) + BaseColor * Metallic;
+
+ if (distribution == "GGX" || Roughness <= 0.075) {
+ BSDF = BSDF + specular_weight *
+ microfacet_ggx_aniso_fresnel(Normal,
+ T,
+ alpha_x,
+ alpha_y,
+ (2.0 / (1.0 - sqrt(0.08 * Specular))) - 1.0,
+ BaseColor,
+ Cspec0);
+ }
+ else {
+ BSDF = BSDF + specular_weight * microfacet_multi_ggx_aniso_fresnel(
+ Normal,
+ T,
+ alpha_x,
+ alpha_y,
+ (2.0 / (1.0 - sqrt(0.08 * Specular))) - 1.0,
+ BaseColor,
+ Cspec0);
+ }
+ }
+
+ if (final_transmission > 1e-5) {
+ color Cspec0 = BaseColor * SpecularTint + color(1.0, 1.0, 1.0) * (1.0 - SpecularTint);
+ float eta = backfacing() ? 1.0 / f : f;
+
+ if (distribution == "GGX" || Roughness <= 5e-2) {
+ float cosNO = dot(Normal, I);
+ float Fr = fresnel_dielectric_cos(cosNO, eta);
+
+ float refl_roughness = Roughness;
+ if (Roughness <= 1e-2)
+ refl_roughness = 0.0;
+
+ float transmission_roughness = refl_roughness;
+ if (distribution == "GGX")
+ transmission_roughness = 1.0 - (1.0 - refl_roughness) * (1.0 - TransmissionRoughness);
+
+ BSDF = BSDF +
+ final_transmission *
+ (Fr * microfacet_ggx_fresnel(
+ Normal, refl_roughness * refl_roughness, eta, BaseColor, Cspec0) +
+ (1.0 - Fr) * BaseColor *
+ microfacet_ggx_refraction(
+ Normal, transmission_roughness * transmission_roughness, eta));
+ }
+ else {
+ BSDF = BSDF +
+ final_transmission * microfacet_multi_ggx_glass_fresnel(
+ Normal, Roughness * Roughness, eta, BaseColor, Cspec0);
+ }
+ }
+
+ if (Clearcoat > 1e-5) {
+ BSDF = BSDF + principled_clearcoat(
+ ClearcoatNormal, Clearcoat, ClearcoatRoughness * ClearcoatRoughness);
+ }
+}
diff --git a/intern/cycles/kernel/osl/shaders/node_principled_hair_bsdf.osl b/intern/cycles/kernel/osl/shaders/node_principled_hair_bsdf.osl
new file mode 100644
index 00000000000..4cf17e0e703
--- /dev/null
+++ b/intern/cycles/kernel/osl/shaders/node_principled_hair_bsdf.osl
@@ -0,0 +1,105 @@
+/*
+ * Copyright 2018 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 "stdcycles.h"
+
+color log3(color a)
+{
+ return color(log(a[0]), log(a[1]), log(a[2]));
+}
+
+color sigma_from_concentration(float eumelanin, float pheomelanin)
+{
+ return eumelanin * color(0.506, 0.841, 1.653) + pheomelanin * color(0.343, 0.733, 1.924);
+}
+
+color sigma_from_reflectance(color c, float azimuthal_roughness)
+{
+ float x = azimuthal_roughness;
+ float roughness_fac = (((((0.245 * x) + 5.574) * x - 10.73) * x + 2.532) * x - 0.215) * x +
+ 5.969;
+ color sigma = log3(c) / roughness_fac;
+ return sigma * sigma;
+}
+
+shader node_principled_hair_bsdf(color Color = color(0.017513, 0.005763, 0.002059),
+ float Melanin = 0.8,
+ float MelaninRedness = 1.0,
+ float RandomColor = 0.0,
+ color Tint = 1.0,
+ color AbsorptionCoefficient = color(0.245531, 0.52, 1.365),
+ normal Normal = Ng,
+ string parametrization = "Absorption coefficient",
+ float Offset = radians(2),
+ float Roughness = 0.3,
+ float RadialRoughness = 0.3,
+ float RandomRoughness = 0.0,
+ float Coat = 0.0,
+ float IOR = 1.55,
+ string AttrRandom = "geom:curve_random",
+ float Random = 0.0,
+
+ output closure color BSDF = 0)
+{
+ /* Get random value from curve in none is specified. */
+ float random_value = 0.0;
+
+ if (isconnected(Random)) {
+ random_value = Random;
+ }
+ else {
+ getattribute(AttrRandom, random_value);
+ }
+
+ /* Compute roughness. */
+ float factor_random_roughness = 1.0 + 2.0 * (random_value - 0.5) * RandomRoughness;
+ float m0_roughness = 1.0 - clamp(Coat, 0.0, 1.0);
+ float roughness = Roughness * factor_random_roughness;
+ float radial_roughness = RadialRoughness * factor_random_roughness;
+
+ /* Compute absorption. */
+ color sigma;
+
+ if (parametrization == "Absorption coefficient") {
+ sigma = AbsorptionCoefficient;
+ }
+ else if (parametrization == "Melanin concentration") {
+ /* Randomize melanin. */
+ float factor_random_color = 1.0 + 2.0 * (random_value - 0.5) * RandomColor;
+ float melanin = Melanin * factor_random_color;
+
+ /* Map melanin 0..inf from more perceptually linear 0..1. */
+ melanin = -log(max(1.0 - melanin, 0.0001));
+
+ /* Benedikt Bitterli's melanin ratio remapping. */
+ float eumelanin = melanin * (1.0 - MelaninRedness);
+ float pheomelanin = melanin * MelaninRedness;
+ color melanin_sigma = sigma_from_concentration(eumelanin, pheomelanin);
+
+ /* Optional tint. */
+ color tint_sigma = sigma_from_reflectance(Tint, radial_roughness);
+ sigma = melanin_sigma + tint_sigma;
+ }
+ else if (parametrization == "Direct coloring") {
+ sigma = sigma_from_reflectance(Color, radial_roughness);
+ }
+ else {
+ /* Fallback to brownish hair, same as defaults for melanin. */
+ sigma = sigma_from_concentration(0.0, 0.8054375);
+ }
+
+ BSDF = principled_hair(Normal, sigma, roughness, radial_roughness, m0_roughness, Offset, IOR);
+}
diff --git a/intern/cycles/kernel/osl/shaders/node_principled_volume.osl b/intern/cycles/kernel/osl/shaders/node_principled_volume.osl
new file mode 100644
index 00000000000..0cb4cdebdaa
--- /dev/null
+++ b/intern/cycles/kernel/osl/shaders/node_principled_volume.osl
@@ -0,0 +1,93 @@
+/*
+ * 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 "stdcycles.h"
+
+shader node_principled_volume(color Color = color(0.5, 0.5, 0.5),
+ float Density = 1.0,
+ float Anisotropy = 0.0,
+ color AbsorptionColor = color(0.0, 0.0, 0.0),
+ float EmissionStrength = 0.0,
+ color EmissionColor = color(1.0, 1.0, 1.0),
+ float BlackbodyIntensity = 0.0,
+ color BlackbodyTint = color(1.0, 1.0, 1.0),
+ float Temperature = 1500.0,
+ string DensityAttribute = "geom:density",
+ string ColorAttribute = "geom:color",
+ string TemperatureAttribute = "geom:temperature",
+ output closure color Volume = 0)
+{
+ /* Compute density. */
+ float primitive_density = 1.0;
+ float density = max(Density, 0.0);
+
+ if (density > 1e-5) {
+ if (getattribute(DensityAttribute, primitive_density)) {
+ density = max(density * primitive_density, 0.0);
+ }
+ }
+
+ if (density > 1e-5) {
+ /* Compute scattering color. */
+ color scatter_color = Color;
+ color primitive_color;
+ if (getattribute(ColorAttribute, primitive_color)) {
+ scatter_color *= primitive_color;
+ }
+
+ /* Add scattering and absorption closures. */
+ color scatter_coeff = scatter_color;
+ color absorption_color = sqrt(max(AbsorptionColor, 0.0));
+ color absorption_coeff = max(1.0 - scatter_color, 0.0) * max(1.0 - absorption_color, 0.0);
+ Volume = scatter_coeff * density * henyey_greenstein(Anisotropy) +
+ absorption_coeff * density * absorption();
+ }
+
+ /* Compute emission. */
+ float emission_strength = max(EmissionStrength, 0.0);
+ float blackbody_intensity = BlackbodyIntensity;
+
+ if (emission_strength > 1e-5) {
+ Volume += emission_strength * EmissionColor * emission();
+ }
+
+ if (blackbody_intensity > 1e-3) {
+ float T = Temperature;
+
+ /* Add temperature from attribute if available. */
+ float temperature;
+ if (getattribute(TemperatureAttribute, temperature)) {
+ T *= max(temperature, 0.0);
+ }
+
+ T = max(T, 0.0);
+
+ /* Stefan-Boltzman law. */
+ float T4 = (T * T) * (T * T);
+ float sigma = 5.670373e-8 * 1e-6 / M_PI;
+ float intensity = sigma * mix(1.0, T4, blackbody_intensity);
+
+ if (intensity > 1e-5) {
+ color bb = blackbody(T);
+ float l = luminance(bb);
+
+ if (l != 0.0) {
+ bb *= BlackbodyTint * intensity / l;
+ Volume += bb * emission();
+ }
+ }
+ }
+}
diff --git a/intern/cycles/kernel/osl/shaders/node_ramp_util.h b/intern/cycles/kernel/osl/shaders/node_ramp_util.h
new file mode 100644
index 00000000000..f7fb07b257d
--- /dev/null
+++ b/intern/cycles/kernel/osl/shaders/node_ramp_util.h
@@ -0,0 +1,93 @@
+/*
+ * 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.
+ */
+
+/* NOTE: svm_ramp.h, svm_ramp_util.h and node_ramp_util.h must stay consistent */
+
+color rgb_ramp_lookup(color ramp[], float at, int interpolate, int extrapolate)
+{
+ float f = at;
+ int table_size = arraylength(ramp);
+
+ if ((f < 0.0 || f > 1.0) && extrapolate) {
+ color t0, dy;
+ if (f < 0.0) {
+ t0 = ramp[0];
+ dy = t0 - ramp[1];
+ f = -f;
+ }
+ else {
+ t0 = ramp[table_size - 1];
+ dy = t0 - ramp[table_size - 2];
+ f = f - 1.0;
+ }
+ return t0 + dy * f * (table_size - 1);
+ }
+
+ f = clamp(at, 0.0, 1.0) * (table_size - 1);
+
+ /* clamp int as well in case of NaN */
+ int i = (int)f;
+ if (i < 0)
+ i = 0;
+ if (i >= table_size)
+ i = table_size - 1;
+ float t = f - (float)i;
+
+ color result = ramp[i];
+
+ if (interpolate && t > 0.0)
+ result = (1.0 - t) * result + t * ramp[i + 1];
+
+ return result;
+}
+
+float rgb_ramp_lookup(float ramp[], float at, int interpolate, int extrapolate)
+{
+ float f = at;
+ int table_size = arraylength(ramp);
+
+ if ((f < 0.0 || f > 1.0) && extrapolate) {
+ float t0, dy;
+ if (f < 0.0) {
+ t0 = ramp[0];
+ dy = t0 - ramp[1];
+ f = -f;
+ }
+ else {
+ t0 = ramp[table_size - 1];
+ dy = t0 - ramp[table_size - 2];
+ f = f - 1.0;
+ }
+ return t0 + dy * f * (table_size - 1);
+ }
+
+ f = clamp(at, 0.0, 1.0) * (table_size - 1);
+
+ /* clamp int as well in case of NaN */
+ int i = (int)f;
+ if (i < 0)
+ i = 0;
+ if (i >= table_size)
+ i = table_size - 1;
+ float t = f - (float)i;
+
+ float result = ramp[i];
+
+ if (interpolate && t > 0.0)
+ result = (1.0 - t) * result + t * ramp[i + 1];
+
+ return result;
+}
diff --git a/intern/cycles/kernel/osl/shaders/node_refraction_bsdf.osl b/intern/cycles/kernel/osl/shaders/node_refraction_bsdf.osl
new file mode 100644
index 00000000000..9e9b31d9a87
--- /dev/null
+++ b/intern/cycles/kernel/osl/shaders/node_refraction_bsdf.osl
@@ -0,0 +1,36 @@
+/*
+ * 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 "stdcycles.h"
+
+shader node_refraction_bsdf(color Color = 0.8,
+ string distribution = "sharp",
+ float Roughness = 0.2,
+ float IOR = 1.45,
+ normal Normal = N,
+ output closure color BSDF = 0)
+{
+ float f = max(IOR, 1e-5);
+ float eta = backfacing() ? 1.0 / f : f;
+ float roughness = Roughness * Roughness;
+
+ if (distribution == "sharp")
+ BSDF = Color * refraction(Normal, eta);
+ else if (distribution == "beckmann")
+ BSDF = Color * microfacet_beckmann_refraction(Normal, roughness, eta);
+ else if (distribution == "GGX")
+ BSDF = Color * microfacet_ggx_refraction(Normal, roughness, eta);
+}
diff --git a/intern/cycles/kernel/osl/shaders/node_rgb_curves.osl b/intern/cycles/kernel/osl/shaders/node_rgb_curves.osl
new file mode 100644
index 00000000000..8850040d580
--- /dev/null
+++ b/intern/cycles/kernel/osl/shaders/node_rgb_curves.osl
@@ -0,0 +1,39 @@
+/*
+ * 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_ramp_util.h"
+#include "stdcycles.h"
+
+shader node_rgb_curves(color ramp[] = {0.0},
+ float min_x = 0.0,
+ float max_x = 1.0,
+
+ color ColorIn = 0.0,
+ float Fac = 0.0,
+ output color ColorOut = 0.0)
+{
+ color c = (ColorIn - color(min_x, min_x, min_x)) / (max_x - min_x);
+
+ color r = rgb_ramp_lookup(ramp, c[0], 1, 1);
+ color g = rgb_ramp_lookup(ramp, c[1], 1, 1);
+ color b = rgb_ramp_lookup(ramp, c[2], 1, 1);
+
+ ColorOut[0] = r[0];
+ ColorOut[1] = g[1];
+ ColorOut[2] = b[2];
+
+ ColorOut = mix(ColorIn, ColorOut, Fac);
+}
diff --git a/intern/cycles/kernel/osl/shaders/node_rgb_ramp.osl b/intern/cycles/kernel/osl/shaders/node_rgb_ramp.osl
new file mode 100644
index 00000000000..2131edb2688
--- /dev/null
+++ b/intern/cycles/kernel/osl/shaders/node_rgb_ramp.osl
@@ -0,0 +1,30 @@
+/*
+ * 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_ramp_util.h"
+#include "stdcycles.h"
+
+shader node_rgb_ramp(color ramp_color[] = {0.0},
+ float ramp_alpha[] = {0.0},
+ int interpolate = 1,
+
+ float Fac = 0.0,
+ output color Color = 0.0,
+ output float Alpha = 1.0)
+{
+ Color = rgb_ramp_lookup(ramp_color, Fac, interpolate, 0);
+ Alpha = rgb_ramp_lookup(ramp_alpha, Fac, interpolate, 0);
+}
diff --git a/intern/cycles/kernel/osl/shaders/node_rgb_to_bw.osl b/intern/cycles/kernel/osl/shaders/node_rgb_to_bw.osl
new file mode 100644
index 00000000000..f0a094d5b57
--- /dev/null
+++ b/intern/cycles/kernel/osl/shaders/node_rgb_to_bw.osl
@@ -0,0 +1,22 @@
+/*
+ * 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 "stdcycles.h"
+
+shader node_rgb_to_bw(color Color = 0.0, output float Val = 0.0)
+{
+ Val = Color[0] * 0.2126 + Color[1] * 0.7152 + Color[2] * 0.0722;
+}
diff --git a/intern/cycles/kernel/osl/shaders/node_scatter_volume.osl b/intern/cycles/kernel/osl/shaders/node_scatter_volume.osl
new file mode 100644
index 00000000000..36ad952dee6
--- /dev/null
+++ b/intern/cycles/kernel/osl/shaders/node_scatter_volume.osl
@@ -0,0 +1,25 @@
+/*
+ * 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 "stdcycles.h"
+
+shader node_scatter_volume(color Color = color(0.8, 0.8, 0.8),
+ float Density = 1.0,
+ float Anisotropy = 0.0,
+ output closure color Volume = 0)
+{
+ Volume = (Color * max(Density, 0.0)) * henyey_greenstein(Anisotropy);
+}
diff --git a/intern/cycles/kernel/osl/shaders/node_separate_hsv.osl b/intern/cycles/kernel/osl/shaders/node_separate_hsv.osl
new file mode 100644
index 00000000000..2f902b72dbc
--- /dev/null
+++ b/intern/cycles/kernel/osl/shaders/node_separate_hsv.osl
@@ -0,0 +1,30 @@
+/*
+ * 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_color.h"
+#include "stdcycles.h"
+
+shader node_separate_hsv(color Color = 0.8,
+ output float H = 0.0,
+ output float S = 0.0,
+ output float V = 0.0)
+{
+ color col = rgb_to_hsv(Color);
+
+ H = col[0];
+ S = col[1];
+ V = col[2];
+}
diff --git a/intern/cycles/kernel/osl/shaders/node_separate_rgb.osl b/intern/cycles/kernel/osl/shaders/node_separate_rgb.osl
new file mode 100644
index 00000000000..62e4aedb879
--- /dev/null
+++ b/intern/cycles/kernel/osl/shaders/node_separate_rgb.osl
@@ -0,0 +1,27 @@
+/*
+ * 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 "stdcycles.h"
+
+shader node_separate_rgb(color Image = 0.8,
+ output float R = 0.0,
+ output float G = 0.0,
+ output float B = 0.0)
+{
+ R = Image[0];
+ G = Image[1];
+ B = Image[2];
+}
diff --git a/intern/cycles/kernel/osl/shaders/node_separate_xyz.osl b/intern/cycles/kernel/osl/shaders/node_separate_xyz.osl
new file mode 100644
index 00000000000..acaf3942b6f
--- /dev/null
+++ b/intern/cycles/kernel/osl/shaders/node_separate_xyz.osl
@@ -0,0 +1,27 @@
+/*
+ * 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 "stdcycles.h"
+
+shader node_separate_xyz(vector Vector = 0.8,
+ output float X = 0.0,
+ output float Y = 0.0,
+ output float Z = 0.0)
+{
+ X = Vector[0];
+ Y = Vector[1];
+ Z = Vector[2];
+}
diff --git a/intern/cycles/kernel/osl/shaders/node_set_normal.osl b/intern/cycles/kernel/osl/shaders/node_set_normal.osl
new file mode 100644
index 00000000000..26a97e2b5d1
--- /dev/null
+++ b/intern/cycles/kernel/osl/shaders/node_set_normal.osl
@@ -0,0 +1,23 @@
+/*
+ * 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 "stdcycles.h"
+
+surface node_set_normal(normal Direction = N, output normal Normal = N)
+{
+ N = Direction;
+ Normal = Direction;
+}
diff --git a/intern/cycles/kernel/osl/shaders/node_sky_texture.osl b/intern/cycles/kernel/osl/shaders/node_sky_texture.osl
new file mode 100644
index 00000000000..43d7bd36973
--- /dev/null
+++ b/intern/cycles/kernel/osl/shaders/node_sky_texture.osl
@@ -0,0 +1,237 @@
+/*
+ * 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_color.h"
+#include "stdcycles.h"
+
+float sky_angle_between(float thetav, float phiv, float theta, float phi)
+{
+ float cospsi = sin(thetav) * sin(theta) * cos(phi - phiv) + cos(thetav) * cos(theta);
+
+ if (cospsi > 1.0)
+ return 0.0;
+ if (cospsi < -1.0)
+ return M_PI;
+
+ return acos(cospsi);
+}
+
+vector sky_spherical_coordinates(vector dir)
+{
+ return vector(acos(dir[2]), atan2(dir[0], dir[1]), 0);
+}
+
+/* Preetham */
+float sky_perez_function(float lam[9], float theta, float gamma)
+{
+ float ctheta = cos(theta);
+ float cgamma = cos(gamma);
+
+ return (1.0 + lam[0] * exp(lam[1] / ctheta)) *
+ (1.0 + lam[2] * exp(lam[3] * gamma) + lam[4] * cgamma * cgamma);
+}
+
+color sky_radiance_preetham(normal dir,
+ float sunphi,
+ float suntheta,
+ color radiance,
+ float config_x[9],
+ float config_y[9],
+ float config_z[9])
+{
+ /* convert vector to spherical coordinates */
+ vector spherical = sky_spherical_coordinates(dir);
+ float theta = spherical[0];
+ float phi = spherical[1];
+
+ /* angle between sun direction and dir */
+ float gamma = sky_angle_between(theta, phi, suntheta, sunphi);
+
+ /* clamp theta to horizon */
+ theta = min(theta, M_PI_2 - 0.001);
+
+ /* compute xyY color space values */
+ float x = radiance[1] * sky_perez_function(config_y, theta, gamma);
+ float y = radiance[2] * sky_perez_function(config_z, theta, gamma);
+ float Y = radiance[0] * sky_perez_function(config_x, theta, gamma);
+
+ /* convert to RGB */
+ color xyz = xyY_to_xyz(x, y, Y);
+ return xyz_to_rgb(xyz[0], xyz[1], xyz[2]);
+}
+
+/* Hosek / Wilkie */
+float sky_radiance_internal(float config[9], float theta, float gamma)
+{
+ float ctheta = cos(theta);
+ float cgamma = cos(gamma);
+
+ float expM = exp(config[4] * gamma);
+ float rayM = cgamma * cgamma;
+ float mieM = (1.0 + rayM) / pow((1.0 + config[8] * config[8] - 2.0 * config[8] * cgamma), 1.5);
+ float zenith = sqrt(ctheta);
+
+ return (1.0 + config[0] * exp(config[1] / (ctheta + 0.01))) *
+ (config[2] + config[3] * expM + config[5] * rayM + config[6] * mieM + config[7] * zenith);
+}
+
+color sky_radiance_hosek(normal dir,
+ float sunphi,
+ float suntheta,
+ color radiance,
+ float config_x[9],
+ float config_y[9],
+ float config_z[9])
+{
+ /* convert vector to spherical coordinates */
+ vector spherical = sky_spherical_coordinates(dir);
+ float theta = spherical[0];
+ float phi = spherical[1];
+
+ /* angle between sun direction and dir */
+ float gamma = sky_angle_between(theta, phi, suntheta, sunphi);
+
+ /* clamp theta to horizon */
+ theta = min(theta, M_PI_2 - 0.001);
+
+ /* compute xyz color space values */
+ float x = sky_radiance_internal(config_x, theta, gamma) * radiance[0];
+ float y = sky_radiance_internal(config_y, theta, gamma) * radiance[1];
+ float z = sky_radiance_internal(config_z, theta, gamma) * radiance[2];
+
+ /* convert to RGB and adjust strength */
+ return xyz_to_rgb(x, y, z) * (M_2PI / 683);
+}
+
+/* Nishita improved */
+vector geographical_to_direction(float lat, float lon)
+{
+ return vector(cos(lat) * cos(lon), cos(lat) * sin(lon), sin(lat));
+}
+
+float precise_angle(vector a, vector b)
+{
+ return 2.0 * atan2(length(a - b), length(a + b));
+}
+
+color sky_radiance_nishita(vector dir, float nishita_data[10], string filename)
+{
+ /* definitions */
+ float sun_elevation = nishita_data[6];
+ float sun_rotation = nishita_data[7];
+ float angular_diameter = nishita_data[8];
+ float sun_intensity = nishita_data[9];
+ int sun_disc = angular_diameter > 0;
+ float alpha = 1.0;
+ color xyz;
+ /* convert dir to spherical coordinates */
+ vector direction = sky_spherical_coordinates(dir);
+
+ /* render above the horizon */
+ if (dir[2] >= 0.0) {
+ /* definitions */
+ vector sun_dir = geographical_to_direction(sun_elevation, sun_rotation + M_PI_2);
+ float sun_dir_angle = precise_angle(dir, sun_dir);
+ float half_angular = angular_diameter / 2.0;
+ float dir_elevation = M_PI_2 - direction[0];
+
+ /* if ray inside sun disc render it, otherwise render sky */
+ if (sun_dir_angle < half_angular && sun_disc == 1) {
+ /* get 2 pixels data */
+ color pixel_bottom = color(nishita_data[0], nishita_data[1], nishita_data[2]);
+ color pixel_top = color(nishita_data[3], nishita_data[4], nishita_data[5]);
+ float y;
+
+ /* sun interpolation */
+ if (sun_elevation - half_angular > 0.0) {
+ if ((sun_elevation + half_angular) > 0.0) {
+ y = ((dir_elevation - sun_elevation) / angular_diameter) + 0.5;
+ xyz = mix(pixel_bottom, pixel_top, y) * sun_intensity;
+ }
+ }
+ else {
+ if (sun_elevation + half_angular > 0.0) {
+ y = dir_elevation / (sun_elevation + half_angular);
+ xyz = mix(pixel_bottom, pixel_top, y) * sun_intensity;
+ }
+ }
+ /* limb darkening, coefficient is 0.6f */
+ float angle_fraction = sun_dir_angle / half_angular;
+ float limb_darkening = (1.0 - 0.6 * (1.0 - sqrt(1.0 - angle_fraction * angle_fraction)));
+ xyz *= limb_darkening;
+ }
+ /* sky */
+ else {
+ /* sky interpolation */
+ float x = (direction[1] + M_PI + sun_rotation) / M_2PI;
+ /* more pixels toward horizon compensation */
+ float y = 1.0 - sqrt(dir_elevation / M_PI_2);
+ if (x > 1.0) {
+ x = x - 1.0;
+ }
+ xyz = (color)texture(filename, x, y, "wrap", "clamp", "interp", "linear", "alpha", alpha);
+ }
+ }
+ /* ground */
+ else {
+ if (dir[2] < -0.4) {
+ xyz = color(0, 0, 0);
+ }
+ else {
+ /* black ground fade */
+ float mul = pow(1.0 + dir[2] * 2.5, 3.0);
+ /* interpolation */
+ float x = (direction[1] + M_PI + sun_rotation) / M_2PI;
+ float y = 1.5;
+ if (x > 1.0) {
+ x = x - 1.0;
+ }
+ xyz = (color)texture(
+ filename, x, y, "wrap", "periodic", "interp", "linear", "alpha", alpha) *
+ mul;
+ }
+ }
+ /* convert to RGB */
+ return xyz_to_rgb(xyz[0], xyz[1], xyz[2]);
+}
+
+shader node_sky_texture(
+ int use_mapping = 0,
+ matrix mapping = matrix(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
+ vector Vector = P,
+ string sky_type = "hosek_wilkie",
+ float theta = 0.0,
+ float phi = 0.0,
+ string filename = "",
+ color radiance = color(0.0, 0.0, 0.0),
+ float config_x[9] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
+ float config_y[9] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
+ float config_z[9] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
+ float nishita_data[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
+ output color Color = color(0.0, 0.0, 0.0))
+{
+ vector p = Vector;
+
+ if (use_mapping)
+ p = transform(mapping, p);
+
+ if (sky_type == "nishita_improved")
+ Color = sky_radiance_nishita(p, nishita_data, filename);
+ if (sky_type == "hosek_wilkie")
+ Color = sky_radiance_hosek(p, phi, theta, radiance, config_x, config_y, config_z);
+ if (sky_type == "preetham")
+ Color = sky_radiance_preetham(p, phi, theta, radiance, config_x, config_y, config_z);
+}
diff --git a/intern/cycles/kernel/osl/shaders/node_subsurface_scattering.osl b/intern/cycles/kernel/osl/shaders/node_subsurface_scattering.osl
new file mode 100644
index 00000000000..f55e38c54ff
--- /dev/null
+++ b/intern/cycles/kernel/osl/shaders/node_subsurface_scattering.osl
@@ -0,0 +1,30 @@
+/*
+ * 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 "stdcycles.h"
+
+shader node_subsurface_scattering(color Color = 0.8,
+ float Scale = 1.0,
+ vector Radius = vector(0.1, 0.1, 0.1),
+ float IOR = 1.4,
+ float Anisotropy = 0.0,
+ string method = "random_walk",
+ normal Normal = N,
+ output closure color BSSRDF = 0)
+{
+ BSSRDF = Color *
+ bssrdf(method, Normal, Scale * Radius, Color, "ior", IOR, "anisotropy", Anisotropy);
+}
diff --git a/intern/cycles/kernel/osl/shaders/node_tangent.osl b/intern/cycles/kernel/osl/shaders/node_tangent.osl
new file mode 100644
index 00000000000..f086fa079ec
--- /dev/null
+++ b/intern/cycles/kernel/osl/shaders/node_tangent.osl
@@ -0,0 +1,46 @@
+/*
+ * 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 "stdcycles.h"
+
+shader node_tangent(normal NormalIn = N,
+ string attr_name = "geom:tangent",
+ string direction_type = "radial",
+ string axis = "z",
+ output normal Tangent = normalize(dPdu))
+{
+ vector T = vector(0.0, 0.0, 0.0);
+
+ if (direction_type == "uv_map") {
+ getattribute(attr_name, T);
+ }
+ else if (direction_type == "radial") {
+ point generated;
+
+ if (!getattribute("geom:generated", generated))
+ generated = P;
+
+ if (axis == "x")
+ T = vector(0.0, -(generated[2] - 0.5), (generated[1] - 0.5));
+ else if (axis == "y")
+ T = vector(-(generated[2] - 0.5), 0.0, (generated[0] - 0.5));
+ else
+ T = vector(-(generated[1] - 0.5), (generated[0] - 0.5), 0.0);
+ }
+
+ T = transform("object", "world", T);
+ Tangent = cross(NormalIn, normalize(cross(T, NormalIn)));
+}
diff --git a/intern/cycles/kernel/osl/shaders/node_texture_coordinate.osl b/intern/cycles/kernel/osl/shaders/node_texture_coordinate.osl
new file mode 100644
index 00000000000..9cdb925dbfa
--- /dev/null
+++ b/intern/cycles/kernel/osl/shaders/node_texture_coordinate.osl
@@ -0,0 +1,99 @@
+/*
+ * 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 "stdcycles.h"
+
+shader node_texture_coordinate(
+ normal NormalIn = N,
+ int is_background = 0,
+ int is_volume = 0,
+ int from_dupli = 0,
+ int use_transform = 0,
+ string bump_offset = "center",
+ matrix object_itfm = matrix(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
+
+ output point Generated = point(0.0, 0.0, 0.0),
+ output point UV = point(0.0, 0.0, 0.0),
+ output point Object = point(0.0, 0.0, 0.0),
+ output point Camera = point(0.0, 0.0, 0.0),
+ output point Window = point(0.0, 0.0, 0.0),
+ output normal Normal = normal(0.0, 0.0, 0.0),
+ output point Reflection = point(0.0, 0.0, 0.0))
+{
+ if (is_background) {
+ Generated = P;
+ UV = point(0.0, 0.0, 0.0);
+ Object = P;
+ point Pcam = transform("camera", "world", point(0, 0, 0));
+ Camera = transform("camera", P + Pcam);
+ getattribute("NDC", Window);
+ Normal = NormalIn;
+ Reflection = I;
+ }
+ else {
+ if (from_dupli) {
+ getattribute("geom:dupli_generated", Generated);
+ getattribute("geom:dupli_uv", UV);
+ }
+ else if (is_volume) {
+ Generated = transform("object", P);
+
+ matrix tfm;
+ if (getattribute("geom:generated_transform", tfm))
+ Generated = transform(tfm, Generated);
+
+ getattribute("geom:uv", UV);
+ }
+ else {
+ if (!getattribute("geom:generated", Generated)) {
+ Generated = transform("object", P);
+ }
+ getattribute("geom:uv", UV);
+ }
+
+ if (use_transform) {
+ Object = transform(object_itfm, P);
+ }
+ else {
+ Object = transform("object", P);
+ }
+ Camera = transform("camera", P);
+ Window = transform("NDC", P);
+ Normal = transform("world", "object", NormalIn);
+ Reflection = -reflect(I, NormalIn);
+ }
+
+ if (bump_offset == "dx") {
+ if (!from_dupli) {
+ Generated += Dx(Generated);
+ UV += Dx(UV);
+ }
+ Object += Dx(Object);
+ Camera += Dx(Camera);
+ Window += Dx(Window);
+ }
+ else if (bump_offset == "dy") {
+ if (!from_dupli) {
+ Generated += Dy(Generated);
+ UV += Dy(UV);
+ }
+ Object += Dy(Object);
+ Camera += Dy(Camera);
+ Window += Dy(Window);
+ }
+
+ Window[2] = 0.0;
+}
diff --git a/intern/cycles/kernel/osl/shaders/node_toon_bsdf.osl b/intern/cycles/kernel/osl/shaders/node_toon_bsdf.osl
new file mode 100644
index 00000000000..4a44730c70c
--- /dev/null
+++ b/intern/cycles/kernel/osl/shaders/node_toon_bsdf.osl
@@ -0,0 +1,30 @@
+/*
+ * 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 "stdcycles.h"
+
+shader node_toon_bsdf(color Color = 0.8,
+ string component = "diffuse",
+ float Size = 0.5,
+ float Smooth = 0.0,
+ normal Normal = N,
+ output closure color BSDF = 0)
+{
+ if (component == "diffuse")
+ BSDF = Color * diffuse_toon(Normal, Size, Smooth);
+ else if (component == "glossy")
+ BSDF = Color * glossy_toon(Normal, Size, Smooth);
+}
diff --git a/intern/cycles/kernel/osl/shaders/node_translucent_bsdf.osl b/intern/cycles/kernel/osl/shaders/node_translucent_bsdf.osl
new file mode 100644
index 00000000000..23a562bf34d
--- /dev/null
+++ b/intern/cycles/kernel/osl/shaders/node_translucent_bsdf.osl
@@ -0,0 +1,22 @@
+/*
+ * 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 "stdcycles.h"
+
+shader node_translucent_bsdf(color Color = 0.8, normal Normal = N, output closure color BSDF = 0)
+{
+ BSDF = Color * translucent(Normal);
+}
diff --git a/intern/cycles/kernel/osl/shaders/node_transparent_bsdf.osl b/intern/cycles/kernel/osl/shaders/node_transparent_bsdf.osl
new file mode 100644
index 00000000000..eb737a05c41
--- /dev/null
+++ b/intern/cycles/kernel/osl/shaders/node_transparent_bsdf.osl
@@ -0,0 +1,22 @@
+/*
+ * 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 "stdcycles.h"
+
+shader node_transparent_bsdf(color Color = 0.8, normal Normal = N, output closure color BSDF = 0)
+{
+ BSDF = Color * transparent();
+}
diff --git a/intern/cycles/kernel/osl/shaders/node_uv_map.osl b/intern/cycles/kernel/osl/shaders/node_uv_map.osl
new file mode 100644
index 00000000000..88d8c5ba394
--- /dev/null
+++ b/intern/cycles/kernel/osl/shaders/node_uv_map.osl
@@ -0,0 +1,44 @@
+/*
+ * 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 "stdcycles.h"
+
+shader node_uv_map(int from_dupli = 0,
+ string attribute = "",
+ string bump_offset = "center",
+ output point UV = point(0.0, 0.0, 0.0))
+{
+ if (from_dupli) {
+ getattribute("geom:dupli_uv", UV);
+ }
+ else {
+ if (attribute == "")
+ getattribute("geom:uv", UV);
+ else
+ getattribute(attribute, UV);
+ }
+
+ if (bump_offset == "dx") {
+ if (!from_dupli) {
+ UV += Dx(UV);
+ }
+ }
+ else if (bump_offset == "dy") {
+ if (!from_dupli) {
+ UV += Dy(UV);
+ }
+ }
+}
diff --git a/intern/cycles/kernel/osl/shaders/node_value.osl b/intern/cycles/kernel/osl/shaders/node_value.osl
new file mode 100644
index 00000000000..13197b9a27a
--- /dev/null
+++ b/intern/cycles/kernel/osl/shaders/node_value.osl
@@ -0,0 +1,29 @@
+/*
+ * 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 "stdcycles.h"
+
+shader node_value(float value_value = 0.0,
+ vector vector_value = vector(0.0, 0.0, 0.0),
+ color color_value = 0.0,
+ output float Value = 0.0,
+ output vector Vector = vector(0.0, 0.0, 0.0),
+ output color Color = 0.0)
+{
+ Value = value_value;
+ Vector = vector_value;
+ Color = color_value;
+}
diff --git a/intern/cycles/kernel/osl/shaders/node_vector_curves.osl b/intern/cycles/kernel/osl/shaders/node_vector_curves.osl
new file mode 100644
index 00000000000..9d3a2b82b0a
--- /dev/null
+++ b/intern/cycles/kernel/osl/shaders/node_vector_curves.osl
@@ -0,0 +1,39 @@
+/*
+ * 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_ramp_util.h"
+#include "stdcycles.h"
+
+shader node_vector_curves(color ramp[] = {0.0},
+ float min_x = 0.0,
+ float max_x = 1.0,
+
+ vector VectorIn = vector(0.0, 0.0, 0.0),
+ float Fac = 0.0,
+ output vector VectorOut = vector(0.0, 0.0, 0.0))
+{
+ vector c = (VectorIn - vector(min_x, min_x, min_x)) / (max_x - min_x);
+
+ color r = rgb_ramp_lookup(ramp, c[0], 1, 1);
+ color g = rgb_ramp_lookup(ramp, c[0], 1, 1);
+ color b = rgb_ramp_lookup(ramp, c[0], 1, 1);
+
+ VectorOut[0] = r[0];
+ VectorOut[1] = g[1];
+ VectorOut[2] = b[2];
+
+ VectorOut = mix(VectorIn, VectorOut, Fac);
+}
diff --git a/intern/cycles/kernel/osl/shaders/node_vector_displacement.osl b/intern/cycles/kernel/osl/shaders/node_vector_displacement.osl
new file mode 100644
index 00000000000..7cd9c2a37f2
--- /dev/null
+++ b/intern/cycles/kernel/osl/shaders/node_vector_displacement.osl
@@ -0,0 +1,58 @@
+/*
+ * 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 "stdcycles.h"
+
+shader node_vector_displacement(color Vector = color(0.0, 0.0, 0.0),
+ float Midlevel = 0.0,
+ float Scale = 1.0,
+ string space = "tangent",
+ string attr_name = "geom:tangent",
+ string attr_sign_name = "geom:tangent_sign",
+ output vector Displacement = vector(0.0, 0.0, 0.0))
+{
+ vector offset = (Vector - vector(Midlevel)) * Scale;
+
+ if (space == "tangent") {
+ /* Tangent space. */
+ vector N_object = normalize(transform("world", "object", N));
+
+ vector T_object;
+ if (getattribute(attr_name, T_object)) {
+ T_object = normalize(T_object);
+ }
+ else {
+ T_object = normalize(dPdu);
+ }
+
+ vector B_object = normalize(cross(N_object, T_object));
+ float tangent_sign;
+ if (getattribute(attr_sign_name, tangent_sign)) {
+ B_object *= tangent_sign;
+ }
+
+ Displacement = T_object * offset[0] + N_object * offset[1] + B_object * offset[2];
+ }
+ else {
+ /* Object or world space. */
+ Displacement = offset;
+ }
+
+ if (space != "world") {
+ /* Tangent or object space. */
+ Displacement = transform("object", "world", Displacement);
+ }
+}
diff --git a/intern/cycles/kernel/osl/shaders/node_vector_math.osl b/intern/cycles/kernel/osl/shaders/node_vector_math.osl
new file mode 100644
index 00000000000..c08d75b99ef
--- /dev/null
+++ b/intern/cycles/kernel/osl/shaders/node_vector_math.osl
@@ -0,0 +1,112 @@
+/*
+ * 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_math.h"
+#include "stdcycles.h"
+
+shader node_vector_math(string math_type = "add",
+ vector Vector1 = vector(0.0, 0.0, 0.0),
+ vector Vector2 = vector(0.0, 0.0, 0.0),
+ vector Vector3 = vector(0.0, 0.0, 0.0),
+ float Scale = 1.0,
+ output float Value = 0.0,
+ output vector Vector = vector(0.0, 0.0, 0.0))
+{
+ if (math_type == "add") {
+ Vector = Vector1 + Vector2;
+ }
+ else if (math_type == "subtract") {
+ Vector = Vector1 - Vector2;
+ }
+ else if (math_type == "multiply") {
+ Vector = Vector1 * Vector2;
+ }
+ else if (math_type == "divide") {
+ Vector = safe_divide(Vector1, Vector2);
+ }
+ else if (math_type == "cross_product") {
+ Vector = cross(Vector1, Vector2);
+ }
+ else if (math_type == "project") {
+ Vector = project(Vector1, Vector2);
+ }
+ else if (math_type == "reflect") {
+ Vector = reflect(Vector1, normalize(Vector2));
+ }
+ else if (math_type == "refract") {
+ Vector = refract(Vector1, normalize(Vector2), Scale);
+ }
+ else if (math_type == "faceforward") {
+ Vector = compatible_faceforward(Vector1, Vector2, Vector3);
+ }
+ else if (math_type == "multiply_add") {
+ Vector = Vector1 * Vector2 + Vector3;
+ }
+ else if (math_type == "dot_product") {
+ Value = dot(Vector1, Vector2);
+ }
+ else if (math_type == "distance") {
+ Value = distance(Vector1, Vector2);
+ }
+ else if (math_type == "length") {
+ Value = length(Vector1);
+ }
+ else if (math_type == "scale") {
+ Vector = Vector1 * Scale;
+ }
+ else if (math_type == "normalize") {
+ Vector = normalize(Vector1);
+ }
+ else if (math_type == "snap") {
+ Vector = snap(Vector1, Vector2);
+ }
+ else if (math_type == "floor") {
+ Vector = floor(Vector1);
+ }
+ else if (math_type == "ceil") {
+ Vector = ceil(Vector1);
+ }
+ else if (math_type == "modulo") {
+ Vector = fmod(Vector1, Vector2);
+ }
+ else if (math_type == "wrap") {
+ Vector = wrap(Vector1, Vector2, Vector3);
+ }
+ else if (math_type == "fraction") {
+ Vector = Vector1 - floor(Vector1);
+ }
+ else if (math_type == "absolute") {
+ Vector = abs(Vector1);
+ }
+ else if (math_type == "minimum") {
+ Vector = min(Vector1, Vector2);
+ }
+ else if (math_type == "maximum") {
+ Vector = max(Vector1, Vector2);
+ }
+ else if (math_type == "sine") {
+ Vector = sin(Vector1);
+ }
+ else if (math_type == "cosine") {
+ Vector = cos(Vector1);
+ }
+ else if (math_type == "tangent") {
+ Vector = tan(Vector1);
+ }
+ else {
+ warning("%s", "Unknown vector math operator!");
+ }
+}
diff --git a/intern/cycles/kernel/osl/shaders/node_vector_rotate.osl b/intern/cycles/kernel/osl/shaders/node_vector_rotate.osl
new file mode 100644
index 00000000000..e99bf7d81b0
--- /dev/null
+++ b/intern/cycles/kernel/osl/shaders/node_vector_rotate.osl
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2011-2020 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_math.h"
+#include "stdcycles.h"
+
+shader node_vector_rotate(int invert = 0,
+ string rotate_type = "axis",
+ vector VectorIn = vector(0.0, 0.0, 0.0),
+ point Center = point(0.0, 0.0, 0.0),
+ point Rotation = point(0.0, 0.0, 0.0),
+ vector Axis = vector(0.0, 0.0, 1.0),
+ float Angle = 0.0,
+ output vector VectorOut = vector(0.0, 0.0, 0.0))
+{
+ if (rotate_type == "euler_xyz") {
+ matrix rmat = (invert) ? transpose(euler_to_mat(Rotation)) : euler_to_mat(Rotation);
+ VectorOut = transform(rmat, VectorIn - Center) + Center;
+ }
+ else {
+ float a = (invert) ? -Angle : Angle;
+ if (rotate_type == "x_axis") {
+ VectorOut = rotate(VectorIn - Center, a, point(0.0), vector(1.0, 0.0, 0.0)) + Center;
+ }
+ else if (rotate_type == "y_axis") {
+ VectorOut = rotate(VectorIn - Center, a, point(0.0), vector(0.0, 1.0, 0.0)) + Center;
+ }
+ else if (rotate_type == "z_axis") {
+ VectorOut = rotate(VectorIn - Center, a, point(0.0), vector(0.0, 0.0, 1.0)) + Center;
+ }
+ else { // axis
+ VectorOut = (length(Axis) != 0.0) ? rotate(VectorIn - Center, a, point(0.0), Axis) + Center :
+ VectorIn;
+ }
+ }
+}
diff --git a/intern/cycles/kernel/osl/shaders/node_vector_transform.osl b/intern/cycles/kernel/osl/shaders/node_vector_transform.osl
new file mode 100644
index 00000000000..b71c6ec4824
--- /dev/null
+++ b/intern/cycles/kernel/osl/shaders/node_vector_transform.osl
@@ -0,0 +1,34 @@
+/*
+ * 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 "stdcycles.h"
+
+shader node_vector_transform(string transform_type = "vector",
+ string convert_from = "world",
+ string convert_to = "object",
+ vector VectorIn = vector(0.0, 0.0, 0.0),
+ output vector VectorOut = vector(0.0, 0.0, 0.0))
+{
+ if (transform_type == "vector" || transform_type == "normal") {
+ VectorOut = transform(convert_from, convert_to, VectorIn);
+ if (transform_type == "normal")
+ VectorOut = normalize(VectorOut);
+ }
+ else if (transform_type == "point") {
+ point Point = (point)VectorIn;
+ VectorOut = transform(convert_from, convert_to, Point);
+ }
+}
diff --git a/intern/cycles/kernel/osl/shaders/node_velvet_bsdf.osl b/intern/cycles/kernel/osl/shaders/node_velvet_bsdf.osl
new file mode 100644
index 00000000000..299acef35ee
--- /dev/null
+++ b/intern/cycles/kernel/osl/shaders/node_velvet_bsdf.osl
@@ -0,0 +1,28 @@
+/*
+ * 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_fresnel.h"
+#include "stdcycles.h"
+
+shader node_velvet_bsdf(color Color = 0.8,
+ float Sigma = 0.0,
+ normal Normal = N,
+ output closure color BSDF = 0)
+{
+ float sigma = clamp(Sigma, 0.0, 1.0);
+
+ BSDF = Color * ashikhmin_velvet(Normal, sigma);
+}
diff --git a/intern/cycles/kernel/osl/shaders/node_vertex_color.osl b/intern/cycles/kernel/osl/shaders/node_vertex_color.osl
new file mode 100644
index 00000000000..ffaf7a2f720
--- /dev/null
+++ b/intern/cycles/kernel/osl/shaders/node_vertex_color.osl
@@ -0,0 +1,50 @@
+/*
+ * 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 "stdcycles.h"
+
+shader node_vertex_color(string bump_offset = "center",
+ string layer_name = "",
+ output color Color = 0.0,
+ output float Alpha = 0.0)
+{
+ float vertex_color[4];
+ string vertex_color_layer;
+
+ if (layer_name == "") {
+ vertex_color_layer = "geom:vertex_color";
+ }
+ else {
+ vertex_color_layer = layer_name;
+ }
+
+ if (getattribute(vertex_color_layer, vertex_color)) {
+ Color = color(vertex_color[0], vertex_color[1], vertex_color[2]);
+ Alpha = vertex_color[3];
+
+ if (bump_offset == "dx") {
+ Color += Dx(Color);
+ Alpha += Dx(Alpha);
+ }
+ else if (bump_offset == "dy") {
+ Color += Dy(Color);
+ Alpha += Dy(Alpha);
+ }
+ }
+ else {
+ warning("%s", "Invalid attribute.");
+ }
+}
diff --git a/intern/cycles/kernel/osl/shaders/node_voronoi_texture.osl b/intern/cycles/kernel/osl/shaders/node_voronoi_texture.osl
new file mode 100644
index 00000000000..de6c697fc85
--- /dev/null
+++ b/intern/cycles/kernel/osl/shaders/node_voronoi_texture.osl
@@ -0,0 +1,1031 @@
+/*
+ * 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_hash.h"
+#include "stdcycles.h"
+#include "vector2.h"
+#include "vector4.h"
+
+#define vector3 point
+
+/* **** Distance Functions **** */
+
+float distance(float a, float b)
+{
+ return abs(a - b);
+}
+
+float distance(vector2 a, vector2 b)
+{
+ return length(a - b);
+}
+
+float distance(vector4 a, vector4 b)
+{
+ return length(a - b);
+}
+
+/* **** Safe Division **** */
+
+vector2 safe_divide(vector2 a, float b)
+{
+ return vector2((b != 0.0) ? a.x / b : 0.0, (b != 0.0) ? a.y / b : 0.0);
+}
+
+vector4 safe_divide(vector4 a, float b)
+{
+ return vector4((b != 0.0) ? a.x / b : 0.0,
+ (b != 0.0) ? a.y / b : 0.0,
+ (b != 0.0) ? a.z / b : 0.0,
+ (b != 0.0) ? a.w / b : 0.0);
+}
+
+/*
+ * Original code is under the MIT License, Copyright (c) 2013 Inigo Quilez.
+ *
+ * Smooth Voronoi:
+ * - https://wiki.blender.org/wiki/User:OmarSquircleArt/GSoC2019/Documentation/Smooth_Voronoi
+ *
+ * Distance To Edge based on:
+ *
+ * - https://www.iquilezles.org/www/articles/voronoilines/voronoilines.htm
+ * - https://www.shadertoy.com/view/ldl3W8
+ *
+ * With optimization to change -2..2 scan window to -1..1 for better performance,
+ * as explained in https://www.shadertoy.com/view/llG3zy.
+ */
+
+/* **** 1D Voronoi **** */
+
+float voronoi_distance(float a, float b, string metric, float exponent)
+{
+ return abs(a - b);
+}
+
+void voronoi_f1_1d(float w,
+ float exponent,
+ float randomness,
+ string metric,
+ output float outDistance,
+ output color outColor,
+ output float outW)
+{
+ float cellPosition = floor(w);
+ float localPosition = w - cellPosition;
+
+ float minDistance = 8.0;
+ float targetOffset, targetPosition;
+ for (int i = -1; i <= 1; i++) {
+ float cellOffset = float(i);
+ float pointPosition = cellOffset + hash_float_to_float(cellPosition + cellOffset) * randomness;
+ float distanceToPoint = voronoi_distance(pointPosition, localPosition, metric, exponent);
+ if (distanceToPoint < minDistance) {
+ targetOffset = cellOffset;
+ minDistance = distanceToPoint;
+ targetPosition = pointPosition;
+ }
+ }
+ outDistance = minDistance;
+ outColor = hash_float_to_color(cellPosition + targetOffset);
+ outW = targetPosition + cellPosition;
+}
+
+void voronoi_smooth_f1_1d(float w,
+ float smoothness,
+ float exponent,
+ float randomness,
+ string metric,
+ output float outDistance,
+ output color outColor,
+ output float outW)
+{
+ float cellPosition = floor(w);
+ float localPosition = w - cellPosition;
+
+ float smoothDistance = 8.0;
+ float smoothPosition = 0.0;
+ color smoothColor = color(0.0);
+ for (int i = -2; i <= 2; i++) {
+ float cellOffset = float(i);
+ float pointPosition = cellOffset + hash_float_to_float(cellPosition + cellOffset) * randomness;
+ float distanceToPoint = voronoi_distance(pointPosition, localPosition, metric, exponent);
+ float h = smoothstep(0.0, 1.0, 0.5 + 0.5 * (smoothDistance - distanceToPoint) / smoothness);
+ float correctionFactor = smoothness * h * (1.0 - h);
+ smoothDistance = mix(smoothDistance, distanceToPoint, h) - correctionFactor;
+ correctionFactor /= 1.0 + 3.0 * smoothness;
+ color cellColor = hash_float_to_color(cellPosition + cellOffset);
+ smoothColor = mix(smoothColor, cellColor, h) - correctionFactor;
+ smoothPosition = mix(smoothPosition, pointPosition, h) - correctionFactor;
+ }
+ outDistance = smoothDistance;
+ outColor = smoothColor;
+ outW = cellPosition + smoothPosition;
+}
+
+void voronoi_f2_1d(float w,
+ float exponent,
+ float randomness,
+ string metric,
+ output float outDistance,
+ output color outColor,
+ output float outW)
+{
+ float cellPosition = floor(w);
+ float localPosition = w - cellPosition;
+
+ float distanceF1 = 8.0;
+ float distanceF2 = 8.0;
+ float offsetF1 = 0.0;
+ float positionF1 = 0.0;
+ float offsetF2, positionF2;
+ for (int i = -1; i <= 1; i++) {
+ float cellOffset = float(i);
+ float pointPosition = cellOffset + hash_float_to_float(cellPosition + cellOffset) * randomness;
+ float distanceToPoint = voronoi_distance(pointPosition, localPosition, metric, exponent);
+ if (distanceToPoint < distanceF1) {
+ distanceF2 = distanceF1;
+ distanceF1 = distanceToPoint;
+ offsetF2 = offsetF1;
+ offsetF1 = cellOffset;
+ positionF2 = positionF1;
+ positionF1 = pointPosition;
+ }
+ else if (distanceToPoint < distanceF2) {
+ distanceF2 = distanceToPoint;
+ offsetF2 = cellOffset;
+ positionF2 = pointPosition;
+ }
+ }
+ outDistance = distanceF2;
+ outColor = hash_float_to_color(cellPosition + offsetF2);
+ outW = positionF2 + cellPosition;
+}
+
+void voronoi_distance_to_edge_1d(float w, float randomness, output float outDistance)
+{
+ float cellPosition = floor(w);
+ float localPosition = w - cellPosition;
+
+ float midPointPosition = hash_float_to_float(cellPosition) * randomness;
+ float leftPointPosition = -1.0 + hash_float_to_float(cellPosition - 1.0) * randomness;
+ float rightPointPosition = 1.0 + hash_float_to_float(cellPosition + 1.0) * randomness;
+ float distanceToMidLeft = distance((midPointPosition + leftPointPosition) / 2.0, localPosition);
+ float distanceToMidRight = distance((midPointPosition + rightPointPosition) / 2.0,
+ localPosition);
+
+ outDistance = min(distanceToMidLeft, distanceToMidRight);
+}
+
+void voronoi_n_sphere_radius_1d(float w, float randomness, output float outRadius)
+{
+ float cellPosition = floor(w);
+ float localPosition = w - cellPosition;
+
+ float closestPoint;
+ float closestPointOffset;
+ float minDistance = 8.0;
+ for (int i = -1; i <= 1; i++) {
+ float cellOffset = float(i);
+ float pointPosition = cellOffset + hash_float_to_float(cellPosition + cellOffset) * randomness;
+ float distanceToPoint = distance(pointPosition, localPosition);
+ if (distanceToPoint < minDistance) {
+ minDistance = distanceToPoint;
+ closestPoint = pointPosition;
+ closestPointOffset = cellOffset;
+ }
+ }
+
+ minDistance = 8.0;
+ float closestPointToClosestPoint;
+ for (int i = -1; i <= 1; i++) {
+ if (i == 0) {
+ continue;
+ }
+ float cellOffset = float(i) + closestPointOffset;
+ float pointPosition = cellOffset + hash_float_to_float(cellPosition + cellOffset) * randomness;
+ float distanceToPoint = distance(closestPoint, pointPosition);
+ if (distanceToPoint < minDistance) {
+ minDistance = distanceToPoint;
+ closestPointToClosestPoint = pointPosition;
+ }
+ }
+ outRadius = distance(closestPointToClosestPoint, closestPoint) / 2.0;
+}
+
+/* **** 2D Voronoi **** */
+
+float voronoi_distance(vector2 a, vector2 b, string metric, float exponent)
+{
+ if (metric == "euclidean") {
+ return distance(a, b);
+ }
+ else if (metric == "manhattan") {
+ return abs(a.x - b.x) + abs(a.y - b.y);
+ }
+ else if (metric == "chebychev") {
+ return max(abs(a.x - b.x), abs(a.y - b.y));
+ }
+ else if (metric == "minkowski") {
+ return pow(pow(abs(a.x - b.x), exponent) + pow(abs(a.y - b.y), exponent), 1.0 / exponent);
+ }
+ else {
+ return 0.0;
+ }
+}
+
+void voronoi_f1_2d(vector2 coord,
+ float exponent,
+ float randomness,
+ string metric,
+ output float outDistance,
+ output color outColor,
+ output vector2 outPosition)
+{
+ vector2 cellPosition = floor(coord);
+ vector2 localPosition = coord - cellPosition;
+
+ float minDistance = 8.0;
+ vector2 targetOffset, targetPosition;
+ for (int j = -1; j <= 1; j++) {
+ for (int i = -1; i <= 1; i++) {
+ vector2 cellOffset = vector2(i, j);
+ vector2 pointPosition = cellOffset +
+ hash_vector2_to_vector2(cellPosition + cellOffset) * randomness;
+ float distanceToPoint = voronoi_distance(pointPosition, localPosition, metric, exponent);
+ if (distanceToPoint < minDistance) {
+ targetOffset = cellOffset;
+ minDistance = distanceToPoint;
+ targetPosition = pointPosition;
+ }
+ }
+ }
+ outDistance = minDistance;
+ outColor = hash_vector2_to_color(cellPosition + targetOffset);
+ outPosition = targetPosition + cellPosition;
+}
+
+void voronoi_smooth_f1_2d(vector2 coord,
+ float smoothness,
+ float exponent,
+ float randomness,
+ string metric,
+ output float outDistance,
+ output color outColor,
+ output vector2 outPosition)
+{
+ vector2 cellPosition = floor(coord);
+ vector2 localPosition = coord - cellPosition;
+
+ float smoothDistance = 8.0;
+ color smoothColor = color(0.0);
+ vector2 smoothPosition = vector2(0.0, 0.0);
+ for (int j = -2; j <= 2; j++) {
+ for (int i = -2; i <= 2; i++) {
+ vector2 cellOffset = vector2(i, j);
+ vector2 pointPosition = cellOffset +
+ hash_vector2_to_vector2(cellPosition + cellOffset) * randomness;
+ float distanceToPoint = voronoi_distance(pointPosition, localPosition, metric, exponent);
+ float h = smoothstep(0.0, 1.0, 0.5 + 0.5 * (smoothDistance - distanceToPoint) / smoothness);
+ float correctionFactor = smoothness * h * (1.0 - h);
+ smoothDistance = mix(smoothDistance, distanceToPoint, h) - correctionFactor;
+ correctionFactor /= 1.0 + 3.0 * smoothness;
+ color cellColor = hash_vector2_to_color(cellPosition + cellOffset);
+ smoothColor = mix(smoothColor, cellColor, h) - correctionFactor;
+ smoothPosition = mix(smoothPosition, pointPosition, h) - correctionFactor;
+ }
+ }
+ outDistance = smoothDistance;
+ outColor = smoothColor;
+ outPosition = cellPosition + smoothPosition;
+}
+
+void voronoi_f2_2d(vector2 coord,
+ float exponent,
+ float randomness,
+ string metric,
+ output float outDistance,
+ output color outColor,
+ output vector2 outPosition)
+{
+ vector2 cellPosition = floor(coord);
+ vector2 localPosition = coord - cellPosition;
+
+ float distanceF1 = 8.0;
+ float distanceF2 = 8.0;
+ vector2 offsetF1 = vector2(0.0, 0.0);
+ vector2 positionF1 = vector2(0.0, 0.0);
+ vector2 offsetF2, positionF2;
+ for (int j = -1; j <= 1; j++) {
+ for (int i = -1; i <= 1; i++) {
+ vector2 cellOffset = vector2(i, j);
+ vector2 pointPosition = cellOffset +
+ hash_vector2_to_vector2(cellPosition + cellOffset) * randomness;
+ float distanceToPoint = voronoi_distance(pointPosition, localPosition, metric, exponent);
+ if (distanceToPoint < distanceF1) {
+ distanceF2 = distanceF1;
+ distanceF1 = distanceToPoint;
+ offsetF2 = offsetF1;
+ offsetF1 = cellOffset;
+ positionF2 = positionF1;
+ positionF1 = pointPosition;
+ }
+ else if (distanceToPoint < distanceF2) {
+ distanceF2 = distanceToPoint;
+ offsetF2 = cellOffset;
+ positionF2 = pointPosition;
+ }
+ }
+ }
+ outDistance = distanceF2;
+ outColor = hash_vector2_to_color(cellPosition + offsetF2);
+ outPosition = positionF2 + cellPosition;
+}
+
+void voronoi_distance_to_edge_2d(vector2 coord, float randomness, output float outDistance)
+{
+ vector2 cellPosition = floor(coord);
+ vector2 localPosition = coord - cellPosition;
+
+ vector2 vectorToClosest;
+ float minDistance = 8.0;
+ for (int j = -1; j <= 1; j++) {
+ for (int i = -1; i <= 1; i++) {
+ vector2 cellOffset = vector2(i, j);
+ vector2 vectorToPoint = cellOffset +
+ hash_vector2_to_vector2(cellPosition + cellOffset) * randomness -
+ localPosition;
+ float distanceToPoint = dot(vectorToPoint, vectorToPoint);
+ if (distanceToPoint < minDistance) {
+ minDistance = distanceToPoint;
+ vectorToClosest = vectorToPoint;
+ }
+ }
+ }
+
+ minDistance = 8.0;
+ for (int j = -1; j <= 1; j++) {
+ for (int i = -1; i <= 1; i++) {
+ vector2 cellOffset = vector2(i, j);
+ vector2 vectorToPoint = cellOffset +
+ hash_vector2_to_vector2(cellPosition + cellOffset) * randomness -
+ localPosition;
+ vector2 perpendicularToEdge = vectorToPoint - vectorToClosest;
+ if (dot(perpendicularToEdge, perpendicularToEdge) > 0.0001) {
+ float distanceToEdge = dot((vectorToClosest + vectorToPoint) / 2.0,
+ normalize(perpendicularToEdge));
+ minDistance = min(minDistance, distanceToEdge);
+ }
+ }
+ }
+ outDistance = minDistance;
+}
+
+void voronoi_n_sphere_radius_2d(vector2 coord, float randomness, output float outRadius)
+{
+ vector2 cellPosition = floor(coord);
+ vector2 localPosition = coord - cellPosition;
+
+ vector2 closestPoint;
+ vector2 closestPointOffset;
+ float minDistance = 8.0;
+ for (int j = -1; j <= 1; j++) {
+ for (int i = -1; i <= 1; i++) {
+ vector2 cellOffset = vector2(i, j);
+ vector2 pointPosition = cellOffset +
+ hash_vector2_to_vector2(cellPosition + cellOffset) * randomness;
+ float distanceToPoint = distance(pointPosition, localPosition);
+ if (distanceToPoint < minDistance) {
+ minDistance = distanceToPoint;
+ closestPoint = pointPosition;
+ closestPointOffset = cellOffset;
+ }
+ }
+ }
+
+ minDistance = 8.0;
+ vector2 closestPointToClosestPoint;
+ for (int j = -1; j <= 1; j++) {
+ for (int i = -1; i <= 1; i++) {
+ if (i == 0 && j == 0) {
+ continue;
+ }
+ vector2 cellOffset = vector2(i, j) + closestPointOffset;
+ vector2 pointPosition = cellOffset +
+ hash_vector2_to_vector2(cellPosition + cellOffset) * randomness;
+ float distanceToPoint = distance(closestPoint, pointPosition);
+ if (distanceToPoint < minDistance) {
+ minDistance = distanceToPoint;
+ closestPointToClosestPoint = pointPosition;
+ }
+ }
+ }
+ outRadius = distance(closestPointToClosestPoint, closestPoint) / 2.0;
+}
+
+/* **** 3D Voronoi **** */
+
+float voronoi_distance(vector3 a, vector3 b, string metric, float exponent)
+{
+ if (metric == "euclidean") {
+ return distance(a, b);
+ }
+ else if (metric == "manhattan") {
+ return abs(a[0] - b[0]) + abs(a[1] - b[1]) + abs(a[2] - b[2]);
+ }
+ else if (metric == "chebychev") {
+ return max(abs(a[0] - b[0]), max(abs(a[1] - b[1]), abs(a[2] - b[2])));
+ }
+ else if (metric == "minkowski") {
+ return pow(pow(abs(a[0] - b[0]), exponent) + pow(abs(a[1] - b[1]), exponent) +
+ pow(abs(a[2] - b[2]), exponent),
+ 1.0 / exponent);
+ }
+ else {
+ return 0.0;
+ }
+}
+
+void voronoi_f1_3d(vector3 coord,
+ float exponent,
+ float randomness,
+ string metric,
+ output float outDistance,
+ output color outColor,
+ output vector3 outPosition)
+{
+ vector3 cellPosition = floor(coord);
+ vector3 localPosition = coord - cellPosition;
+
+ float minDistance = 8.0;
+ vector3 targetOffset, targetPosition;
+ for (int k = -1; k <= 1; k++) {
+ for (int j = -1; j <= 1; j++) {
+ for (int i = -1; i <= 1; i++) {
+ vector3 cellOffset = vector3(i, j, k);
+ vector3 pointPosition = cellOffset +
+ hash_vector3_to_vector3(cellPosition + cellOffset) * randomness;
+ float distanceToPoint = voronoi_distance(pointPosition, localPosition, metric, exponent);
+ if (distanceToPoint < minDistance) {
+ targetOffset = cellOffset;
+ minDistance = distanceToPoint;
+ targetPosition = pointPosition;
+ }
+ }
+ }
+ }
+ outDistance = minDistance;
+ outColor = hash_vector3_to_color(cellPosition + targetOffset);
+ outPosition = targetPosition + cellPosition;
+}
+
+void voronoi_smooth_f1_3d(vector3 coord,
+ float smoothness,
+ float exponent,
+ float randomness,
+ string metric,
+ output float outDistance,
+ output color outColor,
+ output vector3 outPosition)
+{
+ vector3 cellPosition = floor(coord);
+ vector3 localPosition = coord - cellPosition;
+
+ float smoothDistance = 8.0;
+ color smoothColor = color(0.0);
+ vector3 smoothPosition = vector3(0.0);
+ for (int k = -2; k <= 2; k++) {
+ for (int j = -2; j <= 2; j++) {
+ for (int i = -2; i <= 2; i++) {
+ vector3 cellOffset = vector3(i, j, k);
+ vector3 pointPosition = cellOffset +
+ hash_vector3_to_vector3(cellPosition + cellOffset) * randomness;
+ float distanceToPoint = voronoi_distance(pointPosition, localPosition, metric, exponent);
+ float h = smoothstep(
+ 0.0, 1.0, 0.5 + 0.5 * (smoothDistance - distanceToPoint) / smoothness);
+ float correctionFactor = smoothness * h * (1.0 - h);
+ smoothDistance = mix(smoothDistance, distanceToPoint, h) - correctionFactor;
+ correctionFactor /= 1.0 + 3.0 * smoothness;
+ color cellColor = hash_vector3_to_color(cellPosition + cellOffset);
+ smoothColor = mix(smoothColor, cellColor, h) - correctionFactor;
+ smoothPosition = mix(smoothPosition, pointPosition, h) - correctionFactor;
+ }
+ }
+ }
+ outDistance = smoothDistance;
+ outColor = smoothColor;
+ outPosition = cellPosition + smoothPosition;
+}
+
+void voronoi_f2_3d(vector3 coord,
+ float exponent,
+ float randomness,
+ string metric,
+ output float outDistance,
+ output color outColor,
+ output vector3 outPosition)
+{
+ vector3 cellPosition = floor(coord);
+ vector3 localPosition = coord - cellPosition;
+
+ float distanceF1 = 8.0;
+ float distanceF2 = 8.0;
+ vector3 offsetF1 = vector3(0.0);
+ vector3 positionF1 = vector3(0.0);
+ vector3 offsetF2, positionF2;
+ for (int k = -1; k <= 1; k++) {
+ for (int j = -1; j <= 1; j++) {
+ for (int i = -1; i <= 1; i++) {
+ vector3 cellOffset = vector3(i, j, k);
+ vector3 pointPosition = cellOffset +
+ hash_vector3_to_vector3(cellPosition + cellOffset) * randomness;
+ float distanceToPoint = voronoi_distance(pointPosition, localPosition, metric, exponent);
+ if (distanceToPoint < distanceF1) {
+ distanceF2 = distanceF1;
+ distanceF1 = distanceToPoint;
+ offsetF2 = offsetF1;
+ offsetF1 = cellOffset;
+ positionF2 = positionF1;
+ positionF1 = pointPosition;
+ }
+ else if (distanceToPoint < distanceF2) {
+ distanceF2 = distanceToPoint;
+ offsetF2 = cellOffset;
+ positionF2 = pointPosition;
+ }
+ }
+ }
+ }
+ outDistance = distanceF2;
+ outColor = hash_vector3_to_color(cellPosition + offsetF2);
+ outPosition = positionF2 + cellPosition;
+}
+
+void voronoi_distance_to_edge_3d(vector3 coord, float randomness, output float outDistance)
+{
+ vector3 cellPosition = floor(coord);
+ vector3 localPosition = coord - cellPosition;
+
+ vector3 vectorToClosest;
+ float minDistance = 8.0;
+ for (int k = -1; k <= 1; k++) {
+ for (int j = -1; j <= 1; j++) {
+ for (int i = -1; i <= 1; i++) {
+ vector3 cellOffset = vector3(i, j, k);
+ vector3 vectorToPoint = cellOffset +
+ hash_vector3_to_vector3(cellPosition + cellOffset) * randomness -
+ localPosition;
+ float distanceToPoint = dot(vectorToPoint, vectorToPoint);
+ if (distanceToPoint < minDistance) {
+ minDistance = distanceToPoint;
+ vectorToClosest = vectorToPoint;
+ }
+ }
+ }
+ }
+
+ minDistance = 8.0;
+ for (int k = -1; k <= 1; k++) {
+ for (int j = -1; j <= 1; j++) {
+ for (int i = -1; i <= 1; i++) {
+ vector3 cellOffset = vector3(i, j, k);
+ vector3 vectorToPoint = cellOffset +
+ hash_vector3_to_vector3(cellPosition + cellOffset) * randomness -
+ localPosition;
+ vector3 perpendicularToEdge = vectorToPoint - vectorToClosest;
+ if (dot(perpendicularToEdge, perpendicularToEdge) > 0.0001) {
+ float distanceToEdge = dot((vectorToClosest + vectorToPoint) / 2.0,
+ normalize((vector)perpendicularToEdge));
+ minDistance = min(minDistance, distanceToEdge);
+ }
+ }
+ }
+ }
+ outDistance = minDistance;
+}
+
+void voronoi_n_sphere_radius_3d(vector3 coord, float randomness, output float outRadius)
+{
+ vector3 cellPosition = floor(coord);
+ vector3 localPosition = coord - cellPosition;
+
+ vector3 closestPoint;
+ vector3 closestPointOffset;
+ float minDistance = 8.0;
+ for (int k = -1; k <= 1; k++) {
+ for (int j = -1; j <= 1; j++) {
+ for (int i = -1; i <= 1; i++) {
+ vector3 cellOffset = vector3(i, j, k);
+ vector3 pointPosition = cellOffset +
+ hash_vector3_to_vector3(cellPosition + cellOffset) * randomness;
+ float distanceToPoint = distance(pointPosition, localPosition);
+ if (distanceToPoint < minDistance) {
+ minDistance = distanceToPoint;
+ closestPoint = pointPosition;
+ closestPointOffset = cellOffset;
+ }
+ }
+ }
+ }
+
+ minDistance = 8.0;
+ vector3 closestPointToClosestPoint;
+ for (int k = -1; k <= 1; k++) {
+ for (int j = -1; j <= 1; j++) {
+ for (int i = -1; i <= 1; i++) {
+ if (i == 0 && j == 0 && k == 0) {
+ continue;
+ }
+ vector3 cellOffset = vector3(i, j, k) + closestPointOffset;
+ vector3 pointPosition = cellOffset +
+ hash_vector3_to_vector3(cellPosition + cellOffset) * randomness;
+ float distanceToPoint = distance(closestPoint, pointPosition);
+ if (distanceToPoint < minDistance) {
+ minDistance = distanceToPoint;
+ closestPointToClosestPoint = pointPosition;
+ }
+ }
+ }
+ }
+ outRadius = distance(closestPointToClosestPoint, closestPoint) / 2.0;
+}
+
+/* **** 4D Voronoi **** */
+
+float voronoi_distance(vector4 a, vector4 b, string metric, float exponent)
+{
+ if (metric == "euclidean") {
+ return distance(a, b);
+ }
+ else if (metric == "manhattan") {
+ return abs(a.x - b.x) + abs(a.y - b.y) + abs(a.z - b.z) + abs(a.w - b.w);
+ }
+ else if (metric == "chebychev") {
+ return max(abs(a.x - b.x), max(abs(a.y - b.y), max(abs(a.z - b.z), abs(a.w - b.w))));
+ }
+ else if (metric == "minkowski") {
+ return pow(pow(abs(a.x - b.x), exponent) + pow(abs(a.y - b.y), exponent) +
+ pow(abs(a.z - b.z), exponent) + pow(abs(a.w - b.w), exponent),
+ 1.0 / exponent);
+ }
+ else {
+ return 0.0;
+ }
+}
+
+void voronoi_f1_4d(vector4 coord,
+ float exponent,
+ float randomness,
+ string metric,
+ output float outDistance,
+ output color outColor,
+ output vector4 outPosition)
+{
+ vector4 cellPosition = floor(coord);
+ vector4 localPosition = coord - cellPosition;
+
+ float minDistance = 8.0;
+ vector4 targetOffset, targetPosition;
+ for (int u = -1; u <= 1; u++) {
+ for (int k = -1; k <= 1; k++) {
+ for (int j = -1; j <= 1; j++) {
+ for (int i = -1; i <= 1; i++) {
+ vector4 cellOffset = vector4(i, j, k, u);
+ vector4 pointPosition = cellOffset +
+ hash_vector4_to_vector4(cellPosition + cellOffset) * randomness;
+ float distanceToPoint = voronoi_distance(pointPosition, localPosition, metric, exponent);
+ if (distanceToPoint < minDistance) {
+ targetOffset = cellOffset;
+ minDistance = distanceToPoint;
+ targetPosition = pointPosition;
+ }
+ }
+ }
+ }
+ }
+ outDistance = minDistance;
+ outColor = hash_vector4_to_color(cellPosition + targetOffset);
+ outPosition = targetPosition + cellPosition;
+}
+
+void voronoi_smooth_f1_4d(vector4 coord,
+ float smoothness,
+ float exponent,
+ float randomness,
+ string metric,
+ output float outDistance,
+ output color outColor,
+ output vector4 outPosition)
+{
+ vector4 cellPosition = floor(coord);
+ vector4 localPosition = coord - cellPosition;
+
+ float smoothDistance = 8.0;
+ color smoothColor = color(0.0);
+ vector4 smoothPosition = vector4(0.0, 0.0, 0.0, 0.0);
+ for (int u = -2; u <= 2; u++) {
+ for (int k = -2; k <= 2; k++) {
+ for (int j = -2; j <= 2; j++) {
+ for (int i = -2; i <= 2; i++) {
+ vector4 cellOffset = vector4(i, j, k, u);
+ vector4 pointPosition = cellOffset +
+ hash_vector4_to_vector4(cellPosition + cellOffset) * randomness;
+ float distanceToPoint = voronoi_distance(pointPosition, localPosition, metric, exponent);
+ float h = smoothstep(
+ 0.0, 1.0, 0.5 + 0.5 * (smoothDistance - distanceToPoint) / smoothness);
+ float correctionFactor = smoothness * h * (1.0 - h);
+ smoothDistance = mix(smoothDistance, distanceToPoint, h) - correctionFactor;
+ correctionFactor /= 1.0 + 3.0 * smoothness;
+ color cellColor = hash_vector4_to_color(cellPosition + cellOffset);
+ smoothColor = mix(smoothColor, cellColor, h) - correctionFactor;
+ smoothPosition = mix(smoothPosition, pointPosition, h) - correctionFactor;
+ }
+ }
+ }
+ }
+ outDistance = smoothDistance;
+ outColor = smoothColor;
+ outPosition = cellPosition + smoothPosition;
+}
+
+void voronoi_f2_4d(vector4 coord,
+ float exponent,
+ float randomness,
+ string metric,
+ output float outDistance,
+ output color outColor,
+ output vector4 outPosition)
+{
+ vector4 cellPosition = floor(coord);
+ vector4 localPosition = coord - cellPosition;
+
+ float distanceF1 = 8.0;
+ float distanceF2 = 8.0;
+ vector4 offsetF1 = vector4(0.0, 0.0, 0.0, 0.0);
+ vector4 positionF1 = vector4(0.0, 0.0, 0.0, 0.0);
+ vector4 offsetF2, positionF2;
+ for (int u = -1; u <= 1; u++) {
+ for (int k = -1; k <= 1; k++) {
+ for (int j = -1; j <= 1; j++) {
+ for (int i = -1; i <= 1; i++) {
+ vector4 cellOffset = vector4(i, j, k, u);
+ vector4 pointPosition = cellOffset +
+ hash_vector4_to_vector4(cellPosition + cellOffset) * randomness;
+ float distanceToPoint = voronoi_distance(pointPosition, localPosition, metric, exponent);
+ if (distanceToPoint < distanceF1) {
+ distanceF2 = distanceF1;
+ distanceF1 = distanceToPoint;
+ offsetF2 = offsetF1;
+ offsetF1 = cellOffset;
+ positionF2 = positionF1;
+ positionF1 = pointPosition;
+ }
+ else if (distanceToPoint < distanceF2) {
+ distanceF2 = distanceToPoint;
+ offsetF2 = cellOffset;
+ positionF2 = pointPosition;
+ }
+ }
+ }
+ }
+ }
+ outDistance = distanceF2;
+ outColor = hash_vector4_to_color(cellPosition + offsetF2);
+ outPosition = positionF2 + cellPosition;
+}
+
+void voronoi_distance_to_edge_4d(vector4 coord, float randomness, output float outDistance)
+{
+ vector4 cellPosition = floor(coord);
+ vector4 localPosition = coord - cellPosition;
+
+ vector4 vectorToClosest;
+ float minDistance = 8.0;
+ for (int u = -1; u <= 1; u++) {
+ for (int k = -1; k <= 1; k++) {
+ for (int j = -1; j <= 1; j++) {
+ for (int i = -1; i <= 1; i++) {
+ vector4 cellOffset = vector4(i, j, k, u);
+ vector4 vectorToPoint = cellOffset +
+ hash_vector4_to_vector4(cellPosition + cellOffset) * randomness -
+ localPosition;
+ float distanceToPoint = dot(vectorToPoint, vectorToPoint);
+ if (distanceToPoint < minDistance) {
+ minDistance = distanceToPoint;
+ vectorToClosest = vectorToPoint;
+ }
+ }
+ }
+ }
+ }
+
+ minDistance = 8.0;
+ for (int u = -1; u <= 1; u++) {
+ for (int k = -1; k <= 1; k++) {
+ for (int j = -1; j <= 1; j++) {
+ for (int i = -1; i <= 1; i++) {
+ vector4 cellOffset = vector4(i, j, k, u);
+ vector4 vectorToPoint = cellOffset +
+ hash_vector4_to_vector4(cellPosition + cellOffset) * randomness -
+ localPosition;
+ vector4 perpendicularToEdge = vectorToPoint - vectorToClosest;
+ if (dot(perpendicularToEdge, perpendicularToEdge) > 0.0001) {
+ float distanceToEdge = dot((vectorToClosest + vectorToPoint) / 2.0,
+ normalize(perpendicularToEdge));
+ minDistance = min(minDistance, distanceToEdge);
+ }
+ }
+ }
+ }
+ }
+ outDistance = minDistance;
+}
+
+void voronoi_n_sphere_radius_4d(vector4 coord, float randomness, output float outRadius)
+{
+ vector4 cellPosition = floor(coord);
+ vector4 localPosition = coord - cellPosition;
+
+ vector4 closestPoint;
+ vector4 closestPointOffset;
+ float minDistance = 8.0;
+ for (int u = -1; u <= 1; u++) {
+ for (int k = -1; k <= 1; k++) {
+ for (int j = -1; j <= 1; j++) {
+ for (int i = -1; i <= 1; i++) {
+ vector4 cellOffset = vector4(i, j, k, u);
+ vector4 pointPosition = cellOffset +
+ hash_vector4_to_vector4(cellPosition + cellOffset) * randomness;
+ float distanceToPoint = distance(pointPosition, localPosition);
+ if (distanceToPoint < minDistance) {
+ minDistance = distanceToPoint;
+ closestPoint = pointPosition;
+ closestPointOffset = cellOffset;
+ }
+ }
+ }
+ }
+ }
+
+ minDistance = 8.0;
+ vector4 closestPointToClosestPoint;
+ for (int u = -1; u <= 1; u++) {
+ for (int k = -1; k <= 1; k++) {
+ for (int j = -1; j <= 1; j++) {
+ for (int i = -1; i <= 1; i++) {
+ if (i == 0 && j == 0 && k == 0 && u == 0) {
+ continue;
+ }
+ vector4 cellOffset = vector4(i, j, k, u) + closestPointOffset;
+ vector4 pointPosition = cellOffset +
+ hash_vector4_to_vector4(cellPosition + cellOffset) * randomness;
+ float distanceToPoint = distance(closestPoint, pointPosition);
+ if (distanceToPoint < minDistance) {
+ minDistance = distanceToPoint;
+ closestPointToClosestPoint = pointPosition;
+ }
+ }
+ }
+ }
+ }
+ outRadius = distance(closestPointToClosestPoint, closestPoint) / 2.0;
+}
+
+shader node_voronoi_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",
+ string feature = "f1",
+ string metric = "euclidean",
+ vector3 Vector = P,
+ float WIn = 0.0,
+ float Scale = 5.0,
+ float Smoothness = 5.0,
+ float Exponent = 1.0,
+ float Randomness = 1.0,
+ output float Distance = 0.0,
+ output color Color = 0.0,
+ output vector3 Position = P,
+ output float WOut = 0.0,
+ output float Radius = 0.0)
+{
+ float randomness = clamp(Randomness, 0.0, 1.0);
+ float smoothness = clamp(Smoothness / 2.0, 0.0, 0.5);
+
+ vector3 coord = Vector;
+ if (use_mapping)
+ coord = transform(mapping, coord);
+
+ float w = WIn * Scale;
+ coord *= Scale;
+
+ if (dimensions == "1D") {
+ if (feature == "f1") {
+ voronoi_f1_1d(w, Exponent, randomness, metric, Distance, Color, WOut);
+ }
+ else if (feature == "smooth_f1") {
+ voronoi_smooth_f1_1d(w, smoothness, Exponent, randomness, metric, Distance, Color, WOut);
+ }
+ else if (feature == "f2") {
+ voronoi_f2_1d(w, Exponent, randomness, metric, Distance, Color, WOut);
+ }
+ else if (feature == "distance_to_edge") {
+ voronoi_distance_to_edge_1d(w, randomness, Distance);
+ }
+ else if (feature == "n_sphere_radius") {
+ voronoi_n_sphere_radius_1d(w, randomness, Radius);
+ }
+ else {
+ error("Unknown feature!");
+ }
+ WOut = (Scale != 0.0) ? WOut / Scale : 0.0;
+ }
+ else if (dimensions == "2D") {
+ vector2 coord2D = vector2(coord[0], coord[1]);
+ vector2 outPosition2D;
+ if (feature == "f1") {
+ voronoi_f1_2d(coord2D, Exponent, randomness, metric, Distance, Color, outPosition2D);
+ }
+ else if (feature == "smooth_f1") {
+ voronoi_smooth_f1_2d(
+ coord2D, smoothness, Exponent, randomness, metric, Distance, Color, outPosition2D);
+ }
+ else if (feature == "f2") {
+ voronoi_f2_2d(coord2D, Exponent, randomness, metric, Distance, Color, outPosition2D);
+ }
+ else if (feature == "distance_to_edge") {
+ voronoi_distance_to_edge_2d(coord2D, randomness, Distance);
+ }
+ else if (feature == "n_sphere_radius") {
+ voronoi_n_sphere_radius_2d(coord2D, randomness, Radius);
+ }
+ else {
+ error("Unknown feature!");
+ }
+ outPosition2D = safe_divide(outPosition2D, Scale);
+ Position = vector3(outPosition2D.x, outPosition2D.y, 0.0);
+ }
+ else if (dimensions == "3D") {
+ if (feature == "f1") {
+ voronoi_f1_3d(coord, Exponent, randomness, metric, Distance, Color, Position);
+ }
+ else if (feature == "smooth_f1") {
+ voronoi_smooth_f1_3d(
+ coord, smoothness, Exponent, randomness, metric, Distance, Color, Position);
+ }
+ else if (feature == "f2") {
+ voronoi_f2_3d(coord, Exponent, randomness, metric, Distance, Color, Position);
+ }
+ else if (feature == "distance_to_edge") {
+ voronoi_distance_to_edge_3d(coord, randomness, Distance);
+ }
+ else if (feature == "n_sphere_radius") {
+ voronoi_n_sphere_radius_3d(coord, randomness, Radius);
+ }
+ else {
+ error("Unknown feature!");
+ }
+ Position = (Scale != 0.0) ? Position / Scale : vector3(0.0);
+ }
+ else if (dimensions == "4D") {
+ vector4 coord4D = vector4(coord[0], coord[1], coord[2], w);
+ vector4 outPosition4D;
+ if (feature == "f1") {
+ voronoi_f1_4d(coord4D, Exponent, randomness, metric, Distance, Color, outPosition4D);
+ }
+ else if (feature == "smooth_f1") {
+ voronoi_smooth_f1_4d(
+ coord4D, smoothness, Exponent, randomness, metric, Distance, Color, outPosition4D);
+ }
+ else if (feature == "f2") {
+ voronoi_f2_4d(coord4D, Exponent, randomness, metric, Distance, Color, outPosition4D);
+ }
+ else if (feature == "distance_to_edge") {
+ voronoi_distance_to_edge_4d(coord4D, randomness, Distance);
+ }
+ else if (feature == "n_sphere_radius") {
+ voronoi_n_sphere_radius_4d(coord4D, randomness, Radius);
+ }
+ else {
+ error("Unknown feature!");
+ }
+ outPosition4D = safe_divide(outPosition4D, Scale);
+ Position = vector3(outPosition4D.x, outPosition4D.y, outPosition4D.z);
+ WOut = outPosition4D.w;
+ }
+ else {
+ error("Unknown dimension!");
+ }
+}
diff --git a/intern/cycles/kernel/osl/shaders/node_voxel_texture.osl b/intern/cycles/kernel/osl/shaders/node_voxel_texture.osl
new file mode 100644
index 00000000000..14489298367
--- /dev/null
+++ b/intern/cycles/kernel/osl/shaders/node_voxel_texture.osl
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2011-2015 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 "stdcycles.h"
+
+shader node_voxel_texture(string filename = "",
+ string interpolation = "linear",
+ int use_mapping = 0,
+ matrix mapping = matrix(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
+ point Vector = P,
+ output float Density = 0,
+ output color Color = 0)
+{
+ point p = Vector;
+ if (use_mapping) {
+ p = transform(mapping, p);
+ }
+ else {
+ p = transform("object", Vector);
+ matrix tfm;
+ if (getattribute("geom:generated_transform", tfm))
+ p = transform(tfm, p);
+ }
+ if (p[0] < 0.0 || p[1] < 0.0 || p[2] < 0.0 || p[0] > 1.0 || p[1] > 1.0 || p[2] > 1.0) {
+ Density = 0;
+ Color = color(0, 0, 0);
+ }
+ else {
+ Color = (color)texture3d(
+ filename, p, "wrap", "periodic", "interp", interpolation, "alpha", Density);
+ }
+}
diff --git a/intern/cycles/kernel/osl/shaders/node_wave_texture.osl b/intern/cycles/kernel/osl/shaders/node_wave_texture.osl
new file mode 100644
index 00000000000..71d81dff7ec
--- /dev/null
+++ b/intern/cycles/kernel/osl/shaders/node_wave_texture.osl
@@ -0,0 +1,119 @@
+/*
+ * 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"
+
+/* Wave */
+
+float wave(point p_input,
+ string type,
+ string bands_direction,
+ string rings_direction,
+ string profile,
+ float distortion,
+ float detail,
+ float dscale,
+ float droughness,
+ float phase)
+{
+ /* Prevent precision issues on unit coordinates. */
+ point p = (p_input + 0.000001) * 0.999999;
+
+ float n = 0.0;
+
+ if (type == "bands") {
+ if (bands_direction == "x") {
+ n = p[0] * 20.0;
+ }
+ else if (bands_direction == "y") {
+ n = p[1] * 20.0;
+ }
+ else if (bands_direction == "z") {
+ n = p[2] * 20.0;
+ }
+ else { /* diagonal */
+ n = (p[0] + p[1] + p[2]) * 10.0;
+ }
+ }
+ else if (type == "rings") {
+ point rp = p;
+ if (rings_direction == "x") {
+ rp *= point(0.0, 1.0, 1.0);
+ }
+ else if (rings_direction == "y") {
+ rp *= point(1.0, 0.0, 1.0);
+ }
+ else if (rings_direction == "z") {
+ rp *= point(1.0, 1.0, 0.0);
+ }
+ /* else: "spherical" */
+
+ n = length(rp) * 20.0;
+ }
+
+ n += phase;
+
+ if (distortion != 0.0) {
+ n = n + (distortion * (fractal_noise(p * dscale, detail, droughness) * 2.0 - 1.0));
+ }
+
+ if (profile == "sine") {
+ return 0.5 + 0.5 * sin(n - M_PI_2);
+ }
+ else if (profile == "saw") {
+ n /= M_2PI;
+ return n - floor(n);
+ }
+ else { /* profile tri */
+ n /= M_2PI;
+ return abs(n - floor(n + 0.5)) * 2.0;
+ }
+}
+
+shader node_wave_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 wave_type = "bands",
+ string bands_direction = "x",
+ string rings_direction = "x",
+ string profile = "sine",
+ float Scale = 5.0,
+ float Distortion = 0.0,
+ float Detail = 2.0,
+ float DetailScale = 1.0,
+ float DetailRoughness = 0.5,
+ float PhaseOffset = 0.0,
+ point Vector = P,
+ output float Fac = 0.0,
+ output color Color = 0.0)
+{
+ point p = Vector;
+
+ if (use_mapping)
+ p = transform(mapping, p);
+
+ Fac = wave(p * Scale,
+ wave_type,
+ bands_direction,
+ rings_direction,
+ profile,
+ Distortion,
+ Detail,
+ DetailScale,
+ DetailRoughness,
+ PhaseOffset);
+ Color = Fac;
+}
diff --git a/intern/cycles/kernel/osl/shaders/node_wavelength.osl b/intern/cycles/kernel/osl/shaders/node_wavelength.osl
new file mode 100644
index 00000000000..f484c4b4788
--- /dev/null
+++ b/intern/cycles/kernel/osl/shaders/node_wavelength.osl
@@ -0,0 +1,22 @@
+/*
+ * 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 "stdcycles.h"
+
+shader node_wavelength(float Wavelength = 500.0, output color Color = 0.0)
+{
+ Color = wavelength_color(Wavelength);
+}
diff --git a/intern/cycles/kernel/osl/shaders/node_white_noise_texture.osl b/intern/cycles/kernel/osl/shaders/node_white_noise_texture.osl
new file mode 100644
index 00000000000..94735a019d5
--- /dev/null
+++ b/intern/cycles/kernel/osl/shaders/node_white_noise_texture.osl
@@ -0,0 +1,49 @@
+/*
+ * 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_hash.h"
+#include "stdcycles.h"
+#include "vector2.h"
+#include "vector4.h"
+
+#define vector3 point
+
+shader node_white_noise_texture(string dimensions = "3D",
+ point Vector = point(0.0, 0.0, 0.0),
+ float W = 0.0,
+ output float Value = 0.0,
+ output color Color = 0.0)
+{
+ if (dimensions == "1D") {
+ Value = noise("hash", W);
+ Color = hash_float_to_color(W);
+ }
+ else if (dimensions == "2D") {
+ Value = noise("hash", Vector[0], Vector[1]);
+ Color = hash_vector2_to_color(vector2(Vector[0], Vector[1]));
+ }
+ else if (dimensions == "3D") {
+ Value = noise("hash", Vector);
+ Color = hash_vector3_to_color(vector3(Vector[0], Vector[1], Vector[2]));
+ }
+ else if (dimensions == "4D") {
+ Value = noise("hash", Vector, W);
+ Color = hash_vector4_to_color(vector4(Vector[0], Vector[1], Vector[2], W));
+ }
+ else {
+ warning("%s", "Unknown dimension!");
+ }
+}
diff --git a/intern/cycles/kernel/osl/shaders/node_wireframe.osl b/intern/cycles/kernel/osl/shaders/node_wireframe.osl
new file mode 100644
index 00000000000..673a451c928
--- /dev/null
+++ b/intern/cycles/kernel/osl/shaders/node_wireframe.osl
@@ -0,0 +1,40 @@
+/*
+ * 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 "oslutil.h"
+#include "stdcycles.h"
+
+shader node_wireframe(string bump_offset = "center",
+ int use_pixel_size = 0,
+ float Size = 0.01,
+ output float Fac = 0.0)
+{
+ Fac = wireframe("triangles", Size, use_pixel_size);
+ /* TODO(sergey): Since we can't use autodiff here we do algebraic
+ * calculation of derivatives by definition. We could probably
+ * optimize this a bit by doing some extra calculation in wireframe().
+ */
+ if (bump_offset == "dx") {
+ point dx = Dx(P);
+ P -= dx;
+ Fac += (Fac - wireframe("triangles", Size, use_pixel_size)) / length(dx);
+ }
+ else if (bump_offset == "dy") {
+ point dy = Dy(P);
+ P -= dy;
+ Fac += (Fac - wireframe("triangles", Size, use_pixel_size)) / length(dy);
+ }
+}
diff --git a/intern/cycles/kernel/osl/shaders/stdcycles.h b/intern/cycles/kernel/osl/shaders/stdcycles.h
new file mode 100644
index 00000000000..dd604da68ce
--- /dev/null
+++ b/intern/cycles/kernel/osl/shaders/stdcycles.h
@@ -0,0 +1,150 @@
+/////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al. All Rights Reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// * Neither the name of Sony Pictures Imageworks nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef CCL_STDCYCLESOSL_H
+#define CCL_STDCYCLESOSL_H
+
+#include "stdosl.h"
+
+// Declaration of built-in functions and closures, stdosl.h does not make
+// these available so we have to redefine them.
+#define BUILTIN [[int builtin = 1]]
+#define BUILTIN_DERIV [[ int builtin = 1, int deriv = 1 ]]
+
+closure color diffuse_ramp(normal N, color colors[8]) BUILTIN;
+closure color phong_ramp(normal N, float exponent, color colors[8]) BUILTIN;
+closure color diffuse_toon(normal N, float size, float smooth) BUILTIN;
+closure color glossy_toon(normal N, float size, float smooth) BUILTIN;
+closure color microfacet_ggx(normal N, float ag) BUILTIN;
+closure color microfacet_ggx_aniso(normal N, vector T, float ax, float ay) BUILTIN;
+closure color microfacet_ggx_refraction(normal N, float ag, float eta) BUILTIN;
+closure color microfacet_multi_ggx(normal N, float ag, color C) BUILTIN;
+closure color microfacet_multi_ggx_aniso(normal N, vector T, float ax, float ay, color C) BUILTIN;
+closure color microfacet_multi_ggx_glass(normal N, float ag, float eta, color C) BUILTIN;
+closure color microfacet_ggx_fresnel(normal N, float ag, float eta, color C, color Cspec0) BUILTIN;
+closure color microfacet_ggx_aniso_fresnel(
+ normal N, vector T, float ax, float ay, float eta, color C, color Cspec0) BUILTIN;
+closure color
+microfacet_multi_ggx_fresnel(normal N, float ag, float eta, color C, color Cspec0) BUILTIN;
+closure color microfacet_multi_ggx_aniso_fresnel(
+ normal N, vector T, float ax, float ay, float eta, color C, color Cspec0) BUILTIN;
+closure color
+microfacet_multi_ggx_glass_fresnel(normal N, float ag, float eta, color C, color Cspec0) BUILTIN;
+closure color microfacet_beckmann(normal N, float ab) BUILTIN;
+closure color microfacet_beckmann_aniso(normal N, vector T, float ax, float ay) BUILTIN;
+closure color microfacet_beckmann_refraction(normal N, float ab, float eta) BUILTIN;
+closure color ashikhmin_shirley(normal N, vector T, float ax, float ay) BUILTIN;
+closure color ashikhmin_velvet(normal N, float sigma) BUILTIN;
+closure color ambient_occlusion() BUILTIN;
+closure color principled_diffuse(normal N, float roughness) BUILTIN;
+closure color principled_sheen(normal N) BUILTIN;
+closure color principled_clearcoat(normal N, float clearcoat, float clearcoat_roughness) BUILTIN;
+
+// BSSRDF
+closure color bssrdf(string method, normal N, vector radius, color albedo) BUILTIN;
+
+// Hair
+closure color
+hair_reflection(normal N, float roughnessu, float roughnessv, vector T, float offset) BUILTIN;
+closure color
+hair_transmission(normal N, float roughnessu, float roughnessv, vector T, float offset) BUILTIN;
+closure color principled_hair(normal N,
+ color sigma,
+ float roughnessu,
+ float roughnessv,
+ float coat,
+ float alpha,
+ float eta) BUILTIN;
+
+// Volume
+closure color henyey_greenstein(float g) BUILTIN;
+closure color absorption() BUILTIN;
+
+normal ensure_valid_reflection(normal Ng, vector I, normal N)
+{
+ /* The implementation here mirrors the one in kernel_montecarlo.h,
+ * check there for an explanation of the algorithm. */
+
+ float sqr(float x)
+ {
+ return x * x;
+ }
+
+ vector R = 2 * dot(N, I) * N - I;
+
+ float threshold = min(0.9 * dot(Ng, I), 0.01);
+ if (dot(Ng, R) >= threshold) {
+ return N;
+ }
+
+ float NdotNg = dot(N, Ng);
+ vector X = normalize(N - NdotNg * Ng);
+
+ float Ix = dot(I, X), Iz = dot(I, Ng);
+ float Ix2 = sqr(Ix), Iz2 = sqr(Iz);
+ float a = Ix2 + Iz2;
+
+ float b = sqrt(Ix2 * (a - sqr(threshold)));
+ float c = Iz * threshold + a;
+
+ float fac = 0.5 / a;
+ float N1_z2 = fac * (b + c), N2_z2 = fac * (-b + c);
+ int valid1 = (N1_z2 > 1e-5) && (N1_z2 <= (1.0 + 1e-5));
+ int valid2 = (N2_z2 > 1e-5) && (N2_z2 <= (1.0 + 1e-5));
+
+ float N_new_x, N_new_z;
+ if (valid1 && valid2) {
+ float N1_x = sqrt(1.0 - N1_z2), N1_z = sqrt(N1_z2);
+ float N2_x = sqrt(1.0 - N2_z2), N2_z = sqrt(N2_z2);
+
+ float R1 = 2 * (N1_x * Ix + N1_z * Iz) * N1_z - Iz;
+ float R2 = 2 * (N2_x * Ix + N2_z * Iz) * N2_z - Iz;
+
+ valid1 = (R1 >= 1e-5);
+ valid2 = (R2 >= 1e-5);
+ if (valid1 && valid2) {
+ N_new_x = (R1 < R2) ? N1_x : N2_x;
+ N_new_z = (R1 < R2) ? N1_z : N2_z;
+ }
+ else {
+ N_new_x = (R1 > R2) ? N1_x : N2_x;
+ N_new_z = (R1 > R2) ? N1_z : N2_z;
+ }
+ }
+ else if (valid1 || valid2) {
+ float Nz2 = valid1 ? N1_z2 : N2_z2;
+ N_new_x = sqrt(1.0 - Nz2);
+ N_new_z = sqrt(Nz2);
+ }
+ else {
+ return Ng;
+ }
+
+ return N_new_x * X + N_new_z * Ng;
+}
+
+#endif /* CCL_STDOSL_H */