2011-04-27 11:58:34 +00:00
|
|
|
/*
|
2013-08-18 14:16:15 +00:00
|
|
|
* Copyright 2011-2013 Blender Foundation
|
2011-04-27 11:58:34 +00:00
|
|
|
*
|
2013-08-18 14:16:15 +00:00
|
|
|
* 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
|
2011-04-27 11:58:34 +00:00
|
|
|
*
|
2013-08-18 14:16:15 +00:00
|
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
2011-04-27 11:58:34 +00:00
|
|
|
*
|
2013-08-18 14:16:15 +00:00
|
|
|
* 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
|
2014-12-25 01:50:24 +00:00
|
|
|
* limitations under the License.
|
2011-04-27 11:58:34 +00:00
|
|
|
*/
|
|
|
|
|
2019-05-02 13:45:31 +00:00
|
|
|
#include "device/device.h"
|
|
|
|
|
Cycles: Make all #include statements relative to cycles source directory
The idea is to make include statements more explicit and obvious where the
file is coming from, additionally reducing chance of wrong header being
picked up.
For example, it was not obvious whether bvh.h was refferring to builder
or traversal, whenter node.h is a generic graph node or a shader node
and cases like that.
Surely this might look obvious for the active developers, but after some
time of not touching the code it becomes less obvious where file is coming
from.
This was briefly mentioned in T50824 and seems @brecht is fine with such
explicitness, but need to agree with all active developers before committing
this.
Please note that this patch is lacking changes related on GPU/OpenCL
support. This will be solved if/when we all agree this is a good idea to move
forward.
Reviewers: brecht, lukasstockner97, maiself, nirved, dingto, juicyfruit, swerner
Reviewed By: lukasstockner97, maiself, nirved, dingto
Subscribers: brecht
Differential Revision: https://developer.blender.org/D2586
2017-03-28 18:39:14 +00:00
|
|
|
#include "render/background.h"
|
|
|
|
#include "render/camera.h"
|
2019-05-02 13:45:31 +00:00
|
|
|
#include "render/colorspace.h"
|
Cycles: Make all #include statements relative to cycles source directory
The idea is to make include statements more explicit and obvious where the
file is coming from, additionally reducing chance of wrong header being
picked up.
For example, it was not obvious whether bvh.h was refferring to builder
or traversal, whenter node.h is a generic graph node or a shader node
and cases like that.
Surely this might look obvious for the active developers, but after some
time of not touching the code it becomes less obvious where file is coming
from.
This was briefly mentioned in T50824 and seems @brecht is fine with such
explicitness, but need to agree with all active developers before committing
this.
Please note that this patch is lacking changes related on GPU/OpenCL
support. This will be solved if/when we all agree this is a good idea to move
forward.
Reviewers: brecht, lukasstockner97, maiself, nirved, dingto, juicyfruit, swerner
Reviewed By: lukasstockner97, maiself, nirved, dingto
Subscribers: brecht
Differential Revision: https://developer.blender.org/D2586
2017-03-28 18:39:14 +00:00
|
|
|
#include "render/graph.h"
|
|
|
|
#include "render/integrator.h"
|
|
|
|
#include "render/light.h"
|
|
|
|
#include "render/mesh.h"
|
|
|
|
#include "render/nodes.h"
|
|
|
|
#include "render/object.h"
|
|
|
|
#include "render/osl.h"
|
2021-05-02 00:34:56 +00:00
|
|
|
#include "render/procedural.h"
|
Cycles: Make all #include statements relative to cycles source directory
The idea is to make include statements more explicit and obvious where the
file is coming from, additionally reducing chance of wrong header being
picked up.
For example, it was not obvious whether bvh.h was refferring to builder
or traversal, whenter node.h is a generic graph node or a shader node
and cases like that.
Surely this might look obvious for the active developers, but after some
time of not touching the code it becomes less obvious where file is coming
from.
This was briefly mentioned in T50824 and seems @brecht is fine with such
explicitness, but need to agree with all active developers before committing
this.
Please note that this patch is lacking changes related on GPU/OpenCL
support. This will be solved if/when we all agree this is a good idea to move
forward.
Reviewers: brecht, lukasstockner97, maiself, nirved, dingto, juicyfruit, swerner
Reviewed By: lukasstockner97, maiself, nirved, dingto
Subscribers: brecht
Differential Revision: https://developer.blender.org/D2586
2017-03-28 18:39:14 +00:00
|
|
|
#include "render/scene.h"
|
|
|
|
#include "render/shader.h"
|
|
|
|
#include "render/svm.h"
|
|
|
|
#include "render/tables.h"
|
2011-04-27 11:58:34 +00:00
|
|
|
|
Cycles: Make all #include statements relative to cycles source directory
The idea is to make include statements more explicit and obvious where the
file is coming from, additionally reducing chance of wrong header being
picked up.
For example, it was not obvious whether bvh.h was refferring to builder
or traversal, whenter node.h is a generic graph node or a shader node
and cases like that.
Surely this might look obvious for the active developers, but after some
time of not touching the code it becomes less obvious where file is coming
from.
This was briefly mentioned in T50824 and seems @brecht is fine with such
explicitness, but need to agree with all active developers before committing
this.
Please note that this patch is lacking changes related on GPU/OpenCL
support. This will be solved if/when we all agree this is a good idea to move
forward.
Reviewers: brecht, lukasstockner97, maiself, nirved, dingto, juicyfruit, swerner
Reviewed By: lukasstockner97, maiself, nirved, dingto
Subscribers: brecht
Differential Revision: https://developer.blender.org/D2586
2017-03-28 18:39:14 +00:00
|
|
|
#include "util/util_foreach.h"
|
2018-10-28 09:37:41 +00:00
|
|
|
#include "util/util_murmurhash.h"
|
2020-06-05 09:39:11 +00:00
|
|
|
#include "util/util_task.h"
|
OpenColorIO: upgrade to version 2.0.0
Ref T84819
Build System
============
This is an API breaking new version, and the updated code only builds with
OpenColorIO 2.0 and later. Adding backwards compatibility was too complicated.
* Tinyxml was replaced with Expat, adding a new dependency.
* Yaml-cpp is now built as a dependency on Unix, as was already done on Windows.
* Removed currently unused LCMS code.
* Pystring remains built as part of OCIO itself, since it has no good build system.
* Linux and macOS check for the OpenColorIO verison, and disable it if too old.
Ref D10270
Processors and Transforms
=========================
CPU processors now need to be created to do CPU processing. These are cached
internally, but the cache lookup is not fast enough to execute per pixel or
texture sample, so for performance these are now also exposed in the C API.
The C API for transforms will no longer be needed afer all changes, so remove
it to simplify the API and fallback implementation.
Ref D10271
Display Transforms
==================
Needs a bit more manual work constructing the transform. LegacyViewingPipeline
could also have been used, but isn't really any simpler and since it's legacy
we better not rely on it.
We moved more logic into the opencolorio module, to simplify the API. There is
no need to wrap a dozen functions just to be able to do this in C rather than C++.
It's also tightly coupled to the GPU shader logic, and so should be in the same
module.
Ref D10271
GPU Display Shader
==================
To avoid baking exposure and gamma into the GLSL shader and requiring slow
recompiles when tweaking, we manually apply them in the shader. This leads
to some logic duplicaton between the CPU and GPU display processor, but it
seems unavoidable.
Caching was also changed. Previously this was done both on the imbuf and
opencolorio module levels. Now it's all done in the opencolorio module by
simply matching color space names. We no longer use cacheIDs from OpenColorIO
since computing them is expensive, and they are unlikely to match now that
more is baked into the shader code.
Shaders can now use multiple 2D textures, 3D textures and uniforms, rather
than a single 3D texture. So allocating and binding those adds some code.
Color space conversions for blending with overlays is now hardcoded in the
shader. This was using harcoded numbers anyway, if this every becomes a
general OpenColorIO transform it can be changed, but for now there is no
point to add code complexity.
Ref D10273
CIE XYZ
=======
We need standard CIE XYZ values for rendering effects like blackbody emission.
The relation to the scene linear role is based on OpenColorIO configuration.
In OpenColorIO 2.0 configs roles can no longer have the same name as color
spaces, which means our XYZ role and colorspace in the configuration give an
error.
Instead use the new standard aces_interchange role, which relates scene linear
to a known scene referred color space. Compatibility with the old XYZ role is
preserved, if the configuration file has no conflicting names.
Also includes a non-functional change to the configuraton file to use an
XYZ-to-ACES matrix instead of REC709-to-ACES, makes debugging a little easier
since the matrix is the same one we have in the code now and that is also
found easily in the ACES specs.
Ref D10274
2021-01-31 18:35:00 +00:00
|
|
|
#include "util/util_transform.h"
|
2011-04-27 11:58:34 +00:00
|
|
|
|
2018-06-14 15:48:19 +00:00
|
|
|
#ifdef WITH_OCIO
|
|
|
|
# include <OpenColorIO/OpenColorIO.h>
|
|
|
|
namespace OCIO = OCIO_NAMESPACE;
|
|
|
|
#endif
|
|
|
|
|
2011-04-27 11:58:34 +00:00
|
|
|
CCL_NAMESPACE_BEGIN
|
|
|
|
|
2017-10-06 16:06:15 +00:00
|
|
|
thread_mutex ShaderManager::lookup_table_mutex;
|
Cycles: Experiment with making previews more interactive
There were two major problems with the interactivity of material previews:
- Beckmann tables were re-generated on every material tweak.
This is because preview scene is not set to be persistent, so re-triggering
the render leads to the full scene re-sync.
- Images could take rather noticeable time to load with OIIO from the disk
on every tweak.
This patch addressed this two issues in the following way:
- Beckmann tables are now static on CPU memory.
They're couple of hundred kilobytes only, so wouldn't expect this to be
an issue. And they're needed for almost every render anyway.
This actually also makes blackbody table to be static, but it's even smaller
than beckmann table.
Not totally happy with this approach, but others seems to complicate things
quite a bit with all this render engine life time and so..
- For preview rendering all images are considered to be built-in. This means
instead of OIIO which re-loads images on every re-render they're coming
from ImBuf cache which is fully manageable from blender side and unused
images gets freed later.
This would make it impossible to have mipmapping with OSL for now, but we'll
be working on that later anyway and don't think mipmaps are really so crucial
for the material preview.
This seems to be a better alternative to making preview scene persistent,
because of much optimal memory control from blender side.
Reviewers: brecht, juicyfruit, campbellbarton, dingto
Subscribers: eyecandy, venomgfx
Differential Revision: https://developer.blender.org/D1132
2015-02-21 16:55:24 +00:00
|
|
|
vector<float> ShaderManager::beckmann_table;
|
2017-10-06 16:06:15 +00:00
|
|
|
bool ShaderManager::beckmann_table_ready = false;
|
Cycles: Experiment with making previews more interactive
There were two major problems with the interactivity of material previews:
- Beckmann tables were re-generated on every material tweak.
This is because preview scene is not set to be persistent, so re-triggering
the render leads to the full scene re-sync.
- Images could take rather noticeable time to load with OIIO from the disk
on every tweak.
This patch addressed this two issues in the following way:
- Beckmann tables are now static on CPU memory.
They're couple of hundred kilobytes only, so wouldn't expect this to be
an issue. And they're needed for almost every render anyway.
This actually also makes blackbody table to be static, but it's even smaller
than beckmann table.
Not totally happy with this approach, but others seems to complicate things
quite a bit with all this render engine life time and so..
- For preview rendering all images are considered to be built-in. This means
instead of OIIO which re-loads images on every re-render they're coming
from ImBuf cache which is fully manageable from blender side and unused
images gets freed later.
This would make it impossible to have mipmapping with OSL for now, but we'll
be working on that later anyway and don't think mipmaps are really so crucial
for the material preview.
This seems to be a better alternative to making preview scene persistent,
because of much optimal memory control from blender side.
Reviewers: brecht, juicyfruit, campbellbarton, dingto
Subscribers: eyecandy, venomgfx
Differential Revision: https://developer.blender.org/D1132
2015-02-21 16:55:24 +00:00
|
|
|
|
2014-06-20 19:21:05 +00:00
|
|
|
/* Beckmann sampling precomputed table, see bsdf_microfacet.h */
|
|
|
|
|
|
|
|
/* 2D slope distribution (alpha = 1.0) */
|
|
|
|
static float beckmann_table_P22(const float slope_x, const float slope_y)
|
|
|
|
{
|
|
|
|
return expf(-(slope_x * slope_x + slope_y * slope_y));
|
|
|
|
}
|
|
|
|
|
|
|
|
/* maximal slope amplitude (range that contains 99.99% of the distribution) */
|
|
|
|
static float beckmann_table_slope_max()
|
|
|
|
{
|
|
|
|
return 6.0;
|
|
|
|
}
|
|
|
|
|
2017-04-25 20:17:41 +00:00
|
|
|
/* MSVC 2015 needs this ugly hack to prevent a codegen bug on x86
|
|
|
|
* see T50176 for details
|
|
|
|
*/
|
2017-04-26 08:00:31 +00:00
|
|
|
#if defined(_MSC_VER) && (_MSC_VER == 1900)
|
|
|
|
# define MSVC_VOLATILE volatile
|
2017-04-25 20:17:41 +00:00
|
|
|
#else
|
2017-04-26 08:00:31 +00:00
|
|
|
# define MSVC_VOLATILE
|
2017-04-25 20:17:41 +00:00
|
|
|
#endif
|
|
|
|
|
2014-07-10 11:55:56 +00:00
|
|
|
/* Paper used: Importance Sampling Microfacet-Based BSDFs with the
|
|
|
|
* Distribution of Visible Normals. Supplemental Material 2/2.
|
|
|
|
*
|
|
|
|
* http://hal.inria.fr/docs/01/00/66/20/ANNEX/supplemental2.pdf
|
|
|
|
*/
|
2014-06-20 19:21:05 +00:00
|
|
|
static void beckmann_table_rows(float *table, int row_from, int row_to)
|
|
|
|
{
|
|
|
|
/* allocate temporary data */
|
|
|
|
const int DATA_TMP_SIZE = 512;
|
|
|
|
vector<double> slope_x(DATA_TMP_SIZE);
|
|
|
|
vector<double> CDF_P22_omega_i(DATA_TMP_SIZE);
|
2019-04-17 04:17:24 +00:00
|
|
|
|
2014-06-20 19:21:05 +00:00
|
|
|
/* loop over incident directions */
|
|
|
|
for (int index_theta = row_from; index_theta < row_to; index_theta++) {
|
|
|
|
/* incident vector */
|
|
|
|
const float cos_theta = index_theta / (BECKMANN_TABLE_SIZE - 1.0f);
|
|
|
|
const float sin_theta = safe_sqrtf(1.0f - cos_theta * cos_theta);
|
2019-04-17 04:17:24 +00:00
|
|
|
|
2014-06-20 19:21:05 +00:00
|
|
|
/* for a given incident vector
|
|
|
|
* integrate P22_{omega_i}(x_slope, 1, 1), Eq. (10) */
|
2016-05-22 17:11:26 +00:00
|
|
|
slope_x[0] = (double)-beckmann_table_slope_max();
|
2014-06-20 19:21:05 +00:00
|
|
|
CDF_P22_omega_i[0] = 0;
|
2019-04-17 04:17:24 +00:00
|
|
|
|
2017-04-25 20:17:41 +00:00
|
|
|
for (MSVC_VOLATILE int index_slope_x = 1; index_slope_x < DATA_TMP_SIZE; ++index_slope_x) {
|
2014-06-20 19:21:05 +00:00
|
|
|
/* slope_x */
|
2016-05-22 17:11:26 +00:00
|
|
|
slope_x[index_slope_x] = (double)(-beckmann_table_slope_max() +
|
|
|
|
2.0f * beckmann_table_slope_max() * index_slope_x /
|
|
|
|
(DATA_TMP_SIZE - 1.0f));
|
2019-04-17 04:17:24 +00:00
|
|
|
|
2014-06-20 19:21:05 +00:00
|
|
|
/* dot product with incident vector */
|
2014-06-23 07:47:52 +00:00
|
|
|
float dot_product = fmaxf(0.0f, -(float)slope_x[index_slope_x] * sin_theta + cos_theta);
|
2014-06-20 19:21:05 +00:00
|
|
|
/* marginalize P22_{omega_i}(x_slope, 1, 1), Eq. (10) */
|
|
|
|
float P22_omega_i = 0.0f;
|
2019-04-17 04:17:24 +00:00
|
|
|
|
2014-06-20 19:21:05 +00:00
|
|
|
for (int j = 0; j < 100; ++j) {
|
|
|
|
float slope_y = -beckmann_table_slope_max() +
|
|
|
|
2.0f * beckmann_table_slope_max() * j * (1.0f / 99.0f);
|
2014-06-23 07:47:52 +00:00
|
|
|
P22_omega_i += dot_product * beckmann_table_P22((float)slope_x[index_slope_x], slope_y);
|
2014-06-20 19:21:05 +00:00
|
|
|
}
|
2019-04-17 04:17:24 +00:00
|
|
|
|
2014-06-20 19:21:05 +00:00
|
|
|
/* CDF of P22_{omega_i}(x_slope, 1, 1), Eq. (10) */
|
2014-10-07 22:09:36 +00:00
|
|
|
CDF_P22_omega_i[index_slope_x] = CDF_P22_omega_i[index_slope_x - 1] + (double)P22_omega_i;
|
2014-06-20 19:21:05 +00:00
|
|
|
}
|
2019-04-17 04:17:24 +00:00
|
|
|
|
2014-06-20 19:21:05 +00:00
|
|
|
/* renormalize CDF_P22_omega_i */
|
|
|
|
for (int index_slope_x = 1; index_slope_x < DATA_TMP_SIZE; ++index_slope_x)
|
|
|
|
CDF_P22_omega_i[index_slope_x] /= CDF_P22_omega_i[DATA_TMP_SIZE - 1];
|
2019-04-17 04:17:24 +00:00
|
|
|
|
2014-06-20 19:21:05 +00:00
|
|
|
/* loop over random number U1 */
|
|
|
|
int index_slope_x = 0;
|
2019-04-17 04:17:24 +00:00
|
|
|
|
2014-06-20 19:21:05 +00:00
|
|
|
for (int index_U = 0; index_U < BECKMANN_TABLE_SIZE; ++index_U) {
|
2014-07-10 11:42:38 +00:00
|
|
|
const double U = 0.0000001 + 0.9999998 * index_U / (double)(BECKMANN_TABLE_SIZE - 1);
|
2019-04-17 04:17:24 +00:00
|
|
|
|
2014-06-20 19:21:05 +00:00
|
|
|
/* inverse CDF_P22_omega_i, solve Eq.(11) */
|
|
|
|
while (CDF_P22_omega_i[index_slope_x] <= U)
|
|
|
|
++index_slope_x;
|
2019-04-17 04:17:24 +00:00
|
|
|
|
2014-06-20 19:21:05 +00:00
|
|
|
const double interp = (CDF_P22_omega_i[index_slope_x] - U) /
|
|
|
|
(CDF_P22_omega_i[index_slope_x] - CDF_P22_omega_i[index_slope_x - 1]);
|
2019-04-17 04:17:24 +00:00
|
|
|
|
2014-06-20 19:21:05 +00:00
|
|
|
/* store value */
|
|
|
|
table[index_U + index_theta * BECKMANN_TABLE_SIZE] =
|
2014-10-07 22:09:36 +00:00
|
|
|
(float)(interp * slope_x[index_slope_x - 1] + (1.0 - interp) * slope_x[index_slope_x]);
|
2014-06-20 19:21:05 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-04-25 20:17:41 +00:00
|
|
|
#undef MSVC_VOLATILE
|
|
|
|
|
2014-06-20 19:21:05 +00:00
|
|
|
static void beckmann_table_build(vector<float> &table)
|
|
|
|
{
|
|
|
|
table.resize(BECKMANN_TABLE_SIZE * BECKMANN_TABLE_SIZE);
|
|
|
|
|
|
|
|
/* multithreaded build */
|
|
|
|
TaskPool pool;
|
|
|
|
|
|
|
|
for (int i = 0; i < BECKMANN_TABLE_SIZE; i += 8)
|
|
|
|
pool.push(function_bind(&beckmann_table_rows, &table[0], i, i + 8));
|
|
|
|
|
|
|
|
pool.wait_work();
|
|
|
|
}
|
|
|
|
|
2011-04-27 11:58:34 +00:00
|
|
|
/* Shader */
|
|
|
|
|
2016-05-07 22:18:32 +00:00
|
|
|
NODE_DEFINE(Shader)
|
|
|
|
{
|
|
|
|
NodeType *type = NodeType::add("shader", create);
|
2019-04-17 04:17:24 +00:00
|
|
|
|
2016-05-07 22:18:32 +00:00
|
|
|
SOCKET_BOOLEAN(use_mis, "Use MIS", true);
|
|
|
|
SOCKET_BOOLEAN(use_transparent_shadow, "Use Transparent Shadow", true);
|
|
|
|
SOCKET_BOOLEAN(heterogeneous_volume, "Heterogeneous Volume", true);
|
2019-04-17 04:17:24 +00:00
|
|
|
|
2016-05-07 22:18:32 +00:00
|
|
|
static NodeEnum volume_sampling_method_enum;
|
|
|
|
volume_sampling_method_enum.insert("distance", VOLUME_SAMPLING_DISTANCE);
|
|
|
|
volume_sampling_method_enum.insert("equiangular", VOLUME_SAMPLING_EQUIANGULAR);
|
|
|
|
volume_sampling_method_enum.insert("multiple_importance", VOLUME_SAMPLING_MULTIPLE_IMPORTANCE);
|
|
|
|
SOCKET_ENUM(volume_sampling_method,
|
|
|
|
"Volume Sampling Method",
|
|
|
|
volume_sampling_method_enum,
|
2020-03-11 16:49:00 +00:00
|
|
|
VOLUME_SAMPLING_MULTIPLE_IMPORTANCE);
|
2019-04-17 04:17:24 +00:00
|
|
|
|
2016-05-07 22:18:32 +00:00
|
|
|
static NodeEnum volume_interpolation_method_enum;
|
|
|
|
volume_interpolation_method_enum.insert("linear", VOLUME_INTERPOLATION_LINEAR);
|
|
|
|
volume_interpolation_method_enum.insert("cubic", VOLUME_INTERPOLATION_CUBIC);
|
|
|
|
SOCKET_ENUM(volume_interpolation_method,
|
|
|
|
"Volume Interpolation Method",
|
|
|
|
volume_interpolation_method_enum,
|
|
|
|
VOLUME_INTERPOLATION_LINEAR);
|
2019-04-17 04:17:24 +00:00
|
|
|
|
2020-03-07 13:38:52 +00:00
|
|
|
SOCKET_FLOAT(volume_step_rate, "Volume Step Rate", 1.0f);
|
|
|
|
|
2016-08-02 09:13:58 +00:00
|
|
|
static NodeEnum displacement_method_enum;
|
|
|
|
displacement_method_enum.insert("bump", DISPLACE_BUMP);
|
|
|
|
displacement_method_enum.insert("true", DISPLACE_TRUE);
|
|
|
|
displacement_method_enum.insert("both", DISPLACE_BOTH);
|
|
|
|
SOCKET_ENUM(displacement_method, "Displacement Method", displacement_method_enum, DISPLACE_BUMP);
|
2019-04-17 04:17:24 +00:00
|
|
|
|
2020-11-04 10:17:38 +00:00
|
|
|
SOCKET_INT(pass_id, "Pass ID", 0);
|
|
|
|
|
2016-05-07 22:18:32 +00:00
|
|
|
return type;
|
|
|
|
}
|
|
|
|
|
2021-03-15 15:11:12 +00:00
|
|
|
Shader::Shader() : Node(get_node_type())
|
2011-04-27 11:58:34 +00:00
|
|
|
{
|
Cycles: Render Passes
Currently supported passes:
* Combined, Z, Normal, Object Index, Material Index, Emission, Environment,
Diffuse/Glossy/Transmission x Direct/Indirect/Color
Not supported yet:
* UV, Vector, Mist
Only enabled for CPU devices at the moment, will do GPU tweaks tommorrow,
also for environment importance sampling.
Documentation:
http://wiki.blender.org/index.php/Doc:2.6/Manual/Render/Cycles/Passes
2012-01-25 17:23:52 +00:00
|
|
|
pass_id = 0;
|
2019-04-17 04:17:24 +00:00
|
|
|
|
2011-04-27 11:58:34 +00:00
|
|
|
graph = NULL;
|
2019-04-17 04:17:24 +00:00
|
|
|
|
2011-10-12 23:03:12 +00:00
|
|
|
has_surface = false;
|
2011-09-27 20:37:24 +00:00
|
|
|
has_surface_transparent = false;
|
2011-04-27 11:58:34 +00:00
|
|
|
has_surface_emission = false;
|
2013-04-01 20:26:52 +00:00
|
|
|
has_surface_bssrdf = false;
|
2011-04-27 11:58:34 +00:00
|
|
|
has_volume = false;
|
|
|
|
has_displacement = false;
|
2017-08-20 12:02:16 +00:00
|
|
|
has_bump = false;
|
2013-08-18 14:15:57 +00:00
|
|
|
has_bssrdf_bump = false;
|
2016-02-05 21:13:51 +00:00
|
|
|
has_surface_spatial_varying = false;
|
2016-02-05 20:33:37 +00:00
|
|
|
has_volume_spatial_varying = false;
|
2020-03-07 13:38:52 +00:00
|
|
|
has_volume_attribute_dependency = false;
|
2015-11-20 13:18:27 +00:00
|
|
|
has_integrator_dependency = false;
|
2017-07-21 02:18:11 +00:00
|
|
|
has_volume_connected = false;
|
2020-03-07 13:38:52 +00:00
|
|
|
prev_volume_step_rate = 0.0f;
|
2019-04-17 04:17:24 +00:00
|
|
|
|
2016-08-02 09:13:58 +00:00
|
|
|
displacement_method = DISPLACE_BUMP;
|
2019-04-17 04:17:24 +00:00
|
|
|
|
2016-05-14 12:50:03 +00:00
|
|
|
id = -1;
|
2019-04-17 04:17:24 +00:00
|
|
|
|
Cycles: optimize device updates
This optimizes device updates (during user edits or frame changes in
the viewport) by avoiding unnecessary computations. To achieve this,
we use a combination of the sockets' update flags as well as some new
flags passed to the various managers when tagging for an update to tell
exactly what the tagging is for (e.g. shader was modified, object was
removed, etc.).
Besides avoiding recomputations, we also avoid resending to the devices
unmodified data arrays, thus reducing bandwidth usage. For OptiX and
Embree, BVH packing was also multithreaded.
The performance improvements may vary depending on the used device (CPU
or GPU), and the content of the scene. Simple scenes (e.g. with no adaptive
subdivision or volumes) rendered using OptiX will benefit from this work
the most.
On average, for a variety of animated scenes, this gives a 3x speedup.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79174
Differential Revision: https://developer.blender.org/D9555
2021-01-22 14:01:26 +00:00
|
|
|
need_update_uvs = true;
|
|
|
|
need_update_attribute = true;
|
|
|
|
need_update_displacement = true;
|
2011-04-27 11:58:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Shader::~Shader()
|
|
|
|
{
|
|
|
|
delete graph;
|
|
|
|
}
|
|
|
|
|
2016-09-03 20:40:07 +00:00
|
|
|
bool Shader::is_constant_emission(float3 *emission)
|
|
|
|
{
|
2019-12-04 18:57:28 +00:00
|
|
|
/* If the shader has AOVs, they need to be evaluated, so we can't skip the shader. */
|
|
|
|
foreach (ShaderNode *node, graph->nodes) {
|
|
|
|
if (node->special_type == SHADER_SPECIAL_TYPE_OUTPUT_AOV) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-09-03 20:40:07 +00:00
|
|
|
ShaderInput *surf = graph->output()->input("Surface");
|
|
|
|
|
2019-02-19 16:44:58 +00:00
|
|
|
if (surf->link == NULL) {
|
2016-09-03 20:40:07 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2021-03-15 15:11:12 +00:00
|
|
|
if (surf->link->parent->type == EmissionNode::get_node_type()) {
|
2019-02-19 16:44:58 +00:00
|
|
|
EmissionNode *node = (EmissionNode *)surf->link->parent;
|
2016-09-03 20:40:07 +00:00
|
|
|
|
2019-02-19 16:44:58 +00:00
|
|
|
assert(node->input("Color"));
|
|
|
|
assert(node->input("Strength"));
|
2016-09-03 20:40:07 +00:00
|
|
|
|
2019-02-19 16:44:58 +00:00
|
|
|
if (node->input("Color")->link || node->input("Strength")->link) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2020-11-04 10:17:38 +00:00
|
|
|
*emission = node->get_color() * node->get_strength();
|
2016-09-03 20:40:07 +00:00
|
|
|
}
|
2021-03-15 15:11:12 +00:00
|
|
|
else if (surf->link->parent->type == BackgroundNode::get_node_type()) {
|
2019-02-19 16:44:58 +00:00
|
|
|
BackgroundNode *node = (BackgroundNode *)surf->link->parent;
|
2016-09-03 20:40:07 +00:00
|
|
|
|
2019-02-19 16:44:58 +00:00
|
|
|
assert(node->input("Color"));
|
|
|
|
assert(node->input("Strength"));
|
|
|
|
|
|
|
|
if (node->input("Color")->link || node->input("Strength")->link) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2020-11-04 10:17:38 +00:00
|
|
|
*emission = node->get_color() * node->get_strength();
|
2019-02-19 16:44:58 +00:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
return false;
|
|
|
|
}
|
2016-09-03 20:40:07 +00:00
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2011-04-27 11:58:34 +00:00
|
|
|
void Shader::set_graph(ShaderGraph *graph_)
|
|
|
|
{
|
2013-05-10 11:31:57 +00:00
|
|
|
/* do this here already so that we can detect if mesh or object attributes
|
|
|
|
* are needed, since the node attribute callbacks check if their sockets
|
|
|
|
* are connected but proxy nodes should not count */
|
2018-01-24 19:19:48 +00:00
|
|
|
if (graph_) {
|
2016-05-01 22:05:16 +00:00
|
|
|
graph_->remove_proxy_nodes();
|
2019-04-17 04:17:24 +00:00
|
|
|
|
2018-01-24 19:19:48 +00:00
|
|
|
if (displacement_method != DISPLACE_BUMP) {
|
|
|
|
graph_->compute_displacement_hash();
|
|
|
|
}
|
|
|
|
}
|
2019-04-17 04:17:24 +00:00
|
|
|
|
2018-01-24 19:19:48 +00:00
|
|
|
/* update geometry if displacement changed */
|
|
|
|
if (displacement_method != DISPLACE_BUMP) {
|
|
|
|
const char *old_hash = (graph) ? graph->displacement_hash.c_str() : "";
|
|
|
|
const char *new_hash = (graph_) ? graph_->displacement_hash.c_str() : "";
|
2019-04-17 04:17:24 +00:00
|
|
|
|
2018-01-24 19:19:48 +00:00
|
|
|
if (strcmp(old_hash, new_hash) != 0) {
|
Cycles: optimize device updates
This optimizes device updates (during user edits or frame changes in
the viewport) by avoiding unnecessary computations. To achieve this,
we use a combination of the sockets' update flags as well as some new
flags passed to the various managers when tagging for an update to tell
exactly what the tagging is for (e.g. shader was modified, object was
removed, etc.).
Besides avoiding recomputations, we also avoid resending to the devices
unmodified data arrays, thus reducing bandwidth usage. For OptiX and
Embree, BVH packing was also multithreaded.
The performance improvements may vary depending on the used device (CPU
or GPU), and the content of the scene. Simple scenes (e.g. with no adaptive
subdivision or volumes) rendered using OptiX will benefit from this work
the most.
On average, for a variety of animated scenes, this gives a 3x speedup.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79174
Differential Revision: https://developer.blender.org/D9555
2021-01-22 14:01:26 +00:00
|
|
|
need_update_displacement = true;
|
2018-01-24 19:19:48 +00:00
|
|
|
}
|
|
|
|
}
|
2019-04-17 04:17:24 +00:00
|
|
|
|
2011-04-27 11:58:34 +00:00
|
|
|
/* assign graph */
|
|
|
|
delete graph;
|
|
|
|
graph = graph_;
|
2019-04-17 04:17:24 +00:00
|
|
|
|
2017-05-19 02:59:35 +00:00
|
|
|
/* Store info here before graph optimization to make sure that
|
|
|
|
* nodes that get optimized away still count. */
|
|
|
|
has_volume_connected = (graph->output()->input("Volume")->link != NULL);
|
2011-04-27 11:58:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void Shader::tag_update(Scene *scene)
|
|
|
|
{
|
|
|
|
/* update tag */
|
2020-11-04 10:17:38 +00:00
|
|
|
tag_modified();
|
Cycles: optimize device updates
This optimizes device updates (during user edits or frame changes in
the viewport) by avoiding unnecessary computations. To achieve this,
we use a combination of the sockets' update flags as well as some new
flags passed to the various managers when tagging for an update to tell
exactly what the tagging is for (e.g. shader was modified, object was
removed, etc.).
Besides avoiding recomputations, we also avoid resending to the devices
unmodified data arrays, thus reducing bandwidth usage. For OptiX and
Embree, BVH packing was also multithreaded.
The performance improvements may vary depending on the used device (CPU
or GPU), and the content of the scene. Simple scenes (e.g. with no adaptive
subdivision or volumes) rendered using OptiX will benefit from this work
the most.
On average, for a variety of animated scenes, this gives a 3x speedup.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79174
Differential Revision: https://developer.blender.org/D9555
2021-01-22 14:01:26 +00:00
|
|
|
|
|
|
|
scene->shader_manager->tag_update(scene, ShaderManager::SHADER_MODIFIED);
|
2019-04-17 04:17:24 +00:00
|
|
|
|
2011-04-27 11:58:34 +00:00
|
|
|
/* if the shader previously was emissive, update light distribution,
|
|
|
|
* if the new shader is emissive, a light manager update tag will be
|
|
|
|
* done in the shader manager device update. */
|
2013-06-18 09:36:00 +00:00
|
|
|
if (use_mis && has_surface_emission)
|
Cycles: optimize device updates
This optimizes device updates (during user edits or frame changes in
the viewport) by avoiding unnecessary computations. To achieve this,
we use a combination of the sockets' update flags as well as some new
flags passed to the various managers when tagging for an update to tell
exactly what the tagging is for (e.g. shader was modified, object was
removed, etc.).
Besides avoiding recomputations, we also avoid resending to the devices
unmodified data arrays, thus reducing bandwidth usage. For OptiX and
Embree, BVH packing was also multithreaded.
The performance improvements may vary depending on the used device (CPU
or GPU), and the content of the scene. Simple scenes (e.g. with no adaptive
subdivision or volumes) rendered using OptiX will benefit from this work
the most.
On average, for a variety of animated scenes, this gives a 3x speedup.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79174
Differential Revision: https://developer.blender.org/D9555
2021-01-22 14:01:26 +00:00
|
|
|
scene->light_manager->tag_update(scene, LightManager::SHADER_MODIFIED);
|
2019-04-17 04:17:24 +00:00
|
|
|
|
2016-09-02 07:58:41 +00:00
|
|
|
/* Special handle of background MIS light for now: for some reason it
|
|
|
|
* has use_mis set to false. We are quite close to release now, so
|
|
|
|
* better to be safe.
|
|
|
|
*/
|
2020-05-14 15:41:37 +00:00
|
|
|
if (this == scene->background->get_shader(scene)) {
|
|
|
|
scene->light_manager->need_update_background = true;
|
|
|
|
if (scene->light_manager->has_background_light(scene)) {
|
Cycles: optimize device updates
This optimizes device updates (during user edits or frame changes in
the viewport) by avoiding unnecessary computations. To achieve this,
we use a combination of the sockets' update flags as well as some new
flags passed to the various managers when tagging for an update to tell
exactly what the tagging is for (e.g. shader was modified, object was
removed, etc.).
Besides avoiding recomputations, we also avoid resending to the devices
unmodified data arrays, thus reducing bandwidth usage. For OptiX and
Embree, BVH packing was also multithreaded.
The performance improvements may vary depending on the used device (CPU
or GPU), and the content of the scene. Simple scenes (e.g. with no adaptive
subdivision or volumes) rendered using OptiX will benefit from this work
the most.
On average, for a variety of animated scenes, this gives a 3x speedup.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79174
Differential Revision: https://developer.blender.org/D9555
2021-01-22 14:01:26 +00:00
|
|
|
scene->light_manager->tag_update(scene, LightManager::SHADER_MODIFIED);
|
2020-05-14 15:41:37 +00:00
|
|
|
}
|
2016-09-02 07:58:41 +00:00
|
|
|
}
|
2019-04-17 04:17:24 +00:00
|
|
|
|
2013-12-31 16:30:34 +00:00
|
|
|
/* quick detection of which kind of shaders we have to avoid loading
|
|
|
|
* e.g. surface attributes when there is only a volume shader. this could
|
|
|
|
* be more fine grained but it's better than nothing */
|
|
|
|
OutputNode *output = graph->output();
|
2015-01-19 14:08:58 +00:00
|
|
|
bool prev_has_volume = has_volume;
|
2013-12-31 16:30:34 +00:00
|
|
|
has_surface = has_surface || output->input("Surface")->link;
|
|
|
|
has_volume = has_volume || output->input("Volume")->link;
|
|
|
|
has_displacement = has_displacement || output->input("Displacement")->link;
|
2019-04-17 04:17:24 +00:00
|
|
|
|
2011-04-27 11:58:34 +00:00
|
|
|
/* get requested attributes. this could be optimized by pruning unused
|
2012-06-09 17:22:52 +00:00
|
|
|
* nodes here already, but that's the job of the shader manager currently,
|
|
|
|
* and may not be so great for interactive rendering where you temporarily
|
|
|
|
* disconnect a node */
|
2019-04-17 04:17:24 +00:00
|
|
|
|
2011-04-27 11:58:34 +00:00
|
|
|
AttributeRequestSet prev_attributes = attributes;
|
2019-04-17 04:17:24 +00:00
|
|
|
|
2011-04-27 11:58:34 +00:00
|
|
|
attributes.clear();
|
|
|
|
foreach (ShaderNode *node, graph->nodes)
|
2013-12-31 16:30:34 +00:00
|
|
|
node->attributes(this, &attributes);
|
2019-04-17 04:17:24 +00:00
|
|
|
|
2020-12-14 12:42:34 +00:00
|
|
|
if (has_displacement) {
|
|
|
|
if (displacement_method == DISPLACE_BOTH) {
|
|
|
|
attributes.add(ATTR_STD_POSITION_UNDISPLACED);
|
|
|
|
}
|
|
|
|
if (displacement_method_is_modified()) {
|
Cycles: optimize device updates
This optimizes device updates (during user edits or frame changes in
the viewport) by avoiding unnecessary computations. To achieve this,
we use a combination of the sockets' update flags as well as some new
flags passed to the various managers when tagging for an update to tell
exactly what the tagging is for (e.g. shader was modified, object was
removed, etc.).
Besides avoiding recomputations, we also avoid resending to the devices
unmodified data arrays, thus reducing bandwidth usage. For OptiX and
Embree, BVH packing was also multithreaded.
The performance improvements may vary depending on the used device (CPU
or GPU), and the content of the scene. Simple scenes (e.g. with no adaptive
subdivision or volumes) rendered using OptiX will benefit from this work
the most.
On average, for a variety of animated scenes, this gives a 3x speedup.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79174
Differential Revision: https://developer.blender.org/D9555
2021-01-22 14:01:26 +00:00
|
|
|
need_update_displacement = true;
|
|
|
|
scene->geometry_manager->tag_update(scene, GeometryManager::SHADER_DISPLACEMENT_MODIFIED);
|
2020-12-14 12:42:34 +00:00
|
|
|
scene->object_manager->need_flags_update = true;
|
|
|
|
}
|
2016-08-13 16:27:17 +00:00
|
|
|
}
|
2019-04-17 04:17:24 +00:00
|
|
|
|
2011-04-27 11:58:34 +00:00
|
|
|
/* compare if the attributes changed, mesh manager will check
|
Cycles: optimize device updates
This optimizes device updates (during user edits or frame changes in
the viewport) by avoiding unnecessary computations. To achieve this,
we use a combination of the sockets' update flags as well as some new
flags passed to the various managers when tagging for an update to tell
exactly what the tagging is for (e.g. shader was modified, object was
removed, etc.).
Besides avoiding recomputations, we also avoid resending to the devices
unmodified data arrays, thus reducing bandwidth usage. For OptiX and
Embree, BVH packing was also multithreaded.
The performance improvements may vary depending on the used device (CPU
or GPU), and the content of the scene. Simple scenes (e.g. with no adaptive
subdivision or volumes) rendered using OptiX will benefit from this work
the most.
On average, for a variety of animated scenes, this gives a 3x speedup.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79174
Differential Revision: https://developer.blender.org/D9555
2021-01-22 14:01:26 +00:00
|
|
|
* need_update_attribute, update the relevant meshes and clear it. */
|
2011-04-27 11:58:34 +00:00
|
|
|
if (attributes.modified(prev_attributes)) {
|
Cycles: optimize device updates
This optimizes device updates (during user edits or frame changes in
the viewport) by avoiding unnecessary computations. To achieve this,
we use a combination of the sockets' update flags as well as some new
flags passed to the various managers when tagging for an update to tell
exactly what the tagging is for (e.g. shader was modified, object was
removed, etc.).
Besides avoiding recomputations, we also avoid resending to the devices
unmodified data arrays, thus reducing bandwidth usage. For OptiX and
Embree, BVH packing was also multithreaded.
The performance improvements may vary depending on the used device (CPU
or GPU), and the content of the scene. Simple scenes (e.g. with no adaptive
subdivision or volumes) rendered using OptiX will benefit from this work
the most.
On average, for a variety of animated scenes, this gives a 3x speedup.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79174
Differential Revision: https://developer.blender.org/D9555
2021-01-22 14:01:26 +00:00
|
|
|
need_update_attribute = true;
|
|
|
|
scene->geometry_manager->tag_update(scene, GeometryManager::SHADER_ATTRIBUTE_MODIFIED);
|
2021-01-25 13:56:57 +00:00
|
|
|
scene->procedural_manager->tag_update();
|
2011-04-27 11:58:34 +00:00
|
|
|
}
|
2019-04-17 04:17:24 +00:00
|
|
|
|
2020-03-07 13:38:52 +00:00
|
|
|
if (has_volume != prev_has_volume || volume_step_rate != prev_volume_step_rate) {
|
2020-02-02 11:04:19 +00:00
|
|
|
scene->geometry_manager->need_flags_update = true;
|
2015-01-19 14:08:58 +00:00
|
|
|
scene->object_manager->need_flags_update = true;
|
2020-03-07 13:38:52 +00:00
|
|
|
prev_volume_step_rate = volume_step_rate;
|
2015-01-19 14:08:58 +00:00
|
|
|
}
|
2011-04-27 11:58:34 +00:00
|
|
|
}
|
|
|
|
|
2012-10-30 11:51:17 +00:00
|
|
|
void Shader::tag_used(Scene *scene)
|
|
|
|
{
|
|
|
|
/* if an unused shader suddenly gets used somewhere, it needs to be
|
|
|
|
* recompiled because it was skipped for compilation before */
|
2021-05-02 00:34:56 +00:00
|
|
|
if (!reference_count()) {
|
2020-11-04 10:17:38 +00:00
|
|
|
tag_modified();
|
2021-05-02 00:34:56 +00:00
|
|
|
/* We do not reference here as the shader will be referenced when added to a socket. */
|
Cycles: optimize device updates
This optimizes device updates (during user edits or frame changes in
the viewport) by avoiding unnecessary computations. To achieve this,
we use a combination of the sockets' update flags as well as some new
flags passed to the various managers when tagging for an update to tell
exactly what the tagging is for (e.g. shader was modified, object was
removed, etc.).
Besides avoiding recomputations, we also avoid resending to the devices
unmodified data arrays, thus reducing bandwidth usage. For OptiX and
Embree, BVH packing was also multithreaded.
The performance improvements may vary depending on the used device (CPU
or GPU), and the content of the scene. Simple scenes (e.g. with no adaptive
subdivision or volumes) rendered using OptiX will benefit from this work
the most.
On average, for a variety of animated scenes, this gives a 3x speedup.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79174
Differential Revision: https://developer.blender.org/D9555
2021-01-22 14:01:26 +00:00
|
|
|
scene->shader_manager->tag_update(scene, ShaderManager::SHADER_MODIFIED);
|
2012-10-30 11:51:17 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
Cycles: optimize device updates
This optimizes device updates (during user edits or frame changes in
the viewport) by avoiding unnecessary computations. To achieve this,
we use a combination of the sockets' update flags as well as some new
flags passed to the various managers when tagging for an update to tell
exactly what the tagging is for (e.g. shader was modified, object was
removed, etc.).
Besides avoiding recomputations, we also avoid resending to the devices
unmodified data arrays, thus reducing bandwidth usage. For OptiX and
Embree, BVH packing was also multithreaded.
The performance improvements may vary depending on the used device (CPU
or GPU), and the content of the scene. Simple scenes (e.g. with no adaptive
subdivision or volumes) rendered using OptiX will benefit from this work
the most.
On average, for a variety of animated scenes, this gives a 3x speedup.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79174
Differential Revision: https://developer.blender.org/D9555
2021-01-22 14:01:26 +00:00
|
|
|
bool Shader::need_update_geometry() const
|
|
|
|
{
|
|
|
|
return need_update_uvs || need_update_attribute || need_update_displacement;
|
|
|
|
}
|
|
|
|
|
2011-04-27 11:58:34 +00:00
|
|
|
/* Shader Manager */
|
|
|
|
|
|
|
|
ShaderManager::ShaderManager()
|
|
|
|
{
|
Cycles: optimize device updates
This optimizes device updates (during user edits or frame changes in
the viewport) by avoiding unnecessary computations. To achieve this,
we use a combination of the sockets' update flags as well as some new
flags passed to the various managers when tagging for an update to tell
exactly what the tagging is for (e.g. shader was modified, object was
removed, etc.).
Besides avoiding recomputations, we also avoid resending to the devices
unmodified data arrays, thus reducing bandwidth usage. For OptiX and
Embree, BVH packing was also multithreaded.
The performance improvements may vary depending on the used device (CPU
or GPU), and the content of the scene. Simple scenes (e.g. with no adaptive
subdivision or volumes) rendered using OptiX will benefit from this work
the most.
On average, for a variety of animated scenes, this gives a 3x speedup.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79174
Differential Revision: https://developer.blender.org/D9555
2021-01-22 14:01:26 +00:00
|
|
|
update_flags = UPDATE_ALL;
|
2014-06-20 19:21:05 +00:00
|
|
|
beckmann_table_offset = TABLE_OFFSET_INVALID;
|
2018-06-14 15:48:19 +00:00
|
|
|
|
OpenColorIO: upgrade to version 2.0.0
Ref T84819
Build System
============
This is an API breaking new version, and the updated code only builds with
OpenColorIO 2.0 and later. Adding backwards compatibility was too complicated.
* Tinyxml was replaced with Expat, adding a new dependency.
* Yaml-cpp is now built as a dependency on Unix, as was already done on Windows.
* Removed currently unused LCMS code.
* Pystring remains built as part of OCIO itself, since it has no good build system.
* Linux and macOS check for the OpenColorIO verison, and disable it if too old.
Ref D10270
Processors and Transforms
=========================
CPU processors now need to be created to do CPU processing. These are cached
internally, but the cache lookup is not fast enough to execute per pixel or
texture sample, so for performance these are now also exposed in the C API.
The C API for transforms will no longer be needed afer all changes, so remove
it to simplify the API and fallback implementation.
Ref D10271
Display Transforms
==================
Needs a bit more manual work constructing the transform. LegacyViewingPipeline
could also have been used, but isn't really any simpler and since it's legacy
we better not rely on it.
We moved more logic into the opencolorio module, to simplify the API. There is
no need to wrap a dozen functions just to be able to do this in C rather than C++.
It's also tightly coupled to the GPU shader logic, and so should be in the same
module.
Ref D10271
GPU Display Shader
==================
To avoid baking exposure and gamma into the GLSL shader and requiring slow
recompiles when tweaking, we manually apply them in the shader. This leads
to some logic duplicaton between the CPU and GPU display processor, but it
seems unavoidable.
Caching was also changed. Previously this was done both on the imbuf and
opencolorio module levels. Now it's all done in the opencolorio module by
simply matching color space names. We no longer use cacheIDs from OpenColorIO
since computing them is expensive, and they are unlikely to match now that
more is baked into the shader code.
Shaders can now use multiple 2D textures, 3D textures and uniforms, rather
than a single 3D texture. So allocating and binding those adds some code.
Color space conversions for blending with overlays is now hardcoded in the
shader. This was using harcoded numbers anyway, if this every becomes a
general OpenColorIO transform it can be changed, but for now there is no
point to add code complexity.
Ref D10273
CIE XYZ
=======
We need standard CIE XYZ values for rendering effects like blackbody emission.
The relation to the scene linear role is based on OpenColorIO configuration.
In OpenColorIO 2.0 configs roles can no longer have the same name as color
spaces, which means our XYZ role and colorspace in the configuration give an
error.
Instead use the new standard aces_interchange role, which relates scene linear
to a known scene referred color space. Compatibility with the old XYZ role is
preserved, if the configuration file has no conflicting names.
Also includes a non-functional change to the configuraton file to use an
XYZ-to-ACES matrix instead of REC709-to-ACES, makes debugging a little easier
since the matrix is the same one we have in the code now and that is also
found easily in the ACES specs.
Ref D10274
2021-01-31 18:35:00 +00:00
|
|
|
init_xyz_transforms();
|
2011-04-27 11:58:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
ShaderManager::~ShaderManager()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2020-03-11 16:49:00 +00:00
|
|
|
ShaderManager *ShaderManager::create(int shadingsystem)
|
2011-04-27 11:58:34 +00:00
|
|
|
{
|
|
|
|
ShaderManager *manager;
|
|
|
|
|
2018-11-09 11:08:51 +00:00
|
|
|
(void)shadingsystem; /* Ignored when built without OSL. */
|
2015-03-27 14:09:41 +00:00
|
|
|
|
2011-04-27 11:58:34 +00:00
|
|
|
#ifdef WITH_OSL
|
2017-05-20 12:21:27 +00:00
|
|
|
if (shadingsystem == SHADINGSYSTEM_OSL) {
|
2011-04-27 11:58:34 +00:00
|
|
|
manager = new OSLShaderManager();
|
2017-05-20 12:21:27 +00:00
|
|
|
}
|
2011-04-27 11:58:34 +00:00
|
|
|
else
|
|
|
|
#endif
|
2017-05-20 12:21:27 +00:00
|
|
|
{
|
2011-04-27 11:58:34 +00:00
|
|
|
manager = new SVMShaderManager();
|
2017-05-20 12:21:27 +00:00
|
|
|
}
|
2018-07-06 08:17:58 +00:00
|
|
|
|
2011-04-27 11:58:34 +00:00
|
|
|
return manager;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint ShaderManager::get_attribute_id(ustring name)
|
|
|
|
{
|
2017-04-10 14:53:01 +00:00
|
|
|
thread_scoped_spin_lock lock(attribute_lock_);
|
|
|
|
|
2011-04-27 11:58:34 +00:00
|
|
|
/* get a unique id for each name, for SVM attribute lookup */
|
|
|
|
AttributeIDMap::iterator it = unique_attribute_id.find(name);
|
|
|
|
|
|
|
|
if (it != unique_attribute_id.end())
|
|
|
|
return it->second;
|
2018-07-06 08:17:58 +00:00
|
|
|
|
2012-04-30 12:49:26 +00:00
|
|
|
uint id = (uint)ATTR_STD_NUM + unique_attribute_id.size();
|
2011-04-27 11:58:34 +00:00
|
|
|
unique_attribute_id[name] = id;
|
|
|
|
return id;
|
|
|
|
}
|
|
|
|
|
2012-04-30 12:49:26 +00:00
|
|
|
uint ShaderManager::get_attribute_id(AttributeStandard std)
|
2011-04-27 11:58:34 +00:00
|
|
|
{
|
|
|
|
return (uint)std;
|
|
|
|
}
|
|
|
|
|
2016-08-16 23:42:08 +00:00
|
|
|
int ShaderManager::get_shader_id(Shader *shader, bool smooth)
|
2011-04-27 11:58:34 +00:00
|
|
|
{
|
|
|
|
/* get a shader id to pass to the kernel */
|
2016-08-16 23:42:08 +00:00
|
|
|
int id = shader->id;
|
|
|
|
|
2011-09-27 20:37:24 +00:00
|
|
|
/* smooth flag */
|
2011-04-27 11:58:34 +00:00
|
|
|
if (smooth)
|
2011-09-27 20:37:24 +00:00
|
|
|
id |= SHADER_SMOOTH_NORMAL;
|
2018-07-06 08:17:58 +00:00
|
|
|
|
2011-09-27 20:37:24 +00:00
|
|
|
/* default flags */
|
|
|
|
id |= SHADER_CAST_SHADOW | SHADER_AREA_LIGHT;
|
2018-07-06 08:17:58 +00:00
|
|
|
|
2011-04-27 11:58:34 +00:00
|
|
|
return id;
|
|
|
|
}
|
|
|
|
|
2021-05-02 00:34:56 +00:00
|
|
|
void ShaderManager::device_update(Device *device,
|
|
|
|
DeviceScene *dscene,
|
|
|
|
Scene *scene,
|
|
|
|
Progress &progress)
|
2012-10-30 11:51:17 +00:00
|
|
|
{
|
Cycles: optimize device updates
This optimizes device updates (during user edits or frame changes in
the viewport) by avoiding unnecessary computations. To achieve this,
we use a combination of the sockets' update flags as well as some new
flags passed to the various managers when tagging for an update to tell
exactly what the tagging is for (e.g. shader was modified, object was
removed, etc.).
Besides avoiding recomputations, we also avoid resending to the devices
unmodified data arrays, thus reducing bandwidth usage. For OptiX and
Embree, BVH packing was also multithreaded.
The performance improvements may vary depending on the used device (CPU
or GPU), and the content of the scene. Simple scenes (e.g. with no adaptive
subdivision or volumes) rendered using OptiX will benefit from this work
the most.
On average, for a variety of animated scenes, this gives a 3x speedup.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79174
Differential Revision: https://developer.blender.org/D9555
2021-01-22 14:01:26 +00:00
|
|
|
if (!need_update()) {
|
2020-03-11 16:49:00 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2016-05-14 12:50:03 +00:00
|
|
|
uint id = 0;
|
|
|
|
foreach (Shader *shader, scene->shaders) {
|
|
|
|
shader->id = id++;
|
|
|
|
}
|
2019-04-17 04:17:24 +00:00
|
|
|
|
2021-05-02 00:34:56 +00:00
|
|
|
/* Those shaders should always be compiled as they are used as fallback if a shader cannot be
|
|
|
|
* found, e.g. bad shader index for the triangle shaders on a Mesh. */
|
|
|
|
assert(scene->default_surface->reference_count() != 0);
|
|
|
|
assert(scene->default_light->reference_count() != 0);
|
|
|
|
assert(scene->default_background->reference_count() != 0);
|
|
|
|
assert(scene->default_empty->reference_count() != 0);
|
2019-04-17 04:17:24 +00:00
|
|
|
|
2021-05-02 00:34:56 +00:00
|
|
|
device_update_specific(device, dscene, scene, progress);
|
2012-10-30 11:51:17 +00:00
|
|
|
}
|
|
|
|
|
2015-03-27 10:47:55 +00:00
|
|
|
void ShaderManager::device_update_common(Device *device,
|
|
|
|
DeviceScene *dscene,
|
|
|
|
Scene *scene,
|
|
|
|
Progress & /*progress*/)
|
2011-09-27 20:37:24 +00:00
|
|
|
{
|
2018-03-07 23:35:24 +00:00
|
|
|
dscene->shaders.free();
|
2019-04-17 04:17:24 +00:00
|
|
|
|
2011-09-27 20:37:24 +00:00
|
|
|
if (scene->shaders.size() == 0)
|
|
|
|
return;
|
2019-04-17 04:17:24 +00:00
|
|
|
|
2018-03-07 23:35:24 +00:00
|
|
|
KernelShader *kshader = dscene->shaders.alloc(scene->shaders.size());
|
2013-12-28 01:27:48 +00:00
|
|
|
bool has_volumes = false;
|
2015-09-08 06:28:02 +00:00
|
|
|
bool has_transparent_shadow = false;
|
2019-04-17 04:17:24 +00:00
|
|
|
|
2011-09-27 20:37:24 +00:00
|
|
|
foreach (Shader *shader, scene->shaders) {
|
|
|
|
uint flag = 0;
|
2019-04-17 04:17:24 +00:00
|
|
|
|
2020-11-04 10:17:38 +00:00
|
|
|
if (shader->get_use_mis())
|
2013-06-18 09:36:00 +00:00
|
|
|
flag |= SD_USE_MIS;
|
2021-04-15 14:21:37 +00:00
|
|
|
if (shader->has_surface_emission)
|
|
|
|
flag |= SD_HAS_EMISSION;
|
2020-11-04 10:17:38 +00:00
|
|
|
if (shader->has_surface_transparent && shader->get_use_transparent_shadow())
|
2013-06-18 09:36:00 +00:00
|
|
|
flag |= SD_HAS_TRANSPARENT_SHADOW;
|
2013-12-28 01:27:48 +00:00
|
|
|
if (shader->has_volume) {
|
2011-09-27 20:37:24 +00:00
|
|
|
flag |= SD_HAS_VOLUME;
|
2013-12-28 01:27:48 +00:00
|
|
|
has_volumes = true;
|
2019-04-17 04:17:24 +00:00
|
|
|
|
2013-12-28 01:27:48 +00:00
|
|
|
/* todo: this could check more fine grained, to skip useless volumes
|
2015-09-08 06:29:14 +00:00
|
|
|
* enclosed inside an opaque bsdf.
|
|
|
|
*/
|
2013-12-28 01:27:48 +00:00
|
|
|
flag |= SD_HAS_TRANSPARENT_SHADOW;
|
|
|
|
}
|
2017-05-19 02:59:35 +00:00
|
|
|
/* in this case we can assume transparent surface */
|
|
|
|
if (shader->has_volume_connected && !shader->has_surface)
|
|
|
|
flag |= SD_HAS_ONLY_VOLUME;
|
2020-03-07 13:38:52 +00:00
|
|
|
if (shader->has_volume) {
|
2020-11-04 10:17:38 +00:00
|
|
|
if (shader->get_heterogeneous_volume() && shader->has_volume_spatial_varying)
|
2020-03-07 13:38:52 +00:00
|
|
|
flag |= SD_HETEROGENEOUS_VOLUME;
|
|
|
|
}
|
|
|
|
if (shader->has_volume_attribute_dependency)
|
|
|
|
flag |= SD_NEED_VOLUME_ATTRIBUTES;
|
2013-08-18 14:15:57 +00:00
|
|
|
if (shader->has_bssrdf_bump)
|
|
|
|
flag |= SD_HAS_BSSRDF_BUMP;
|
2017-10-08 02:32:25 +00:00
|
|
|
if (device->info.has_volume_decoupled) {
|
2020-11-04 10:17:38 +00:00
|
|
|
if (shader->get_volume_sampling_method() == VOLUME_SAMPLING_EQUIANGULAR)
|
2017-10-08 02:32:25 +00:00
|
|
|
flag |= SD_VOLUME_EQUIANGULAR;
|
2020-11-04 10:17:38 +00:00
|
|
|
if (shader->get_volume_sampling_method() == VOLUME_SAMPLING_MULTIPLE_IMPORTANCE)
|
2017-10-08 02:32:25 +00:00
|
|
|
flag |= SD_VOLUME_MIS;
|
|
|
|
}
|
2020-11-04 10:17:38 +00:00
|
|
|
if (shader->get_volume_interpolation_method() == VOLUME_INTERPOLATION_CUBIC)
|
2014-10-22 13:23:45 +00:00
|
|
|
flag |= SD_VOLUME_CUBIC;
|
2017-08-20 12:02:16 +00:00
|
|
|
if (shader->has_bump)
|
2014-11-11 20:21:56 +00:00
|
|
|
flag |= SD_HAS_BUMP;
|
2020-11-04 10:17:38 +00:00
|
|
|
if (shader->get_displacement_method() != DISPLACE_BUMP)
|
2016-08-14 15:44:25 +00:00
|
|
|
flag |= SD_HAS_DISPLACEMENT;
|
2019-04-17 04:17:24 +00:00
|
|
|
|
2016-09-14 16:53:35 +00:00
|
|
|
/* constant emission check */
|
2021-02-17 00:47:18 +00:00
|
|
|
float3 constant_emission = zero_float3();
|
2016-09-14 16:53:35 +00:00
|
|
|
if (shader->is_constant_emission(&constant_emission))
|
|
|
|
flag |= SD_HAS_CONSTANT_EMISSION;
|
2019-04-17 04:17:24 +00:00
|
|
|
|
2018-10-28 09:37:41 +00:00
|
|
|
uint32_t cryptomatte_id = util_murmur_hash3(shader->name.c_str(), shader->name.length(), 0);
|
2019-04-17 04:17:24 +00:00
|
|
|
|
2016-08-16 23:42:08 +00:00
|
|
|
/* regular shader */
|
2018-03-07 23:35:24 +00:00
|
|
|
kshader->flags = flag;
|
2020-11-04 10:17:38 +00:00
|
|
|
kshader->pass_id = shader->get_pass_id();
|
2018-03-07 23:35:24 +00:00
|
|
|
kshader->constant_emission[0] = constant_emission.x;
|
|
|
|
kshader->constant_emission[1] = constant_emission.y;
|
|
|
|
kshader->constant_emission[2] = constant_emission.z;
|
2018-10-28 09:37:41 +00:00
|
|
|
kshader->cryptomatte_id = util_hash_to_float(cryptomatte_id);
|
2018-03-07 23:35:24 +00:00
|
|
|
kshader++;
|
2019-04-17 04:17:24 +00:00
|
|
|
|
2016-01-07 06:45:13 +00:00
|
|
|
has_transparent_shadow |= (flag & SD_HAS_TRANSPARENT_SHADOW) != 0;
|
2011-09-27 20:37:24 +00:00
|
|
|
}
|
2019-04-17 04:17:24 +00:00
|
|
|
|
2018-03-07 23:35:24 +00:00
|
|
|
dscene->shaders.copy_to_device();
|
2019-04-17 04:17:24 +00:00
|
|
|
|
2015-04-25 22:06:38 +00:00
|
|
|
/* lookup tables */
|
2014-06-20 19:21:05 +00:00
|
|
|
KernelTables *ktables = &dscene->data.tables;
|
2019-04-17 04:17:24 +00:00
|
|
|
|
2014-06-20 19:21:05 +00:00
|
|
|
/* beckmann lookup table */
|
|
|
|
if (beckmann_table_offset == TABLE_OFFSET_INVALID) {
|
2017-10-06 16:06:15 +00:00
|
|
|
if (!beckmann_table_ready) {
|
Cycles: Experiment with making previews more interactive
There were two major problems with the interactivity of material previews:
- Beckmann tables were re-generated on every material tweak.
This is because preview scene is not set to be persistent, so re-triggering
the render leads to the full scene re-sync.
- Images could take rather noticeable time to load with OIIO from the disk
on every tweak.
This patch addressed this two issues in the following way:
- Beckmann tables are now static on CPU memory.
They're couple of hundred kilobytes only, so wouldn't expect this to be
an issue. And they're needed for almost every render anyway.
This actually also makes blackbody table to be static, but it's even smaller
than beckmann table.
Not totally happy with this approach, but others seems to complicate things
quite a bit with all this render engine life time and so..
- For preview rendering all images are considered to be built-in. This means
instead of OIIO which re-loads images on every re-render they're coming
from ImBuf cache which is fully manageable from blender side and unused
images gets freed later.
This would make it impossible to have mipmapping with OSL for now, but we'll
be working on that later anyway and don't think mipmaps are really so crucial
for the material preview.
This seems to be a better alternative to making preview scene persistent,
because of much optimal memory control from blender side.
Reviewers: brecht, juicyfruit, campbellbarton, dingto
Subscribers: eyecandy, venomgfx
Differential Revision: https://developer.blender.org/D1132
2015-02-21 16:55:24 +00:00
|
|
|
thread_scoped_lock lock(lookup_table_mutex);
|
2017-10-06 16:06:15 +00:00
|
|
|
if (!beckmann_table_ready) {
|
Cycles: Experiment with making previews more interactive
There were two major problems with the interactivity of material previews:
- Beckmann tables were re-generated on every material tweak.
This is because preview scene is not set to be persistent, so re-triggering
the render leads to the full scene re-sync.
- Images could take rather noticeable time to load with OIIO from the disk
on every tweak.
This patch addressed this two issues in the following way:
- Beckmann tables are now static on CPU memory.
They're couple of hundred kilobytes only, so wouldn't expect this to be
an issue. And they're needed for almost every render anyway.
This actually also makes blackbody table to be static, but it's even smaller
than beckmann table.
Not totally happy with this approach, but others seems to complicate things
quite a bit with all this render engine life time and so..
- For preview rendering all images are considered to be built-in. This means
instead of OIIO which re-loads images on every re-render they're coming
from ImBuf cache which is fully manageable from blender side and unused
images gets freed later.
This would make it impossible to have mipmapping with OSL for now, but we'll
be working on that later anyway and don't think mipmaps are really so crucial
for the material preview.
This seems to be a better alternative to making preview scene persistent,
because of much optimal memory control from blender side.
Reviewers: brecht, juicyfruit, campbellbarton, dingto
Subscribers: eyecandy, venomgfx
Differential Revision: https://developer.blender.org/D1132
2015-02-21 16:55:24 +00:00
|
|
|
beckmann_table_build(beckmann_table);
|
2017-10-06 16:06:15 +00:00
|
|
|
beckmann_table_ready = true;
|
Cycles: Experiment with making previews more interactive
There were two major problems with the interactivity of material previews:
- Beckmann tables were re-generated on every material tweak.
This is because preview scene is not set to be persistent, so re-triggering
the render leads to the full scene re-sync.
- Images could take rather noticeable time to load with OIIO from the disk
on every tweak.
This patch addressed this two issues in the following way:
- Beckmann tables are now static on CPU memory.
They're couple of hundred kilobytes only, so wouldn't expect this to be
an issue. And they're needed for almost every render anyway.
This actually also makes blackbody table to be static, but it's even smaller
than beckmann table.
Not totally happy with this approach, but others seems to complicate things
quite a bit with all this render engine life time and so..
- For preview rendering all images are considered to be built-in. This means
instead of OIIO which re-loads images on every re-render they're coming
from ImBuf cache which is fully manageable from blender side and unused
images gets freed later.
This would make it impossible to have mipmapping with OSL for now, but we'll
be working on that later anyway and don't think mipmaps are really so crucial
for the material preview.
This seems to be a better alternative to making preview scene persistent,
because of much optimal memory control from blender side.
Reviewers: brecht, juicyfruit, campbellbarton, dingto
Subscribers: eyecandy, venomgfx
Differential Revision: https://developer.blender.org/D1132
2015-02-21 16:55:24 +00:00
|
|
|
}
|
2015-01-23 09:00:48 +00:00
|
|
|
}
|
|
|
|
beckmann_table_offset = scene->lookup_tables->add_table(dscene, beckmann_table);
|
2014-06-20 19:21:05 +00:00
|
|
|
}
|
2016-05-07 23:44:01 +00:00
|
|
|
ktables->beckmann_offset = (int)beckmann_table_offset;
|
2019-04-17 04:17:24 +00:00
|
|
|
|
2014-06-01 05:11:13 +00:00
|
|
|
/* integrator */
|
2013-12-28 01:27:48 +00:00
|
|
|
KernelIntegrator *kintegrator = &dscene->data.integrator;
|
|
|
|
kintegrator->use_volumes = has_volumes;
|
2015-09-08 06:28:02 +00:00
|
|
|
/* TODO(sergey): De-duplicate with flags set in integrator.cpp. */
|
2017-08-02 13:23:50 +00:00
|
|
|
kintegrator->transparent_shadows = has_transparent_shadow;
|
2019-04-17 04:17:24 +00:00
|
|
|
|
2018-06-14 15:48:19 +00:00
|
|
|
/* film */
|
|
|
|
KernelFilm *kfilm = &dscene->data.film;
|
|
|
|
/* color space, needs to be here because e.g. displacement shaders could depend on it */
|
2018-06-15 13:58:48 +00:00
|
|
|
kfilm->xyz_to_r = float3_to_float4(xyz_to_r);
|
|
|
|
kfilm->xyz_to_g = float3_to_float4(xyz_to_g);
|
|
|
|
kfilm->xyz_to_b = float3_to_float4(xyz_to_b);
|
|
|
|
kfilm->rgb_to_y = float3_to_float4(rgb_to_y);
|
2011-09-27 20:37:24 +00:00
|
|
|
}
|
|
|
|
|
2017-10-20 23:09:59 +00:00
|
|
|
void ShaderManager::device_free_common(Device *, DeviceScene *dscene, Scene *scene)
|
2011-09-27 20:37:24 +00:00
|
|
|
{
|
2016-05-07 23:44:01 +00:00
|
|
|
scene->lookup_tables->remove_table(&beckmann_table_offset);
|
2014-06-20 19:21:05 +00:00
|
|
|
|
2018-03-07 23:35:24 +00:00
|
|
|
dscene->shaders.free();
|
2011-09-27 20:37:24 +00:00
|
|
|
}
|
|
|
|
|
2011-04-27 11:58:34 +00:00
|
|
|
void ShaderManager::add_default(Scene *scene)
|
|
|
|
{
|
|
|
|
/* default surface */
|
|
|
|
{
|
2016-05-14 12:50:03 +00:00
|
|
|
ShaderGraph *graph = new ShaderGraph();
|
2019-04-17 04:17:24 +00:00
|
|
|
|
Cycles: introduce an ownership system to protect nodes from unwanted deletions.
Problem: the Blender synchronization process creates and tags nodes for usage. It does
this by directly adding and removing nodes from the scene data. If some node is not tagged
as used at the end of a synchronization, it then deletes the node from the scene. This poses
a problem when it comes to supporting procedural nodes who can create other nodes not known
by the Blender synchonization system, which will remove them.
Nodes now have a NodeOwner, which is set after creation. Those owners for now are the Scene
for scene level nodes and ShaderGraph for shader nodes. Instead of creating and deleting
nodes using `new` and `delete` explicitely, we now use `create_node` and `delete_node` methods
found on the owners. `delete_node` will assert that the owner is the right one.
Whenever a scene level node is created or deleted, the appropriate node manager is tagged for
an update, freeing this responsability from BlenderSync or other software exporters.
Concerning BlenderSync, the `id_maps` do not explicitely manipulate scene data anymore, they
only keep track of which nodes are used, employing the scene to create and delete them. To
achieve this, the ParticleSystem is now a Node, although it does not have any sockets.
This is part of T79131.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79131
Differential Revision: https://developer.blender.org/D8540
2020-08-30 21:20:51 +00:00
|
|
|
DiffuseBsdfNode *diffuse = graph->create_node<DiffuseBsdfNode>();
|
2020-11-04 10:17:38 +00:00
|
|
|
diffuse->set_color(make_float3(0.8f, 0.8f, 0.8f));
|
2016-05-07 17:48:28 +00:00
|
|
|
graph->add(diffuse);
|
2019-04-17 04:17:24 +00:00
|
|
|
|
2016-05-07 17:48:28 +00:00
|
|
|
graph->connect(diffuse->output("BSDF"), graph->output()->input("Surface"));
|
2019-04-17 04:17:24 +00:00
|
|
|
|
Cycles: introduce an ownership system to protect nodes from unwanted deletions.
Problem: the Blender synchronization process creates and tags nodes for usage. It does
this by directly adding and removing nodes from the scene data. If some node is not tagged
as used at the end of a synchronization, it then deletes the node from the scene. This poses
a problem when it comes to supporting procedural nodes who can create other nodes not known
by the Blender synchonization system, which will remove them.
Nodes now have a NodeOwner, which is set after creation. Those owners for now are the Scene
for scene level nodes and ShaderGraph for shader nodes. Instead of creating and deleting
nodes using `new` and `delete` explicitely, we now use `create_node` and `delete_node` methods
found on the owners. `delete_node` will assert that the owner is the right one.
Whenever a scene level node is created or deleted, the appropriate node manager is tagged for
an update, freeing this responsability from BlenderSync or other software exporters.
Concerning BlenderSync, the `id_maps` do not explicitely manipulate scene data anymore, they
only keep track of which nodes are used, employing the scene to create and delete them. To
achieve this, the ParticleSystem is now a Node, although it does not have any sockets.
This is part of T79131.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79131
Differential Revision: https://developer.blender.org/D8540
2020-08-30 21:20:51 +00:00
|
|
|
Shader *shader = scene->create_node<Shader>();
|
2011-04-27 11:58:34 +00:00
|
|
|
shader->name = "default_surface";
|
2020-03-11 16:49:00 +00:00
|
|
|
shader->set_graph(graph);
|
2021-05-02 00:34:56 +00:00
|
|
|
shader->reference();
|
2016-05-14 12:50:03 +00:00
|
|
|
scene->default_surface = shader;
|
2020-03-11 16:49:00 +00:00
|
|
|
shader->tag_update(scene);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* default volume */
|
|
|
|
{
|
|
|
|
ShaderGraph *graph = new ShaderGraph();
|
|
|
|
|
Cycles: introduce an ownership system to protect nodes from unwanted deletions.
Problem: the Blender synchronization process creates and tags nodes for usage. It does
this by directly adding and removing nodes from the scene data. If some node is not tagged
as used at the end of a synchronization, it then deletes the node from the scene. This poses
a problem when it comes to supporting procedural nodes who can create other nodes not known
by the Blender synchonization system, which will remove them.
Nodes now have a NodeOwner, which is set after creation. Those owners for now are the Scene
for scene level nodes and ShaderGraph for shader nodes. Instead of creating and deleting
nodes using `new` and `delete` explicitely, we now use `create_node` and `delete_node` methods
found on the owners. `delete_node` will assert that the owner is the right one.
Whenever a scene level node is created or deleted, the appropriate node manager is tagged for
an update, freeing this responsability from BlenderSync or other software exporters.
Concerning BlenderSync, the `id_maps` do not explicitely manipulate scene data anymore, they
only keep track of which nodes are used, employing the scene to create and delete them. To
achieve this, the ParticleSystem is now a Node, although it does not have any sockets.
This is part of T79131.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79131
Differential Revision: https://developer.blender.org/D8540
2020-08-30 21:20:51 +00:00
|
|
|
PrincipledVolumeNode *principled = graph->create_node<PrincipledVolumeNode>();
|
2020-03-11 16:49:00 +00:00
|
|
|
graph->add(principled);
|
|
|
|
|
|
|
|
graph->connect(principled->output("Volume"), graph->output()->input("Volume"));
|
|
|
|
|
Cycles: introduce an ownership system to protect nodes from unwanted deletions.
Problem: the Blender synchronization process creates and tags nodes for usage. It does
this by directly adding and removing nodes from the scene data. If some node is not tagged
as used at the end of a synchronization, it then deletes the node from the scene. This poses
a problem when it comes to supporting procedural nodes who can create other nodes not known
by the Blender synchonization system, which will remove them.
Nodes now have a NodeOwner, which is set after creation. Those owners for now are the Scene
for scene level nodes and ShaderGraph for shader nodes. Instead of creating and deleting
nodes using `new` and `delete` explicitely, we now use `create_node` and `delete_node` methods
found on the owners. `delete_node` will assert that the owner is the right one.
Whenever a scene level node is created or deleted, the appropriate node manager is tagged for
an update, freeing this responsability from BlenderSync or other software exporters.
Concerning BlenderSync, the `id_maps` do not explicitely manipulate scene data anymore, they
only keep track of which nodes are used, employing the scene to create and delete them. To
achieve this, the ParticleSystem is now a Node, although it does not have any sockets.
This is part of T79131.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79131
Differential Revision: https://developer.blender.org/D8540
2020-08-30 21:20:51 +00:00
|
|
|
Shader *shader = scene->create_node<Shader>();
|
2020-03-11 16:49:00 +00:00
|
|
|
shader->name = "default_volume";
|
|
|
|
shader->set_graph(graph);
|
|
|
|
scene->default_volume = shader;
|
|
|
|
shader->tag_update(scene);
|
2021-05-02 00:34:56 +00:00
|
|
|
/* No default reference for the volume to avoid compiling volume kernels if there are no actual
|
|
|
|
* volumes in the scene */
|
2011-04-27 11:58:34 +00:00
|
|
|
}
|
2019-04-17 04:17:24 +00:00
|
|
|
|
2011-04-27 11:58:34 +00:00
|
|
|
/* default light */
|
|
|
|
{
|
2016-05-14 12:50:03 +00:00
|
|
|
ShaderGraph *graph = new ShaderGraph();
|
2019-04-17 04:17:24 +00:00
|
|
|
|
Cycles: introduce an ownership system to protect nodes from unwanted deletions.
Problem: the Blender synchronization process creates and tags nodes for usage. It does
this by directly adding and removing nodes from the scene data. If some node is not tagged
as used at the end of a synchronization, it then deletes the node from the scene. This poses
a problem when it comes to supporting procedural nodes who can create other nodes not known
by the Blender synchonization system, which will remove them.
Nodes now have a NodeOwner, which is set after creation. Those owners for now are the Scene
for scene level nodes and ShaderGraph for shader nodes. Instead of creating and deleting
nodes using `new` and `delete` explicitely, we now use `create_node` and `delete_node` methods
found on the owners. `delete_node` will assert that the owner is the right one.
Whenever a scene level node is created or deleted, the appropriate node manager is tagged for
an update, freeing this responsability from BlenderSync or other software exporters.
Concerning BlenderSync, the `id_maps` do not explicitely manipulate scene data anymore, they
only keep track of which nodes are used, employing the scene to create and delete them. To
achieve this, the ParticleSystem is now a Node, although it does not have any sockets.
This is part of T79131.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79131
Differential Revision: https://developer.blender.org/D8540
2020-08-30 21:20:51 +00:00
|
|
|
EmissionNode *emission = graph->create_node<EmissionNode>();
|
2020-11-04 10:17:38 +00:00
|
|
|
emission->set_color(make_float3(0.8f, 0.8f, 0.8f));
|
|
|
|
emission->set_strength(0.0f);
|
2016-05-07 17:48:28 +00:00
|
|
|
graph->add(emission);
|
2019-04-17 04:17:24 +00:00
|
|
|
|
2016-05-07 17:48:28 +00:00
|
|
|
graph->connect(emission->output("Emission"), graph->output()->input("Surface"));
|
2019-04-17 04:17:24 +00:00
|
|
|
|
Cycles: introduce an ownership system to protect nodes from unwanted deletions.
Problem: the Blender synchronization process creates and tags nodes for usage. It does
this by directly adding and removing nodes from the scene data. If some node is not tagged
as used at the end of a synchronization, it then deletes the node from the scene. This poses
a problem when it comes to supporting procedural nodes who can create other nodes not known
by the Blender synchonization system, which will remove them.
Nodes now have a NodeOwner, which is set after creation. Those owners for now are the Scene
for scene level nodes and ShaderGraph for shader nodes. Instead of creating and deleting
nodes using `new` and `delete` explicitely, we now use `create_node` and `delete_node` methods
found on the owners. `delete_node` will assert that the owner is the right one.
Whenever a scene level node is created or deleted, the appropriate node manager is tagged for
an update, freeing this responsability from BlenderSync or other software exporters.
Concerning BlenderSync, the `id_maps` do not explicitely manipulate scene data anymore, they
only keep track of which nodes are used, employing the scene to create and delete them. To
achieve this, the ParticleSystem is now a Node, although it does not have any sockets.
This is part of T79131.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79131
Differential Revision: https://developer.blender.org/D8540
2020-08-30 21:20:51 +00:00
|
|
|
Shader *shader = scene->create_node<Shader>();
|
2011-04-27 11:58:34 +00:00
|
|
|
shader->name = "default_light";
|
2020-03-11 16:49:00 +00:00
|
|
|
shader->set_graph(graph);
|
2021-05-02 00:34:56 +00:00
|
|
|
shader->reference();
|
2016-05-14 12:50:03 +00:00
|
|
|
scene->default_light = shader;
|
2020-03-11 16:49:00 +00:00
|
|
|
shader->tag_update(scene);
|
2011-04-27 11:58:34 +00:00
|
|
|
}
|
2019-04-17 04:17:24 +00:00
|
|
|
|
2011-04-27 11:58:34 +00:00
|
|
|
/* default background */
|
|
|
|
{
|
2016-05-14 12:50:03 +00:00
|
|
|
ShaderGraph *graph = new ShaderGraph();
|
2019-04-17 04:17:24 +00:00
|
|
|
|
Cycles: introduce an ownership system to protect nodes from unwanted deletions.
Problem: the Blender synchronization process creates and tags nodes for usage. It does
this by directly adding and removing nodes from the scene data. If some node is not tagged
as used at the end of a synchronization, it then deletes the node from the scene. This poses
a problem when it comes to supporting procedural nodes who can create other nodes not known
by the Blender synchonization system, which will remove them.
Nodes now have a NodeOwner, which is set after creation. Those owners for now are the Scene
for scene level nodes and ShaderGraph for shader nodes. Instead of creating and deleting
nodes using `new` and `delete` explicitely, we now use `create_node` and `delete_node` methods
found on the owners. `delete_node` will assert that the owner is the right one.
Whenever a scene level node is created or deleted, the appropriate node manager is tagged for
an update, freeing this responsability from BlenderSync or other software exporters.
Concerning BlenderSync, the `id_maps` do not explicitely manipulate scene data anymore, they
only keep track of which nodes are used, employing the scene to create and delete them. To
achieve this, the ParticleSystem is now a Node, although it does not have any sockets.
This is part of T79131.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79131
Differential Revision: https://developer.blender.org/D8540
2020-08-30 21:20:51 +00:00
|
|
|
Shader *shader = scene->create_node<Shader>();
|
2011-04-27 11:58:34 +00:00
|
|
|
shader->name = "default_background";
|
2020-03-11 16:49:00 +00:00
|
|
|
shader->set_graph(graph);
|
2021-05-02 00:34:56 +00:00
|
|
|
shader->reference();
|
2016-05-14 12:50:03 +00:00
|
|
|
scene->default_background = shader;
|
2020-03-11 16:49:00 +00:00
|
|
|
shader->tag_update(scene);
|
2011-04-27 11:58:34 +00:00
|
|
|
}
|
2019-04-17 04:17:24 +00:00
|
|
|
|
2012-04-13 12:58:12 +00:00
|
|
|
/* default empty */
|
|
|
|
{
|
2016-05-14 12:50:03 +00:00
|
|
|
ShaderGraph *graph = new ShaderGraph();
|
2019-04-17 04:17:24 +00:00
|
|
|
|
Cycles: introduce an ownership system to protect nodes from unwanted deletions.
Problem: the Blender synchronization process creates and tags nodes for usage. It does
this by directly adding and removing nodes from the scene data. If some node is not tagged
as used at the end of a synchronization, it then deletes the node from the scene. This poses
a problem when it comes to supporting procedural nodes who can create other nodes not known
by the Blender synchonization system, which will remove them.
Nodes now have a NodeOwner, which is set after creation. Those owners for now are the Scene
for scene level nodes and ShaderGraph for shader nodes. Instead of creating and deleting
nodes using `new` and `delete` explicitely, we now use `create_node` and `delete_node` methods
found on the owners. `delete_node` will assert that the owner is the right one.
Whenever a scene level node is created or deleted, the appropriate node manager is tagged for
an update, freeing this responsability from BlenderSync or other software exporters.
Concerning BlenderSync, the `id_maps` do not explicitely manipulate scene data anymore, they
only keep track of which nodes are used, employing the scene to create and delete them. To
achieve this, the ParticleSystem is now a Node, although it does not have any sockets.
This is part of T79131.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79131
Differential Revision: https://developer.blender.org/D8540
2020-08-30 21:20:51 +00:00
|
|
|
Shader *shader = scene->create_node<Shader>();
|
2012-04-13 12:58:12 +00:00
|
|
|
shader->name = "default_empty";
|
2020-03-11 16:49:00 +00:00
|
|
|
shader->set_graph(graph);
|
2021-05-02 00:34:56 +00:00
|
|
|
shader->reference();
|
2016-05-14 12:50:03 +00:00
|
|
|
scene->default_empty = shader;
|
2020-03-11 16:49:00 +00:00
|
|
|
shader->tag_update(scene);
|
2012-04-13 12:58:12 +00:00
|
|
|
}
|
2011-04-27 11:58:34 +00:00
|
|
|
}
|
|
|
|
|
2015-06-01 10:52:00 +00:00
|
|
|
void ShaderManager::get_requested_graph_features(ShaderGraph *graph,
|
2015-11-21 17:31:58 +00:00
|
|
|
DeviceRequestedFeatures *requested_features)
|
2015-06-01 10:52:00 +00:00
|
|
|
{
|
|
|
|
foreach (ShaderNode *node, graph->nodes) {
|
2015-11-21 17:31:58 +00:00
|
|
|
requested_features->max_nodes_group = max(requested_features->max_nodes_group,
|
|
|
|
node->get_group());
|
|
|
|
requested_features->nodes_features |= node->get_feature();
|
2015-06-01 10:52:00 +00:00
|
|
|
if (node->special_type == SHADER_SPECIAL_TYPE_CLOSURE) {
|
2019-01-18 01:56:59 +00:00
|
|
|
BsdfBaseNode *bsdf_node = static_cast<BsdfBaseNode *>(node);
|
2020-11-04 10:17:38 +00:00
|
|
|
if (CLOSURE_IS_VOLUME(bsdf_node->get_closure_type())) {
|
2015-11-21 17:31:58 +00:00
|
|
|
requested_features->nodes_features |= NODE_FEATURE_VOLUME;
|
2015-06-01 10:52:00 +00:00
|
|
|
}
|
2020-11-04 10:17:38 +00:00
|
|
|
else if (CLOSURE_IS_PRINCIPLED(bsdf_node->get_closure_type())) {
|
2017-04-21 10:56:54 +00:00
|
|
|
requested_features->use_principled = true;
|
|
|
|
}
|
2015-06-01 10:52:00 +00:00
|
|
|
}
|
2015-11-21 17:31:58 +00:00
|
|
|
if (node->has_surface_bssrdf()) {
|
|
|
|
requested_features->use_subsurface = true;
|
|
|
|
}
|
2016-12-09 15:28:04 +00:00
|
|
|
if (node->has_surface_transparent()) {
|
|
|
|
requested_features->use_transparent = true;
|
|
|
|
}
|
2017-10-30 19:25:08 +00:00
|
|
|
if (node->has_raytrace()) {
|
|
|
|
requested_features->use_shader_raytrace = true;
|
|
|
|
}
|
2015-06-01 10:52:00 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void ShaderManager::get_requested_features(Scene *scene,
|
2015-11-21 17:31:58 +00:00
|
|
|
DeviceRequestedFeatures *requested_features)
|
2015-05-09 14:22:16 +00:00
|
|
|
{
|
2015-11-21 17:31:58 +00:00
|
|
|
requested_features->max_nodes_group = NODE_GROUP_LEVEL_0;
|
|
|
|
requested_features->nodes_features = 0;
|
2015-05-09 14:22:16 +00:00
|
|
|
for (int i = 0; i < scene->shaders.size(); i++) {
|
|
|
|
Shader *shader = scene->shaders[i];
|
2021-05-02 00:34:56 +00:00
|
|
|
if (!shader->reference_count()) {
|
2020-03-11 16:49:00 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2015-06-01 10:26:36 +00:00
|
|
|
/* Gather requested features from all the nodes from the graph nodes. */
|
2015-11-21 17:31:58 +00:00
|
|
|
get_requested_graph_features(shader->graph, requested_features);
|
2015-06-01 10:26:36 +00:00
|
|
|
ShaderNode *output_node = shader->graph->output();
|
|
|
|
if (output_node->input("Displacement")->link != NULL) {
|
2015-11-21 17:31:58 +00:00
|
|
|
requested_features->nodes_features |= NODE_FEATURE_BUMP;
|
2020-11-04 10:17:38 +00:00
|
|
|
if (shader->get_displacement_method() == DISPLACE_BOTH) {
|
2016-09-07 23:33:41 +00:00
|
|
|
requested_features->nodes_features |= NODE_FEATURE_BUMP_STATE;
|
2019-09-24 08:15:43 +00:00
|
|
|
requested_features->max_nodes_group = max(requested_features->max_nodes_group,
|
|
|
|
NODE_GROUP_LEVEL_1);
|
2016-09-07 23:33:41 +00:00
|
|
|
}
|
2015-06-01 10:26:36 +00:00
|
|
|
}
|
2016-05-06 21:11:41 +00:00
|
|
|
/* On top of volume nodes, also check if we need volume sampling because
|
|
|
|
* e.g. an Emission node would slip through the NODE_FEATURE_VOLUME check */
|
|
|
|
if (shader->has_volume)
|
|
|
|
requested_features->use_volume |= true;
|
2015-05-09 14:22:16 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-02-06 22:40:41 +00:00
|
|
|
void ShaderManager::free_memory()
|
|
|
|
{
|
|
|
|
beckmann_table.free_memory();
|
2019-03-13 17:26:11 +00:00
|
|
|
|
|
|
|
#ifdef WITH_OSL
|
|
|
|
OSLShaderManager::free_memory();
|
|
|
|
#endif
|
2019-05-02 13:45:31 +00:00
|
|
|
|
|
|
|
ColorSpaceManager::free_memory();
|
2016-02-06 22:40:41 +00:00
|
|
|
}
|
|
|
|
|
2018-06-14 15:48:19 +00:00
|
|
|
float ShaderManager::linear_rgb_to_gray(float3 c)
|
|
|
|
{
|
|
|
|
return dot(c, rgb_to_y);
|
|
|
|
}
|
|
|
|
|
2018-11-07 03:05:47 +00:00
|
|
|
string ShaderManager::get_cryptomatte_materials(Scene *scene)
|
|
|
|
{
|
|
|
|
string manifest = "{";
|
|
|
|
unordered_set<ustring, ustringHash> materials;
|
|
|
|
foreach (Shader *shader, scene->shaders) {
|
|
|
|
if (materials.count(shader->name)) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
materials.insert(shader->name);
|
|
|
|
uint32_t cryptomatte_id = util_murmur_hash3(shader->name.c_str(), shader->name.length(), 0);
|
|
|
|
manifest += string_printf("\"%s\":\"%08x\",", shader->name.c_str(), cryptomatte_id);
|
|
|
|
}
|
|
|
|
manifest[manifest.size() - 1] = '}';
|
|
|
|
return manifest;
|
|
|
|
}
|
|
|
|
|
Cycles: optimize device updates
This optimizes device updates (during user edits or frame changes in
the viewport) by avoiding unnecessary computations. To achieve this,
we use a combination of the sockets' update flags as well as some new
flags passed to the various managers when tagging for an update to tell
exactly what the tagging is for (e.g. shader was modified, object was
removed, etc.).
Besides avoiding recomputations, we also avoid resending to the devices
unmodified data arrays, thus reducing bandwidth usage. For OptiX and
Embree, BVH packing was also multithreaded.
The performance improvements may vary depending on the used device (CPU
or GPU), and the content of the scene. Simple scenes (e.g. with no adaptive
subdivision or volumes) rendered using OptiX will benefit from this work
the most.
On average, for a variety of animated scenes, this gives a 3x speedup.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79174
Differential Revision: https://developer.blender.org/D9555
2021-01-22 14:01:26 +00:00
|
|
|
void ShaderManager::tag_update(Scene * /*scene*/, uint32_t /*flag*/)
|
|
|
|
{
|
|
|
|
/* update everything for now */
|
|
|
|
update_flags = ShaderManager::UPDATE_ALL;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ShaderManager::need_update() const
|
|
|
|
{
|
|
|
|
return update_flags != UPDATE_NONE;
|
|
|
|
}
|
|
|
|
|
OpenColorIO: upgrade to version 2.0.0
Ref T84819
Build System
============
This is an API breaking new version, and the updated code only builds with
OpenColorIO 2.0 and later. Adding backwards compatibility was too complicated.
* Tinyxml was replaced with Expat, adding a new dependency.
* Yaml-cpp is now built as a dependency on Unix, as was already done on Windows.
* Removed currently unused LCMS code.
* Pystring remains built as part of OCIO itself, since it has no good build system.
* Linux and macOS check for the OpenColorIO verison, and disable it if too old.
Ref D10270
Processors and Transforms
=========================
CPU processors now need to be created to do CPU processing. These are cached
internally, but the cache lookup is not fast enough to execute per pixel or
texture sample, so for performance these are now also exposed in the C API.
The C API for transforms will no longer be needed afer all changes, so remove
it to simplify the API and fallback implementation.
Ref D10271
Display Transforms
==================
Needs a bit more manual work constructing the transform. LegacyViewingPipeline
could also have been used, but isn't really any simpler and since it's legacy
we better not rely on it.
We moved more logic into the opencolorio module, to simplify the API. There is
no need to wrap a dozen functions just to be able to do this in C rather than C++.
It's also tightly coupled to the GPU shader logic, and so should be in the same
module.
Ref D10271
GPU Display Shader
==================
To avoid baking exposure and gamma into the GLSL shader and requiring slow
recompiles when tweaking, we manually apply them in the shader. This leads
to some logic duplicaton between the CPU and GPU display processor, but it
seems unavoidable.
Caching was also changed. Previously this was done both on the imbuf and
opencolorio module levels. Now it's all done in the opencolorio module by
simply matching color space names. We no longer use cacheIDs from OpenColorIO
since computing them is expensive, and they are unlikely to match now that
more is baked into the shader code.
Shaders can now use multiple 2D textures, 3D textures and uniforms, rather
than a single 3D texture. So allocating and binding those adds some code.
Color space conversions for blending with overlays is now hardcoded in the
shader. This was using harcoded numbers anyway, if this every becomes a
general OpenColorIO transform it can be changed, but for now there is no
point to add code complexity.
Ref D10273
CIE XYZ
=======
We need standard CIE XYZ values for rendering effects like blackbody emission.
The relation to the scene linear role is based on OpenColorIO configuration.
In OpenColorIO 2.0 configs roles can no longer have the same name as color
spaces, which means our XYZ role and colorspace in the configuration give an
error.
Instead use the new standard aces_interchange role, which relates scene linear
to a known scene referred color space. Compatibility with the old XYZ role is
preserved, if the configuration file has no conflicting names.
Also includes a non-functional change to the configuraton file to use an
XYZ-to-ACES matrix instead of REC709-to-ACES, makes debugging a little easier
since the matrix is the same one we have in the code now and that is also
found easily in the ACES specs.
Ref D10274
2021-01-31 18:35:00 +00:00
|
|
|
#ifdef WITH_OCIO
|
|
|
|
static bool to_scene_linear_transform(OCIO::ConstConfigRcPtr &config,
|
|
|
|
const char *colorspace,
|
|
|
|
Transform &to_scene_linear)
|
|
|
|
{
|
|
|
|
OCIO::ConstProcessorRcPtr processor;
|
|
|
|
try {
|
|
|
|
processor = config->getProcessor(OCIO::ROLE_SCENE_LINEAR, colorspace);
|
|
|
|
}
|
2021-02-18 15:09:08 +00:00
|
|
|
catch (OCIO::Exception &) {
|
OpenColorIO: upgrade to version 2.0.0
Ref T84819
Build System
============
This is an API breaking new version, and the updated code only builds with
OpenColorIO 2.0 and later. Adding backwards compatibility was too complicated.
* Tinyxml was replaced with Expat, adding a new dependency.
* Yaml-cpp is now built as a dependency on Unix, as was already done on Windows.
* Removed currently unused LCMS code.
* Pystring remains built as part of OCIO itself, since it has no good build system.
* Linux and macOS check for the OpenColorIO verison, and disable it if too old.
Ref D10270
Processors and Transforms
=========================
CPU processors now need to be created to do CPU processing. These are cached
internally, but the cache lookup is not fast enough to execute per pixel or
texture sample, so for performance these are now also exposed in the C API.
The C API for transforms will no longer be needed afer all changes, so remove
it to simplify the API and fallback implementation.
Ref D10271
Display Transforms
==================
Needs a bit more manual work constructing the transform. LegacyViewingPipeline
could also have been used, but isn't really any simpler and since it's legacy
we better not rely on it.
We moved more logic into the opencolorio module, to simplify the API. There is
no need to wrap a dozen functions just to be able to do this in C rather than C++.
It's also tightly coupled to the GPU shader logic, and so should be in the same
module.
Ref D10271
GPU Display Shader
==================
To avoid baking exposure and gamma into the GLSL shader and requiring slow
recompiles when tweaking, we manually apply them in the shader. This leads
to some logic duplicaton between the CPU and GPU display processor, but it
seems unavoidable.
Caching was also changed. Previously this was done both on the imbuf and
opencolorio module levels. Now it's all done in the opencolorio module by
simply matching color space names. We no longer use cacheIDs from OpenColorIO
since computing them is expensive, and they are unlikely to match now that
more is baked into the shader code.
Shaders can now use multiple 2D textures, 3D textures and uniforms, rather
than a single 3D texture. So allocating and binding those adds some code.
Color space conversions for blending with overlays is now hardcoded in the
shader. This was using harcoded numbers anyway, if this every becomes a
general OpenColorIO transform it can be changed, but for now there is no
point to add code complexity.
Ref D10273
CIE XYZ
=======
We need standard CIE XYZ values for rendering effects like blackbody emission.
The relation to the scene linear role is based on OpenColorIO configuration.
In OpenColorIO 2.0 configs roles can no longer have the same name as color
spaces, which means our XYZ role and colorspace in the configuration give an
error.
Instead use the new standard aces_interchange role, which relates scene linear
to a known scene referred color space. Compatibility with the old XYZ role is
preserved, if the configuration file has no conflicting names.
Also includes a non-functional change to the configuraton file to use an
XYZ-to-ACES matrix instead of REC709-to-ACES, makes debugging a little easier
since the matrix is the same one we have in the code now and that is also
found easily in the ACES specs.
Ref D10274
2021-01-31 18:35:00 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!processor) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
OCIO::ConstCPUProcessorRcPtr device_processor = processor->getDefaultCPUProcessor();
|
|
|
|
if (!device_processor) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
to_scene_linear = transform_identity();
|
|
|
|
device_processor->applyRGB(&to_scene_linear.x.x);
|
|
|
|
device_processor->applyRGB(&to_scene_linear.y.x);
|
|
|
|
device_processor->applyRGB(&to_scene_linear.z.x);
|
|
|
|
to_scene_linear = transform_transposed_inverse(to_scene_linear);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
void ShaderManager::init_xyz_transforms()
|
|
|
|
{
|
2021-03-10 15:38:26 +00:00
|
|
|
/* Default to ITU-BT.709 in case no appropriate transform found.
|
|
|
|
* Note XYZ here is defined as having a D65 white point. */
|
OpenColorIO: upgrade to version 2.0.0
Ref T84819
Build System
============
This is an API breaking new version, and the updated code only builds with
OpenColorIO 2.0 and later. Adding backwards compatibility was too complicated.
* Tinyxml was replaced with Expat, adding a new dependency.
* Yaml-cpp is now built as a dependency on Unix, as was already done on Windows.
* Removed currently unused LCMS code.
* Pystring remains built as part of OCIO itself, since it has no good build system.
* Linux and macOS check for the OpenColorIO verison, and disable it if too old.
Ref D10270
Processors and Transforms
=========================
CPU processors now need to be created to do CPU processing. These are cached
internally, but the cache lookup is not fast enough to execute per pixel or
texture sample, so for performance these are now also exposed in the C API.
The C API for transforms will no longer be needed afer all changes, so remove
it to simplify the API and fallback implementation.
Ref D10271
Display Transforms
==================
Needs a bit more manual work constructing the transform. LegacyViewingPipeline
could also have been used, but isn't really any simpler and since it's legacy
we better not rely on it.
We moved more logic into the opencolorio module, to simplify the API. There is
no need to wrap a dozen functions just to be able to do this in C rather than C++.
It's also tightly coupled to the GPU shader logic, and so should be in the same
module.
Ref D10271
GPU Display Shader
==================
To avoid baking exposure and gamma into the GLSL shader and requiring slow
recompiles when tweaking, we manually apply them in the shader. This leads
to some logic duplicaton between the CPU and GPU display processor, but it
seems unavoidable.
Caching was also changed. Previously this was done both on the imbuf and
opencolorio module levels. Now it's all done in the opencolorio module by
simply matching color space names. We no longer use cacheIDs from OpenColorIO
since computing them is expensive, and they are unlikely to match now that
more is baked into the shader code.
Shaders can now use multiple 2D textures, 3D textures and uniforms, rather
than a single 3D texture. So allocating and binding those adds some code.
Color space conversions for blending with overlays is now hardcoded in the
shader. This was using harcoded numbers anyway, if this every becomes a
general OpenColorIO transform it can be changed, but for now there is no
point to add code complexity.
Ref D10273
CIE XYZ
=======
We need standard CIE XYZ values for rendering effects like blackbody emission.
The relation to the scene linear role is based on OpenColorIO configuration.
In OpenColorIO 2.0 configs roles can no longer have the same name as color
spaces, which means our XYZ role and colorspace in the configuration give an
error.
Instead use the new standard aces_interchange role, which relates scene linear
to a known scene referred color space. Compatibility with the old XYZ role is
preserved, if the configuration file has no conflicting names.
Also includes a non-functional change to the configuraton file to use an
XYZ-to-ACES matrix instead of REC709-to-ACES, makes debugging a little easier
since the matrix is the same one we have in the code now and that is also
found easily in the ACES specs.
Ref D10274
2021-01-31 18:35:00 +00:00
|
|
|
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
|
|
|
|
/* Get from OpenColorO config if it has the required roles. */
|
|
|
|
OCIO::ConstConfigRcPtr config = OCIO::GetCurrentConfig();
|
|
|
|
if (!(config && config->hasRole(OCIO::ROLE_SCENE_LINEAR))) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
Transform xyz_to_rgb;
|
|
|
|
|
|
|
|
if (config->hasRole("aces_interchange")) {
|
|
|
|
/* Standard OpenColorIO role, defined as ACES2065-1. */
|
2021-03-10 15:38:26 +00:00
|
|
|
const Transform xyz_E_to_aces = make_transform(1.0498110175f,
|
|
|
|
0.0f,
|
|
|
|
-0.0000974845f,
|
|
|
|
0.0f,
|
|
|
|
-0.4959030231f,
|
|
|
|
1.3733130458f,
|
|
|
|
0.0982400361f,
|
|
|
|
0.0f,
|
|
|
|
0.0f,
|
|
|
|
0.0f,
|
|
|
|
0.9912520182f,
|
|
|
|
0.0f);
|
|
|
|
const Transform xyz_D65_to_E = make_transform(
|
|
|
|
1.0521111f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.9184170f, 0.0f);
|
|
|
|
|
OpenColorIO: upgrade to version 2.0.0
Ref T84819
Build System
============
This is an API breaking new version, and the updated code only builds with
OpenColorIO 2.0 and later. Adding backwards compatibility was too complicated.
* Tinyxml was replaced with Expat, adding a new dependency.
* Yaml-cpp is now built as a dependency on Unix, as was already done on Windows.
* Removed currently unused LCMS code.
* Pystring remains built as part of OCIO itself, since it has no good build system.
* Linux and macOS check for the OpenColorIO verison, and disable it if too old.
Ref D10270
Processors and Transforms
=========================
CPU processors now need to be created to do CPU processing. These are cached
internally, but the cache lookup is not fast enough to execute per pixel or
texture sample, so for performance these are now also exposed in the C API.
The C API for transforms will no longer be needed afer all changes, so remove
it to simplify the API and fallback implementation.
Ref D10271
Display Transforms
==================
Needs a bit more manual work constructing the transform. LegacyViewingPipeline
could also have been used, but isn't really any simpler and since it's legacy
we better not rely on it.
We moved more logic into the opencolorio module, to simplify the API. There is
no need to wrap a dozen functions just to be able to do this in C rather than C++.
It's also tightly coupled to the GPU shader logic, and so should be in the same
module.
Ref D10271
GPU Display Shader
==================
To avoid baking exposure and gamma into the GLSL shader and requiring slow
recompiles when tweaking, we manually apply them in the shader. This leads
to some logic duplicaton between the CPU and GPU display processor, but it
seems unavoidable.
Caching was also changed. Previously this was done both on the imbuf and
opencolorio module levels. Now it's all done in the opencolorio module by
simply matching color space names. We no longer use cacheIDs from OpenColorIO
since computing them is expensive, and they are unlikely to match now that
more is baked into the shader code.
Shaders can now use multiple 2D textures, 3D textures and uniforms, rather
than a single 3D texture. So allocating and binding those adds some code.
Color space conversions for blending with overlays is now hardcoded in the
shader. This was using harcoded numbers anyway, if this every becomes a
general OpenColorIO transform it can be changed, but for now there is no
point to add code complexity.
Ref D10273
CIE XYZ
=======
We need standard CIE XYZ values for rendering effects like blackbody emission.
The relation to the scene linear role is based on OpenColorIO configuration.
In OpenColorIO 2.0 configs roles can no longer have the same name as color
spaces, which means our XYZ role and colorspace in the configuration give an
error.
Instead use the new standard aces_interchange role, which relates scene linear
to a known scene referred color space. Compatibility with the old XYZ role is
preserved, if the configuration file has no conflicting names.
Also includes a non-functional change to the configuraton file to use an
XYZ-to-ACES matrix instead of REC709-to-ACES, makes debugging a little easier
since the matrix is the same one we have in the code now and that is also
found easily in the ACES specs.
Ref D10274
2021-01-31 18:35:00 +00:00
|
|
|
Transform aces_to_rgb;
|
|
|
|
if (!to_scene_linear_transform(config, "aces_interchange", aces_to_rgb)) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2021-03-10 15:38:26 +00:00
|
|
|
xyz_to_rgb = aces_to_rgb * xyz_E_to_aces * xyz_D65_to_E;
|
OpenColorIO: upgrade to version 2.0.0
Ref T84819
Build System
============
This is an API breaking new version, and the updated code only builds with
OpenColorIO 2.0 and later. Adding backwards compatibility was too complicated.
* Tinyxml was replaced with Expat, adding a new dependency.
* Yaml-cpp is now built as a dependency on Unix, as was already done on Windows.
* Removed currently unused LCMS code.
* Pystring remains built as part of OCIO itself, since it has no good build system.
* Linux and macOS check for the OpenColorIO verison, and disable it if too old.
Ref D10270
Processors and Transforms
=========================
CPU processors now need to be created to do CPU processing. These are cached
internally, but the cache lookup is not fast enough to execute per pixel or
texture sample, so for performance these are now also exposed in the C API.
The C API for transforms will no longer be needed afer all changes, so remove
it to simplify the API and fallback implementation.
Ref D10271
Display Transforms
==================
Needs a bit more manual work constructing the transform. LegacyViewingPipeline
could also have been used, but isn't really any simpler and since it's legacy
we better not rely on it.
We moved more logic into the opencolorio module, to simplify the API. There is
no need to wrap a dozen functions just to be able to do this in C rather than C++.
It's also tightly coupled to the GPU shader logic, and so should be in the same
module.
Ref D10271
GPU Display Shader
==================
To avoid baking exposure and gamma into the GLSL shader and requiring slow
recompiles when tweaking, we manually apply them in the shader. This leads
to some logic duplicaton between the CPU and GPU display processor, but it
seems unavoidable.
Caching was also changed. Previously this was done both on the imbuf and
opencolorio module levels. Now it's all done in the opencolorio module by
simply matching color space names. We no longer use cacheIDs from OpenColorIO
since computing them is expensive, and they are unlikely to match now that
more is baked into the shader code.
Shaders can now use multiple 2D textures, 3D textures and uniforms, rather
than a single 3D texture. So allocating and binding those adds some code.
Color space conversions for blending with overlays is now hardcoded in the
shader. This was using harcoded numbers anyway, if this every becomes a
general OpenColorIO transform it can be changed, but for now there is no
point to add code complexity.
Ref D10273
CIE XYZ
=======
We need standard CIE XYZ values for rendering effects like blackbody emission.
The relation to the scene linear role is based on OpenColorIO configuration.
In OpenColorIO 2.0 configs roles can no longer have the same name as color
spaces, which means our XYZ role and colorspace in the configuration give an
error.
Instead use the new standard aces_interchange role, which relates scene linear
to a known scene referred color space. Compatibility with the old XYZ role is
preserved, if the configuration file has no conflicting names.
Also includes a non-functional change to the configuraton file to use an
XYZ-to-ACES matrix instead of REC709-to-ACES, makes debugging a little easier
since the matrix is the same one we have in the code now and that is also
found easily in the ACES specs.
Ref D10274
2021-01-31 18:35:00 +00:00
|
|
|
}
|
|
|
|
else if (config->hasRole("XYZ")) {
|
|
|
|
/* Custom role used before the standard existed. */
|
|
|
|
if (!to_scene_linear_transform(config, "XYZ", xyz_to_rgb)) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
2021-02-17 05:13:49 +00:00
|
|
|
else {
|
|
|
|
/* No reference role found to determine XYZ. */
|
|
|
|
return;
|
|
|
|
}
|
OpenColorIO: upgrade to version 2.0.0
Ref T84819
Build System
============
This is an API breaking new version, and the updated code only builds with
OpenColorIO 2.0 and later. Adding backwards compatibility was too complicated.
* Tinyxml was replaced with Expat, adding a new dependency.
* Yaml-cpp is now built as a dependency on Unix, as was already done on Windows.
* Removed currently unused LCMS code.
* Pystring remains built as part of OCIO itself, since it has no good build system.
* Linux and macOS check for the OpenColorIO verison, and disable it if too old.
Ref D10270
Processors and Transforms
=========================
CPU processors now need to be created to do CPU processing. These are cached
internally, but the cache lookup is not fast enough to execute per pixel or
texture sample, so for performance these are now also exposed in the C API.
The C API for transforms will no longer be needed afer all changes, so remove
it to simplify the API and fallback implementation.
Ref D10271
Display Transforms
==================
Needs a bit more manual work constructing the transform. LegacyViewingPipeline
could also have been used, but isn't really any simpler and since it's legacy
we better not rely on it.
We moved more logic into the opencolorio module, to simplify the API. There is
no need to wrap a dozen functions just to be able to do this in C rather than C++.
It's also tightly coupled to the GPU shader logic, and so should be in the same
module.
Ref D10271
GPU Display Shader
==================
To avoid baking exposure and gamma into the GLSL shader and requiring slow
recompiles when tweaking, we manually apply them in the shader. This leads
to some logic duplicaton between the CPU and GPU display processor, but it
seems unavoidable.
Caching was also changed. Previously this was done both on the imbuf and
opencolorio module levels. Now it's all done in the opencolorio module by
simply matching color space names. We no longer use cacheIDs from OpenColorIO
since computing them is expensive, and they are unlikely to match now that
more is baked into the shader code.
Shaders can now use multiple 2D textures, 3D textures and uniforms, rather
than a single 3D texture. So allocating and binding those adds some code.
Color space conversions for blending with overlays is now hardcoded in the
shader. This was using harcoded numbers anyway, if this every becomes a
general OpenColorIO transform it can be changed, but for now there is no
point to add code complexity.
Ref D10273
CIE XYZ
=======
We need standard CIE XYZ values for rendering effects like blackbody emission.
The relation to the scene linear role is based on OpenColorIO configuration.
In OpenColorIO 2.0 configs roles can no longer have the same name as color
spaces, which means our XYZ role and colorspace in the configuration give an
error.
Instead use the new standard aces_interchange role, which relates scene linear
to a known scene referred color space. Compatibility with the old XYZ role is
preserved, if the configuration file has no conflicting names.
Also includes a non-functional change to the configuraton file to use an
XYZ-to-ACES matrix instead of REC709-to-ACES, makes debugging a little easier
since the matrix is the same one we have in the code now and that is also
found easily in the ACES specs.
Ref D10274
2021-01-31 18:35:00 +00:00
|
|
|
|
|
|
|
xyz_to_r = float4_to_float3(xyz_to_rgb.x);
|
|
|
|
xyz_to_g = float4_to_float3(xyz_to_rgb.y);
|
|
|
|
xyz_to_b = float4_to_float3(xyz_to_rgb.z);
|
|
|
|
|
|
|
|
const Transform rgb_to_xyz = transform_inverse(xyz_to_rgb);
|
|
|
|
rgb_to_y = float4_to_float3(rgb_to_xyz.y);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2011-04-27 11:58:34 +00:00
|
|
|
CCL_NAMESPACE_END
|