2023-06-14 16:52:36 +10:00
|
|
|
/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation
|
|
|
|
|
*
|
|
|
|
|
* SPDX-License-Identifier: Apache-2.0 */
|
2011-04-27 11:58:34 +00:00
|
|
|
|
2019-05-02 15:45:31 +02:00
|
|
|
#include "device/device.h"
|
|
|
|
|
|
2021-10-24 14:19:19 +02:00
|
|
|
#include "scene/background.h"
|
|
|
|
|
#include "scene/camera.h"
|
|
|
|
|
#include "scene/colorspace.h"
|
|
|
|
|
#include "scene/integrator.h"
|
|
|
|
|
#include "scene/light.h"
|
|
|
|
|
#include "scene/mesh.h"
|
|
|
|
|
#include "scene/object.h"
|
|
|
|
|
#include "scene/osl.h"
|
|
|
|
|
#include "scene/procedural.h"
|
|
|
|
|
#include "scene/scene.h"
|
|
|
|
|
#include "scene/shader.h"
|
|
|
|
|
#include "scene/shader_graph.h"
|
|
|
|
|
#include "scene/shader_nodes.h"
|
|
|
|
|
#include "scene/svm.h"
|
|
|
|
|
#include "scene/tables.h"
|
2011-04-27 11:58:34 +00:00
|
|
|
|
2024-12-31 10:28:46 +01:00
|
|
|
#include "util/log.h"
|
2021-10-24 14:19:19 +02:00
|
|
|
#include "util/murmurhash.h"
|
|
|
|
|
#include "util/transform.h"
|
2011-04-27 11:58:34 +00:00
|
|
|
|
2018-06-14 17:48:19 +02:00
|
|
|
#ifdef WITH_OCIO
|
|
|
|
|
# include <OpenColorIO/OpenColorIO.h>
|
|
|
|
|
namespace OCIO = OCIO_NAMESPACE;
|
|
|
|
|
#endif
|
|
|
|
|
|
Cycles: Remove MultiGGX code, replace with albedo scaling
While the multiscattering GGX code is cool and solves the darkening problem at higher roughnesses, it's also currently buggy, hard to maintain and often impractical to use due to the higher noise and render time.
In practice, though, having the exact correct directional distribution is not that important as long as the overall albedo is correct and we a) don't get the darkening effect and b) do get the saturation effect at higher roughnesses.
This can simply be achieved by adding a second lobe (https://blog.selfshadow.com/publications/s2017-shading-course/imageworks/s2017_pbs_imageworks_slides_v2.pdf) or scaling the single-scattering GGX lobe (https://blog.selfshadow.com/publications/turquin/ms_comp_final.pdf). Both approaches require the same precomputation and produce outputs of comparable quality, so I went for the simple albedo scaling since it's easier to implement and more efficient.
Overall, the results are pretty good: All scenarios that I tested (Glossy BSDF, Glass BSDF, Principled BSDF with metallic or transmissive = 1) pass the white furnace test (a material with pure-white color in front of a pure-white background should be indistinguishable from the background if it preserves energy), and the overall albedo for non-white materials matches that produced by the real multi-scattering code (with the expected saturation increase as the roughness increases).
In order to produce the precomputed tables, the PR also includes a utility that computes them. This is not built by default, since there's no reason for a user to run it (it only makes sense for documentation/reproducibility purposes and when making changes to the microfacet models).
Pull Request: https://projects.blender.org/blender/blender/pulls/107958
2023-06-05 02:20:57 +02:00
|
|
|
#include "scene/shader.tables"
|
|
|
|
|
|
2011-04-27 11:58:34 +00:00
|
|
|
CCL_NAMESPACE_BEGIN
|
|
|
|
|
|
2017-10-06 21:06:15 +05:00
|
|
|
thread_mutex ShaderManager::lookup_table_mutex;
|
2014-06-20 21:21:05 +02:00
|
|
|
|
2011-04-27 11:58:34 +00:00
|
|
|
/* Shader */
|
|
|
|
|
|
2016-05-08 00:18:32 +02:00
|
|
|
NODE_DEFINE(Shader)
|
|
|
|
|
{
|
|
|
|
|
NodeType *type = NodeType::add("shader", create);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2022-11-30 20:50:11 +01:00
|
|
|
static NodeEnum emission_sampling_method_enum;
|
|
|
|
|
emission_sampling_method_enum.insert("none", EMISSION_SAMPLING_NONE);
|
|
|
|
|
emission_sampling_method_enum.insert("auto", EMISSION_SAMPLING_AUTO);
|
|
|
|
|
emission_sampling_method_enum.insert("front", EMISSION_SAMPLING_FRONT);
|
|
|
|
|
emission_sampling_method_enum.insert("back", EMISSION_SAMPLING_BACK);
|
|
|
|
|
emission_sampling_method_enum.insert("front_back", EMISSION_SAMPLING_FRONT_BACK);
|
|
|
|
|
SOCKET_ENUM(emission_sampling_method,
|
|
|
|
|
"Emission Sampling Method",
|
|
|
|
|
emission_sampling_method_enum,
|
|
|
|
|
EMISSION_SAMPLING_AUTO);
|
|
|
|
|
|
2016-05-08 00:18:32 +02:00
|
|
|
SOCKET_BOOLEAN(use_transparent_shadow, "Use Transparent Shadow", true);
|
2023-10-11 15:07:21 +02:00
|
|
|
SOCKET_BOOLEAN(use_bump_map_correction, "Bump Map Correction", true);
|
2016-05-08 00:18:32 +02:00
|
|
|
SOCKET_BOOLEAN(heterogeneous_volume, "Heterogeneous Volume", true);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2016-05-08 00:18:32 +02: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 17:49:00 +01:00
|
|
|
VOLUME_SAMPLING_MULTIPLE_IMPORTANCE);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2016-05-08 00:18:32 +02: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 06:17:24 +02:00
|
|
|
|
2020-03-07 14:38:52 +01:00
|
|
|
SOCKET_FLOAT(volume_step_rate, "Volume Step Rate", 1.0f);
|
|
|
|
|
|
2016-08-02 05:13:58 -04: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 06:17:24 +02:00
|
|
|
|
2020-11-04 11:17:38 +01:00
|
|
|
SOCKET_INT(pass_id, "Pass ID", 0);
|
|
|
|
|
|
2016-05-08 00:18:32 +02:00
|
|
|
return type;
|
|
|
|
|
}
|
|
|
|
|
|
2021-03-15 16:11:12 +01: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 06:17:24 +02:00
|
|
|
|
2024-12-26 17:53:55 +01:00
|
|
|
graph = nullptr;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2011-10-12 23:03:12 +00:00
|
|
|
has_surface = false;
|
2011-09-27 20:37:24 +00:00
|
|
|
has_surface_transparent = false;
|
Cycles: merge of cycles-x branch, a major update to the renderer
This includes much improved GPU rendering performance, viewport interactivity,
new shadow catcher, revamped sampling settings, subsurface scattering anisotropy,
new GPU volume sampling, improved PMJ sampling pattern, and more.
Some features have also been removed or changed, breaking backwards compatibility.
Including the removal of the OpenCL backend, for which alternatives are under
development.
Release notes and code docs:
https://wiki.blender.org/wiki/Reference/Release_Notes/3.0/Cycles
https://wiki.blender.org/wiki/Source/Render/Cycles
Credits:
* Sergey Sharybin
* Brecht Van Lommel
* Patrick Mours (OptiX backend)
* Christophe Hery (subsurface scattering anisotropy)
* William Leeson (PMJ sampling pattern)
* Alaska (various fixes and tweaks)
* Thomas Dinges (various fixes)
For the full commit history, see the cycles-x branch. This squashes together
all the changes since intermediate changes would often fail building or tests.
Ref T87839, T87837, T87836
Fixes T90734, T89353, T80267, T80267, T77185, T69800
2021-09-20 17:59:20 +02:00
|
|
|
has_surface_raytrace = 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 14:02:16 +02:00
|
|
|
has_bump = false;
|
2013-08-18 14:15:57 +00:00
|
|
|
has_bssrdf_bump = false;
|
2016-02-05 22:13:51 +01:00
|
|
|
has_surface_spatial_varying = false;
|
2016-02-05 21:33:37 +01:00
|
|
|
has_volume_spatial_varying = false;
|
2020-03-07 14:38:52 +01:00
|
|
|
has_volume_attribute_dependency = false;
|
2017-07-21 04:18:11 +02:00
|
|
|
has_volume_connected = false;
|
2020-03-07 14:38:52 +01:00
|
|
|
prev_volume_step_rate = 0.0f;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2022-11-30 20:50:11 +01:00
|
|
|
emission_estimate = zero_float3();
|
|
|
|
|
emission_sampling = EMISSION_SAMPLING_NONE;
|
|
|
|
|
emission_is_constant = true;
|
|
|
|
|
|
2016-08-02 05:13:58 -04:00
|
|
|
displacement_method = DISPLACE_BUMP;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2016-05-14 14:50:03 +02:00
|
|
|
id = -1;
|
2019-04-17 06:17:24 +02: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 15:01:26 +01:00
|
|
|
need_update_uvs = true;
|
|
|
|
|
need_update_attribute = true;
|
|
|
|
|
need_update_displacement = true;
|
2011-04-27 11:58:34 +00:00
|
|
|
}
|
|
|
|
|
|
2022-11-30 20:50:11 +01:00
|
|
|
static float3 output_estimate_emission(ShaderOutput *output, bool &is_constant)
|
2016-09-03 22:40:07 +02:00
|
|
|
{
|
2022-11-30 20:50:11 +01:00
|
|
|
/* Only supports a few nodes for now, not arbitrary shader graphs. */
|
|
|
|
|
ShaderNode *node = (output) ? output->parent : nullptr;
|
|
|
|
|
|
|
|
|
|
if (node == nullptr) {
|
|
|
|
|
return zero_float3();
|
2019-12-04 19:57:28 +01:00
|
|
|
}
|
2024-12-26 17:53:59 +01:00
|
|
|
if (node->type == EmissionNode::get_node_type() ||
|
|
|
|
|
node->type == BackgroundNode::get_node_type() ||
|
|
|
|
|
node->type == PrincipledBsdfNode::get_node_type())
|
2022-11-30 20:50:11 +01:00
|
|
|
{
|
2023-09-13 03:05:27 +02:00
|
|
|
const bool is_principled = (node->type == PrincipledBsdfNode::get_node_type());
|
2022-11-30 20:50:11 +01:00
|
|
|
/* Emission and Background node. */
|
2023-09-22 17:05:47 +02:00
|
|
|
ShaderInput *color_in = node->input(is_principled ? "Emission Color" : "Color");
|
2023-09-13 03:05:27 +02:00
|
|
|
ShaderInput *strength_in = node->input(is_principled ? "Emission Strength" : "Strength");
|
|
|
|
|
|
|
|
|
|
if (is_principled) {
|
|
|
|
|
/* Too many parameters (coat, sheen, alpha) influence Emission for the Principled BSDF. */
|
|
|
|
|
is_constant = false;
|
|
|
|
|
}
|
2019-12-04 19:57:28 +01:00
|
|
|
|
2022-11-30 20:50:11 +01:00
|
|
|
float3 estimate = one_float3();
|
2016-09-03 22:40:07 +02:00
|
|
|
|
2022-11-30 20:50:11 +01:00
|
|
|
if (color_in->link) {
|
|
|
|
|
is_constant = false;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
estimate *= node->get_float3(color_in->socket_type);
|
|
|
|
|
}
|
2016-09-03 22:40:07 +02:00
|
|
|
|
2022-11-30 20:50:11 +01:00
|
|
|
if (strength_in->link) {
|
|
|
|
|
is_constant = false;
|
|
|
|
|
estimate *= output_estimate_emission(strength_in->link, is_constant);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
estimate *= node->get_float(strength_in->socket_type);
|
|
|
|
|
}
|
2016-09-03 22:40:07 +02:00
|
|
|
|
2023-03-16 14:44:50 +01:00
|
|
|
/* Lower importance of emission nodes from automatic value/color to shader
|
|
|
|
|
* conversion, as these are likely used for previewing and can be slow to
|
|
|
|
|
* build a light tree for on dense meshes. */
|
|
|
|
|
if (node->type == EmissionNode::get_node_type()) {
|
|
|
|
|
EmissionNode *emission_node = static_cast<EmissionNode *>(node);
|
|
|
|
|
if (emission_node->from_auto_conversion) {
|
|
|
|
|
estimate *= 0.1f;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-11-30 20:50:11 +01:00
|
|
|
return estimate;
|
|
|
|
|
}
|
2024-12-26 17:53:59 +01:00
|
|
|
if (node->type == LightFalloffNode::get_node_type() ||
|
|
|
|
|
node->type == IESLightNode::get_node_type())
|
2023-01-05 19:06:05 +01:00
|
|
|
{
|
|
|
|
|
/* Get strength from Light Falloff and IES texture node. */
|
2022-11-30 20:50:11 +01:00
|
|
|
ShaderInput *strength_in = node->input("Strength");
|
|
|
|
|
is_constant = false;
|
2016-09-03 22:40:07 +02:00
|
|
|
|
2022-11-30 20:50:11 +01:00
|
|
|
return (strength_in->link) ? output_estimate_emission(strength_in->link, is_constant) :
|
|
|
|
|
make_float3(node->get_float(strength_in->socket_type));
|
|
|
|
|
}
|
2024-12-26 17:53:59 +01:00
|
|
|
if (node->type == AddClosureNode::get_node_type()) {
|
2022-11-30 20:50:11 +01:00
|
|
|
/* Add Closure. */
|
|
|
|
|
ShaderInput *closure1_in = node->input("Closure1");
|
|
|
|
|
ShaderInput *closure2_in = node->input("Closure2");
|
|
|
|
|
|
|
|
|
|
const float3 estimate1 = (closure1_in->link) ?
|
|
|
|
|
output_estimate_emission(closure1_in->link, is_constant) :
|
|
|
|
|
zero_float3();
|
|
|
|
|
const float3 estimate2 = (closure2_in->link) ?
|
|
|
|
|
output_estimate_emission(closure2_in->link, is_constant) :
|
|
|
|
|
zero_float3();
|
|
|
|
|
|
|
|
|
|
return estimate1 + estimate2;
|
|
|
|
|
}
|
2024-12-26 17:53:59 +01:00
|
|
|
if (node->type == MixClosureNode::get_node_type()) {
|
2022-11-30 20:50:11 +01:00
|
|
|
/* Mix Closure. */
|
|
|
|
|
ShaderInput *fac_in = node->input("Fac");
|
|
|
|
|
ShaderInput *closure1_in = node->input("Closure1");
|
|
|
|
|
ShaderInput *closure2_in = node->input("Closure2");
|
|
|
|
|
|
|
|
|
|
const float3 estimate1 = (closure1_in->link) ?
|
|
|
|
|
output_estimate_emission(closure1_in->link, is_constant) :
|
|
|
|
|
zero_float3();
|
|
|
|
|
const float3 estimate2 = (closure2_in->link) ?
|
|
|
|
|
output_estimate_emission(closure2_in->link, is_constant) :
|
|
|
|
|
zero_float3();
|
|
|
|
|
|
|
|
|
|
if (fac_in->link) {
|
|
|
|
|
is_constant = false;
|
|
|
|
|
return estimate1 + estimate2;
|
|
|
|
|
}
|
2024-12-26 17:53:59 +01:00
|
|
|
|
|
|
|
|
const float fac = node->get_float(fac_in->socket_type);
|
|
|
|
|
return (1.0f - fac) * estimate1 + fac * estimate2;
|
2022-11-30 20:50:11 +01:00
|
|
|
}
|
|
|
|
|
|
2024-12-26 17:53:59 +01:00
|
|
|
/* Other nodes, potentially OSL nodes with arbitrary code for which all we can
|
|
|
|
|
* determine is if it has emission or not. */
|
|
|
|
|
const bool has_emission = node->has_surface_emission();
|
|
|
|
|
float3 estimate;
|
|
|
|
|
|
|
|
|
|
if (output->type() == SocketType::CLOSURE) {
|
|
|
|
|
if (has_emission) {
|
2022-11-30 20:50:11 +01:00
|
|
|
estimate = one_float3();
|
|
|
|
|
is_constant = false;
|
2019-02-19 17:44:58 +01:00
|
|
|
}
|
2024-12-26 17:53:59 +01:00
|
|
|
else {
|
|
|
|
|
estimate = zero_float3();
|
|
|
|
|
}
|
2019-02-19 17:44:58 +01:00
|
|
|
|
2024-12-26 19:41:25 +01:00
|
|
|
for (const ShaderInput *in : node->inputs) {
|
2024-12-26 17:53:59 +01:00
|
|
|
if (in->type() == SocketType::CLOSURE && in->link) {
|
|
|
|
|
estimate += output_estimate_emission(in->link, is_constant);
|
|
|
|
|
}
|
|
|
|
|
}
|
2016-09-03 22:40:07 +02:00
|
|
|
}
|
2024-12-26 17:53:59 +01:00
|
|
|
else {
|
|
|
|
|
estimate = one_float3();
|
|
|
|
|
is_constant = false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return estimate;
|
2022-11-30 20:50:11 +01:00
|
|
|
}
|
2016-09-03 22:40:07 +02:00
|
|
|
|
2022-11-30 20:50:11 +01:00
|
|
|
void Shader::estimate_emission()
|
|
|
|
|
{
|
|
|
|
|
/* If the shader has AOVs, they need to be evaluated, so we can't skip the shader. */
|
|
|
|
|
emission_is_constant = true;
|
2019-02-19 17:44:58 +01:00
|
|
|
|
2024-12-26 19:41:25 +01:00
|
|
|
for (ShaderNode *node : graph->nodes) {
|
2022-11-30 20:50:11 +01:00
|
|
|
if (node->special_type == SHADER_SPECIAL_TYPE_OUTPUT_AOV) {
|
|
|
|
|
emission_is_constant = false;
|
2019-02-19 17:44:58 +01:00
|
|
|
}
|
2022-11-30 20:50:11 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ShaderInput *surf = graph->output()->input("Surface");
|
2024-02-22 19:06:22 +01:00
|
|
|
emission_estimate = output_estimate_emission(surf->link, emission_is_constant);
|
2019-02-19 17:44:58 +01:00
|
|
|
|
2022-11-30 20:50:11 +01:00
|
|
|
if (is_zero(emission_estimate)) {
|
|
|
|
|
emission_sampling = EMISSION_SAMPLING_NONE;
|
|
|
|
|
}
|
|
|
|
|
else if (emission_sampling_method == EMISSION_SAMPLING_AUTO) {
|
|
|
|
|
/* Automatically disable MIS when emission is low, to avoid weakly emitting
|
|
|
|
|
* using a lot of memory in the light tree and potentially wasting samples
|
|
|
|
|
* where indirect light samples are sufficient.
|
|
|
|
|
* Possible optimization: estimate front and back emission separately. */
|
2024-02-22 19:06:22 +01:00
|
|
|
emission_sampling = (reduce_max(fabs(emission_estimate)) > 0.5f) ?
|
|
|
|
|
EMISSION_SAMPLING_FRONT_BACK :
|
|
|
|
|
EMISSION_SAMPLING_NONE;
|
2019-02-19 17:44:58 +01:00
|
|
|
}
|
|
|
|
|
else {
|
2022-11-30 20:50:11 +01:00
|
|
|
emission_sampling = emission_sampling_method;
|
2019-02-19 17:44:58 +01:00
|
|
|
}
|
2016-09-03 22:40:07 +02:00
|
|
|
}
|
|
|
|
|
|
2024-12-29 23:13:45 +01:00
|
|
|
void Shader::set_graph(unique_ptr<ShaderGraph> &&graph_)
|
2011-04-27 11:58:34 +00:00
|
|
|
{
|
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 20:19:48 +01:00
|
|
|
if (graph_) {
|
2016-05-02 00:05:16 +02:00
|
|
|
graph_->remove_proxy_nodes();
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-01-24 20:19:48 +01:00
|
|
|
if (displacement_method != DISPLACE_BUMP) {
|
|
|
|
|
graph_->compute_displacement_hash();
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-01-24 20:19:48 +01: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 06:17:24 +02:00
|
|
|
|
2018-01-24 20:19:48 +01: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 15:01:26 +01:00
|
|
|
need_update_displacement = true;
|
2018-01-24 20:19:48 +01:00
|
|
|
}
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2011-04-27 11:58:34 +00:00
|
|
|
/* assign graph */
|
2024-12-29 23:13:45 +01:00
|
|
|
graph = std::move(graph_);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2017-05-19 04:59:35 +02:00
|
|
|
/* Store info here before graph optimization to make sure that
|
|
|
|
|
* nodes that get optimized away still count. */
|
2024-12-26 17:53:55 +01:00
|
|
|
has_volume_connected = (graph->output()->input("Volume")->link != nullptr);
|
2011-04-27 11:58:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Shader::tag_update(Scene *scene)
|
|
|
|
|
{
|
|
|
|
|
/* update tag */
|
2020-11-04 11:17:38 +01: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 15:01:26 +01:00
|
|
|
|
|
|
|
|
scene->shader_manager->tag_update(scene, ShaderManager::SHADER_MODIFIED);
|
2019-04-17 06:17:24 +02: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. */
|
2023-09-17 09:01:48 +10:00
|
|
|
if (emission_sampling != EMISSION_SAMPLING_NONE) {
|
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 15:01:26 +01:00
|
|
|
scene->light_manager->tag_update(scene, LightManager::SHADER_MODIFIED);
|
2023-09-17 09:01:48 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2016-09-02 09:58:41 +02: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 17:41:37 +02: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 15:01:26 +01:00
|
|
|
scene->light_manager->tag_update(scene, LightManager::SHADER_MODIFIED);
|
2020-05-14 17:41:37 +02:00
|
|
|
}
|
2016-09-02 09:58:41 +02:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2013-12-31 17:30:34 +01: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();
|
2024-12-29 17:32:00 +01:00
|
|
|
const bool prev_has_volume = has_volume;
|
2013-12-31 17:30:34 +01: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 06:17:24 +02:00
|
|
|
|
2023-10-20 15:24:46 +02:00
|
|
|
if (!has_surface && !has_volume) {
|
2023-10-18 15:39:38 +02:00
|
|
|
/* If we need to output surface AOVs, add a Transparent BSDF so that the
|
|
|
|
|
* surface shader runs. */
|
2024-12-26 19:41:25 +01:00
|
|
|
for (ShaderNode *node : graph->nodes) {
|
2023-07-28 17:33:39 +02:00
|
|
|
if (node->special_type == SHADER_SPECIAL_TYPE_OUTPUT_AOV) {
|
2024-12-26 19:41:25 +01:00
|
|
|
for (const ShaderInput *in : node->inputs) {
|
2023-07-28 17:33:39 +02:00
|
|
|
if (in->link) {
|
2023-10-18 15:39:38 +02:00
|
|
|
TransparentBsdfNode *transparent = graph->create_node<TransparentBsdfNode>();
|
|
|
|
|
graph->connect(transparent->output("BSDF"), output->input("Surface"));
|
2023-07-28 17:33:39 +02:00
|
|
|
has_surface = true;
|
2023-10-18 15:39:38 +02:00
|
|
|
break;
|
2023-07-28 17:33:39 +02:00
|
|
|
}
|
|
|
|
|
}
|
2023-10-18 15:39:38 +02:00
|
|
|
if (has_surface) {
|
|
|
|
|
break;
|
|
|
|
|
}
|
2023-07-28 17:33:39 +02: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 06:17:24 +02:00
|
|
|
|
2024-12-29 17:32:00 +01:00
|
|
|
const AttributeRequestSet prev_attributes = attributes;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2011-04-27 11:58:34 +00:00
|
|
|
attributes.clear();
|
2024-12-26 19:41:25 +01:00
|
|
|
for (ShaderNode *node : graph->nodes) {
|
2013-12-31 17:30:34 +01:00
|
|
|
node->attributes(this, &attributes);
|
2023-07-28 17:33:39 +02:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-12-14 13:42:34 +01: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 15:01:26 +01:00
|
|
|
need_update_displacement = true;
|
|
|
|
|
scene->geometry_manager->tag_update(scene, GeometryManager::SHADER_DISPLACEMENT_MODIFIED);
|
2020-12-14 13:42:34 +01:00
|
|
|
scene->object_manager->need_flags_update = true;
|
|
|
|
|
}
|
2016-08-13 12:27:17 -04:00
|
|
|
}
|
2019-04-17 06:17:24 +02: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 15:01:26 +01: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 15:01:26 +01:00
|
|
|
need_update_attribute = true;
|
|
|
|
|
scene->geometry_manager->tag_update(scene, GeometryManager::SHADER_ATTRIBUTE_MODIFIED);
|
2021-01-25 14:56:57 +01:00
|
|
|
scene->procedural_manager->tag_update();
|
2011-04-27 11:58:34 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-03-07 14:38:52 +01:00
|
|
|
if (has_volume != prev_has_volume || volume_step_rate != prev_volume_step_rate) {
|
2020-02-02 12:04:19 +01:00
|
|
|
scene->geometry_manager->need_flags_update = true;
|
2015-01-19 19:08:58 +05:00
|
|
|
scene->object_manager->need_flags_update = true;
|
2020-03-07 14:38:52 +01:00
|
|
|
prev_volume_step_rate = volume_step_rate;
|
2015-01-19 19:08:58 +05: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 02:34:56 +02:00
|
|
|
if (!reference_count()) {
|
2020-11-04 11:17:38 +01:00
|
|
|
tag_modified();
|
2021-05-02 02:34:56 +02: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 15:01:26 +01: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 15:01:26 +01: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 15:01:26 +01:00
|
|
|
update_flags = UPDATE_ALL;
|
2018-06-14 17:48:19 +02: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 19:35:00 +01:00
|
|
|
init_xyz_transforms();
|
2011-04-27 11:58:34 +00:00
|
|
|
}
|
|
|
|
|
|
2024-12-26 17:53:59 +01:00
|
|
|
ShaderManager::~ShaderManager() = default;
|
2011-04-27 11:58:34 +00:00
|
|
|
|
2025-03-04 17:27:10 +01:00
|
|
|
unique_ptr<ShaderManager> ShaderManager::create(const int shadingsystem)
|
2011-04-27 11:58:34 +00:00
|
|
|
{
|
2024-12-29 23:13:45 +01:00
|
|
|
unique_ptr<ShaderManager> manager;
|
2011-04-27 11:58:34 +00:00
|
|
|
|
2018-11-09 12:08:51 +01:00
|
|
|
(void)shadingsystem; /* Ignored when built without OSL. */
|
2015-03-27 19:09:41 +05:00
|
|
|
|
2011-04-27 11:58:34 +00:00
|
|
|
#ifdef WITH_OSL
|
2017-05-20 05:21:27 -07:00
|
|
|
if (shadingsystem == SHADINGSYSTEM_OSL) {
|
2025-03-04 17:27:10 +01:00
|
|
|
manager = make_unique<OSLShaderManager>();
|
2017-05-20 05:21:27 -07:00
|
|
|
}
|
2011-04-27 11:58:34 +00:00
|
|
|
else
|
|
|
|
|
#endif
|
2017-05-20 05:21:27 -07:00
|
|
|
{
|
2024-12-29 23:13:45 +01:00
|
|
|
manager = make_unique<SVMShaderManager>();
|
2017-05-20 05:21:27 -07:00
|
|
|
}
|
2018-07-06 10:17:58 +02:00
|
|
|
|
2011-04-27 11:58:34 +00:00
|
|
|
return manager;
|
|
|
|
|
}
|
|
|
|
|
|
2022-09-09 11:55:35 +02:00
|
|
|
uint64_t ShaderManager::get_attribute_id(ustring name)
|
2011-04-27 11:58:34 +00:00
|
|
|
{
|
2024-12-29 17:32:00 +01:00
|
|
|
const thread_scoped_spin_lock lock(attribute_lock_);
|
2017-04-10 16:53:01 +02:00
|
|
|
|
2011-04-27 11:58:34 +00:00
|
|
|
/* get a unique id for each name, for SVM attribute lookup */
|
2024-12-29 17:32:00 +01:00
|
|
|
const AttributeIDMap::iterator it = unique_attribute_id.find(name);
|
2011-04-27 11:58:34 +00:00
|
|
|
|
2023-09-17 09:01:48 +10:00
|
|
|
if (it != unique_attribute_id.end()) {
|
2011-04-27 11:58:34 +00:00
|
|
|
return it->second;
|
2023-09-17 09:01:48 +10:00
|
|
|
}
|
2018-07-06 10:17:58 +02:00
|
|
|
|
2024-12-29 17:32:00 +01:00
|
|
|
const uint64_t id = ATTR_STD_NUM + unique_attribute_id.size();
|
2011-04-27 11:58:34 +00:00
|
|
|
unique_attribute_id[name] = id;
|
|
|
|
|
return id;
|
|
|
|
|
}
|
|
|
|
|
|
2022-09-09 11:55:35 +02:00
|
|
|
uint64_t ShaderManager::get_attribute_id(AttributeStandard std)
|
2011-04-27 11:58:34 +00:00
|
|
|
{
|
2022-09-09 11:55:35 +02:00
|
|
|
return (uint64_t)std;
|
2011-04-27 11:58:34 +00:00
|
|
|
}
|
|
|
|
|
|
2016-08-16 19:42:08 -04: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 19:42:08 -04:00
|
|
|
int id = shader->id;
|
|
|
|
|
|
2011-09-27 20:37:24 +00:00
|
|
|
/* smooth flag */
|
2023-09-17 09:01:48 +10:00
|
|
|
if (smooth) {
|
2011-09-27 20:37:24 +00:00
|
|
|
id |= SHADER_SMOOTH_NORMAL;
|
2023-09-17 09:01:48 +10:00
|
|
|
}
|
2018-07-06 10:17:58 +02:00
|
|
|
|
2011-09-27 20:37:24 +00:00
|
|
|
/* default flags */
|
|
|
|
|
id |= SHADER_CAST_SHADOW | SHADER_AREA_LIGHT;
|
2018-07-06 10:17:58 +02:00
|
|
|
|
2011-04-27 11:58:34 +00:00
|
|
|
return id;
|
|
|
|
|
}
|
|
|
|
|
|
2021-10-21 14:52:34 +02: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 15:01:26 +01:00
|
|
|
if (!need_update()) {
|
2020-03-11 17:49:00 +01:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2016-05-14 14:50:03 +02:00
|
|
|
uint id = 0;
|
2024-12-26 19:41:25 +01:00
|
|
|
for (Shader *shader : scene->shaders) {
|
2016-05-14 14:50:03 +02:00
|
|
|
shader->id = id++;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-05-02 02:34:56 +02: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 06:17:24 +02:00
|
|
|
|
2021-05-02 02:34:56 +02:00
|
|
|
device_update_specific(device, dscene, scene, progress);
|
2012-10-30 11:51:17 +00:00
|
|
|
}
|
|
|
|
|
|
Cycles: merge of cycles-x branch, a major update to the renderer
This includes much improved GPU rendering performance, viewport interactivity,
new shadow catcher, revamped sampling settings, subsurface scattering anisotropy,
new GPU volume sampling, improved PMJ sampling pattern, and more.
Some features have also been removed or changed, breaking backwards compatibility.
Including the removal of the OpenCL backend, for which alternatives are under
development.
Release notes and code docs:
https://wiki.blender.org/wiki/Reference/Release_Notes/3.0/Cycles
https://wiki.blender.org/wiki/Source/Render/Cycles
Credits:
* Sergey Sharybin
* Brecht Van Lommel
* Patrick Mours (OptiX backend)
* Christophe Hery (subsurface scattering anisotropy)
* William Leeson (PMJ sampling pattern)
* Alaska (various fixes and tweaks)
* Thomas Dinges (various fixes)
For the full commit history, see the cycles-x branch. This squashes together
all the changes since intermediate changes would often fail building or tests.
Ref T87839, T87837, T87836
Fixes T90734, T89353, T80267, T80267, T77185, T69800
2021-09-20 17:59:20 +02:00
|
|
|
void ShaderManager::device_update_common(Device * /*device*/,
|
2015-03-27 15:47:55 +05:00
|
|
|
DeviceScene *dscene,
|
|
|
|
|
Scene *scene,
|
|
|
|
|
Progress & /*progress*/)
|
2011-09-27 20:37:24 +00:00
|
|
|
{
|
2018-03-08 00:35:24 +01:00
|
|
|
dscene->shaders.free();
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2024-12-26 17:53:59 +01:00
|
|
|
if (scene->shaders.empty()) {
|
2011-09-27 20:37:24 +00:00
|
|
|
return;
|
2023-09-17 09:01:48 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-03-08 00:35:24 +01:00
|
|
|
KernelShader *kshader = dscene->shaders.alloc(scene->shaders.size());
|
2013-12-28 02:27:48 +01:00
|
|
|
bool has_volumes = false;
|
2015-09-08 11:28:02 +05:00
|
|
|
bool has_transparent_shadow = false;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2024-12-26 19:41:25 +01:00
|
|
|
for (Shader *shader : scene->shaders) {
|
2011-09-27 20:37:24 +00:00
|
|
|
uint flag = 0;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2022-11-30 20:50:11 +01:00
|
|
|
if (shader->emission_sampling == EMISSION_SAMPLING_FRONT) {
|
|
|
|
|
flag |= SD_MIS_FRONT;
|
|
|
|
|
}
|
|
|
|
|
else if (shader->emission_sampling == EMISSION_SAMPLING_BACK) {
|
|
|
|
|
flag |= SD_MIS_BACK;
|
|
|
|
|
}
|
|
|
|
|
else if (shader->emission_sampling == EMISSION_SAMPLING_FRONT_BACK) {
|
|
|
|
|
flag |= SD_MIS_FRONT | SD_MIS_BACK;
|
|
|
|
|
}
|
|
|
|
|
|
2023-09-17 09:01:48 +10:00
|
|
|
if (!is_zero(shader->emission_estimate)) {
|
2021-04-15 16:21:37 +02:00
|
|
|
flag |= SD_HAS_EMISSION;
|
2023-09-17 09:01:48 +10:00
|
|
|
}
|
|
|
|
|
if (shader->has_surface_transparent && shader->get_use_transparent_shadow()) {
|
2013-06-18 09:36:00 +00:00
|
|
|
flag |= SD_HAS_TRANSPARENT_SHADOW;
|
2023-09-17 09:01:48 +10:00
|
|
|
}
|
|
|
|
|
if (shader->has_surface_raytrace) {
|
Cycles: merge of cycles-x branch, a major update to the renderer
This includes much improved GPU rendering performance, viewport interactivity,
new shadow catcher, revamped sampling settings, subsurface scattering anisotropy,
new GPU volume sampling, improved PMJ sampling pattern, and more.
Some features have also been removed or changed, breaking backwards compatibility.
Including the removal of the OpenCL backend, for which alternatives are under
development.
Release notes and code docs:
https://wiki.blender.org/wiki/Reference/Release_Notes/3.0/Cycles
https://wiki.blender.org/wiki/Source/Render/Cycles
Credits:
* Sergey Sharybin
* Brecht Van Lommel
* Patrick Mours (OptiX backend)
* Christophe Hery (subsurface scattering anisotropy)
* William Leeson (PMJ sampling pattern)
* Alaska (various fixes and tweaks)
* Thomas Dinges (various fixes)
For the full commit history, see the cycles-x branch. This squashes together
all the changes since intermediate changes would often fail building or tests.
Ref T87839, T87837, T87836
Fixes T90734, T89353, T80267, T80267, T77185, T69800
2021-09-20 17:59:20 +02:00
|
|
|
flag |= SD_HAS_RAYTRACE;
|
2023-09-17 09:01:48 +10:00
|
|
|
}
|
2013-12-28 02:27:48 +01:00
|
|
|
if (shader->has_volume) {
|
2011-09-27 20:37:24 +00:00
|
|
|
flag |= SD_HAS_VOLUME;
|
2013-12-28 02:27:48 +01:00
|
|
|
has_volumes = true;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2013-12-28 02:27:48 +01:00
|
|
|
/* todo: this could check more fine grained, to skip useless volumes
|
2015-09-08 11:29:14 +05:00
|
|
|
* enclosed inside an opaque bsdf.
|
|
|
|
|
*/
|
2013-12-28 02:27:48 +01:00
|
|
|
flag |= SD_HAS_TRANSPARENT_SHADOW;
|
|
|
|
|
}
|
2017-05-19 04:59:35 +02:00
|
|
|
/* in this case we can assume transparent surface */
|
2023-09-17 09:01:48 +10:00
|
|
|
if (shader->has_volume_connected && !shader->has_surface) {
|
2017-05-19 04:59:35 +02:00
|
|
|
flag |= SD_HAS_ONLY_VOLUME;
|
2023-09-17 09:01:48 +10:00
|
|
|
}
|
2020-03-07 14:38:52 +01:00
|
|
|
if (shader->has_volume) {
|
2023-09-17 09:01:48 +10:00
|
|
|
if (shader->get_heterogeneous_volume() && shader->has_volume_spatial_varying) {
|
2020-03-07 14:38:52 +01:00
|
|
|
flag |= SD_HETEROGENEOUS_VOLUME;
|
2023-09-17 09:01:48 +10:00
|
|
|
}
|
2020-03-07 14:38:52 +01:00
|
|
|
}
|
2023-09-17 09:01:48 +10:00
|
|
|
if (shader->has_volume_attribute_dependency) {
|
2020-03-07 14:38:52 +01:00
|
|
|
flag |= SD_NEED_VOLUME_ATTRIBUTES;
|
2023-09-17 09:01:48 +10:00
|
|
|
}
|
|
|
|
|
if (shader->has_bssrdf_bump) {
|
2013-08-18 14:15:57 +00:00
|
|
|
flag |= SD_HAS_BSSRDF_BUMP;
|
2023-09-17 09:01:48 +10:00
|
|
|
}
|
|
|
|
|
if (shader->get_volume_sampling_method() == VOLUME_SAMPLING_EQUIANGULAR) {
|
Cycles: merge of cycles-x branch, a major update to the renderer
This includes much improved GPU rendering performance, viewport interactivity,
new shadow catcher, revamped sampling settings, subsurface scattering anisotropy,
new GPU volume sampling, improved PMJ sampling pattern, and more.
Some features have also been removed or changed, breaking backwards compatibility.
Including the removal of the OpenCL backend, for which alternatives are under
development.
Release notes and code docs:
https://wiki.blender.org/wiki/Reference/Release_Notes/3.0/Cycles
https://wiki.blender.org/wiki/Source/Render/Cycles
Credits:
* Sergey Sharybin
* Brecht Van Lommel
* Patrick Mours (OptiX backend)
* Christophe Hery (subsurface scattering anisotropy)
* William Leeson (PMJ sampling pattern)
* Alaska (various fixes and tweaks)
* Thomas Dinges (various fixes)
For the full commit history, see the cycles-x branch. This squashes together
all the changes since intermediate changes would often fail building or tests.
Ref T87839, T87837, T87836
Fixes T90734, T89353, T80267, T80267, T77185, T69800
2021-09-20 17:59:20 +02:00
|
|
|
flag |= SD_VOLUME_EQUIANGULAR;
|
2023-09-17 09:01:48 +10:00
|
|
|
}
|
|
|
|
|
if (shader->get_volume_sampling_method() == VOLUME_SAMPLING_MULTIPLE_IMPORTANCE) {
|
Cycles: merge of cycles-x branch, a major update to the renderer
This includes much improved GPU rendering performance, viewport interactivity,
new shadow catcher, revamped sampling settings, subsurface scattering anisotropy,
new GPU volume sampling, improved PMJ sampling pattern, and more.
Some features have also been removed or changed, breaking backwards compatibility.
Including the removal of the OpenCL backend, for which alternatives are under
development.
Release notes and code docs:
https://wiki.blender.org/wiki/Reference/Release_Notes/3.0/Cycles
https://wiki.blender.org/wiki/Source/Render/Cycles
Credits:
* Sergey Sharybin
* Brecht Van Lommel
* Patrick Mours (OptiX backend)
* Christophe Hery (subsurface scattering anisotropy)
* William Leeson (PMJ sampling pattern)
* Alaska (various fixes and tweaks)
* Thomas Dinges (various fixes)
For the full commit history, see the cycles-x branch. This squashes together
all the changes since intermediate changes would often fail building or tests.
Ref T87839, T87837, T87836
Fixes T90734, T89353, T80267, T80267, T77185, T69800
2021-09-20 17:59:20 +02:00
|
|
|
flag |= SD_VOLUME_MIS;
|
2023-09-17 09:01:48 +10:00
|
|
|
}
|
|
|
|
|
if (shader->get_volume_interpolation_method() == VOLUME_INTERPOLATION_CUBIC) {
|
2014-10-22 19:23:45 +06:00
|
|
|
flag |= SD_VOLUME_CUBIC;
|
2023-09-17 09:01:48 +10:00
|
|
|
}
|
|
|
|
|
if (shader->has_bump) {
|
2014-11-11 18:21:56 -02:00
|
|
|
flag |= SD_HAS_BUMP;
|
2023-09-17 09:01:48 +10:00
|
|
|
}
|
|
|
|
|
if (shader->get_displacement_method() != DISPLACE_BUMP) {
|
2016-08-14 11:44:25 -04:00
|
|
|
flag |= SD_HAS_DISPLACEMENT;
|
2023-09-17 09:01:48 +10:00
|
|
|
}
|
2023-10-11 15:07:21 +02:00
|
|
|
if (shader->get_use_bump_map_correction()) {
|
|
|
|
|
flag |= SD_USE_BUMP_MAP_CORRECTION;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2016-09-14 18:53:35 +02:00
|
|
|
/* constant emission check */
|
2023-09-17 09:01:48 +10:00
|
|
|
if (shader->emission_is_constant) {
|
2016-09-14 18:53:35 +02:00
|
|
|
flag |= SD_HAS_CONSTANT_EMISSION;
|
2023-09-17 09:01:48 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2024-12-29 17:32:00 +01:00
|
|
|
const uint32_t cryptomatte_id = util_murmur_hash3(
|
|
|
|
|
shader->name.c_str(), shader->name.length(), 0);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2016-08-16 19:42:08 -04:00
|
|
|
/* regular shader */
|
2018-03-08 00:35:24 +01:00
|
|
|
kshader->flags = flag;
|
2020-11-04 11:17:38 +01:00
|
|
|
kshader->pass_id = shader->get_pass_id();
|
2022-11-30 20:50:11 +01:00
|
|
|
kshader->constant_emission[0] = shader->emission_estimate.x;
|
|
|
|
|
kshader->constant_emission[1] = shader->emission_estimate.y;
|
|
|
|
|
kshader->constant_emission[2] = shader->emission_estimate.z;
|
2018-10-28 05:37:41 -04:00
|
|
|
kshader->cryptomatte_id = util_hash_to_float(cryptomatte_id);
|
2018-03-08 00:35:24 +01:00
|
|
|
kshader++;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2016-01-07 11:45:13 +05:00
|
|
|
has_transparent_shadow |= (flag & SD_HAS_TRANSPARENT_SHADOW) != 0;
|
2011-09-27 20:37:24 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-03-08 00:35:24 +01:00
|
|
|
dscene->shaders.copy_to_device();
|
2019-04-17 06:17:24 +02:00
|
|
|
|
Cycles: Remove MultiGGX code, replace with albedo scaling
While the multiscattering GGX code is cool and solves the darkening problem at higher roughnesses, it's also currently buggy, hard to maintain and often impractical to use due to the higher noise and render time.
In practice, though, having the exact correct directional distribution is not that important as long as the overall albedo is correct and we a) don't get the darkening effect and b) do get the saturation effect at higher roughnesses.
This can simply be achieved by adding a second lobe (https://blog.selfshadow.com/publications/s2017-shading-course/imageworks/s2017_pbs_imageworks_slides_v2.pdf) or scaling the single-scattering GGX lobe (https://blog.selfshadow.com/publications/turquin/ms_comp_final.pdf). Both approaches require the same precomputation and produce outputs of comparable quality, so I went for the simple albedo scaling since it's easier to implement and more efficient.
Overall, the results are pretty good: All scenarios that I tested (Glossy BSDF, Glass BSDF, Principled BSDF with metallic or transmissive = 1) pass the white furnace test (a material with pure-white color in front of a pure-white background should be indistinguishable from the background if it preserves energy), and the overall albedo for non-white materials matches that produced by the real multi-scattering code (with the expected saturation increase as the roughness increases).
In order to produce the precomputed tables, the PR also includes a utility that computes them. This is not built by default, since there's no reason for a user to run it (it only makes sense for documentation/reproducibility purposes and when making changes to the microfacet models).
Pull Request: https://projects.blender.org/blender/blender/pulls/107958
2023-06-05 02:20:57 +02:00
|
|
|
/* lookup tables */
|
|
|
|
|
KernelTables *ktables = &dscene->data.tables;
|
|
|
|
|
ktables->ggx_E = ensure_bsdf_table(dscene, scene, table_ggx_E);
|
|
|
|
|
ktables->ggx_Eavg = ensure_bsdf_table(dscene, scene, table_ggx_Eavg);
|
|
|
|
|
ktables->ggx_glass_E = ensure_bsdf_table(dscene, scene, table_ggx_glass_E);
|
|
|
|
|
ktables->ggx_glass_Eavg = ensure_bsdf_table(dscene, scene, table_ggx_glass_Eavg);
|
|
|
|
|
ktables->ggx_glass_inv_E = ensure_bsdf_table(dscene, scene, table_ggx_glass_inv_E);
|
|
|
|
|
ktables->ggx_glass_inv_Eavg = ensure_bsdf_table(dscene, scene, table_ggx_glass_inv_Eavg);
|
2023-07-24 15:36:36 +02:00
|
|
|
ktables->sheen_ltc = ensure_bsdf_table(dscene, scene, table_sheen_ltc);
|
2023-08-10 23:53:37 +02:00
|
|
|
ktables->ggx_gen_schlick_ior_s = ensure_bsdf_table(dscene, scene, table_ggx_gen_schlick_ior_s);
|
|
|
|
|
ktables->ggx_gen_schlick_s = ensure_bsdf_table(dscene, scene, table_ggx_gen_schlick_s);
|
Cycles: Remove MultiGGX code, replace with albedo scaling
While the multiscattering GGX code is cool and solves the darkening problem at higher roughnesses, it's also currently buggy, hard to maintain and often impractical to use due to the higher noise and render time.
In practice, though, having the exact correct directional distribution is not that important as long as the overall albedo is correct and we a) don't get the darkening effect and b) do get the saturation effect at higher roughnesses.
This can simply be achieved by adding a second lobe (https://blog.selfshadow.com/publications/s2017-shading-course/imageworks/s2017_pbs_imageworks_slides_v2.pdf) or scaling the single-scattering GGX lobe (https://blog.selfshadow.com/publications/turquin/ms_comp_final.pdf). Both approaches require the same precomputation and produce outputs of comparable quality, so I went for the simple albedo scaling since it's easier to implement and more efficient.
Overall, the results are pretty good: All scenarios that I tested (Glossy BSDF, Glass BSDF, Principled BSDF with metallic or transmissive = 1) pass the white furnace test (a material with pure-white color in front of a pure-white background should be indistinguishable from the background if it preserves energy), and the overall albedo for non-white materials matches that produced by the real multi-scattering code (with the expected saturation increase as the roughness increases).
In order to produce the precomputed tables, the PR also includes a utility that computes them. This is not built by default, since there's no reason for a user to run it (it only makes sense for documentation/reproducibility purposes and when making changes to the microfacet models).
Pull Request: https://projects.blender.org/blender/blender/pulls/107958
2023-06-05 02:20:57 +02:00
|
|
|
|
2014-06-01 07:11:13 +02:00
|
|
|
/* integrator */
|
2013-12-28 02:27:48 +01:00
|
|
|
KernelIntegrator *kintegrator = &dscene->data.integrator;
|
|
|
|
|
kintegrator->use_volumes = has_volumes;
|
2015-09-08 11:28:02 +05:00
|
|
|
/* TODO(sergey): De-duplicate with flags set in integrator.cpp. */
|
2017-08-02 15:23:50 +02:00
|
|
|
kintegrator->transparent_shadows = has_transparent_shadow;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-06-14 17:48:19 +02:00
|
|
|
/* film */
|
|
|
|
|
KernelFilm *kfilm = &dscene->data.film;
|
|
|
|
|
/* color space, needs to be here because e.g. displacement shaders could depend on it */
|
2024-12-19 09:41:55 +01:00
|
|
|
kfilm->xyz_to_r = make_float4(xyz_to_r);
|
|
|
|
|
kfilm->xyz_to_g = make_float4(xyz_to_g);
|
|
|
|
|
kfilm->xyz_to_b = make_float4(xyz_to_b);
|
|
|
|
|
kfilm->rgb_to_y = make_float4(rgb_to_y);
|
|
|
|
|
kfilm->white_xyz = make_float4(white_xyz);
|
|
|
|
|
kfilm->rec709_to_r = make_float4(rec709_to_r);
|
|
|
|
|
kfilm->rec709_to_g = make_float4(rec709_to_g);
|
|
|
|
|
kfilm->rec709_to_b = make_float4(rec709_to_b);
|
2022-03-22 20:41:46 +01:00
|
|
|
kfilm->is_rec709 = is_rec709;
|
2011-09-27 20:37:24 +00:00
|
|
|
}
|
|
|
|
|
|
Cycles: Remove MultiGGX code, replace with albedo scaling
While the multiscattering GGX code is cool and solves the darkening problem at higher roughnesses, it's also currently buggy, hard to maintain and often impractical to use due to the higher noise and render time.
In practice, though, having the exact correct directional distribution is not that important as long as the overall albedo is correct and we a) don't get the darkening effect and b) do get the saturation effect at higher roughnesses.
This can simply be achieved by adding a second lobe (https://blog.selfshadow.com/publications/s2017-shading-course/imageworks/s2017_pbs_imageworks_slides_v2.pdf) or scaling the single-scattering GGX lobe (https://blog.selfshadow.com/publications/turquin/ms_comp_final.pdf). Both approaches require the same precomputation and produce outputs of comparable quality, so I went for the simple albedo scaling since it's easier to implement and more efficient.
Overall, the results are pretty good: All scenarios that I tested (Glossy BSDF, Glass BSDF, Principled BSDF with metallic or transmissive = 1) pass the white furnace test (a material with pure-white color in front of a pure-white background should be indistinguishable from the background if it preserves energy), and the overall albedo for non-white materials matches that produced by the real multi-scattering code (with the expected saturation increase as the roughness increases).
In order to produce the precomputed tables, the PR also includes a utility that computes them. This is not built by default, since there's no reason for a user to run it (it only makes sense for documentation/reproducibility purposes and when making changes to the microfacet models).
Pull Request: https://projects.blender.org/blender/blender/pulls/107958
2023-06-05 02:20:57 +02:00
|
|
|
void ShaderManager::device_free_common(Device * /*device*/, DeviceScene *dscene, Scene *scene)
|
2011-09-27 20:37:24 +00:00
|
|
|
{
|
Cycles: Remove MultiGGX code, replace with albedo scaling
While the multiscattering GGX code is cool and solves the darkening problem at higher roughnesses, it's also currently buggy, hard to maintain and often impractical to use due to the higher noise and render time.
In practice, though, having the exact correct directional distribution is not that important as long as the overall albedo is correct and we a) don't get the darkening effect and b) do get the saturation effect at higher roughnesses.
This can simply be achieved by adding a second lobe (https://blog.selfshadow.com/publications/s2017-shading-course/imageworks/s2017_pbs_imageworks_slides_v2.pdf) or scaling the single-scattering GGX lobe (https://blog.selfshadow.com/publications/turquin/ms_comp_final.pdf). Both approaches require the same precomputation and produce outputs of comparable quality, so I went for the simple albedo scaling since it's easier to implement and more efficient.
Overall, the results are pretty good: All scenarios that I tested (Glossy BSDF, Glass BSDF, Principled BSDF with metallic or transmissive = 1) pass the white furnace test (a material with pure-white color in front of a pure-white background should be indistinguishable from the background if it preserves energy), and the overall albedo for non-white materials matches that produced by the real multi-scattering code (with the expected saturation increase as the roughness increases).
In order to produce the precomputed tables, the PR also includes a utility that computes them. This is not built by default, since there's no reason for a user to run it (it only makes sense for documentation/reproducibility purposes and when making changes to the microfacet models).
Pull Request: https://projects.blender.org/blender/blender/pulls/107958
2023-06-05 02:20:57 +02:00
|
|
|
for (auto &entry : bsdf_tables) {
|
|
|
|
|
scene->lookup_tables->remove_table(&entry.second);
|
|
|
|
|
}
|
|
|
|
|
bsdf_tables.clear();
|
|
|
|
|
|
2018-03-08 00:35:24 +01: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 */
|
|
|
|
|
{
|
2024-12-29 23:13:45 +01:00
|
|
|
unique_ptr<ShaderGraph> graph = make_unique<ShaderGraph>();
|
2019-04-17 06:17:24 +02: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 23:20:51 +02:00
|
|
|
DiffuseBsdfNode *diffuse = graph->create_node<DiffuseBsdfNode>();
|
2020-11-04 11:17:38 +01:00
|
|
|
diffuse->set_color(make_float3(0.8f, 0.8f, 0.8f));
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2016-05-07 19:48:28 +02:00
|
|
|
graph->connect(diffuse->output("BSDF"), graph->output()->input("Surface"));
|
2019-04-17 06:17:24 +02: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 23:20:51 +02:00
|
|
|
Shader *shader = scene->create_node<Shader>();
|
2011-04-27 11:58:34 +00:00
|
|
|
shader->name = "default_surface";
|
2024-12-29 23:13:45 +01:00
|
|
|
shader->set_graph(std::move(graph));
|
2021-05-02 02:34:56 +02:00
|
|
|
shader->reference();
|
2016-05-14 14:50:03 +02:00
|
|
|
scene->default_surface = shader;
|
2020-03-11 17:49:00 +01:00
|
|
|
shader->tag_update(scene);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* default volume */
|
|
|
|
|
{
|
2024-12-29 23:13:45 +01:00
|
|
|
unique_ptr<ShaderGraph> graph = make_unique<ShaderGraph>();
|
2020-03-11 17:49:00 +01: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 23:20:51 +02:00
|
|
|
PrincipledVolumeNode *principled = graph->create_node<PrincipledVolumeNode>();
|
2020-03-11 17:49:00 +01:00
|
|
|
|
|
|
|
|
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 23:20:51 +02:00
|
|
|
Shader *shader = scene->create_node<Shader>();
|
2020-03-11 17:49:00 +01:00
|
|
|
shader->name = "default_volume";
|
2024-12-29 23:13:45 +01:00
|
|
|
shader->set_graph(std::move(graph));
|
2020-03-11 17:49:00 +01:00
|
|
|
scene->default_volume = shader;
|
|
|
|
|
shader->tag_update(scene);
|
2022-11-30 20:50:11 +01: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 06:17:24 +02:00
|
|
|
|
2011-04-27 11:58:34 +00:00
|
|
|
/* default light */
|
|
|
|
|
{
|
2024-12-29 23:13:45 +01:00
|
|
|
unique_ptr<ShaderGraph> graph = make_unique<ShaderGraph>();
|
2019-04-17 06:17:24 +02: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 23:20:51 +02:00
|
|
|
EmissionNode *emission = graph->create_node<EmissionNode>();
|
2020-11-04 11:17:38 +01:00
|
|
|
emission->set_color(make_float3(0.8f, 0.8f, 0.8f));
|
|
|
|
|
emission->set_strength(0.0f);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2016-05-07 19:48:28 +02:00
|
|
|
graph->connect(emission->output("Emission"), graph->output()->input("Surface"));
|
2019-04-17 06:17:24 +02: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 23:20:51 +02:00
|
|
|
Shader *shader = scene->create_node<Shader>();
|
2011-04-27 11:58:34 +00:00
|
|
|
shader->name = "default_light";
|
2024-12-29 23:13:45 +01:00
|
|
|
shader->set_graph(std::move(graph));
|
2021-05-02 02:34:56 +02:00
|
|
|
shader->reference();
|
2016-05-14 14:50:03 +02:00
|
|
|
scene->default_light = shader;
|
2020-03-11 17:49:00 +01:00
|
|
|
shader->tag_update(scene);
|
2011-04-27 11:58:34 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2011-04-27 11:58:34 +00:00
|
|
|
/* default background */
|
|
|
|
|
{
|
2024-12-29 23:13:45 +01:00
|
|
|
unique_ptr<ShaderGraph> graph = make_unique<ShaderGraph>();
|
2019-04-17 06:17:24 +02: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 23:20:51 +02:00
|
|
|
Shader *shader = scene->create_node<Shader>();
|
2011-04-27 11:58:34 +00:00
|
|
|
shader->name = "default_background";
|
2024-12-29 23:13:45 +01:00
|
|
|
shader->set_graph(std::move(graph));
|
2021-05-02 02:34:56 +02:00
|
|
|
shader->reference();
|
2016-05-14 14:50:03 +02:00
|
|
|
scene->default_background = shader;
|
2020-03-11 17:49:00 +01:00
|
|
|
shader->tag_update(scene);
|
2011-04-27 11:58:34 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-04-13 12:58:12 +00:00
|
|
|
/* default empty */
|
|
|
|
|
{
|
2024-12-29 23:13:45 +01:00
|
|
|
unique_ptr<ShaderGraph> graph = make_unique<ShaderGraph>();
|
2019-04-17 06:17:24 +02: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 23:20:51 +02:00
|
|
|
Shader *shader = scene->create_node<Shader>();
|
2012-04-13 12:58:12 +00:00
|
|
|
shader->name = "default_empty";
|
2024-12-29 23:13:45 +01:00
|
|
|
shader->set_graph(std::move(graph));
|
2021-05-02 02:34:56 +02:00
|
|
|
shader->reference();
|
2016-05-14 14:50:03 +02:00
|
|
|
scene->default_empty = shader;
|
2020-03-11 17:49:00 +01:00
|
|
|
shader->tag_update(scene);
|
2012-04-13 12:58:12 +00:00
|
|
|
}
|
2011-04-27 11:58:34 +00:00
|
|
|
}
|
|
|
|
|
|
Cycles: merge of cycles-x branch, a major update to the renderer
This includes much improved GPU rendering performance, viewport interactivity,
new shadow catcher, revamped sampling settings, subsurface scattering anisotropy,
new GPU volume sampling, improved PMJ sampling pattern, and more.
Some features have also been removed or changed, breaking backwards compatibility.
Including the removal of the OpenCL backend, for which alternatives are under
development.
Release notes and code docs:
https://wiki.blender.org/wiki/Reference/Release_Notes/3.0/Cycles
https://wiki.blender.org/wiki/Source/Render/Cycles
Credits:
* Sergey Sharybin
* Brecht Van Lommel
* Patrick Mours (OptiX backend)
* Christophe Hery (subsurface scattering anisotropy)
* William Leeson (PMJ sampling pattern)
* Alaska (various fixes and tweaks)
* Thomas Dinges (various fixes)
For the full commit history, see the cycles-x branch. This squashes together
all the changes since intermediate changes would often fail building or tests.
Ref T87839, T87837, T87836
Fixes T90734, T89353, T80267, T80267, T77185, T69800
2021-09-20 17:59:20 +02:00
|
|
|
uint ShaderManager::get_graph_kernel_features(ShaderGraph *graph)
|
2015-06-01 15:52:00 +05:00
|
|
|
{
|
Cycles: merge of cycles-x branch, a major update to the renderer
This includes much improved GPU rendering performance, viewport interactivity,
new shadow catcher, revamped sampling settings, subsurface scattering anisotropy,
new GPU volume sampling, improved PMJ sampling pattern, and more.
Some features have also been removed or changed, breaking backwards compatibility.
Including the removal of the OpenCL backend, for which alternatives are under
development.
Release notes and code docs:
https://wiki.blender.org/wiki/Reference/Release_Notes/3.0/Cycles
https://wiki.blender.org/wiki/Source/Render/Cycles
Credits:
* Sergey Sharybin
* Brecht Van Lommel
* Patrick Mours (OptiX backend)
* Christophe Hery (subsurface scattering anisotropy)
* William Leeson (PMJ sampling pattern)
* Alaska (various fixes and tweaks)
* Thomas Dinges (various fixes)
For the full commit history, see the cycles-x branch. This squashes together
all the changes since intermediate changes would often fail building or tests.
Ref T87839, T87837, T87836
Fixes T90734, T89353, T80267, T80267, T77185, T69800
2021-09-20 17:59:20 +02:00
|
|
|
uint kernel_features = 0;
|
|
|
|
|
|
2024-12-26 19:41:25 +01:00
|
|
|
for (ShaderNode *node : graph->nodes) {
|
Cycles: merge of cycles-x branch, a major update to the renderer
This includes much improved GPU rendering performance, viewport interactivity,
new shadow catcher, revamped sampling settings, subsurface scattering anisotropy,
new GPU volume sampling, improved PMJ sampling pattern, and more.
Some features have also been removed or changed, breaking backwards compatibility.
Including the removal of the OpenCL backend, for which alternatives are under
development.
Release notes and code docs:
https://wiki.blender.org/wiki/Reference/Release_Notes/3.0/Cycles
https://wiki.blender.org/wiki/Source/Render/Cycles
Credits:
* Sergey Sharybin
* Brecht Van Lommel
* Patrick Mours (OptiX backend)
* Christophe Hery (subsurface scattering anisotropy)
* William Leeson (PMJ sampling pattern)
* Alaska (various fixes and tweaks)
* Thomas Dinges (various fixes)
For the full commit history, see the cycles-x branch. This squashes together
all the changes since intermediate changes would often fail building or tests.
Ref T87839, T87837, T87836
Fixes T90734, T89353, T80267, T80267, T77185, T69800
2021-09-20 17:59:20 +02:00
|
|
|
kernel_features |= node->get_feature();
|
2015-06-01 15:52:00 +05:00
|
|
|
if (node->special_type == SHADER_SPECIAL_TYPE_CLOSURE) {
|
2019-01-18 02:56:59 +01:00
|
|
|
BsdfBaseNode *bsdf_node = static_cast<BsdfBaseNode *>(node);
|
2020-11-04 11:17:38 +01:00
|
|
|
if (CLOSURE_IS_VOLUME(bsdf_node->get_closure_type())) {
|
Cycles: merge of cycles-x branch, a major update to the renderer
This includes much improved GPU rendering performance, viewport interactivity,
new shadow catcher, revamped sampling settings, subsurface scattering anisotropy,
new GPU volume sampling, improved PMJ sampling pattern, and more.
Some features have also been removed or changed, breaking backwards compatibility.
Including the removal of the OpenCL backend, for which alternatives are under
development.
Release notes and code docs:
https://wiki.blender.org/wiki/Reference/Release_Notes/3.0/Cycles
https://wiki.blender.org/wiki/Source/Render/Cycles
Credits:
* Sergey Sharybin
* Brecht Van Lommel
* Patrick Mours (OptiX backend)
* Christophe Hery (subsurface scattering anisotropy)
* William Leeson (PMJ sampling pattern)
* Alaska (various fixes and tweaks)
* Thomas Dinges (various fixes)
For the full commit history, see the cycles-x branch. This squashes together
all the changes since intermediate changes would often fail building or tests.
Ref T87839, T87837, T87836
Fixes T90734, T89353, T80267, T80267, T77185, T69800
2021-09-20 17:59:20 +02:00
|
|
|
kernel_features |= KERNEL_FEATURE_NODE_VOLUME;
|
2015-06-01 15:52:00 +05:00
|
|
|
}
|
|
|
|
|
}
|
2015-11-21 22:31:58 +05:00
|
|
|
if (node->has_surface_bssrdf()) {
|
Cycles: merge of cycles-x branch, a major update to the renderer
This includes much improved GPU rendering performance, viewport interactivity,
new shadow catcher, revamped sampling settings, subsurface scattering anisotropy,
new GPU volume sampling, improved PMJ sampling pattern, and more.
Some features have also been removed or changed, breaking backwards compatibility.
Including the removal of the OpenCL backend, for which alternatives are under
development.
Release notes and code docs:
https://wiki.blender.org/wiki/Reference/Release_Notes/3.0/Cycles
https://wiki.blender.org/wiki/Source/Render/Cycles
Credits:
* Sergey Sharybin
* Brecht Van Lommel
* Patrick Mours (OptiX backend)
* Christophe Hery (subsurface scattering anisotropy)
* William Leeson (PMJ sampling pattern)
* Alaska (various fixes and tweaks)
* Thomas Dinges (various fixes)
For the full commit history, see the cycles-x branch. This squashes together
all the changes since intermediate changes would often fail building or tests.
Ref T87839, T87837, T87836
Fixes T90734, T89353, T80267, T80267, T77185, T69800
2021-09-20 17:59:20 +02:00
|
|
|
kernel_features |= KERNEL_FEATURE_SUBSURFACE;
|
2015-11-21 22:31:58 +05:00
|
|
|
}
|
2016-12-09 08:28:04 -07:00
|
|
|
if (node->has_surface_transparent()) {
|
Cycles: merge of cycles-x branch, a major update to the renderer
This includes much improved GPU rendering performance, viewport interactivity,
new shadow catcher, revamped sampling settings, subsurface scattering anisotropy,
new GPU volume sampling, improved PMJ sampling pattern, and more.
Some features have also been removed or changed, breaking backwards compatibility.
Including the removal of the OpenCL backend, for which alternatives are under
development.
Release notes and code docs:
https://wiki.blender.org/wiki/Reference/Release_Notes/3.0/Cycles
https://wiki.blender.org/wiki/Source/Render/Cycles
Credits:
* Sergey Sharybin
* Brecht Van Lommel
* Patrick Mours (OptiX backend)
* Christophe Hery (subsurface scattering anisotropy)
* William Leeson (PMJ sampling pattern)
* Alaska (various fixes and tweaks)
* Thomas Dinges (various fixes)
For the full commit history, see the cycles-x branch. This squashes together
all the changes since intermediate changes would often fail building or tests.
Ref T87839, T87837, T87836
Fixes T90734, T89353, T80267, T80267, T77185, T69800
2021-09-20 17:59:20 +02:00
|
|
|
kernel_features |= KERNEL_FEATURE_TRANSPARENT;
|
2017-10-30 20:25:08 +01:00
|
|
|
}
|
2015-06-01 15:52:00 +05:00
|
|
|
}
|
Cycles: merge of cycles-x branch, a major update to the renderer
This includes much improved GPU rendering performance, viewport interactivity,
new shadow catcher, revamped sampling settings, subsurface scattering anisotropy,
new GPU volume sampling, improved PMJ sampling pattern, and more.
Some features have also been removed or changed, breaking backwards compatibility.
Including the removal of the OpenCL backend, for which alternatives are under
development.
Release notes and code docs:
https://wiki.blender.org/wiki/Reference/Release_Notes/3.0/Cycles
https://wiki.blender.org/wiki/Source/Render/Cycles
Credits:
* Sergey Sharybin
* Brecht Van Lommel
* Patrick Mours (OptiX backend)
* Christophe Hery (subsurface scattering anisotropy)
* William Leeson (PMJ sampling pattern)
* Alaska (various fixes and tweaks)
* Thomas Dinges (various fixes)
For the full commit history, see the cycles-x branch. This squashes together
all the changes since intermediate changes would often fail building or tests.
Ref T87839, T87837, T87836
Fixes T90734, T89353, T80267, T80267, T77185, T69800
2021-09-20 17:59:20 +02:00
|
|
|
|
|
|
|
|
return kernel_features;
|
2015-06-01 15:52:00 +05:00
|
|
|
}
|
|
|
|
|
|
Cycles: merge of cycles-x branch, a major update to the renderer
This includes much improved GPU rendering performance, viewport interactivity,
new shadow catcher, revamped sampling settings, subsurface scattering anisotropy,
new GPU volume sampling, improved PMJ sampling pattern, and more.
Some features have also been removed or changed, breaking backwards compatibility.
Including the removal of the OpenCL backend, for which alternatives are under
development.
Release notes and code docs:
https://wiki.blender.org/wiki/Reference/Release_Notes/3.0/Cycles
https://wiki.blender.org/wiki/Source/Render/Cycles
Credits:
* Sergey Sharybin
* Brecht Van Lommel
* Patrick Mours (OptiX backend)
* Christophe Hery (subsurface scattering anisotropy)
* William Leeson (PMJ sampling pattern)
* Alaska (various fixes and tweaks)
* Thomas Dinges (various fixes)
For the full commit history, see the cycles-x branch. This squashes together
all the changes since intermediate changes would often fail building or tests.
Ref T87839, T87837, T87836
Fixes T90734, T89353, T80267, T80267, T77185, T69800
2021-09-20 17:59:20 +02:00
|
|
|
uint ShaderManager::get_kernel_features(Scene *scene)
|
2015-05-09 19:22:16 +05:00
|
|
|
{
|
Cycles: merge of cycles-x branch, a major update to the renderer
This includes much improved GPU rendering performance, viewport interactivity,
new shadow catcher, revamped sampling settings, subsurface scattering anisotropy,
new GPU volume sampling, improved PMJ sampling pattern, and more.
Some features have also been removed or changed, breaking backwards compatibility.
Including the removal of the OpenCL backend, for which alternatives are under
development.
Release notes and code docs:
https://wiki.blender.org/wiki/Reference/Release_Notes/3.0/Cycles
https://wiki.blender.org/wiki/Source/Render/Cycles
Credits:
* Sergey Sharybin
* Brecht Van Lommel
* Patrick Mours (OptiX backend)
* Christophe Hery (subsurface scattering anisotropy)
* William Leeson (PMJ sampling pattern)
* Alaska (various fixes and tweaks)
* Thomas Dinges (various fixes)
For the full commit history, see the cycles-x branch. This squashes together
all the changes since intermediate changes would often fail building or tests.
Ref T87839, T87837, T87836
Fixes T90734, T89353, T80267, T80267, T77185, T69800
2021-09-20 17:59:20 +02:00
|
|
|
uint kernel_features = KERNEL_FEATURE_NODE_BSDF | KERNEL_FEATURE_NODE_EMISSION;
|
2015-05-09 19:22:16 +05:00
|
|
|
for (int i = 0; i < scene->shaders.size(); i++) {
|
|
|
|
|
Shader *shader = scene->shaders[i];
|
2021-05-02 02:34:56 +02:00
|
|
|
if (!shader->reference_count()) {
|
2020-03-11 17:49:00 +01:00
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-01 15:26:36 +05:00
|
|
|
/* Gather requested features from all the nodes from the graph nodes. */
|
2024-12-29 23:13:45 +01:00
|
|
|
kernel_features |= get_graph_kernel_features(shader->graph.get());
|
2015-06-01 15:26:36 +05:00
|
|
|
ShaderNode *output_node = shader->graph->output();
|
2024-12-26 17:53:55 +01:00
|
|
|
if (output_node->input("Displacement")->link != nullptr) {
|
Cycles: merge of cycles-x branch, a major update to the renderer
This includes much improved GPU rendering performance, viewport interactivity,
new shadow catcher, revamped sampling settings, subsurface scattering anisotropy,
new GPU volume sampling, improved PMJ sampling pattern, and more.
Some features have also been removed or changed, breaking backwards compatibility.
Including the removal of the OpenCL backend, for which alternatives are under
development.
Release notes and code docs:
https://wiki.blender.org/wiki/Reference/Release_Notes/3.0/Cycles
https://wiki.blender.org/wiki/Source/Render/Cycles
Credits:
* Sergey Sharybin
* Brecht Van Lommel
* Patrick Mours (OptiX backend)
* Christophe Hery (subsurface scattering anisotropy)
* William Leeson (PMJ sampling pattern)
* Alaska (various fixes and tweaks)
* Thomas Dinges (various fixes)
For the full commit history, see the cycles-x branch. This squashes together
all the changes since intermediate changes would often fail building or tests.
Ref T87839, T87837, T87836
Fixes T90734, T89353, T80267, T80267, T77185, T69800
2021-09-20 17:59:20 +02:00
|
|
|
kernel_features |= KERNEL_FEATURE_NODE_BUMP;
|
2020-11-04 11:17:38 +01:00
|
|
|
if (shader->get_displacement_method() == DISPLACE_BOTH) {
|
Cycles: merge of cycles-x branch, a major update to the renderer
This includes much improved GPU rendering performance, viewport interactivity,
new shadow catcher, revamped sampling settings, subsurface scattering anisotropy,
new GPU volume sampling, improved PMJ sampling pattern, and more.
Some features have also been removed or changed, breaking backwards compatibility.
Including the removal of the OpenCL backend, for which alternatives are under
development.
Release notes and code docs:
https://wiki.blender.org/wiki/Reference/Release_Notes/3.0/Cycles
https://wiki.blender.org/wiki/Source/Render/Cycles
Credits:
* Sergey Sharybin
* Brecht Van Lommel
* Patrick Mours (OptiX backend)
* Christophe Hery (subsurface scattering anisotropy)
* William Leeson (PMJ sampling pattern)
* Alaska (various fixes and tweaks)
* Thomas Dinges (various fixes)
For the full commit history, see the cycles-x branch. This squashes together
all the changes since intermediate changes would often fail building or tests.
Ref T87839, T87837, T87836
Fixes T90734, T89353, T80267, T80267, T77185, T69800
2021-09-20 17:59:20 +02:00
|
|
|
kernel_features |= KERNEL_FEATURE_NODE_BUMP_STATE;
|
2016-09-08 01:33:41 +02:00
|
|
|
}
|
2015-06-01 15:26:36 +05:00
|
|
|
}
|
2016-05-06 23:11:41 +02:00
|
|
|
/* On top of volume nodes, also check if we need volume sampling because
|
Cycles: merge of cycles-x branch, a major update to the renderer
This includes much improved GPU rendering performance, viewport interactivity,
new shadow catcher, revamped sampling settings, subsurface scattering anisotropy,
new GPU volume sampling, improved PMJ sampling pattern, and more.
Some features have also been removed or changed, breaking backwards compatibility.
Including the removal of the OpenCL backend, for which alternatives are under
development.
Release notes and code docs:
https://wiki.blender.org/wiki/Reference/Release_Notes/3.0/Cycles
https://wiki.blender.org/wiki/Source/Render/Cycles
Credits:
* Sergey Sharybin
* Brecht Van Lommel
* Patrick Mours (OptiX backend)
* Christophe Hery (subsurface scattering anisotropy)
* William Leeson (PMJ sampling pattern)
* Alaska (various fixes and tweaks)
* Thomas Dinges (various fixes)
For the full commit history, see the cycles-x branch. This squashes together
all the changes since intermediate changes would often fail building or tests.
Ref T87839, T87837, T87836
Fixes T90734, T89353, T80267, T80267, T77185, T69800
2021-09-20 17:59:20 +02:00
|
|
|
* e.g. an Emission node would slip through the KERNEL_FEATURE_NODE_VOLUME check */
|
2021-09-22 17:05:44 +02:00
|
|
|
if (shader->has_volume_connected) {
|
Cycles: merge of cycles-x branch, a major update to the renderer
This includes much improved GPU rendering performance, viewport interactivity,
new shadow catcher, revamped sampling settings, subsurface scattering anisotropy,
new GPU volume sampling, improved PMJ sampling pattern, and more.
Some features have also been removed or changed, breaking backwards compatibility.
Including the removal of the OpenCL backend, for which alternatives are under
development.
Release notes and code docs:
https://wiki.blender.org/wiki/Reference/Release_Notes/3.0/Cycles
https://wiki.blender.org/wiki/Source/Render/Cycles
Credits:
* Sergey Sharybin
* Brecht Van Lommel
* Patrick Mours (OptiX backend)
* Christophe Hery (subsurface scattering anisotropy)
* William Leeson (PMJ sampling pattern)
* Alaska (various fixes and tweaks)
* Thomas Dinges (various fixes)
For the full commit history, see the cycles-x branch. This squashes together
all the changes since intermediate changes would often fail building or tests.
Ref T87839, T87837, T87836
Fixes T90734, T89353, T80267, T80267, T77185, T69800
2021-09-20 17:59:20 +02:00
|
|
|
kernel_features |= KERNEL_FEATURE_VOLUME;
|
|
|
|
|
}
|
2015-05-09 19:22:16 +05:00
|
|
|
}
|
Cycles: merge of cycles-x branch, a major update to the renderer
This includes much improved GPU rendering performance, viewport interactivity,
new shadow catcher, revamped sampling settings, subsurface scattering anisotropy,
new GPU volume sampling, improved PMJ sampling pattern, and more.
Some features have also been removed or changed, breaking backwards compatibility.
Including the removal of the OpenCL backend, for which alternatives are under
development.
Release notes and code docs:
https://wiki.blender.org/wiki/Reference/Release_Notes/3.0/Cycles
https://wiki.blender.org/wiki/Source/Render/Cycles
Credits:
* Sergey Sharybin
* Brecht Van Lommel
* Patrick Mours (OptiX backend)
* Christophe Hery (subsurface scattering anisotropy)
* William Leeson (PMJ sampling pattern)
* Alaska (various fixes and tweaks)
* Thomas Dinges (various fixes)
For the full commit history, see the cycles-x branch. This squashes together
all the changes since intermediate changes would often fail building or tests.
Ref T87839, T87837, T87836
Fixes T90734, T89353, T80267, T80267, T77185, T69800
2021-09-20 17:59:20 +02:00
|
|
|
|
2022-11-09 14:25:32 +01:00
|
|
|
if (use_osl()) {
|
|
|
|
|
kernel_features |= KERNEL_FEATURE_OSL;
|
|
|
|
|
}
|
|
|
|
|
|
Cycles: merge of cycles-x branch, a major update to the renderer
This includes much improved GPU rendering performance, viewport interactivity,
new shadow catcher, revamped sampling settings, subsurface scattering anisotropy,
new GPU volume sampling, improved PMJ sampling pattern, and more.
Some features have also been removed or changed, breaking backwards compatibility.
Including the removal of the OpenCL backend, for which alternatives are under
development.
Release notes and code docs:
https://wiki.blender.org/wiki/Reference/Release_Notes/3.0/Cycles
https://wiki.blender.org/wiki/Source/Render/Cycles
Credits:
* Sergey Sharybin
* Brecht Van Lommel
* Patrick Mours (OptiX backend)
* Christophe Hery (subsurface scattering anisotropy)
* William Leeson (PMJ sampling pattern)
* Alaska (various fixes and tweaks)
* Thomas Dinges (various fixes)
For the full commit history, see the cycles-x branch. This squashes together
all the changes since intermediate changes would often fail building or tests.
Ref T87839, T87837, T87836
Fixes T90734, T89353, T80267, T80267, T77185, T69800
2021-09-20 17:59:20 +02:00
|
|
|
return kernel_features;
|
2015-05-09 19:22:16 +05:00
|
|
|
}
|
|
|
|
|
|
2025-01-01 18:15:54 +01:00
|
|
|
float ShaderManager::linear_rgb_to_gray(const float3 c)
|
2018-06-14 17:48:19 +02:00
|
|
|
{
|
|
|
|
|
return dot(c, rgb_to_y);
|
|
|
|
|
}
|
|
|
|
|
|
2025-01-01 18:15:54 +01:00
|
|
|
float3 ShaderManager::rec709_to_scene_linear(const float3 c)
|
2022-03-22 20:41:46 +01:00
|
|
|
{
|
2024-10-07 02:18:49 +02:00
|
|
|
return to_local(c, rec709_to_r, rec709_to_g, rec709_to_b);
|
2022-03-22 20:41:46 +01:00
|
|
|
}
|
|
|
|
|
|
2018-11-07 04:05:47 +01:00
|
|
|
string ShaderManager::get_cryptomatte_materials(Scene *scene)
|
|
|
|
|
{
|
|
|
|
|
string manifest = "{";
|
2024-10-17 19:48:38 +02:00
|
|
|
unordered_set<ustring> materials;
|
2024-12-26 19:41:25 +01:00
|
|
|
for (Shader *shader : scene->shaders) {
|
2018-11-07 04:05:47 +01:00
|
|
|
if (materials.count(shader->name)) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
materials.insert(shader->name);
|
2024-12-29 17:32:00 +01:00
|
|
|
const uint32_t cryptomatte_id = util_murmur_hash3(
|
|
|
|
|
shader->name.c_str(), shader->name.length(), 0);
|
2018-11-07 04:05:47 +01:00
|
|
|
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 15:01:26 +01: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 19:35:00 +01:00
|
|
|
#ifdef WITH_OCIO
|
|
|
|
|
static bool to_scene_linear_transform(OCIO::ConstConfigRcPtr &config,
|
|
|
|
|
const char *colorspace,
|
|
|
|
|
Transform &to_scene_linear)
|
|
|
|
|
{
|
|
|
|
|
OCIO::ConstProcessorRcPtr processor;
|
|
|
|
|
try {
|
2022-09-18 17:32:53 +02:00
|
|
|
processor = config->getProcessor("scene_linear", colorspace);
|
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 19:35:00 +01:00
|
|
|
}
|
2021-02-18 08:09:08 -07: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 19:35:00 +01:00
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!processor) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2024-12-29 17:32:00 +01:00
|
|
|
const OCIO::ConstCPUProcessorRcPtr device_processor = processor->getDefaultCPUProcessor();
|
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 19:35:00 +01:00
|
|
|
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 16:38:26 +01:00
|
|
|
/* Default to ITU-BT.709 in case no appropriate transform found.
|
|
|
|
|
* Note XYZ here is defined as having a D65 white point. */
|
2022-03-22 20:41:46 +01:00
|
|
|
const Transform xyz_to_rec709 = make_transform(3.2404542f,
|
|
|
|
|
-1.5371385f,
|
|
|
|
|
-0.4985314f,
|
|
|
|
|
0.0f,
|
|
|
|
|
-0.9692660f,
|
|
|
|
|
1.8760108f,
|
|
|
|
|
0.0415560f,
|
|
|
|
|
0.0f,
|
|
|
|
|
0.0556434f,
|
|
|
|
|
-0.2040259f,
|
|
|
|
|
1.0572252f,
|
|
|
|
|
0.0f);
|
|
|
|
|
|
2024-12-19 09:41:55 +01:00
|
|
|
xyz_to_r = make_float3(xyz_to_rec709.x);
|
|
|
|
|
xyz_to_g = make_float3(xyz_to_rec709.y);
|
|
|
|
|
xyz_to_b = make_float3(xyz_to_rec709.z);
|
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 19:35:00 +01:00
|
|
|
rgb_to_y = make_float3(0.2126729f, 0.7151522f, 0.0721750f);
|
Cycles: Add thin film iridescence to Principled BSDF
This is an implementation of thin film iridescence in the Principled BSDF based on "A Practical Extension to Microfacet Theory for the Modeling of Varying Iridescence".
There are still several open topics that are left for future work:
- Currently, the thin film only affects dielectric Fresnel, not metallic. Properly specifying thin films on metals requires a proper conductive Fresnel term with complex IOR inputs, any attempt of trying to hack it into the F82 model we currently use for the Principled BSDF is fundamentally flawed. In the future, we'll add a node for proper conductive Fresnel, including thin films.
- The F0/F90 control is not very elegantly implemented right now. It fundamentally works, but enabling thin film while using a Specular Tint causes a jump in appearance since the models integrate it differently. Then again, thin film interference is a physical effect, so of course a non-physical tweak doesn't play nicely with it.
- The white point handling is currently quite crude. In short: The code computes XYZ values of the reflectance spectrum, but we'd need the XYZ values of the product of the reflectance spectrum and the neutral illuminant of the working color space. Currently, this is addressed by just dividing by the XYZ values of the illuminant, but it would be better to do a proper chromatic adaptation transform or to use the proper reference curves for the working space instead of the XYZ curves from the paper.
Pull Request: https://projects.blender.org/blender/blender/pulls/118477
2024-05-02 14:28:44 +02:00
|
|
|
white_xyz = make_float3(0.95047f, 1.0f, 1.08883f);
|
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 19:35:00 +01:00
|
|
|
|
2022-03-22 20:41:46 +01:00
|
|
|
rec709_to_r = make_float3(1.0f, 0.0f, 0.0f);
|
|
|
|
|
rec709_to_g = make_float3(0.0f, 1.0f, 0.0f);
|
|
|
|
|
rec709_to_b = make_float3(0.0f, 0.0f, 1.0f);
|
|
|
|
|
is_rec709 = true;
|
|
|
|
|
|
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 19:35:00 +01:00
|
|
|
#ifdef WITH_OCIO
|
|
|
|
|
/* Get from OpenColorO config if it has the required roles. */
|
2024-12-31 10:28:46 +01:00
|
|
|
OCIO::ConstConfigRcPtr config = nullptr;
|
|
|
|
|
try {
|
|
|
|
|
config = OCIO::GetCurrentConfig();
|
|
|
|
|
}
|
|
|
|
|
catch (OCIO::Exception &exception) {
|
|
|
|
|
VLOG_WARNING << "OCIO config error: " << exception.what();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2022-09-18 17:32:53 +02:00
|
|
|
if (!(config && config->hasRole("scene_linear"))) {
|
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 19:35:00 +01:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Transform xyz_to_rgb;
|
|
|
|
|
|
|
|
|
|
if (config->hasRole("aces_interchange")) {
|
2022-02-17 19:37:55 +01:00
|
|
|
/* Standard OpenColorIO role, defined as ACES AP0 (ACES2065-1). */
|
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 19:35:00 +01:00
|
|
|
Transform aces_to_rgb;
|
|
|
|
|
if (!to_scene_linear_transform(config, "aces_interchange", aces_to_rgb)) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2022-02-17 19:37:55 +01:00
|
|
|
/* This is the OpenColorIO builtin transform:
|
|
|
|
|
* UTILITY - ACES-AP0_to_CIE-XYZ-D65_BFD. */
|
2022-02-17 20:27:45 +01:00
|
|
|
const Transform ACES_AP0_to_xyz_D65 = make_transform(0.938280f,
|
|
|
|
|
-0.004451f,
|
|
|
|
|
0.016628f,
|
|
|
|
|
0.000000f,
|
|
|
|
|
0.337369f,
|
|
|
|
|
0.729522f,
|
|
|
|
|
-0.066890f,
|
|
|
|
|
0.000000f,
|
|
|
|
|
0.001174f,
|
|
|
|
|
-0.003711f,
|
|
|
|
|
1.091595f,
|
|
|
|
|
0.000000f);
|
2022-02-17 19:37:55 +01:00
|
|
|
const Transform xyz_to_aces = transform_inverse(ACES_AP0_to_xyz_D65);
|
|
|
|
|
xyz_to_rgb = aces_to_rgb * xyz_to_aces;
|
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 19:35:00 +01: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 06:13:49 +01: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 19:35:00 +01:00
|
|
|
|
2024-12-19 09:41:55 +01:00
|
|
|
xyz_to_r = make_float3(xyz_to_rgb.x);
|
|
|
|
|
xyz_to_g = make_float3(xyz_to_rgb.y);
|
|
|
|
|
xyz_to_b = make_float3(xyz_to_rgb.z);
|
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 19:35:00 +01:00
|
|
|
|
|
|
|
|
const Transform rgb_to_xyz = transform_inverse(xyz_to_rgb);
|
2024-12-19 09:41:55 +01:00
|
|
|
rgb_to_y = make_float3(rgb_to_xyz.y);
|
Cycles: Add thin film iridescence to Principled BSDF
This is an implementation of thin film iridescence in the Principled BSDF based on "A Practical Extension to Microfacet Theory for the Modeling of Varying Iridescence".
There are still several open topics that are left for future work:
- Currently, the thin film only affects dielectric Fresnel, not metallic. Properly specifying thin films on metals requires a proper conductive Fresnel term with complex IOR inputs, any attempt of trying to hack it into the F82 model we currently use for the Principled BSDF is fundamentally flawed. In the future, we'll add a node for proper conductive Fresnel, including thin films.
- The F0/F90 control is not very elegantly implemented right now. It fundamentally works, but enabling thin film while using a Specular Tint causes a jump in appearance since the models integrate it differently. Then again, thin film interference is a physical effect, so of course a non-physical tweak doesn't play nicely with it.
- The white point handling is currently quite crude. In short: The code computes XYZ values of the reflectance spectrum, but we'd need the XYZ values of the product of the reflectance spectrum and the neutral illuminant of the working color space. Currently, this is addressed by just dividing by the XYZ values of the illuminant, but it would be better to do a proper chromatic adaptation transform or to use the proper reference curves for the working space instead of the XYZ curves from the paper.
Pull Request: https://projects.blender.org/blender/blender/pulls/118477
2024-05-02 14:28:44 +02:00
|
|
|
white_xyz = transform_direction(&rgb_to_xyz, one_float3());
|
2022-03-22 20:41:46 +01:00
|
|
|
|
|
|
|
|
const Transform rec709_to_rgb = xyz_to_rgb * transform_inverse(xyz_to_rec709);
|
2024-12-19 09:41:55 +01:00
|
|
|
rec709_to_r = make_float3(rec709_to_rgb.x);
|
|
|
|
|
rec709_to_g = make_float3(rec709_to_rgb.y);
|
|
|
|
|
rec709_to_b = make_float3(rec709_to_rgb.z);
|
2022-03-22 20:41:46 +01:00
|
|
|
is_rec709 = transform_equal_threshold(xyz_to_rgb, xyz_to_rec709, 0.0001f);
|
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 19:35:00 +01:00
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
Cycles: Remove MultiGGX code, replace with albedo scaling
While the multiscattering GGX code is cool and solves the darkening problem at higher roughnesses, it's also currently buggy, hard to maintain and often impractical to use due to the higher noise and render time.
In practice, though, having the exact correct directional distribution is not that important as long as the overall albedo is correct and we a) don't get the darkening effect and b) do get the saturation effect at higher roughnesses.
This can simply be achieved by adding a second lobe (https://blog.selfshadow.com/publications/s2017-shading-course/imageworks/s2017_pbs_imageworks_slides_v2.pdf) or scaling the single-scattering GGX lobe (https://blog.selfshadow.com/publications/turquin/ms_comp_final.pdf). Both approaches require the same precomputation and produce outputs of comparable quality, so I went for the simple albedo scaling since it's easier to implement and more efficient.
Overall, the results are pretty good: All scenarios that I tested (Glossy BSDF, Glass BSDF, Principled BSDF with metallic or transmissive = 1) pass the white furnace test (a material with pure-white color in front of a pure-white background should be indistinguishable from the background if it preserves energy), and the overall albedo for non-white materials matches that produced by the real multi-scattering code (with the expected saturation increase as the roughness increases).
In order to produce the precomputed tables, the PR also includes a utility that computes them. This is not built by default, since there's no reason for a user to run it (it only makes sense for documentation/reproducibility purposes and when making changes to the microfacet models).
Pull Request: https://projects.blender.org/blender/blender/pulls/107958
2023-06-05 02:20:57 +02:00
|
|
|
size_t ShaderManager::ensure_bsdf_table_impl(DeviceScene *dscene,
|
|
|
|
|
Scene *scene,
|
|
|
|
|
const float *table,
|
2025-01-01 18:15:54 +01:00
|
|
|
const size_t n)
|
Cycles: Remove MultiGGX code, replace with albedo scaling
While the multiscattering GGX code is cool and solves the darkening problem at higher roughnesses, it's also currently buggy, hard to maintain and often impractical to use due to the higher noise and render time.
In practice, though, having the exact correct directional distribution is not that important as long as the overall albedo is correct and we a) don't get the darkening effect and b) do get the saturation effect at higher roughnesses.
This can simply be achieved by adding a second lobe (https://blog.selfshadow.com/publications/s2017-shading-course/imageworks/s2017_pbs_imageworks_slides_v2.pdf) or scaling the single-scattering GGX lobe (https://blog.selfshadow.com/publications/turquin/ms_comp_final.pdf). Both approaches require the same precomputation and produce outputs of comparable quality, so I went for the simple albedo scaling since it's easier to implement and more efficient.
Overall, the results are pretty good: All scenarios that I tested (Glossy BSDF, Glass BSDF, Principled BSDF with metallic or transmissive = 1) pass the white furnace test (a material with pure-white color in front of a pure-white background should be indistinguishable from the background if it preserves energy), and the overall albedo for non-white materials matches that produced by the real multi-scattering code (with the expected saturation increase as the roughness increases).
In order to produce the precomputed tables, the PR also includes a utility that computes them. This is not built by default, since there's no reason for a user to run it (it only makes sense for documentation/reproducibility purposes and when making changes to the microfacet models).
Pull Request: https://projects.blender.org/blender/blender/pulls/107958
2023-06-05 02:20:57 +02:00
|
|
|
{
|
|
|
|
|
/* Since the BSDF tables are static arrays, we can use their address to identify them. */
|
|
|
|
|
if (!(bsdf_tables.count(table))) {
|
|
|
|
|
vector<float> entries(table, table + n);
|
|
|
|
|
bsdf_tables[table] = scene->lookup_tables->add_table(dscene, entries);
|
|
|
|
|
}
|
|
|
|
|
return bsdf_tables[table];
|
|
|
|
|
}
|
|
|
|
|
|
2011-04-27 11:58:34 +00:00
|
|
|
CCL_NAMESPACE_END
|