Merge remote-tracking branch 'origin/master' into blender2.8

This commit is contained in:
Lukas Stockner 2018-06-14 22:54:42 +02:00
commit 27de412ca8
Notes: blender-bot 2023-02-14 09:24:53 +01:00
Referenced by issue #55489, 2.8 crash on startup
41 changed files with 384 additions and 176 deletions

View File

@ -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()

View File

@ -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}

View File

@ -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,

View File

@ -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)

View File

@ -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'

View File

@ -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]);
}
}
}

View File

@ -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]];

View File

@ -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");

View File

@ -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.

View File

@ -97,6 +97,12 @@ if(CYCLES_STANDALONE_REPOSITORY)
find_package(LLVM REQUIRED)
endif()
####
# OpenColorIO
if(WITH_OPENCOLORIO)
find_package(OpenColorIO REQUIRED)
endif()
####
# Boost
set(__boost_packages filesystem regex system thread date_time)

View File

@ -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__ */

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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)

View File

@ -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"

View File

@ -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);

View File

@ -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 */

View File

@ -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;
}

View File

@ -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;

View File

@ -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);
}

View File

@ -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)

View File

@ -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 */

View File

@ -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)
{
}

View File

@ -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;

View File

@ -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();

View File

@ -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();

View File

@ -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. */

View File

@ -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,

View File

@ -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";

View File

@ -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 */

View File

@ -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

View File

@ -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

View File

@ -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})

View File

@ -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__ */

View File

@ -40,6 +40,9 @@ roles:
# Non-color data
data: Non-Color
# CIE XYZ color space
XYZ: XYZ
displays:
sRGB:
- !<View> {name: Default, colorspace: sRGB}
@ -188,8 +191,7 @@ colorspaces:
allocationvars: [-8.5, 5]
from_reference: !<GroupTransform>
children:
- !<FileTransform> {src: rec709_to_aces.spimtx, interpolation: linear}
- !<FileTransform> {src: aces_to_xyz.spimtx, interpolation: linear}
- !<FileTransform> {src: srgb_to_xyz.spimtx, interpolation: linear}
- !<ColorSpace>
name: rrt_xyz