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

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLukas Stockner <lukas.stockner@freenet.de>2018-06-14 23:54:42 +0300
committerLukas Stockner <lukas.stockner@freenet.de>2018-06-14 23:54:42 +0300
commit27de412ca8de4edad99a46ebdb8aadd7003e42a6 (patch)
tree4e2659e3490519021195ba626de74adc4813e825 /intern/cycles
parent525be2f579c994777328bd7ac206be4769d3e6a4 (diff)
parent3ee606621cf53a2a4897e534e7e04d3632f419f8 (diff)
Merge remote-tracking branch 'origin/master' into blender2.8
Diffstat (limited to 'intern/cycles')
-rw-r--r--intern/cycles/CMakeLists.txt8
-rw-r--r--intern/cycles/app/CMakeLists.txt4
-rw-r--r--intern/cycles/blender/addon/properties.py18
-rw-r--r--intern/cycles/blender/addon/ui.py8
-rw-r--r--intern/cycles/blender/addon/version_update.py13
-rw-r--r--intern/cycles/blender/blender_curves.cpp16
-rw-r--r--intern/cycles/blender/blender_mesh.cpp12
-rw-r--r--intern/cycles/blender/blender_object.cpp17
-rw-r--r--intern/cycles/blender/blender_session.cpp4
-rw-r--r--intern/cycles/cmake/external_libs.cmake6
-rw-r--r--intern/cycles/kernel/kernel_color.h38
-rw-r--r--intern/cycles/kernel/kernel_emission.h4
-rw-r--r--intern/cycles/kernel/kernel_film.h6
-rw-r--r--intern/cycles/kernel/kernel_light.h41
-rw-r--r--intern/cycles/kernel/kernel_types.h10
-rw-r--r--intern/cycles/kernel/kernels/cpu/kernel_cpu_impl.h1
-rw-r--r--intern/cycles/kernel/kernels/cuda/kernel.cu1
-rw-r--r--intern/cycles/kernel/kernels/opencl/kernel.cl1
-rw-r--r--intern/cycles/kernel/osl/osl_services.cpp1
-rw-r--r--intern/cycles/kernel/shaders/node_color.h2
-rw-r--r--intern/cycles/kernel/split/kernel_split_common.h1
-rw-r--r--intern/cycles/kernel/svm/svm.h4
-rw-r--r--intern/cycles/kernel/svm/svm_closure.h2
-rw-r--r--intern/cycles/kernel/svm/svm_convert.h6
-rw-r--r--intern/cycles/kernel/svm/svm_image.h3
-rw-r--r--intern/cycles/kernel/svm/svm_math_util.h2
-rw-r--r--intern/cycles/kernel/svm/svm_sky.h4
-rw-r--r--intern/cycles/kernel/svm/svm_wavelength.h4
-rw-r--r--intern/cycles/render/constant_fold.cpp4
-rw-r--r--intern/cycles/render/constant_fold.h5
-rw-r--r--intern/cycles/render/graph.cpp17
-rw-r--r--intern/cycles/render/graph.h2
-rw-r--r--intern/cycles/render/image.cpp56
-rw-r--r--intern/cycles/render/image.h10
-rw-r--r--intern/cycles/render/light.cpp108
-rw-r--r--intern/cycles/render/nodes.cpp7
-rw-r--r--intern/cycles/render/shader.cpp52
-rw-r--r--intern/cycles/render/shader.h7
-rw-r--r--intern/cycles/test/CMakeLists.txt5
-rw-r--r--intern/cycles/util/util_color.h44
40 files changed, 380 insertions, 174 deletions
diff --git a/intern/cycles/CMakeLists.txt b/intern/cycles/CMakeLists.txt
index 100a52625d1..233bc639fd8 100644
--- a/intern/cycles/CMakeLists.txt
+++ b/intern/cycles/CMakeLists.txt
@@ -326,6 +326,14 @@ if(WITH_CYCLES_NETWORK)
add_definitions(-DWITH_NETWORK)
endif()
+if(WITH_OPENCOLORIO)
+ add_definitions(-DWITH_OCIO)
+ include_directories(
+ SYSTEM
+ ${OPENCOLORIO_INCLUDE_DIRS}
+ )
+endif()
+
if(WITH_CYCLES_STANDALONE OR WITH_CYCLES_NETWORK OR WITH_CYCLES_CUBIN_COMPILER)
add_subdirectory(app)
endif()
diff --git a/intern/cycles/app/CMakeLists.txt b/intern/cycles/app/CMakeLists.txt
index d1f86a5fe7d..cfca45600a5 100644
--- a/intern/cycles/app/CMakeLists.txt
+++ b/intern/cycles/app/CMakeLists.txt
@@ -80,6 +80,10 @@ macro(cycles_target_link_libraries target)
if(WITH_CYCLES_OPENSUBDIV)
target_link_libraries(${target} ${OPENSUBDIV_LIBRARIES})
endif()
+ if(WITH_OPENCOLORIO)
+ link_directories(${OPENCOLORIO_LIBPATH})
+ target_link_libraries(${target} ${OPENCOLORIO_LIBRARIES})
+ endif()
target_link_libraries(
${target}
${OPENIMAGEIO_LIBRARIES}
diff --git a/intern/cycles/blender/addon/properties.py b/intern/cycles/blender/addon/properties.py
index 3b79b6e52fd..df6949f2095 100644
--- a/intern/cycles/blender/addon/properties.py
+++ b/intern/cycles/blender/addon/properties.py
@@ -128,6 +128,12 @@ enum_volume_interpolation = (
('CUBIC', "Cubic", "Smoothed high quality interpolation, but slower")
)
+enum_world_mis = (
+ ('NONE', "None", "Don't sample the background, faster but might cause noise for non-solid backgrounds"),
+ ('AUTOMATIC', "Auto", "Automatically try to determine the best setting"),
+ ('MANUAL', "Manual", "Manually set the resolution of the sampling map, higher values are slower and require more memory but reduce noise")
+ )
+
enum_device_type = (
('CPU', "CPU", "CPU", 0),
('CUDA', "CUDA", "CUDA", 1),
@@ -932,15 +938,15 @@ class CyclesWorldSettings(bpy.types.PropertyGroup):
description="Cycles world settings",
type=cls,
)
- cls.sample_as_light = BoolProperty(
- name="Multiple Importance Sample",
- description="Use multiple importance sampling for the environment, "
- "enabling for non-solid colors is recommended",
- default=True,
+ cls.sampling_method = EnumProperty(
+ name="Sampling method",
+ description="How to sample the background light",
+ items=enum_world_mis,
+ default='AUTOMATIC',
)
cls.sample_map_resolution = IntProperty(
name="Map Resolution",
- description="Importance map size is resolution x resolution; "
+ description="Importance map size is resolution x resolution/2; "
"higher values potentially produce less noise, at the cost of memory and speed",
min=4, max=8192,
default=1024,
diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py
index c5eafe9ebfb..2f9c486367a 100644
--- a/intern/cycles/blender/addon/ui.py
+++ b/intern/cycles/blender/addon/ui.py
@@ -1367,11 +1367,13 @@ class CYCLES_WORLD_PT_settings_surface(CyclesButtonsPanel, Panel):
cworld = world.cycles
col = layout.column()
- col.prop(cworld, "sample_as_light", text="Multiple Importance")
+ col.prop(cworld, "sampling_method", text="Sampling")
sub = col.column()
- sub.active = cworld.sample_as_light
- sub.prop(cworld, "sample_map_resolution")
+ sub.active = cworld.sampling_method != 'NONE'
+ subsub = sub.row(align=True)
+ subsub.active = cworld.sampling_method == 'MANUAL'
+ subsub.prop(cworld, "sample_map_resolution")
if use_branched_path(context):
subsub = sub.column(align=True)
subsub.active = use_sample_all_lights(context)
diff --git a/intern/cycles/blender/addon/version_update.py b/intern/cycles/blender/addon/version_update.py
index 611ba5cae70..2db4def9dcb 100644
--- a/intern/cycles/blender/addon/version_update.py
+++ b/intern/cycles/blender/addon/version_update.py
@@ -377,10 +377,6 @@ def do_versions(self):
for world in bpy.data.worlds:
cworld = world.cycles
- # World MIS
- if not cworld.is_property_set("sample_as_light"):
- cworld.sample_as_light = False
-
# World MIS Samples
if not cworld.is_property_set("samples"):
cworld.samples = 4
@@ -444,3 +440,12 @@ def do_versions(self):
part.tip_radius = cpart.get("tip_width", 0.0)
part.radius_scale = cpart.get("radius_scale", 0.01)
part.use_close_tip = cpart.get("use_closetip", True)
+
+ for world in bpy.data.worlds:
+ cworld = world.cycles
+ # World MIS
+ if not cworld.is_property_set("sampling_method"):
+ if cworld.get("sample_as_light", False):
+ cworld.sampling_method = 'MANUAL'
+ else:
+ cworld.sampling_method = 'NONE'
diff --git a/intern/cycles/blender/blender_curves.cpp b/intern/cycles/blender/blender_curves.cpp
index e9270ee5539..a1fd153b4fd 100644
--- a/intern/cycles/blender/blender_curves.cpp
+++ b/intern/cycles/blender/blender_curves.cpp
@@ -770,17 +770,18 @@ static void ExportCurveTriangleVcol(ParticleCurveData *CData,
for(int curvekey = CData->curve_firstkey[curve]; curvekey < CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1; curvekey++) {
for(int section = 0; section < resol; section++) {
- cdata[vertexindex] = color_float_to_byte(color_srgb_to_scene_linear_v3(CData->curve_vcol[curve]));
+ /* Encode vertex color using the sRGB curve. */
+ cdata[vertexindex] = color_float_to_byte(color_srgb_to_linear_v3(CData->curve_vcol[curve]));
vertexindex++;
- cdata[vertexindex] = color_float_to_byte(color_srgb_to_scene_linear_v3(CData->curve_vcol[curve]));
+ cdata[vertexindex] = color_float_to_byte(color_srgb_to_linear_v3(CData->curve_vcol[curve]));
vertexindex++;
- cdata[vertexindex] = color_float_to_byte(color_srgb_to_scene_linear_v3(CData->curve_vcol[curve]));
+ cdata[vertexindex] = color_float_to_byte(color_srgb_to_linear_v3(CData->curve_vcol[curve]));
vertexindex++;
- cdata[vertexindex] = color_float_to_byte(color_srgb_to_scene_linear_v3(CData->curve_vcol[curve]));
+ cdata[vertexindex] = color_float_to_byte(color_srgb_to_linear_v3(CData->curve_vcol[curve]));
vertexindex++;
- cdata[vertexindex] = color_float_to_byte(color_srgb_to_scene_linear_v3(CData->curve_vcol[curve]));
+ cdata[vertexindex] = color_float_to_byte(color_srgb_to_linear_v3(CData->curve_vcol[curve]));
vertexindex++;
- cdata[vertexindex] = color_float_to_byte(color_srgb_to_scene_linear_v3(CData->curve_vcol[curve]));
+ cdata[vertexindex] = color_float_to_byte(color_srgb_to_linear_v3(CData->curve_vcol[curve]));
vertexindex++;
}
}
@@ -993,9 +994,10 @@ void BlenderSync::sync_curves(Mesh *mesh,
if(fdata) {
size_t i = 0;
+ /* Encode vertex color using the sRGB curve. */
for(size_t curve = 0; curve < CData.curve_vcol.size(); curve++)
if(!(CData.curve_keynum[curve] <= 1 || CData.curve_length[curve] == 0.0f))
- fdata[i++] = color_srgb_to_scene_linear_v3(CData.curve_vcol[curve]);
+ fdata[i++] = color_srgb_to_linear_v3(CData.curve_vcol[curve]);
}
}
}
diff --git a/intern/cycles/blender/blender_mesh.cpp b/intern/cycles/blender/blender_mesh.cpp
index 6fe650f3699..b7d6c1bb36d 100644
--- a/intern/cycles/blender/blender_mesh.cpp
+++ b/intern/cycles/blender/blender_mesh.cpp
@@ -401,7 +401,8 @@ static void attr_create_vertex_color(Scene *scene,
int n = p->loop_total();
for(int i = 0; i < n; i++) {
float3 color = get_float3(l->data[p->loop_start() + i].color());
- *(cdata++) = color_float_to_byte(color_srgb_to_scene_linear_v3(color));
+ /* Encode vertex color using the sRGB curve. */
+ *(cdata++) = color_float_to_byte(color_srgb_to_linear_v3(color));
}
}
}
@@ -424,12 +425,13 @@ static void attr_create_vertex_color(Scene *scene,
int tri_a[3], tri_b[3];
face_split_tri_indices(face_flags[i], tri_a, tri_b);
+ /* Encode vertex color using the sRGB curve. */
uchar4 colors[4];
- colors[0] = color_float_to_byte(color_srgb_to_scene_linear_v3(get_float3(c->color1())));
- colors[1] = color_float_to_byte(color_srgb_to_scene_linear_v3(get_float3(c->color2())));
- colors[2] = color_float_to_byte(color_srgb_to_scene_linear_v3(get_float3(c->color3())));
+ colors[0] = color_float_to_byte(color_srgb_to_linear_v3(get_float3(c->color1())));
+ colors[1] = color_float_to_byte(color_srgb_to_linear_v3(get_float3(c->color2())));
+ colors[2] = color_float_to_byte(color_srgb_to_linear_v3(get_float3(c->color3())));
if(nverts[i] == 4) {
- colors[3] = color_float_to_byte(color_srgb_to_scene_linear_v3(get_float3(c->color4())));
+ colors[3] = color_float_to_byte(color_srgb_to_linear_v3(get_float3(c->color4())));
}
cdata[0] = colors[tri_a[0]];
diff --git a/intern/cycles/blender/blender_object.cpp b/intern/cycles/blender/blender_object.cpp
index dbeab2fdf61..e0737d5118a 100644
--- a/intern/cycles/blender/blender_object.cpp
+++ b/intern/cycles/blender/blender_object.cpp
@@ -242,7 +242,15 @@ void BlenderSync::sync_background_light(bool use_portal)
if(b_world) {
PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
PointerRNA cworld = RNA_pointer_get(&b_world.ptr, "cycles");
- bool sample_as_light = get_boolean(cworld, "sample_as_light");
+
+ enum SamplingMethod {
+ SAMPLING_NONE = 0,
+ SAMPLING_AUTOMATIC,
+ SAMPLING_MANUAL,
+ SAMPLING_NUM
+ };
+ int sampling_method = get_enum(cworld, "sampling_method", SAMPLING_NUM, SAMPLING_AUTOMATIC);
+ bool sample_as_light = (sampling_method != SAMPLING_NONE);
if(sample_as_light || use_portal) {
/* test if we need to sync */
@@ -254,7 +262,12 @@ void BlenderSync::sync_background_light(bool use_portal)
b_world.ptr.data != world_map)
{
light->type = LIGHT_BACKGROUND;
- light->map_resolution = get_int(cworld, "sample_map_resolution");
+ if(sampling_method == SAMPLING_MANUAL) {
+ light->map_resolution = get_int(cworld, "sample_map_resolution");
+ }
+ else {
+ light->map_resolution = 0;
+ }
light->shader = scene->default_background;
light->use_mis = sample_as_light;
light->max_bounces = get_int(cworld, "max_bounces");
diff --git a/intern/cycles/blender/blender_session.cpp b/intern/cycles/blender/blender_session.cpp
index eec13d04d7d..8e76a4c0061 100644
--- a/intern/cycles/blender/blender_session.cpp
+++ b/intern/cycles/blender/blender_session.cpp
@@ -141,6 +141,10 @@ void BlenderSession::create_session()
scene->image_manager->builtin_image_pixels_cb = function_bind(&BlenderSession::builtin_image_pixels, this, _1, _2, _3, _4, _5);
scene->image_manager->builtin_image_float_pixels_cb = function_bind(&BlenderSession::builtin_image_float_pixels, this, _1, _2, _3, _4, _5);
+#ifdef WITH_OCIO
+ scene->film->set_color_config(OCIO_getCurrentConfig());
+#endif
+
session->scene = scene;
/* There is no single depsgraph to use for the entire render.
diff --git a/intern/cycles/cmake/external_libs.cmake b/intern/cycles/cmake/external_libs.cmake
index 8d04025e6fd..2e386a6bfc5 100644
--- a/intern/cycles/cmake/external_libs.cmake
+++ b/intern/cycles/cmake/external_libs.cmake
@@ -98,6 +98,12 @@ if(CYCLES_STANDALONE_REPOSITORY)
endif()
####
+ # OpenColorIO
+ if(WITH_OPENCOLORIO)
+ find_package(OpenColorIO REQUIRED)
+ endif()
+
+ ####
# Boost
set(__boost_packages filesystem regex system thread date_time)
if(WITH_CYCLES_NETWORK)
diff --git a/intern/cycles/kernel/kernel_color.h b/intern/cycles/kernel/kernel_color.h
new file mode 100644
index 00000000000..d1c3dac824d
--- /dev/null
+++ b/intern/cycles/kernel/kernel_color.h
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+#ifndef __KERNEL_COLOR_H__
+#define __KERNEL_COLOR_H__
+
+#include "util/util_color.h"
+
+CCL_NAMESPACE_BEGIN
+
+ccl_device float3 xyz_to_rgb(KernelGlobals *kg, float3 xyz)
+{
+ return make_float3(dot(kernel_data.film.xyz_to_r, xyz),
+ dot(kernel_data.film.xyz_to_g, xyz),
+ dot(kernel_data.film.xyz_to_b, xyz));
+}
+
+ccl_device float linear_rgb_to_gray(KernelGlobals *kg, float3 c)
+{
+ return dot(c, kernel_data.film.rgb_to_y);
+}
+
+CCL_NAMESPACE_END
+
+#endif /* __KERNEL_COLOR_H__ */ \ No newline at end of file
diff --git a/intern/cycles/kernel/kernel_emission.h b/intern/cycles/kernel/kernel_emission.h
index a5556c3be8f..524e2467ebc 100644
--- a/intern/cycles/kernel/kernel_emission.h
+++ b/intern/cycles/kernel/kernel_emission.h
@@ -319,9 +319,9 @@ ccl_device_noinline float3 indirect_background(KernelGlobals *kg,
#ifdef __BACKGROUND_MIS__
/* check if background light exists or if we should skip pdf */
- int res = kernel_data.integrator.pdf_background_res;
+ int res_x = kernel_data.integrator.pdf_background_res_x;
- if(!(state->flag & PATH_RAY_MIS_SKIP) && res) {
+ if(!(state->flag & PATH_RAY_MIS_SKIP) && res_x) {
/* multiple importance sampling, get background light pdf for ray
* direction, and compute weight with respect to BSDF pdf */
float pdf = background_light_pdf(kg, ray->P, ray->D);
diff --git a/intern/cycles/kernel/kernel_film.h b/intern/cycles/kernel/kernel_film.h
index f9e9b413898..94815601179 100644
--- a/intern/cycles/kernel/kernel_film.h
+++ b/intern/cycles/kernel/kernel_film.h
@@ -22,9 +22,9 @@ ccl_device float4 film_map(KernelGlobals *kg, float4 irradiance, float scale)
float4 result = irradiance*scale;
/* conversion to srgb */
- result.x = color_scene_linear_to_srgb(result.x*exposure);
- result.y = color_scene_linear_to_srgb(result.y*exposure);
- result.z = color_scene_linear_to_srgb(result.z*exposure);
+ result.x = color_linear_to_srgb(result.x*exposure);
+ result.y = color_linear_to_srgb(result.y*exposure);
+ result.z = color_linear_to_srgb(result.z*exposure);
/* clamp since alpha might be > 1.0 due to russian roulette */
result.w = saturate(result.w);
diff --git a/intern/cycles/kernel/kernel_light.h b/intern/cycles/kernel/kernel_light.h
index b1be0b2155a..32cb924d25f 100644
--- a/intern/cycles/kernel/kernel_light.h
+++ b/intern/cycles/kernel/kernel_light.h
@@ -197,12 +197,13 @@ float3 background_map_sample(KernelGlobals *kg, float randu, float randv, float
/* for the following, the CDF values are actually a pair of floats, with the
* function value as X and the actual CDF as Y. The last entry's function
* value is the CDF total. */
- int res = kernel_data.integrator.pdf_background_res;
- int cdf_count = res + 1;
+ int res_x = kernel_data.integrator.pdf_background_res_x;
+ int res_y = kernel_data.integrator.pdf_background_res_y;
+ int cdf_width = res_x + 1;
/* this is basically std::lower_bound as used by pbrt */
int first = 0;
- int count = res;
+ int count = res_y;
while(count > 0) {
int step = count >> 1;
@@ -217,24 +218,24 @@ float3 background_map_sample(KernelGlobals *kg, float randu, float randv, float
}
int index_v = max(0, first - 1);
- kernel_assert(index_v >= 0 && index_v < res);
+ kernel_assert(index_v >= 0 && index_v < res_y);
float2 cdf_v = kernel_tex_fetch(__light_background_marginal_cdf, index_v);
float2 cdf_next_v = kernel_tex_fetch(__light_background_marginal_cdf, index_v + 1);
- float2 cdf_last_v = kernel_tex_fetch(__light_background_marginal_cdf, res);
+ float2 cdf_last_v = kernel_tex_fetch(__light_background_marginal_cdf, res_y);
/* importance-sampled V direction */
float dv = inverse_lerp(cdf_v.y, cdf_next_v.y, randv);
- float v = (index_v + dv) / res;
+ float v = (index_v + dv) / res_y;
/* this is basically std::lower_bound as used by pbrt */
first = 0;
- count = res;
+ count = res_x;
while(count > 0) {
int step = count >> 1;
int middle = first + step;
- if(kernel_tex_fetch(__light_background_conditional_cdf, index_v * cdf_count + middle).y < randu) {
+ if(kernel_tex_fetch(__light_background_conditional_cdf, index_v * cdf_width + middle).y < randu) {
first = middle + 1;
count -= step + 1;
}
@@ -243,15 +244,15 @@ float3 background_map_sample(KernelGlobals *kg, float randu, float randv, float
}
int index_u = max(0, first - 1);
- kernel_assert(index_u >= 0 && index_u < res);
+ kernel_assert(index_u >= 0 && index_u < res_x);
- float2 cdf_u = kernel_tex_fetch(__light_background_conditional_cdf, index_v * cdf_count + index_u);
- float2 cdf_next_u = kernel_tex_fetch(__light_background_conditional_cdf, index_v * cdf_count + index_u + 1);
- float2 cdf_last_u = kernel_tex_fetch(__light_background_conditional_cdf, index_v * cdf_count + res);
+ float2 cdf_u = kernel_tex_fetch(__light_background_conditional_cdf, index_v * cdf_width + index_u);
+ float2 cdf_next_u = kernel_tex_fetch(__light_background_conditional_cdf, index_v * cdf_width + index_u + 1);
+ float2 cdf_last_u = kernel_tex_fetch(__light_background_conditional_cdf, index_v * cdf_width + res_x);
/* importance-sampled U direction */
float du = inverse_lerp(cdf_u.y, cdf_next_u.y, randu);
- float u = (index_u + du) / res;
+ float u = (index_u + du) / res_x;
/* compute pdf */
float denom = cdf_last_u.x * cdf_last_v.x;
@@ -277,19 +278,21 @@ ccl_device
float background_map_pdf(KernelGlobals *kg, float3 direction)
{
float2 uv = direction_to_equirectangular(direction);
- int res = kernel_data.integrator.pdf_background_res;
+ int res_x = kernel_data.integrator.pdf_background_res_x;
+ int res_y = kernel_data.integrator.pdf_background_res_y;
+ int cdf_width = res_x + 1;
float sin_theta = sinf(uv.y * M_PI_F);
if(sin_theta == 0.0f)
return 0.0f;
- int index_u = clamp(float_to_int(uv.x * res), 0, res - 1);
- int index_v = clamp(float_to_int(uv.y * res), 0, res - 1);
+ int index_u = clamp(float_to_int(uv.x * res_x), 0, res_x - 1);
+ int index_v = clamp(float_to_int(uv.y * res_y), 0, res_y - 1);
/* pdfs in V direction */
- float2 cdf_last_u = kernel_tex_fetch(__light_background_conditional_cdf, index_v * (res + 1) + res);
- float2 cdf_last_v = kernel_tex_fetch(__light_background_marginal_cdf, res);
+ float2 cdf_last_u = kernel_tex_fetch(__light_background_conditional_cdf, index_v * cdf_width + res_x);
+ float2 cdf_last_v = kernel_tex_fetch(__light_background_marginal_cdf, res_y);
float denom = cdf_last_u.x * cdf_last_v.x;
@@ -297,7 +300,7 @@ float background_map_pdf(KernelGlobals *kg, float3 direction)
return 0.0f;
/* pdfs in U direction */
- float2 cdf_u = kernel_tex_fetch(__light_background_conditional_cdf, index_v * (res + 1) + index_u);
+ float2 cdf_u = kernel_tex_fetch(__light_background_conditional_cdf, index_v * cdf_width + index_u);
float2 cdf_v = kernel_tex_fetch(__light_background_marginal_cdf, index_v);
return (cdf_u.x * cdf_v.x)/(M_2PI_F * M_PI_F * sin_theta * denom);
diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h
index 72fbf7be557..633518c7926 100644
--- a/intern/cycles/kernel/kernel_types.h
+++ b/intern/cycles/kernel/kernel_types.h
@@ -1272,6 +1272,11 @@ typedef struct KernelFilm {
int pass_denoising_clean;
int denoising_flags;
+ float3 xyz_to_r;
+ float3 xyz_to_g;
+ float3 xyz_to_b;
+ float3 rgb_to_y;
+
int pad1, pad2, pad3;
#ifdef __KERNEL_DEBUG__
@@ -1306,7 +1311,8 @@ typedef struct KernelIntegrator {
int num_all_lights;
float pdf_triangles;
float pdf_lights;
- int pdf_background_res;
+ int pdf_background_res_x;
+ int pdf_background_res_y;
float light_inv_rr_threshold;
/* light portals */
@@ -1368,6 +1374,8 @@ typedef struct KernelIntegrator {
int start_sample;
int max_closures;
+
+ int pad1, pad2, pad3;
} KernelIntegrator;
static_assert_align(KernelIntegrator, 16);
diff --git a/intern/cycles/kernel/kernels/cpu/kernel_cpu_impl.h b/intern/cycles/kernel/kernels/cpu/kernel_cpu_impl.h
index ccca023a15f..5ec1655ab05 100644
--- a/intern/cycles/kernel/kernels/cpu/kernel_cpu_impl.h
+++ b/intern/cycles/kernel/kernels/cpu/kernel_cpu_impl.h
@@ -30,6 +30,7 @@
# include "kernel/split/kernel_split_data.h"
# include "kernel/kernel_globals.h"
+# include "kernel/kernel_color.h"
# include "kernel/kernels/cpu/kernel_cpu_image.h"
# include "kernel/kernel_film.h"
# include "kernel/kernel_path.h"
diff --git a/intern/cycles/kernel/kernels/cuda/kernel.cu b/intern/cycles/kernel/kernels/cuda/kernel.cu
index 3c93e00ccf1..8a180a509e8 100644
--- a/intern/cycles/kernel/kernels/cuda/kernel.cu
+++ b/intern/cycles/kernel/kernels/cuda/kernel.cu
@@ -26,6 +26,7 @@
#include "kernel/kernel_math.h"
#include "kernel/kernel_types.h"
#include "kernel/kernel_globals.h"
+#include "kernel/kernel_color.h"
#include "kernel/kernels/cuda/kernel_cuda_image.h"
#include "kernel/kernel_film.h"
#include "kernel/kernel_path.h"
diff --git a/intern/cycles/kernel/kernels/opencl/kernel.cl b/intern/cycles/kernel/kernels/opencl/kernel.cl
index 9d5d784e140..63128d0aecf 100644
--- a/intern/cycles/kernel/kernels/opencl/kernel.cl
+++ b/intern/cycles/kernel/kernels/opencl/kernel.cl
@@ -20,6 +20,7 @@
#include "kernel/kernel_math.h"
#include "kernel/kernel_types.h"
#include "kernel/kernel_globals.h"
+#include "kernel/kernel_color.h"
#include "kernel/kernels/opencl/kernel_opencl_image.h"
#include "kernel/kernel_film.h"
diff --git a/intern/cycles/kernel/osl/osl_services.cpp b/intern/cycles/kernel/osl/osl_services.cpp
index 5f4baf6fda3..1aca54d2ad5 100644
--- a/intern/cycles/kernel/osl/osl_services.cpp
+++ b/intern/cycles/kernel/osl/osl_services.cpp
@@ -41,6 +41,7 @@
#include "kernel/kernel_compat_cpu.h"
#include "kernel/split/kernel_split_data_types.h"
#include "kernel/kernel_globals.h"
+#include "kernel/kernel_color.h"
#include "kernel/kernel_random.h"
#include "kernel/kernel_projection.h"
#include "kernel/kernel_differential.h"
diff --git a/intern/cycles/kernel/shaders/node_color.h b/intern/cycles/kernel/shaders/node_color.h
index 4a17286a07f..2c3a810cb18 100644
--- a/intern/cycles/kernel/shaders/node_color.h
+++ b/intern/cycles/kernel/shaders/node_color.h
@@ -14,6 +14,8 @@
* limitations under the License.
*/
+/* TODO(lukas): Fix colors in OSL. */
+
float color_srgb_to_scene_linear(float c)
{
if (c < 0.04045)
diff --git a/intern/cycles/kernel/split/kernel_split_common.h b/intern/cycles/kernel/split/kernel_split_common.h
index abe68104449..4b86696691a 100644
--- a/intern/cycles/kernel/split/kernel_split_common.h
+++ b/intern/cycles/kernel/split/kernel_split_common.h
@@ -23,6 +23,7 @@
#include "kernel/split/kernel_split_data.h"
#include "kernel/kernel_globals.h"
+#include "kernel/kernel_color.h"
#ifdef __OSL__
# include "kernel/osl/osl_shader.h"
diff --git a/intern/cycles/kernel/svm/svm.h b/intern/cycles/kernel/svm/svm.h
index bfa146f2d93..ce2affe96c8 100644
--- a/intern/cycles/kernel/svm/svm.h
+++ b/intern/cycles/kernel/svm/svm.h
@@ -243,7 +243,7 @@ ccl_device_noinline void svm_eval_nodes(KernelGlobals *kg, ShaderData *sd, ccl_a
svm_node_geometry(kg, sd, stack, node.y, node.z);
break;
case NODE_CONVERT:
- svm_node_convert(sd, stack, node.y, node.z, node.w);
+ svm_node_convert(kg, sd, stack, node.y, node.z, node.w);
break;
case NODE_TEX_COORD:
svm_node_tex_coord(kg, sd, path_flag, stack, node, &offset);
@@ -465,7 +465,7 @@ ccl_device_noinline void svm_eval_nodes(KernelGlobals *kg, ShaderData *sd, ccl_a
svm_node_wireframe(kg, sd, stack, node);
break;
case NODE_WAVELENGTH:
- svm_node_wavelength(sd, stack, node.y, node.z);
+ svm_node_wavelength(kg, sd, stack, node.y, node.z);
break;
case NODE_BLACKBODY:
svm_node_blackbody(kg, sd, stack, node.y, node.z);
diff --git a/intern/cycles/kernel/svm/svm_closure.h b/intern/cycles/kernel/svm/svm_closure.h
index 886a1333fa3..76464e37c66 100644
--- a/intern/cycles/kernel/svm/svm_closure.h
+++ b/intern/cycles/kernel/svm/svm_closure.h
@@ -217,7 +217,7 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *
/* sheen */
if(diffuse_weight > CLOSURE_WEIGHT_CUTOFF && sheen > CLOSURE_WEIGHT_CUTOFF) {
- float m_cdlum = linear_rgb_to_gray(base_color);
+ float m_cdlum = linear_rgb_to_gray(kg, base_color);
float3 m_ctint = m_cdlum > 0.0f ? base_color / m_cdlum : make_float3(1.0f, 1.0f, 1.0f); // normalize lum. to isolate hue+sat
/* color of the sheen component */
diff --git a/intern/cycles/kernel/svm/svm_convert.h b/intern/cycles/kernel/svm/svm_convert.h
index 34080377083..c88ac57e20d 100644
--- a/intern/cycles/kernel/svm/svm_convert.h
+++ b/intern/cycles/kernel/svm/svm_convert.h
@@ -18,7 +18,7 @@ CCL_NAMESPACE_BEGIN
/* Conversion Nodes */
-ccl_device void svm_node_convert(ShaderData *sd, float *stack, uint type, uint from, uint to)
+ccl_device void svm_node_convert(KernelGlobals *kg, ShaderData *sd, float *stack, uint type, uint from, uint to)
{
switch(type) {
case NODE_CONVERT_FI: {
@@ -33,13 +33,13 @@ ccl_device void svm_node_convert(ShaderData *sd, float *stack, uint type, uint f
}
case NODE_CONVERT_CF: {
float3 f = stack_load_float3(stack, from);
- float g = linear_rgb_to_gray(f);
+ float g = linear_rgb_to_gray(kg, f);
stack_store_float(stack, to, g);
break;
}
case NODE_CONVERT_CI: {
float3 f = stack_load_float3(stack, from);
- int i = (int)linear_rgb_to_gray(f);
+ int i = (int)linear_rgb_to_gray(kg, f);
stack_store_int(stack, to, i);
break;
}
diff --git a/intern/cycles/kernel/svm/svm_image.h b/intern/cycles/kernel/svm/svm_image.h
index 4226e7adfe0..28565308867 100644
--- a/intern/cycles/kernel/svm/svm_image.h
+++ b/intern/cycles/kernel/svm/svm_image.h
@@ -33,7 +33,8 @@ ccl_device float4 svm_image_texture(KernelGlobals *kg, int id, float x, float y,
}
if(srgb) {
- r = color_srgb_to_scene_linear_v4(r);
+ /* TODO(lukas): Implement proper conversion for image textures. */
+ r = color_srgb_to_linear_v4(r);
}
return r;
diff --git a/intern/cycles/kernel/svm/svm_math_util.h b/intern/cycles/kernel/svm/svm_math_util.h
index 8e6bc73ddc7..caf0addbf35 100644
--- a/intern/cycles/kernel/svm/svm_math_util.h
+++ b/intern/cycles/kernel/svm/svm_math_util.h
@@ -138,6 +138,8 @@ ccl_static_constant float blackbody_table_b[6][4] = {
ccl_device float3 svm_math_blackbody_color(float t)
{
+ /* TODO(lukas): Reimplement in XYZ. */
+
if(t >= 12000.0f) {
return make_float3(0.826270103f, 0.994478524f, 1.56626022f);
}
diff --git a/intern/cycles/kernel/svm/svm_sky.h b/intern/cycles/kernel/svm/svm_sky.h
index 854e85fd326..b83a7168541 100644
--- a/intern/cycles/kernel/svm/svm_sky.h
+++ b/intern/cycles/kernel/svm/svm_sky.h
@@ -59,7 +59,7 @@ ccl_device float3 sky_radiance_old(KernelGlobals *kg, float3 dir,
/* convert to RGB */
float3 xyz = xyY_to_xyz(x, y, Y);
- return xyz_to_rgb(xyz.x, xyz.y, xyz.z);
+ return xyz_to_rgb(kg, xyz);
}
/*
@@ -102,7 +102,7 @@ ccl_device float3 sky_radiance_new(KernelGlobals *kg, float3 dir,
float z = sky_radiance_internal(config_z, theta, gamma) * radiance_z;
/* convert to RGB and adjust strength */
- return xyz_to_rgb(x, y, z) * (M_2PI_F/683);
+ return xyz_to_rgb(kg, make_float3(x, y, z)) * (M_2PI_F/683);
}
ccl_device void svm_node_tex_sky(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node, int *offset)
diff --git a/intern/cycles/kernel/svm/svm_wavelength.h b/intern/cycles/kernel/svm/svm_wavelength.h
index 855b356b397..62e026278ac 100644
--- a/intern/cycles/kernel/svm/svm_wavelength.h
+++ b/intern/cycles/kernel/svm/svm_wavelength.h
@@ -70,7 +70,7 @@ ccl_static_constant float cie_colour_match[81][3] = {
{0.0001f,0.0000f,0.0000f}, {0.0001f,0.0000f,0.0000f}, {0.0000f,0.0000f,0.0000f}
};
-ccl_device void svm_node_wavelength(ShaderData *sd, float *stack, uint wavelength, uint color_out)
+ccl_device void svm_node_wavelength(KernelGlobals *kg, ShaderData *sd, float *stack, uint wavelength, uint color_out)
{
float lambda_nm = stack_load_float(stack, wavelength);
float ii = (lambda_nm-380.0f) * (1.0f/5.0f); // scaled 0..80
@@ -86,7 +86,7 @@ ccl_device void svm_node_wavelength(ShaderData *sd, float *stack, uint wavelengt
color = interp(make_float3(c[0], c[1], c[2]), make_float3(c[3], c[4], c[5]), ii);
}
- color = xyz_to_rgb(color.x, color.y, color.z);
+ color = xyz_to_rgb(kg, color);
color *= 1.0f/2.52f; // Empirical scale from lg to make all comps <= 1
/* Clamp to zero if values are smaller */
diff --git a/intern/cycles/render/constant_fold.cpp b/intern/cycles/render/constant_fold.cpp
index 943b218f0e4..98c3e99996c 100644
--- a/intern/cycles/render/constant_fold.cpp
+++ b/intern/cycles/render/constant_fold.cpp
@@ -22,8 +22,8 @@
CCL_NAMESPACE_BEGIN
-ConstantFolder::ConstantFolder(ShaderGraph *graph, ShaderNode *node, ShaderOutput *output)
-: graph(graph), node(node), output(output)
+ConstantFolder::ConstantFolder(ShaderGraph *graph, ShaderNode *node, ShaderOutput *output, Scene *scene)
+: graph(graph), node(node), output(output), scene(scene)
{
}
diff --git a/intern/cycles/render/constant_fold.h b/intern/cycles/render/constant_fold.h
index 33f93b8c0ab..cc24d614206 100644
--- a/intern/cycles/render/constant_fold.h
+++ b/intern/cycles/render/constant_fold.h
@@ -22,6 +22,7 @@
CCL_NAMESPACE_BEGIN
+class Scene;
class ShaderGraph;
class ShaderInput;
class ShaderNode;
@@ -33,7 +34,9 @@ public:
ShaderNode *const node;
ShaderOutput *const output;
- ConstantFolder(ShaderGraph *graph, ShaderNode *node, ShaderOutput *output);
+ Scene *scene;
+
+ ConstantFolder(ShaderGraph *graph, ShaderNode *node, ShaderOutput *output, Scene *scene);
bool all_inputs_constant() const;
diff --git a/intern/cycles/render/graph.cpp b/intern/cycles/render/graph.cpp
index dca168824d9..8b179f742c4 100644
--- a/intern/cycles/render/graph.cpp
+++ b/intern/cycles/render/graph.cpp
@@ -243,18 +243,27 @@ void ShaderGraph::connect(ShaderOutput *from, ShaderInput *to)
/* add automatic conversion node in case of type mismatch */
ShaderNode *convert;
+ ShaderInput *convert_in;
if (to->type() == SocketType::CLOSURE) {
EmissionNode *emission = new EmissionNode();
emission->color = make_float3(1.0f, 1.0f, 1.0f);
emission->strength = 1.0f;
convert = add(emission);
+ /* Connect float inputs to Strength to save an additional Falue->Color conversion. */
+ if(from->type() == SocketType::FLOAT) {
+ convert_in = convert->input("Strength");
+ }
+ else {
+ convert_in = convert->input("Color");
+ }
}
else {
convert = add(new ConvertNode(from->type(), to->type(), true));
+ convert_in = convert->inputs[0];
}
- connect(from, convert->inputs[0]);
+ connect(from, convert_in);
connect(convert->outputs[0], to);
}
else {
@@ -487,7 +496,7 @@ void ShaderGraph::remove_proxy_nodes()
* Try to constant fold some nodes, and pipe result directly to
* the input socket of connected nodes.
*/
-void ShaderGraph::constant_fold()
+void ShaderGraph::constant_fold(Scene *scene)
{
ShaderNodeSet done, scheduled;
queue<ShaderNode*> traverse_queue;
@@ -527,7 +536,7 @@ void ShaderGraph::constant_fold()
}
}
/* Optimize current node. */
- ConstantFolder folder(this, node, output);
+ ConstantFolder folder(this, node, output, scene);
node->constant_fold(folder);
}
}
@@ -725,7 +734,7 @@ void ShaderGraph::clean(Scene *scene)
/* Graph simplification */
/* NOTE: Remove proxy nodes was already done. */
- constant_fold();
+ constant_fold(scene);
simplify_settings(scene);
deduplicate_nodes();
verify_volume_output();
diff --git a/intern/cycles/render/graph.h b/intern/cycles/render/graph.h
index 2c134932b3c..5d986ae4827 100644
--- a/intern/cycles/render/graph.h
+++ b/intern/cycles/render/graph.h
@@ -285,7 +285,7 @@ protected:
/* Graph simplification routines. */
void clean(Scene *scene);
- void constant_fold();
+ void constant_fold(Scene *scene);
void simplify_settings(Scene *scene);
void deduplicate_nodes();
void verify_volume_output();
diff --git a/intern/cycles/render/image.cpp b/intern/cycles/render/image.cpp
index 6867ea95d63..023ca4b47c2 100644
--- a/intern/cycles/render/image.cpp
+++ b/intern/cycles/render/image.cpp
@@ -94,6 +94,25 @@ device_memory *ImageManager::image_memory(int flat_slot)
return img->mem;
}
+bool ImageManager::get_image_metadata(int flat_slot,
+ ImageMetaData& metadata)
+{
+ if(flat_slot == -1) {
+ return false;
+ }
+
+ ImageDataType type;
+ int slot = flattened_slot_to_type_index(flat_slot, &type);
+
+ Image *img = images[type][slot];
+ if(img) {
+ metadata = img->metadata;
+ return true;
+ }
+
+ return false;
+}
+
bool ImageManager::get_image_metadata(const string& filename,
void *builtin_data,
ImageMetaData& metadata)
@@ -329,7 +348,7 @@ int ImageManager::add_image(const string& filename,
img = new Image();
img->filename = filename;
img->builtin_data = builtin_data;
- img->builtin_free_cache = metadata.builtin_free_cache;
+ img->metadata = metadata;
img->need_load = true;
img->animated = animated;
img->frame = frame;
@@ -417,11 +436,7 @@ void ImageManager::tag_reload_image(const string& filename,
}
bool ImageManager::file_load_image_generic(Image *img,
- ImageInput **in,
- int &width,
- int &height,
- int &depth,
- int &components)
+ ImageInput **in)
{
if(img->filename == "")
return false;
@@ -449,28 +464,15 @@ bool ImageManager::file_load_image_generic(Image *img,
*in = NULL;
return false;
}
-
- width = spec.width;
- height = spec.height;
- depth = spec.depth;
- components = spec.nchannels;
}
else {
/* load image using builtin images callbacks */
if(!builtin_image_info_cb || !builtin_image_pixels_cb)
return false;
-
- ImageMetaData metadata;
- builtin_image_info_cb(img->filename, img->builtin_data, metadata);
-
- width = metadata.width;
- height = metadata.height;
- depth = metadata.depth;
- components = metadata.channels;
}
/* we only handle certain number of components */
- if(!(components >= 1 && components <= 4)) {
+ if(!(img->metadata.channels >= 1 && img->metadata.channels <= 4)) {
if(*in) {
(*in)->close();
delete *in;
@@ -493,10 +495,16 @@ bool ImageManager::file_load_image(Image *img,
{
const StorageType alpha_one = (FileFormat == TypeDesc::UINT8)? 255 : 1;
ImageInput *in = NULL;
- int width, height, depth, components;
- if(!file_load_image_generic(img, &in, width, height, depth, components)) {
+ if(!file_load_image_generic(img, &in)) {
return false;
}
+
+ /* Get metadata. */
+ int width = img->metadata.width;
+ int height = img->metadata.height;
+ int depth = img->metadata.depth;
+ int components = img->metadata.channels;
+
/* Read RGBA pixels. */
vector<StorageType> pixels_storage;
StorageType *pixels;
@@ -557,14 +565,14 @@ bool ImageManager::file_load_image(Image *img,
img->builtin_data,
(float*)&pixels[0],
num_pixels * components,
- img->builtin_free_cache);
+ img->metadata.builtin_free_cache);
}
else if(FileFormat == TypeDesc::UINT8) {
builtin_image_pixels_cb(img->filename,
img->builtin_data,
(uchar*)&pixels[0],
num_pixels * components,
- img->builtin_free_cache);
+ img->metadata.builtin_free_cache);
}
else {
/* TODO(dingto): Support half for ImBuf. */
diff --git a/intern/cycles/render/image.h b/intern/cycles/render/image.h
index 66f929aa03a..59b9f9ea28d 100644
--- a/intern/cycles/render/image.h
+++ b/intern/cycles/render/image.h
@@ -71,6 +71,8 @@ public:
bool get_image_metadata(const string& filename,
void *builtin_data,
ImageMetaData& metadata);
+ bool get_image_metadata(int flat_slot,
+ ImageMetaData& metadata);
void device_update(Device *device,
Scene *scene,
@@ -114,7 +116,7 @@ public:
struct Image {
string filename;
void *builtin_data;
- bool builtin_free_cache;
+ ImageMetaData metadata;
bool use_alpha;
bool need_load;
@@ -141,11 +143,7 @@ private:
void *osl_texture_system;
bool file_load_image_generic(Image *img,
- ImageInput **in,
- int &width,
- int &height,
- int &depth,
- int &components);
+ ImageInput **in);
template<TypeDesc::BASETYPE FileFormat,
typename StorageType,
diff --git a/intern/cycles/render/light.cpp b/intern/cycles/render/light.cpp
index d45d4543e16..5a58ef1aa8e 100644
--- a/intern/cycles/render/light.cpp
+++ b/intern/cycles/render/light.cpp
@@ -18,8 +18,10 @@
#include "device/device.h"
#include "render/integrator.h"
#include "render/film.h"
+#include "render/graph.h"
#include "render/light.h"
#include "render/mesh.h"
+#include "render/nodes.h"
#include "render/object.h"
#include "render/scene.h"
#include "render/shader.h"
@@ -32,12 +34,9 @@
CCL_NAMESPACE_BEGIN
-static void shade_background_pixels(Device *device, DeviceScene *dscene, int res, vector<float3>& pixels, Progress& progress)
+static void shade_background_pixels(Device *device, DeviceScene *dscene, int width, int height, vector<float3>& pixels, Progress& progress)
{
/* create input */
- int width = res;
- int height = res;
-
device_vector<uint4> d_input(device, "background_input", MEM_READ_ONLY);
device_vector<float4> d_output(device, "background_output", MEM_READ_WRITE);
@@ -121,7 +120,7 @@ NODE_DEFINE(Light)
SOCKET_FLOAT(sizev, "Size V", 1.0f);
SOCKET_BOOLEAN(round, "Round", false);
- SOCKET_INT(map_resolution, "Map Resolution", 512);
+ SOCKET_INT(map_resolution, "Map Resolution", 0);
SOCKET_FLOAT(spot_angle, "Spot Angle", M_PI_4_F);
SOCKET_FLOAT(spot_smooth, "Spot Smooth", 0.0f);
@@ -482,40 +481,41 @@ void LightManager::device_update_distribution(Device *, DeviceScene *dscene, Sce
static void background_cdf(int start,
int end,
- int res,
- int cdf_count,
+ int res_x,
+ int res_y,
const vector<float3> *pixels,
float2 *cond_cdf)
{
+ int cdf_width = res_x+1;
/* Conditional CDFs (rows, U direction). */
for(int i = start; i < end; i++) {
- float sin_theta = sinf(M_PI_F * (i + 0.5f) / res);
- float3 env_color = (*pixels)[i * res];
+ float sin_theta = sinf(M_PI_F * (i + 0.5f) / res_y);
+ float3 env_color = (*pixels)[i * res_x];
float ave_luminance = average(env_color);
- cond_cdf[i * cdf_count].x = ave_luminance * sin_theta;
- cond_cdf[i * cdf_count].y = 0.0f;
+ cond_cdf[i * cdf_width].x = ave_luminance * sin_theta;
+ cond_cdf[i * cdf_width].y = 0.0f;
- for(int j = 1; j < res; j++) {
- env_color = (*pixels)[i * res + j];
+ for(int j = 1; j < res_x; j++) {
+ env_color = (*pixels)[i * res_x + j];
ave_luminance = average(env_color);
- cond_cdf[i * cdf_count + j].x = ave_luminance * sin_theta;
- cond_cdf[i * cdf_count + j].y = cond_cdf[i * cdf_count + j - 1].y + cond_cdf[i * cdf_count + j - 1].x / res;
+ cond_cdf[i * cdf_width + j].x = ave_luminance * sin_theta;
+ cond_cdf[i * cdf_width + j].y = cond_cdf[i * cdf_width + j - 1].y + cond_cdf[i * cdf_width + j - 1].x / res_x;
}
- float cdf_total = cond_cdf[i * cdf_count + res - 1].y + cond_cdf[i * cdf_count + res - 1].x / res;
+ float cdf_total = cond_cdf[i * cdf_width + res_x - 1].y + cond_cdf[i * cdf_width + res_x - 1].x / res_x;
float cdf_total_inv = 1.0f / cdf_total;
/* stuff the total into the brightness value for the last entry, because
* we are going to normalize the CDFs to 0.0 to 1.0 afterwards */
- cond_cdf[i * cdf_count + res].x = cdf_total;
+ cond_cdf[i * cdf_width + res_x].x = cdf_total;
if(cdf_total > 0.0f)
- for(int j = 1; j < res; j++)
- cond_cdf[i * cdf_count + j].y *= cdf_total_inv;
+ for(int j = 1; j < res_x; j++)
+ cond_cdf[i * cdf_width + j].y *= cdf_total_inv;
- cond_cdf[i * cdf_count + res].y = 1.0f;
+ cond_cdf[i * cdf_width + res_x].y = 1.0f;
}
}
@@ -537,7 +537,8 @@ void LightManager::device_update_background(Device *device,
/* no background light found, signal renderer to skip sampling */
if(!background_light || !background_light->is_enabled) {
- kintegrator->pdf_background_res = 0;
+ kintegrator->pdf_background_res_x = 0;
+ kintegrator->pdf_background_res_y = 0;
return;
}
@@ -546,41 +547,62 @@ void LightManager::device_update_background(Device *device,
assert(kintegrator->use_direct_light);
/* get the resolution from the light's size (we stuff it in there) */
- int res = background_light->map_resolution;
- kintegrator->pdf_background_res = res;
-
- assert(res > 0);
+ int2 res = make_int2(background_light->map_resolution, background_light->map_resolution/2);
+ /* If the resolution isn't set manually, try to find an environment texture. */
+ if (res.x == 0) {
+ Shader *shader = (scene->background->shader) ? scene->background->shader : scene->default_background;
+ foreach(ShaderNode *node, shader->graph->nodes) {
+ if(node->type == EnvironmentTextureNode::node_type) {
+ EnvironmentTextureNode *env = (EnvironmentTextureNode*) node;
+ ImageMetaData metadata;
+ if(env->image_manager && env->image_manager->get_image_metadata(env->slot, metadata)) {
+ res.x = max(res.x, metadata.width);
+ res.y = max(res.y, metadata.height);
+ }
+ }
+ }
+ if (res.x > 0 && res.y > 0) {
+ VLOG(2) << "Automatically set World MIS resolution to " << res.x << " by " << res.y << "\n";
+ }
+ }
+ /* If it's still unknown, just use the default. */
+ if (res.x == 0 || res.y == 0) {
+ res = make_int2(1024, 512);
+ VLOG(2) << "Setting World MIS resolution to default\n";
+ }
+ kintegrator->pdf_background_res_x = res.x;
+ kintegrator->pdf_background_res_y = res.y;
vector<float3> pixels;
- shade_background_pixels(device, dscene, res, pixels, progress);
+ shade_background_pixels(device, dscene, res.x, res.y, pixels, progress);
if(progress.get_cancel())
return;
/* build row distributions and column distribution for the infinite area environment light */
- int cdf_count = res + 1;
- float2 *marg_cdf = dscene->light_background_marginal_cdf.alloc(cdf_count);
- float2 *cond_cdf = dscene->light_background_conditional_cdf.alloc(cdf_count * cdf_count);
+ int cdf_width = res.x+1;
+ float2 *marg_cdf = dscene->light_background_marginal_cdf.alloc(res.y + 1);
+ float2 *cond_cdf = dscene->light_background_conditional_cdf.alloc(cdf_width * res.y);
double time_start = time_dt();
- if(res < 512) {
+ if(max(res.x, res.y) < 512) {
/* Small enough resolution, faster to do single-threaded. */
- background_cdf(0, res, res, cdf_count, &pixels, cond_cdf);
+ background_cdf(0, res.x, res.x, res.y, &pixels, cond_cdf);
}
else {
/* Threaded evaluation for large resolution. */
const int num_blocks = TaskScheduler::num_threads();
- const int chunk_size = res / num_blocks;
+ const int chunk_size = res.y / num_blocks;
int start_row = 0;
TaskPool pool;
for(int i = 0; i < num_blocks; ++i) {
const int current_chunk_size =
(i != num_blocks - 1) ? chunk_size
- : (res - i * chunk_size);
+ : (res.y - i * chunk_size);
pool.push(function_bind(&background_cdf,
start_row, start_row + current_chunk_size,
- res,
- cdf_count,
+ res.x,
+ res.y,
&pixels,
cond_cdf));
start_row += current_chunk_size;
@@ -589,22 +611,22 @@ void LightManager::device_update_background(Device *device,
}
/* marginal CDFs (column, V direction, sum of rows) */
- marg_cdf[0].x = cond_cdf[res].x;
+ marg_cdf[0].x = cond_cdf[res.x].x;
marg_cdf[0].y = 0.0f;
- for(int i = 1; i < res; i++) {
- marg_cdf[i].x = cond_cdf[i * cdf_count + res].x;
- marg_cdf[i].y = marg_cdf[i - 1].y + marg_cdf[i - 1].x / res;
+ for(int i = 1; i < res.y; i++) {
+ marg_cdf[i].x = cond_cdf[i * cdf_width + res.x].x;
+ marg_cdf[i].y = marg_cdf[i - 1].y + marg_cdf[i - 1].x / res.y;
}
- float cdf_total = marg_cdf[res - 1].y + marg_cdf[res - 1].x / res;
- marg_cdf[res].x = cdf_total;
+ float cdf_total = marg_cdf[res.y - 1].y + marg_cdf[res.y - 1].x / res.y;
+ marg_cdf[res.y].x = cdf_total;
if(cdf_total > 0.0f)
- for(int i = 1; i < res; i++)
+ for(int i = 1; i < res.y; i++)
marg_cdf[i].y /= cdf_total;
- marg_cdf[res].y = 1.0f;
+ marg_cdf[res.y].y = 1.0f;
VLOG(2) << "Background MIS build time " << time_dt() - time_start << "\n";
diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp
index 3a531f87c10..1ddc84848cc 100644
--- a/intern/cycles/render/nodes.cpp
+++ b/intern/cycles/render/nodes.cpp
@@ -14,6 +14,7 @@
* limitations under the License.
*/
+#include "render/film.h"
#include "render/image.h"
#include "render/integrator.h"
#include "render/light.h"
@@ -1670,7 +1671,8 @@ RGBToBWNode::RGBToBWNode()
void RGBToBWNode::constant_fold(const ConstantFolder& folder)
{
if(folder.all_inputs_constant()) {
- folder.make_constant(linear_rgb_to_gray(color));
+ float val = folder.scene->shader_manager->linear_rgb_to_gray(color);
+ folder.make_constant(val);
}
}
@@ -1766,7 +1768,8 @@ void ConvertNode::constant_fold(const ConstantFolder& folder)
if(to == SocketType::FLOAT) {
if(from == SocketType::COLOR) {
/* color to float */
- folder.make_constant(linear_rgb_to_gray(value_color));
+ float val = folder.scene->shader_manager->linear_rgb_to_gray(value_color);
+ folder.make_constant(val);
}
else {
/* vector/point/normal to float */
diff --git a/intern/cycles/render/shader.cpp b/intern/cycles/render/shader.cpp
index c1621cd817b..f8bd14859f2 100644
--- a/intern/cycles/render/shader.cpp
+++ b/intern/cycles/render/shader.cpp
@@ -31,6 +31,11 @@
#include "util/util_foreach.h"
+#ifdef WITH_OCIO
+# include <OpenColorIO/OpenColorIO.h>
+namespace OCIO = OCIO_NAMESPACE;
+#endif
+
CCL_NAMESPACE_BEGIN
thread_mutex ShaderManager::lookup_table_mutex;
@@ -339,6 +344,40 @@ ShaderManager::ShaderManager()
{
need_update = true;
beckmann_table_offset = TABLE_OFFSET_INVALID;
+
+ xyz_to_r = make_float3( 3.2404542f, -1.5371385f, -0.4985314f);
+ xyz_to_g = make_float3(-0.9692660f, 1.8760108f, 0.0415560f);
+ xyz_to_b = make_float3( 0.0556434f, -0.2040259f, 1.0572252f);
+ rgb_to_y = make_float3( 0.2126729f, 0.7151522f, 0.0721750f);
+
+#ifdef WITH_OCIO
+ OCIO::ConstConfigRcPtr config = OCIO::GetCurrentConfig();
+ if(config) {
+ if(config->hasRole("XYZ") && config->hasRole("scene_linear")) {
+ OCIO::ConstProcessorRcPtr to_rgb_processor = config->getProcessor("XYZ", "scene_linear");
+ OCIO::ConstProcessorRcPtr to_xyz_processor = config->getProcessor("scene_linear", "XYZ");
+ if(to_rgb_processor && to_xyz_processor) {
+ float r[] = {1.0f, 0.0f, 0.0f};
+ float g[] = {0.0f, 1.0f, 0.0f};
+ float b[] = {0.0f, 0.0f, 1.0f};
+ to_xyz_processor->applyRGB(r);
+ to_xyz_processor->applyRGB(g);
+ to_xyz_processor->applyRGB(b);
+ rgb_to_y = make_float3(r[1], g[1], b[1]);
+
+ float x[] = {1.0f, 0.0f, 0.0f};
+ float y[] = {0.0f, 1.0f, 0.0f};
+ float z[] = {0.0f, 0.0f, 1.0f};
+ to_rgb_processor->applyRGB(x);
+ to_rgb_processor->applyRGB(y);
+ to_rgb_processor->applyRGB(z);
+ xyz_to_r = make_float3(x[0], y[0], z[0]);
+ xyz_to_g = make_float3(x[1], y[1], z[1]);
+ xyz_to_b = make_float3(x[2], y[2], z[2]);
+ }
+ }
+ }
+#endif
}
ShaderManager::~ShaderManager()
@@ -519,6 +558,14 @@ void ShaderManager::device_update_common(Device *device,
kintegrator->use_volumes = has_volumes;
/* TODO(sergey): De-duplicate with flags set in integrator.cpp. */
kintegrator->transparent_shadows = has_transparent_shadow;
+
+ /* film */
+ KernelFilm *kfilm = &dscene->data.film;
+ /* color space, needs to be here because e.g. displacement shaders could depend on it */
+ kfilm->xyz_to_r = xyz_to_r;
+ kfilm->xyz_to_g = xyz_to_g;
+ kfilm->xyz_to_b = xyz_to_b;
+ kfilm->rgb_to_y = rgb_to_y;
}
void ShaderManager::device_free_common(Device *, DeviceScene *dscene, Scene *scene)
@@ -644,5 +691,10 @@ void ShaderManager::free_memory()
beckmann_table.free_memory();
}
+float ShaderManager::linear_rgb_to_gray(float3 c)
+{
+ return dot(c, rgb_to_y);
+}
+
CCL_NAMESPACE_END
diff --git a/intern/cycles/render/shader.h b/intern/cycles/render/shader.h
index ffaef522124..d787c3b266b 100644
--- a/intern/cycles/render/shader.h
+++ b/intern/cycles/render/shader.h
@@ -196,6 +196,8 @@ public:
static void free_memory();
+ float linear_rgb_to_gray(float3 c);
+
protected:
ShaderManager();
@@ -212,6 +214,11 @@ protected:
DeviceRequestedFeatures *requested_features);
thread_spin_lock attribute_lock_;
+
+ float3 xyz_to_r;
+ float3 xyz_to_g;
+ float3 xyz_to_b;
+ float3 rgb_to_y;
};
CCL_NAMESPACE_END
diff --git a/intern/cycles/test/CMakeLists.txt b/intern/cycles/test/CMakeLists.txt
index f3e49dc0c4e..46c525eb3bb 100644
--- a/intern/cycles/test/CMakeLists.txt
+++ b/intern/cycles/test/CMakeLists.txt
@@ -42,6 +42,11 @@ if(WITH_CYCLES_OSL)
${LLVM_LIBRARIES}
)
endif()
+if(WITH_OPENCOLORIO)
+ list(APPEND ALL_CYCLES_LIBRARIES
+ ${OPENCOLORIO_LIBRARIES}
+ )
+endif()
if(WITH_IMAGE_OPENJPEG)
if(WITH_SYSTEM_OPENJPEG)
list(APPEND ALL_CYCLES_LIBRARIES ${OPENJPEG_LIBRARIES})
diff --git a/intern/cycles/util/util_color.h b/intern/cycles/util/util_color.h
index c73beab98dc..62a9bf8e47d 100644
--- a/intern/cycles/util/util_color.h
+++ b/intern/cycles/util/util_color.h
@@ -47,7 +47,7 @@ ccl_device_inline float3 color_byte_to_float(uchar4 c)
return make_float3(c.x*(1.0f/255.0f), c.y*(1.0f/255.0f), c.z*(1.0f/255.0f));
}
-ccl_device float color_srgb_to_scene_linear(float c)
+ccl_device float color_srgb_to_linear(float c)
{
if(c < 0.04045f)
return (c < 0.0f)? 0.0f: c * (1.0f/12.92f);
@@ -55,7 +55,7 @@ ccl_device float color_srgb_to_scene_linear(float c)
return powf((c + 0.055f) * (1.0f / 1.055f), 2.4f);
}
-ccl_device float color_scene_linear_to_srgb(float c)
+ccl_device float color_linear_to_srgb(float c)
{
if(c < 0.0031308f)
return (c < 0.0f)? 0.0f: c * 12.92f;
@@ -150,13 +150,6 @@ ccl_device float3 xyY_to_xyz(float x, float y, float Y)
return make_float3(X, Y, Z);
}
-ccl_device float3 xyz_to_rgb(float x, float y, float z)
-{
- return make_float3(3.240479f * x + -1.537150f * y + -0.498535f * z,
- -0.969256f * x + 1.875991f * y + 0.041556f * z,
- 0.055648f * x + -0.204043f * y + 1.057311f * z);
-}
-
#ifdef __KERNEL_SSE2__
/*
* Calculate initial guess for arg^exp based on float representation
@@ -204,7 +197,7 @@ ccl_device_inline ssef fastpow24(const ssef &arg)
return x * (x * x);
}
-ccl_device ssef color_srgb_to_scene_linear(const ssef &c)
+ccl_device ssef color_srgb_to_linear(const ssef &c)
{
sseb cmp = c < ssef(0.04045f);
ssef lt = max(c * ssef(1.0f/12.92f), ssef(0.0f));
@@ -214,42 +207,37 @@ ccl_device ssef color_srgb_to_scene_linear(const ssef &c)
}
#endif /* __KERNEL_SSE2__ */
-ccl_device float3 color_srgb_to_scene_linear_v3(float3 c)
+ccl_device float3 color_srgb_to_linear_v3(float3 c)
{
- return make_float3(color_srgb_to_scene_linear(c.x),
- color_srgb_to_scene_linear(c.y),
- color_srgb_to_scene_linear(c.z));
+ return make_float3(color_srgb_to_linear(c.x),
+ color_srgb_to_linear(c.y),
+ color_srgb_to_linear(c.z));
}
-ccl_device float3 color_scene_linear_to_srgb_v3(float3 c)
+ccl_device float3 color_linear_to_srgb_v3(float3 c)
{
- return make_float3(color_scene_linear_to_srgb(c.x),
- color_scene_linear_to_srgb(c.y),
- color_scene_linear_to_srgb(c.z));
+ return make_float3(color_linear_to_srgb(c.x),
+ color_linear_to_srgb(c.y),
+ color_linear_to_srgb(c.z));
}
-ccl_device float4 color_srgb_to_scene_linear_v4(float4 c)
+ccl_device float4 color_srgb_to_linear_v4(float4 c)
{
#ifdef __KERNEL_SSE2__
ssef r_ssef;
float4 &r = (float4 &)r_ssef;
r = c;
- r_ssef = color_srgb_to_scene_linear(r_ssef);
+ r_ssef = color_srgb_to_linear(r_ssef);
r.w = c.w;
return r;
#else
- return make_float4(color_srgb_to_scene_linear(c.x),
- color_srgb_to_scene_linear(c.y),
- color_srgb_to_scene_linear(c.z),
+ return make_float4(color_srgb_to_linear(c.x),
+ color_srgb_to_linear(c.y),
+ color_srgb_to_linear(c.z),
c.w);
#endif
}
-ccl_device float linear_rgb_to_gray(float3 c)
-{
- return c.x*0.2126f + c.y*0.7152f + c.z*0.0722f;
-}
-
CCL_NAMESPACE_END
#endif /* __UTIL_COLOR_H__ */