Fix: Cycles blackbody renders wrong with OSL and ACEScg
OSL only supports a fixed number of color space, so detect a few common ones and set those. This makes functions like blackbody work correctly. Pull Request: https://projects.blender.org/blender/blender/pulls/145755
This commit is contained in:
@@ -899,6 +899,9 @@ void Camera::set_osl_camera(Scene *scene,
|
||||
const std::string &bytecode)
|
||||
{
|
||||
#ifdef WITH_OSL
|
||||
/* Ensure shading system exists before we try to load a shader. */
|
||||
scene->osl_manager->shading_system_init(scene->shader_manager->get_scene_linear_space());
|
||||
|
||||
/* Load the shader. */
|
||||
const char *hash;
|
||||
|
||||
|
||||
@@ -124,7 +124,7 @@ bool OSLManager::need_update() const
|
||||
void OSLManager::device_update_pre(Device *device, Scene *scene)
|
||||
{
|
||||
if (scene->shader_manager->use_osl() || !scene->camera->script_name.empty()) {
|
||||
shading_system_init();
|
||||
shading_system_init(scene->shader_manager->get_scene_linear_space());
|
||||
}
|
||||
|
||||
if (!need_update()) {
|
||||
@@ -343,7 +343,7 @@ void OSLManager::texture_system_free()
|
||||
}
|
||||
}
|
||||
|
||||
void OSLManager::shading_system_init()
|
||||
void OSLManager::shading_system_init(ShaderManager::SceneLinearSpace colorspace)
|
||||
{
|
||||
/* No need to do anything if we already have shading systems. */
|
||||
if (!ss_map.empty()) {
|
||||
@@ -353,7 +353,7 @@ void OSLManager::shading_system_init()
|
||||
/* create shading system, shared between different renders to reduce memory usage */
|
||||
const thread_scoped_lock lock(ss_shared_mutex);
|
||||
|
||||
foreach_osl_device(device_, [this](Device *sub_device, OSLGlobals *) {
|
||||
foreach_osl_device(device_, [this, colorspace](Device *sub_device, OSLGlobals *) {
|
||||
const DeviceType device_type = sub_device->info.type;
|
||||
|
||||
if (!ss_shared[device_type]) {
|
||||
@@ -381,6 +381,21 @@ void OSLManager::shading_system_init()
|
||||
ss->attribute("searchpath:shader", shader_path);
|
||||
ss->attribute("greedyjit", 1);
|
||||
|
||||
/* OSL doesn't accept an arbitrary space, so support a few specific spaces. */
|
||||
switch (colorspace) {
|
||||
case ShaderManager::SceneLinearSpace::Rec709:
|
||||
ss->attribute("colorspace", OSL::Strings::Rec709);
|
||||
break;
|
||||
case ShaderManager::SceneLinearSpace::Rec2020:
|
||||
ss->attribute("colorspace", OSL::Strings::HDTV);
|
||||
break;
|
||||
case ShaderManager::SceneLinearSpace::ACEScg:
|
||||
ss->attribute("colorspace", OSL::Strings::ACEScg);
|
||||
break;
|
||||
case ShaderManager::SceneLinearSpace::Unknown:
|
||||
break;
|
||||
}
|
||||
|
||||
const char *groupdata_alloc_str = getenv("CYCLES_OSL_GROUPDATA_ALLOC");
|
||||
if (groupdata_alloc_str) {
|
||||
ss->attribute("max_optix_groupdata_alloc", atoi(groupdata_alloc_str));
|
||||
@@ -582,8 +597,6 @@ const char *OSLManager::shader_load_filepath(string filepath)
|
||||
|
||||
const char *OSLManager::shader_load_bytecode(const string &hash, const string &bytecode)
|
||||
{
|
||||
shading_system_init();
|
||||
|
||||
foreach_shading_system(
|
||||
[hash, bytecode](OSL::ShadingSystem *ss) { ss->LoadMemoryCompiledShader(hash, bytecode); });
|
||||
|
||||
@@ -740,7 +753,10 @@ OSLNode *OSLShaderManager::osl_node(ShaderGraph *graph,
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/* create query */
|
||||
/* Ensure shading system exists before we try to load a shader. */
|
||||
scene->osl_manager->shading_system_init(scene->shader_manager->get_scene_linear_space());
|
||||
|
||||
/* Load shader code. */
|
||||
const char *hash;
|
||||
|
||||
if (!filepath.empty()) {
|
||||
|
||||
@@ -79,6 +79,8 @@ class OSLManager {
|
||||
const char *shader_load_filepath(string filepath);
|
||||
OSLShaderInfo *shader_loaded_info(const string &hash);
|
||||
|
||||
void shading_system_init(ShaderManager::SceneLinearSpace colorspace);
|
||||
|
||||
OSL::ShadingSystem *get_shading_system(Device *sub_device);
|
||||
OSL::TextureSystem *get_texture_system();
|
||||
static void foreach_osl_device(Device *device,
|
||||
@@ -93,7 +95,6 @@ class OSLManager {
|
||||
void texture_system_init();
|
||||
void texture_system_free();
|
||||
|
||||
void shading_system_init();
|
||||
void shading_system_free();
|
||||
|
||||
void foreach_shading_system(const std::function<void(OSL::ShadingSystem *)> &callback);
|
||||
|
||||
@@ -696,7 +696,7 @@ void ShaderManager::device_update_common(Device * /*device*/,
|
||||
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);
|
||||
kfilm->is_rec709 = is_rec709;
|
||||
kfilm->is_rec709 = scene_linear_space == SceneLinearSpace::Rec709;
|
||||
}
|
||||
|
||||
void ShaderManager::device_free_common(Device * /*device*/, DeviceScene *dscene, Scene *scene)
|
||||
@@ -1011,7 +1011,7 @@ void ShaderManager::init_xyz_transforms()
|
||||
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;
|
||||
scene_linear_space = SceneLinearSpace::Rec709;
|
||||
|
||||
compute_thin_film_table(xyz_to_rec709);
|
||||
|
||||
@@ -1079,9 +1079,46 @@ void ShaderManager::init_xyz_transforms()
|
||||
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);
|
||||
is_rec709 = transform_equal_threshold(xyz_to_rgb, xyz_to_rec709, 0.0001f);
|
||||
|
||||
compute_thin_film_table(xyz_to_rgb);
|
||||
|
||||
const Transform xyz_to_rec2020 = make_transform(1.7166512f,
|
||||
-0.3556708f,
|
||||
-0.2533663f,
|
||||
0.0f,
|
||||
-0.6666844,
|
||||
1.6164812f,
|
||||
0.0157685f,
|
||||
0.0f,
|
||||
0.0176399f,
|
||||
-0.0427706f,
|
||||
0.9421031f,
|
||||
0.0f);
|
||||
const Transform acescg_to_xyz = make_transform(0.652238f,
|
||||
0.128237f,
|
||||
0.169983f,
|
||||
0.0f,
|
||||
0.267672f,
|
||||
0.674340f,
|
||||
0.057988f,
|
||||
0.0f,
|
||||
-0.005382f,
|
||||
0.001369f,
|
||||
1.093071f,
|
||||
0.0f);
|
||||
|
||||
if (transform_equal_threshold(xyz_to_rgb, xyz_to_rec709, 0.001f)) {
|
||||
scene_linear_space = SceneLinearSpace::Rec709;
|
||||
}
|
||||
else if (transform_equal_threshold(xyz_to_rgb, xyz_to_rec2020, 0.001f)) {
|
||||
scene_linear_space = SceneLinearSpace::Rec2020;
|
||||
}
|
||||
else if (transform_equal_threshold(rgb_to_xyz, acescg_to_xyz, 0.001f)) {
|
||||
scene_linear_space = SceneLinearSpace::ACEScg;
|
||||
}
|
||||
else {
|
||||
scene_linear_space = SceneLinearSpace::Unknown;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -212,6 +212,13 @@ class ShaderManager {
|
||||
|
||||
void init_xyz_transforms();
|
||||
|
||||
enum class SceneLinearSpace { Rec709, Rec2020, ACEScg, Unknown };
|
||||
|
||||
SceneLinearSpace get_scene_linear_space()
|
||||
{
|
||||
return scene_linear_space;
|
||||
}
|
||||
|
||||
protected:
|
||||
ShaderManager();
|
||||
|
||||
@@ -235,7 +242,7 @@ class ShaderManager {
|
||||
float3 rec709_to_r;
|
||||
float3 rec709_to_g;
|
||||
float3 rec709_to_b;
|
||||
bool is_rec709;
|
||||
SceneLinearSpace scene_linear_space;
|
||||
vector<float> thin_film_table;
|
||||
|
||||
template<std::size_t n>
|
||||
|
||||
Reference in New Issue
Block a user