diff options
Diffstat (limited to 'intern/cycles/kernel/osl')
108 files changed, 7804 insertions, 19 deletions
diff --git a/intern/cycles/kernel/osl/CMakeLists.txt b/intern/cycles/kernel/osl/CMakeLists.txt index 6cdc7367fbb..7be1b7129e0 100644 --- a/intern/cycles/kernel/osl/CMakeLists.txt +++ b/intern/cycles/kernel/osl/CMakeLists.txt @@ -39,7 +39,7 @@ set(HEADER_SRC ) set(LIB - cycles_render + cycles_scene ${OSL_LIBRARIES} ${OPENIMAGEIO_LIBRARIES} diff --git a/intern/cycles/kernel/osl/bsdf_diffuse_ramp.cpp b/intern/cycles/kernel/osl/bsdf_diffuse_ramp.cpp index 45216f4c74d..2ec7f14c0fa 100644 --- a/intern/cycles/kernel/osl/bsdf_diffuse_ramp.cpp +++ b/intern/cycles/kernel/osl/bsdf_diffuse_ramp.cpp @@ -39,7 +39,6 @@ // clang-format off #include "kernel/kernel_types.h" -#include "kernel/kernel_montecarlo.h" #include "kernel/closure/alloc.h" #include "kernel/closure/bsdf_diffuse_ramp.h" // clang-format on diff --git a/intern/cycles/kernel/osl/osl_bssrdf.cpp b/intern/cycles/kernel/osl/osl_bssrdf.cpp index 5bf7b604498..3b8661ce45d 100644 --- a/intern/cycles/kernel/osl/osl_bssrdf.cpp +++ b/intern/cycles/kernel/osl/osl_bssrdf.cpp @@ -37,7 +37,6 @@ // clang-format off #include "kernel/kernel_types.h" -#include "kernel/kernel_montecarlo.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/osl_closures.cpp index a2062046ae8..89bab35b60b 100644 --- a/intern/cycles/kernel/osl/osl_closures.cpp +++ b/intern/cycles/kernel/osl/osl_closures.cpp @@ -44,8 +44,6 @@ #include "kernel/device/cpu/globals.h" #include "kernel/kernel_types.h" -#include "kernel/kernel_montecarlo.h" -#include "kernel/kernel_random.h" #include "kernel/closure/alloc.h" #include "kernel/closure/bsdf_util.h" diff --git a/intern/cycles/kernel/osl/osl_services.cpp b/intern/cycles/kernel/osl/osl_services.cpp index cbe1bf1bfc0..56b04fd280e 100644 --- a/intern/cycles/kernel/osl/osl_services.cpp +++ b/intern/cycles/kernel/osl/osl_services.cpp @@ -25,10 +25,10 @@ #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" @@ -44,19 +44,22 @@ #include "kernel/device/cpu/globals.h" #include "kernel/device/cpu/image.h" -#include "kernel/kernel_differential.h" +#include "kernel/util/util_differential.h" #include "kernel/integrator/integrator_state.h" #include "kernel/integrator/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/camera_projection.h" + +#include "kernel/integrator/integrator_path_state.h" +#include "kernel/integrator/integrator_shader_eval.h" + +#include "kernel/util/util_color.h" // clang-format on CCL_NAMESPACE_BEGIN diff --git a/intern/cycles/kernel/osl/osl_shader.cpp b/intern/cycles/kernel/osl/osl_shader.cpp index fba207e7230..6426a09b33d 100644 --- a/intern/cycles/kernel/osl/osl_shader.cpp +++ b/intern/cycles/kernel/osl/osl_shader.cpp @@ -20,7 +20,6 @@ #include "kernel/device/cpu/compat.h" #include "kernel/device/cpu/globals.h" -#include "kernel/kernel_montecarlo.h" #include "kernel/kernel_types.h" #include "kernel/geom/geom_object.h" @@ -33,9 +32,7 @@ #include "kernel/osl/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/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 */ |