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
|
|
|
|
2015-02-02 22:15:33 +05:00
|
|
|
/* TODO(sergey): There is a bit of headers dependency hell going on
|
|
|
|
|
* here, so for now we just put here. In the future it might be better
|
|
|
|
|
* to have dedicated file for such tweaks.
|
|
|
|
|
*/
|
2015-10-25 20:48:28 +01:00
|
|
|
#if (defined(__GNUC__) && !defined(__clang__)) && defined(NDEBUG)
|
2015-02-02 22:15:33 +05:00
|
|
|
# pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
|
2015-06-13 16:17:55 +02:00
|
|
|
# pragma GCC diagnostic ignored "-Wuninitialized"
|
2015-02-02 22:15:33 +05:00
|
|
|
#endif
|
|
|
|
|
|
2024-12-26 17:53:57 +01:00
|
|
|
#include <cstring>
|
2011-04-27 11:58:34 +00:00
|
|
|
|
2021-10-24 14:19:19 +02:00
|
|
|
#include "scene/colorspace.h"
|
|
|
|
|
#include "scene/object.h"
|
2011-04-27 11:58:34 +00:00
|
|
|
|
2021-10-24 14:19:19 +02:00
|
|
|
#include "util/log.h"
|
|
|
|
|
#include "util/string.h"
|
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
|
|
|
#include "kernel/device/cpu/image.h"
|
|
|
|
|
|
2024-07-16 09:43:28 +02:00
|
|
|
#include "kernel/osl/globals.h"
|
|
|
|
|
#include "kernel/osl/services.h"
|
2025-02-06 16:22:19 +01:00
|
|
|
#include "kernel/osl/services_shared.h"
|
2024-07-16 09:43:28 +02:00
|
|
|
#include "kernel/osl/types.h"
|
|
|
|
|
|
2021-10-24 14:19:19 +02:00
|
|
|
#include "kernel/integrator/state.h"
|
2025-01-20 12:40:11 +01:00
|
|
|
#include "kernel/integrator/state_util.h"
|
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
|
|
|
|
2024-12-26 17:53:57 +01:00
|
|
|
#include "kernel/geom/primitive.h"
|
|
|
|
|
#include "kernel/geom/shader_data.h"
|
2021-10-24 14:19:19 +02:00
|
|
|
|
Cycles: Make all #include statements relative to cycles source directory
The idea is to make include statements more explicit and obvious where the
file is coming from, additionally reducing chance of wrong header being
picked up.
For example, it was not obvious whether bvh.h was refferring to builder
or traversal, whenter node.h is a generic graph node or a shader node
and cases like that.
Surely this might look obvious for the active developers, but after some
time of not touching the code it becomes less obvious where file is coming
from.
This was briefly mentioned in T50824 and seems @brecht is fine with such
explicitness, but need to agree with all active developers before committing
this.
Please note that this patch is lacking changes related on GPU/OpenCL
support. This will be solved if/when we all agree this is a good idea to move
forward.
Reviewers: brecht, lukasstockner97, maiself, nirved, dingto, juicyfruit, swerner
Reviewed By: lukasstockner97, maiself, nirved, dingto
Subscribers: brecht
Differential Revision: https://developer.blender.org/D2586
2017-03-28 20:39:14 +02:00
|
|
|
#include "kernel/bvh/bvh.h"
|
2014-03-29 13:03:48 +01:00
|
|
|
|
2021-10-24 14:19:19 +02:00
|
|
|
#include "kernel/camera/camera.h"
|
|
|
|
|
|
2024-12-26 17:53:57 +01:00
|
|
|
#include "kernel/svm/ao.h"
|
|
|
|
|
#include "kernel/svm/bevel.h"
|
2022-09-02 15:32:46 +02:00
|
|
|
|
2024-12-26 17:53:57 +01:00
|
|
|
#include "kernel/util/ies.h"
|
2021-10-24 14:19:19 +02:00
|
|
|
|
2011-04-27 11:58:34 +00:00
|
|
|
CCL_NAMESPACE_BEGIN
|
|
|
|
|
|
|
|
|
|
/* RenderServices implementation */
|
|
|
|
|
|
2018-03-08 05:33:55 +01:00
|
|
|
static void copy_matrix(OSL::Matrix44 &m, const Transform &tfm)
|
|
|
|
|
{
|
2018-03-08 06:48:14 +01:00
|
|
|
ProjectionTransform t = projection_transpose(ProjectionTransform(tfm));
|
2024-12-27 21:50:31 +01:00
|
|
|
memcpy((float *)&m, (const float *)&t, sizeof(m));
|
2018-03-08 05:33:55 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void copy_matrix(OSL::Matrix44 &m, const ProjectionTransform &tfm)
|
|
|
|
|
{
|
|
|
|
|
ProjectionTransform t = projection_transpose(tfm);
|
2024-12-27 21:50:31 +01:00
|
|
|
memcpy((float *)&m, (const float *)&t, sizeof(m));
|
2018-03-08 05:33:55 +01:00
|
|
|
}
|
2011-04-27 11:58:34 +00:00
|
|
|
|
|
|
|
|
/* static ustrings */
|
|
|
|
|
ustring OSLRenderServices::u_distance("distance");
|
|
|
|
|
ustring OSLRenderServices::u_index("index");
|
2014-05-06 16:39:28 +02:00
|
|
|
ustring OSLRenderServices::u_world("world");
|
2011-04-27 11:58:34 +00:00
|
|
|
ustring OSLRenderServices::u_camera("camera");
|
|
|
|
|
ustring OSLRenderServices::u_screen("screen");
|
|
|
|
|
ustring OSLRenderServices::u_raster("raster");
|
|
|
|
|
ustring OSLRenderServices::u_ndc("NDC");
|
2012-12-01 19:15:05 +00:00
|
|
|
ustring OSLRenderServices::u_object_location("object:location");
|
2019-08-22 14:26:09 +02:00
|
|
|
ustring OSLRenderServices::u_object_color("object:color");
|
2022-03-07 17:34:52 +01:00
|
|
|
ustring OSLRenderServices::u_object_alpha("object:alpha");
|
2012-12-01 19:15:05 +00:00
|
|
|
ustring OSLRenderServices::u_object_index("object:index");
|
2024-07-24 12:16:44 +02:00
|
|
|
ustring OSLRenderServices::u_object_is_light("object:is_light");
|
2025-02-06 16:22:19 +01:00
|
|
|
ustring OSLRenderServices::u_bump_map_normal("geom:bump_map_normal");
|
2012-12-01 19:15:05 +00:00
|
|
|
ustring OSLRenderServices::u_geom_dupli_generated("geom:dupli_generated");
|
|
|
|
|
ustring OSLRenderServices::u_geom_dupli_uv("geom:dupli_uv");
|
|
|
|
|
ustring OSLRenderServices::u_material_index("material:index");
|
|
|
|
|
ustring OSLRenderServices::u_object_random("object:random");
|
2018-02-14 17:02:28 +01:00
|
|
|
ustring OSLRenderServices::u_particle_index("particle:index");
|
2018-02-14 14:32:38 +01:00
|
|
|
ustring OSLRenderServices::u_particle_random("particle:random");
|
2012-12-01 19:15:05 +00:00
|
|
|
ustring OSLRenderServices::u_particle_age("particle:age");
|
|
|
|
|
ustring OSLRenderServices::u_particle_lifetime("particle:lifetime");
|
|
|
|
|
ustring OSLRenderServices::u_particle_location("particle:location");
|
|
|
|
|
ustring OSLRenderServices::u_particle_rotation("particle:rotation");
|
|
|
|
|
ustring OSLRenderServices::u_particle_size("particle:size");
|
|
|
|
|
ustring OSLRenderServices::u_particle_velocity("particle:velocity");
|
|
|
|
|
ustring OSLRenderServices::u_particle_angular_velocity("particle:angular_velocity");
|
|
|
|
|
ustring OSLRenderServices::u_geom_numpolyvertices("geom:numpolyvertices");
|
|
|
|
|
ustring OSLRenderServices::u_geom_trianglevertices("geom:trianglevertices");
|
|
|
|
|
ustring OSLRenderServices::u_geom_polyvertices("geom:polyvertices");
|
|
|
|
|
ustring OSLRenderServices::u_geom_name("geom:name");
|
2016-08-14 11:44:25 -04:00
|
|
|
ustring OSLRenderServices::u_geom_undisplaced("geom:undisplaced");
|
2013-05-11 09:31:58 +00:00
|
|
|
ustring OSLRenderServices::u_is_smooth("geom:is_smooth");
|
2013-01-03 12:08:54 +00:00
|
|
|
ustring OSLRenderServices::u_is_curve("geom:is_curve");
|
|
|
|
|
ustring OSLRenderServices::u_curve_thickness("geom:curve_thickness");
|
2021-09-24 07:42:36 +02:00
|
|
|
ustring OSLRenderServices::u_curve_length("geom:curve_length");
|
2013-01-03 12:08:54 +00:00
|
|
|
ustring OSLRenderServices::u_curve_tangent_normal("geom:curve_tangent_normal");
|
2018-02-14 14:32:38 +01:00
|
|
|
ustring OSLRenderServices::u_curve_random("geom:curve_random");
|
2021-12-01 17:30:46 +01:00
|
|
|
ustring OSLRenderServices::u_is_point("geom:is_point");
|
|
|
|
|
ustring OSLRenderServices::u_point_radius("geom:point_radius");
|
2022-01-25 13:25:33 +01:00
|
|
|
ustring OSLRenderServices::u_point_position("geom:point_position");
|
|
|
|
|
ustring OSLRenderServices::u_point_random("geom:point_random");
|
2021-10-04 12:19:18 +02:00
|
|
|
ustring OSLRenderServices::u_normal_map_normal("geom:normal_map_normal");
|
2012-12-01 19:15:05 +00:00
|
|
|
ustring OSLRenderServices::u_path_ray_length("path:ray_length");
|
2013-07-31 20:30:37 +00:00
|
|
|
ustring OSLRenderServices::u_path_ray_depth("path:ray_depth");
|
2016-12-06 16:15:36 +01:00
|
|
|
ustring OSLRenderServices::u_path_diffuse_depth("path:diffuse_depth");
|
|
|
|
|
ustring OSLRenderServices::u_path_glossy_depth("path:glossy_depth");
|
2014-04-21 14:20:29 +02:00
|
|
|
ustring OSLRenderServices::u_path_transparent_depth("path:transparent_depth");
|
2016-01-06 23:38:13 +01:00
|
|
|
ustring OSLRenderServices::u_path_transmission_depth("path:transmission_depth");
|
2012-12-01 19:15:05 +00:00
|
|
|
ustring OSLRenderServices::u_trace("trace");
|
|
|
|
|
ustring OSLRenderServices::u_hit("hit");
|
|
|
|
|
ustring OSLRenderServices::u_hitdist("hitdist");
|
|
|
|
|
ustring OSLRenderServices::u_N("N");
|
|
|
|
|
ustring OSLRenderServices::u_Ng("Ng");
|
|
|
|
|
ustring OSLRenderServices::u_P("P");
|
|
|
|
|
ustring OSLRenderServices::u_I("I");
|
|
|
|
|
ustring OSLRenderServices::u_u("u");
|
|
|
|
|
ustring OSLRenderServices::u_v("v");
|
2011-04-27 11:58:34 +00:00
|
|
|
ustring OSLRenderServices::u_empty;
|
|
|
|
|
|
2025-04-25 19:27:30 +02:00
|
|
|
ustring OSLRenderServices::u_sensor_size("cam:sensor_size");
|
|
|
|
|
ustring OSLRenderServices::u_image_resolution("cam:image_resolution");
|
|
|
|
|
ustring OSLRenderServices::u_aperture_aspect_ratio("cam:aperture_aspect_ratio");
|
|
|
|
|
ustring OSLRenderServices::u_aperture_size("cam:aperture_size");
|
|
|
|
|
ustring OSLRenderServices::u_aperture_position("cam:aperture_position");
|
|
|
|
|
ustring OSLRenderServices::u_focal_distance("cam:focal_distance");
|
|
|
|
|
|
2023-01-18 17:28:03 +01:00
|
|
|
ImageManager *OSLRenderServices::image_manager = nullptr;
|
|
|
|
|
|
2025-01-01 18:15:54 +01:00
|
|
|
OSLRenderServices::OSLRenderServices(OSL::TextureSystem *texture_system, const int device_type)
|
2022-11-09 14:25:32 +01:00
|
|
|
: OSL::RendererServices(texture_system), device_type_(device_type)
|
2011-04-27 11:58:34 +00:00
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
OSLRenderServices::~OSLRenderServices()
|
|
|
|
|
{
|
2022-09-12 18:46:20 +02:00
|
|
|
if (m_texturesys) {
|
|
|
|
|
VLOG_INFO << "OSL texture system stats:\n" << m_texturesys->getstats();
|
2016-08-17 08:42:10 -04:00
|
|
|
}
|
2011-04-27 11:58:34 +00:00
|
|
|
}
|
|
|
|
|
|
2022-11-09 14:25:32 +01:00
|
|
|
int OSLRenderServices::supports(string_view feature) const
|
|
|
|
|
{
|
|
|
|
|
#ifdef WITH_OPTIX
|
|
|
|
|
if (feature == "OptiX") {
|
|
|
|
|
return device_type_ == DEVICE_OPTIX;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2014-07-24 23:07:49 +02:00
|
|
|
bool OSLRenderServices::get_matrix(OSL::ShaderGlobals *sg,
|
|
|
|
|
OSL::Matrix44 &result,
|
|
|
|
|
OSL::TransformationPtr xform,
|
2025-01-01 18:15:54 +01:00
|
|
|
const float time)
|
2011-04-27 11:58:34 +00:00
|
|
|
{
|
Cycles: Refactor: Store Cycles-specific pointers in our own ShaderGlobals
OSL has OSL::ShaderGlobals, which contains all the state for OSL shader
execution. The renderer fills it out and hands a pointer to OSL, and any
callbacks (e.g. for querying attributes) get the pointer back.
In order to store renderer-specific data in it, there's a few opaque pointers
in the struct, but using those has led to a mess of reinterpret_cast<> and
pointer indirection in order to carry all the data around.
However, there is a way to do this nicer: Good old C-style struct inheritance.
In short: Unless you're doing pointer arithmetic, you can just add additional
data at the end of a base struct, and the rest of the code won't care.
In this case, this means that we can have our own ShaderGlobals struct and
add more Cycles-specific data at the end. Additionally, we can replace the
generic opaque void pointers with ones of the correct type, which saves us
from needing to cast them back.
Since we have a copy of ShaderGlobals for GPU OSL anyways, it's just a matter
of refactoring the code a bit to make use of that.
The advantages of this are:
- Avoids casts all over the place, just needs one cast to turn our
ShaderGlobals into the "base" type that OSL expects and one to turn the
pointer that OSL gives us on callbacks back into our "derived" type.
- Removes indirection, all the relevant stuff (sd, kg, state) is now
directly in the ShaderGlobals
- Removes some OSL-specific state from ShaderData, which helps to keep
memory usage down
Pull Request: https://projects.blender.org/blender/blender/pulls/133689
2025-01-28 03:39:00 +01:00
|
|
|
ShaderGlobals *globals = reinterpret_cast<ShaderGlobals *>(sg);
|
|
|
|
|
|
|
|
|
|
if (globals == nullptr || globals->sd == nullptr) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2011-04-27 11:58:34 +00:00
|
|
|
/* this is only used for shader and object space, we don't really have
|
2012-06-09 17:22:52 +00:00
|
|
|
* a concept of shader space, so we just use object space for both. */
|
Cycles: Refactor: Store Cycles-specific pointers in our own ShaderGlobals
OSL has OSL::ShaderGlobals, which contains all the state for OSL shader
execution. The renderer fills it out and hands a pointer to OSL, and any
callbacks (e.g. for querying attributes) get the pointer back.
In order to store renderer-specific data in it, there's a few opaque pointers
in the struct, but using those has led to a mess of reinterpret_cast<> and
pointer indirection in order to carry all the data around.
However, there is a way to do this nicer: Good old C-style struct inheritance.
In short: Unless you're doing pointer arithmetic, you can just add additional
data at the end of a base struct, and the rest of the code won't care.
In this case, this means that we can have our own ShaderGlobals struct and
add more Cycles-specific data at the end. Additionally, we can replace the
generic opaque void pointers with ones of the correct type, which saves us
from needing to cast them back.
Since we have a copy of ShaderGlobals for GPU OSL anyways, it's just a matter
of refactoring the code a bit to make use of that.
The advantages of this are:
- Avoids casts all over the place, just needs one cast to turn our
ShaderGlobals into the "base" type that OSL expects and one to turn the
pointer that OSL gives us on callbacks back into our "derived" type.
- Removes indirection, all the relevant stuff (sd, kg, state) is now
directly in the ShaderGlobals
- Removes some OSL-specific state from ShaderData, which helps to keep
memory usage down
Pull Request: https://projects.blender.org/blender/blender/pulls/133689
2025-01-28 03:39:00 +01:00
|
|
|
const ShaderData *sd = globals->sd;
|
|
|
|
|
const ThreadKernelGlobalsCPU *kg = globals->kg;
|
|
|
|
|
const int object = sd->object;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
Cycles: Refactor: Store Cycles-specific pointers in our own ShaderGlobals
OSL has OSL::ShaderGlobals, which contains all the state for OSL shader
execution. The renderer fills it out and hands a pointer to OSL, and any
callbacks (e.g. for querying attributes) get the pointer back.
In order to store renderer-specific data in it, there's a few opaque pointers
in the struct, but using those has led to a mess of reinterpret_cast<> and
pointer indirection in order to carry all the data around.
However, there is a way to do this nicer: Good old C-style struct inheritance.
In short: Unless you're doing pointer arithmetic, you can just add additional
data at the end of a base struct, and the rest of the code won't care.
In this case, this means that we can have our own ShaderGlobals struct and
add more Cycles-specific data at the end. Additionally, we can replace the
generic opaque void pointers with ones of the correct type, which saves us
from needing to cast them back.
Since we have a copy of ShaderGlobals for GPU OSL anyways, it's just a matter
of refactoring the code a bit to make use of that.
The advantages of this are:
- Avoids casts all over the place, just needs one cast to turn our
ShaderGlobals into the "base" type that OSL expects and one to turn the
pointer that OSL gives us on callbacks back into our "derived" type.
- Removes indirection, all the relevant stuff (sd, kg, state) is now
directly in the ShaderGlobals
- Removes some OSL-specific state from ShaderData, which helps to keep
memory usage down
Pull Request: https://projects.blender.org/blender/blender/pulls/133689
2025-01-28 03:39:00 +01:00
|
|
|
if (object != OBJECT_NONE) {
|
2012-10-16 10:59:35 +00:00
|
|
|
#ifdef __OBJECT_MOTION__
|
Cycles: Refactor: Store Cycles-specific pointers in our own ShaderGlobals
OSL has OSL::ShaderGlobals, which contains all the state for OSL shader
execution. The renderer fills it out and hands a pointer to OSL, and any
callbacks (e.g. for querying attributes) get the pointer back.
In order to store renderer-specific data in it, there's a few opaque pointers
in the struct, but using those has led to a mess of reinterpret_cast<> and
pointer indirection in order to carry all the data around.
However, there is a way to do this nicer: Good old C-style struct inheritance.
In short: Unless you're doing pointer arithmetic, you can just add additional
data at the end of a base struct, and the rest of the code won't care.
In this case, this means that we can have our own ShaderGlobals struct and
add more Cycles-specific data at the end. Additionally, we can replace the
generic opaque void pointers with ones of the correct type, which saves us
from needing to cast them back.
Since we have a copy of ShaderGlobals for GPU OSL anyways, it's just a matter
of refactoring the code a bit to make use of that.
The advantages of this are:
- Avoids casts all over the place, just needs one cast to turn our
ShaderGlobals into the "base" type that OSL expects and one to turn the
pointer that OSL gives us on callbacks back into our "derived" type.
- Removes indirection, all the relevant stuff (sd, kg, state) is now
directly in the ShaderGlobals
- Removes some OSL-specific state from ShaderData, which helps to keep
memory usage down
Pull Request: https://projects.blender.org/blender/blender/pulls/133689
2025-01-28 03:39:00 +01:00
|
|
|
Transform tfm;
|
2012-11-29 16:11:37 +00:00
|
|
|
|
Cycles: Refactor: Store Cycles-specific pointers in our own ShaderGlobals
OSL has OSL::ShaderGlobals, which contains all the state for OSL shader
execution. The renderer fills it out and hands a pointer to OSL, and any
callbacks (e.g. for querying attributes) get the pointer back.
In order to store renderer-specific data in it, there's a few opaque pointers
in the struct, but using those has led to a mess of reinterpret_cast<> and
pointer indirection in order to carry all the data around.
However, there is a way to do this nicer: Good old C-style struct inheritance.
In short: Unless you're doing pointer arithmetic, you can just add additional
data at the end of a base struct, and the rest of the code won't care.
In this case, this means that we can have our own ShaderGlobals struct and
add more Cycles-specific data at the end. Additionally, we can replace the
generic opaque void pointers with ones of the correct type, which saves us
from needing to cast them back.
Since we have a copy of ShaderGlobals for GPU OSL anyways, it's just a matter
of refactoring the code a bit to make use of that.
The advantages of this are:
- Avoids casts all over the place, just needs one cast to turn our
ShaderGlobals into the "base" type that OSL expects and one to turn the
pointer that OSL gives us on callbacks back into our "derived" type.
- Removes indirection, all the relevant stuff (sd, kg, state) is now
directly in the ShaderGlobals
- Removes some OSL-specific state from ShaderData, which helps to keep
memory usage down
Pull Request: https://projects.blender.org/blender/blender/pulls/133689
2025-01-28 03:39:00 +01:00
|
|
|
if (time == sd->time) {
|
|
|
|
|
tfm = object_get_transform(kg, sd);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
tfm = object_fetch_transform_motion_test(kg, object, time, nullptr);
|
|
|
|
|
}
|
2012-10-16 10:59:35 +00:00
|
|
|
#else
|
Cycles: Refactor: Store Cycles-specific pointers in our own ShaderGlobals
OSL has OSL::ShaderGlobals, which contains all the state for OSL shader
execution. The renderer fills it out and hands a pointer to OSL, and any
callbacks (e.g. for querying attributes) get the pointer back.
In order to store renderer-specific data in it, there's a few opaque pointers
in the struct, but using those has led to a mess of reinterpret_cast<> and
pointer indirection in order to carry all the data around.
However, there is a way to do this nicer: Good old C-style struct inheritance.
In short: Unless you're doing pointer arithmetic, you can just add additional
data at the end of a base struct, and the rest of the code won't care.
In this case, this means that we can have our own ShaderGlobals struct and
add more Cycles-specific data at the end. Additionally, we can replace the
generic opaque void pointers with ones of the correct type, which saves us
from needing to cast them back.
Since we have a copy of ShaderGlobals for GPU OSL anyways, it's just a matter
of refactoring the code a bit to make use of that.
The advantages of this are:
- Avoids casts all over the place, just needs one cast to turn our
ShaderGlobals into the "base" type that OSL expects and one to turn the
pointer that OSL gives us on callbacks back into our "derived" type.
- Removes indirection, all the relevant stuff (sd, kg, state) is now
directly in the ShaderGlobals
- Removes some OSL-specific state from ShaderData, which helps to keep
memory usage down
Pull Request: https://projects.blender.org/blender/blender/pulls/133689
2025-01-28 03:39:00 +01:00
|
|
|
const Transform tfm = object_get_transform(kg, sd);
|
2012-10-16 10:59:35 +00:00
|
|
|
#endif
|
Cycles: Refactor: Store Cycles-specific pointers in our own ShaderGlobals
OSL has OSL::ShaderGlobals, which contains all the state for OSL shader
execution. The renderer fills it out and hands a pointer to OSL, and any
callbacks (e.g. for querying attributes) get the pointer back.
In order to store renderer-specific data in it, there's a few opaque pointers
in the struct, but using those has led to a mess of reinterpret_cast<> and
pointer indirection in order to carry all the data around.
However, there is a way to do this nicer: Good old C-style struct inheritance.
In short: Unless you're doing pointer arithmetic, you can just add additional
data at the end of a base struct, and the rest of the code won't care.
In this case, this means that we can have our own ShaderGlobals struct and
add more Cycles-specific data at the end. Additionally, we can replace the
generic opaque void pointers with ones of the correct type, which saves us
from needing to cast them back.
Since we have a copy of ShaderGlobals for GPU OSL anyways, it's just a matter
of refactoring the code a bit to make use of that.
The advantages of this are:
- Avoids casts all over the place, just needs one cast to turn our
ShaderGlobals into the "base" type that OSL expects and one to turn the
pointer that OSL gives us on callbacks back into our "derived" type.
- Removes indirection, all the relevant stuff (sd, kg, state) is now
directly in the ShaderGlobals
- Removes some OSL-specific state from ShaderData, which helps to keep
memory usage down
Pull Request: https://projects.blender.org/blender/blender/pulls/133689
2025-01-28 03:39:00 +01:00
|
|
|
copy_matrix(result, tfm);
|
2011-04-27 11:58:34 +00:00
|
|
|
|
Cycles: Refactor: Store Cycles-specific pointers in our own ShaderGlobals
OSL has OSL::ShaderGlobals, which contains all the state for OSL shader
execution. The renderer fills it out and hands a pointer to OSL, and any
callbacks (e.g. for querying attributes) get the pointer back.
In order to store renderer-specific data in it, there's a few opaque pointers
in the struct, but using those has led to a mess of reinterpret_cast<> and
pointer indirection in order to carry all the data around.
However, there is a way to do this nicer: Good old C-style struct inheritance.
In short: Unless you're doing pointer arithmetic, you can just add additional
data at the end of a base struct, and the rest of the code won't care.
In this case, this means that we can have our own ShaderGlobals struct and
add more Cycles-specific data at the end. Additionally, we can replace the
generic opaque void pointers with ones of the correct type, which saves us
from needing to cast them back.
Since we have a copy of ShaderGlobals for GPU OSL anyways, it's just a matter
of refactoring the code a bit to make use of that.
The advantages of this are:
- Avoids casts all over the place, just needs one cast to turn our
ShaderGlobals into the "base" type that OSL expects and one to turn the
pointer that OSL gives us on callbacks back into our "derived" type.
- Removes indirection, all the relevant stuff (sd, kg, state) is now
directly in the ShaderGlobals
- Removes some OSL-specific state from ShaderData, which helps to keep
memory usage down
Pull Request: https://projects.blender.org/blender/blender/pulls/133689
2025-01-28 03:39:00 +01:00
|
|
|
return true;
|
|
|
|
|
}
|
2011-04-27 11:58:34 +00:00
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2014-07-24 23:07:49 +02:00
|
|
|
bool OSLRenderServices::get_inverse_matrix(OSL::ShaderGlobals *sg,
|
|
|
|
|
OSL::Matrix44 &result,
|
|
|
|
|
OSL::TransformationPtr xform,
|
2025-01-01 18:15:54 +01:00
|
|
|
const float time)
|
2011-04-27 11:58:34 +00:00
|
|
|
{
|
Cycles: Refactor: Store Cycles-specific pointers in our own ShaderGlobals
OSL has OSL::ShaderGlobals, which contains all the state for OSL shader
execution. The renderer fills it out and hands a pointer to OSL, and any
callbacks (e.g. for querying attributes) get the pointer back.
In order to store renderer-specific data in it, there's a few opaque pointers
in the struct, but using those has led to a mess of reinterpret_cast<> and
pointer indirection in order to carry all the data around.
However, there is a way to do this nicer: Good old C-style struct inheritance.
In short: Unless you're doing pointer arithmetic, you can just add additional
data at the end of a base struct, and the rest of the code won't care.
In this case, this means that we can have our own ShaderGlobals struct and
add more Cycles-specific data at the end. Additionally, we can replace the
generic opaque void pointers with ones of the correct type, which saves us
from needing to cast them back.
Since we have a copy of ShaderGlobals for GPU OSL anyways, it's just a matter
of refactoring the code a bit to make use of that.
The advantages of this are:
- Avoids casts all over the place, just needs one cast to turn our
ShaderGlobals into the "base" type that OSL expects and one to turn the
pointer that OSL gives us on callbacks back into our "derived" type.
- Removes indirection, all the relevant stuff (sd, kg, state) is now
directly in the ShaderGlobals
- Removes some OSL-specific state from ShaderData, which helps to keep
memory usage down
Pull Request: https://projects.blender.org/blender/blender/pulls/133689
2025-01-28 03:39:00 +01:00
|
|
|
ShaderGlobals *globals = reinterpret_cast<ShaderGlobals *>(sg);
|
|
|
|
|
|
|
|
|
|
if (globals == nullptr || globals->sd == nullptr) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2011-04-27 11:58:34 +00:00
|
|
|
/* this is only used for shader and object space, we don't really have
|
2012-06-09 17:22:52 +00:00
|
|
|
* a concept of shader space, so we just use object space for both. */
|
Cycles: Refactor: Store Cycles-specific pointers in our own ShaderGlobals
OSL has OSL::ShaderGlobals, which contains all the state for OSL shader
execution. The renderer fills it out and hands a pointer to OSL, and any
callbacks (e.g. for querying attributes) get the pointer back.
In order to store renderer-specific data in it, there's a few opaque pointers
in the struct, but using those has led to a mess of reinterpret_cast<> and
pointer indirection in order to carry all the data around.
However, there is a way to do this nicer: Good old C-style struct inheritance.
In short: Unless you're doing pointer arithmetic, you can just add additional
data at the end of a base struct, and the rest of the code won't care.
In this case, this means that we can have our own ShaderGlobals struct and
add more Cycles-specific data at the end. Additionally, we can replace the
generic opaque void pointers with ones of the correct type, which saves us
from needing to cast them back.
Since we have a copy of ShaderGlobals for GPU OSL anyways, it's just a matter
of refactoring the code a bit to make use of that.
The advantages of this are:
- Avoids casts all over the place, just needs one cast to turn our
ShaderGlobals into the "base" type that OSL expects and one to turn the
pointer that OSL gives us on callbacks back into our "derived" type.
- Removes indirection, all the relevant stuff (sd, kg, state) is now
directly in the ShaderGlobals
- Removes some OSL-specific state from ShaderData, which helps to keep
memory usage down
Pull Request: https://projects.blender.org/blender/blender/pulls/133689
2025-01-28 03:39:00 +01:00
|
|
|
const ShaderData *sd = globals->sd;
|
|
|
|
|
const ThreadKernelGlobalsCPU *kg = globals->kg;
|
|
|
|
|
const int object = sd->object;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
Cycles: Refactor: Store Cycles-specific pointers in our own ShaderGlobals
OSL has OSL::ShaderGlobals, which contains all the state for OSL shader
execution. The renderer fills it out and hands a pointer to OSL, and any
callbacks (e.g. for querying attributes) get the pointer back.
In order to store renderer-specific data in it, there's a few opaque pointers
in the struct, but using those has led to a mess of reinterpret_cast<> and
pointer indirection in order to carry all the data around.
However, there is a way to do this nicer: Good old C-style struct inheritance.
In short: Unless you're doing pointer arithmetic, you can just add additional
data at the end of a base struct, and the rest of the code won't care.
In this case, this means that we can have our own ShaderGlobals struct and
add more Cycles-specific data at the end. Additionally, we can replace the
generic opaque void pointers with ones of the correct type, which saves us
from needing to cast them back.
Since we have a copy of ShaderGlobals for GPU OSL anyways, it's just a matter
of refactoring the code a bit to make use of that.
The advantages of this are:
- Avoids casts all over the place, just needs one cast to turn our
ShaderGlobals into the "base" type that OSL expects and one to turn the
pointer that OSL gives us on callbacks back into our "derived" type.
- Removes indirection, all the relevant stuff (sd, kg, state) is now
directly in the ShaderGlobals
- Removes some OSL-specific state from ShaderData, which helps to keep
memory usage down
Pull Request: https://projects.blender.org/blender/blender/pulls/133689
2025-01-28 03:39:00 +01:00
|
|
|
if (object != OBJECT_NONE) {
|
2012-10-16 10:59:35 +00:00
|
|
|
#ifdef __OBJECT_MOTION__
|
Cycles: Refactor: Store Cycles-specific pointers in our own ShaderGlobals
OSL has OSL::ShaderGlobals, which contains all the state for OSL shader
execution. The renderer fills it out and hands a pointer to OSL, and any
callbacks (e.g. for querying attributes) get the pointer back.
In order to store renderer-specific data in it, there's a few opaque pointers
in the struct, but using those has led to a mess of reinterpret_cast<> and
pointer indirection in order to carry all the data around.
However, there is a way to do this nicer: Good old C-style struct inheritance.
In short: Unless you're doing pointer arithmetic, you can just add additional
data at the end of a base struct, and the rest of the code won't care.
In this case, this means that we can have our own ShaderGlobals struct and
add more Cycles-specific data at the end. Additionally, we can replace the
generic opaque void pointers with ones of the correct type, which saves us
from needing to cast them back.
Since we have a copy of ShaderGlobals for GPU OSL anyways, it's just a matter
of refactoring the code a bit to make use of that.
The advantages of this are:
- Avoids casts all over the place, just needs one cast to turn our
ShaderGlobals into the "base" type that OSL expects and one to turn the
pointer that OSL gives us on callbacks back into our "derived" type.
- Removes indirection, all the relevant stuff (sd, kg, state) is now
directly in the ShaderGlobals
- Removes some OSL-specific state from ShaderData, which helps to keep
memory usage down
Pull Request: https://projects.blender.org/blender/blender/pulls/133689
2025-01-28 03:39:00 +01:00
|
|
|
Transform itfm;
|
2012-11-29 16:11:37 +00:00
|
|
|
|
Cycles: Refactor: Store Cycles-specific pointers in our own ShaderGlobals
OSL has OSL::ShaderGlobals, which contains all the state for OSL shader
execution. The renderer fills it out and hands a pointer to OSL, and any
callbacks (e.g. for querying attributes) get the pointer back.
In order to store renderer-specific data in it, there's a few opaque pointers
in the struct, but using those has led to a mess of reinterpret_cast<> and
pointer indirection in order to carry all the data around.
However, there is a way to do this nicer: Good old C-style struct inheritance.
In short: Unless you're doing pointer arithmetic, you can just add additional
data at the end of a base struct, and the rest of the code won't care.
In this case, this means that we can have our own ShaderGlobals struct and
add more Cycles-specific data at the end. Additionally, we can replace the
generic opaque void pointers with ones of the correct type, which saves us
from needing to cast them back.
Since we have a copy of ShaderGlobals for GPU OSL anyways, it's just a matter
of refactoring the code a bit to make use of that.
The advantages of this are:
- Avoids casts all over the place, just needs one cast to turn our
ShaderGlobals into the "base" type that OSL expects and one to turn the
pointer that OSL gives us on callbacks back into our "derived" type.
- Removes indirection, all the relevant stuff (sd, kg, state) is now
directly in the ShaderGlobals
- Removes some OSL-specific state from ShaderData, which helps to keep
memory usage down
Pull Request: https://projects.blender.org/blender/blender/pulls/133689
2025-01-28 03:39:00 +01:00
|
|
|
if (time == sd->time) {
|
|
|
|
|
itfm = object_get_inverse_transform(kg, sd);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
object_fetch_transform_motion_test(kg, object, time, &itfm);
|
|
|
|
|
}
|
2012-10-16 10:59:35 +00:00
|
|
|
#else
|
Cycles: Refactor: Store Cycles-specific pointers in our own ShaderGlobals
OSL has OSL::ShaderGlobals, which contains all the state for OSL shader
execution. The renderer fills it out and hands a pointer to OSL, and any
callbacks (e.g. for querying attributes) get the pointer back.
In order to store renderer-specific data in it, there's a few opaque pointers
in the struct, but using those has led to a mess of reinterpret_cast<> and
pointer indirection in order to carry all the data around.
However, there is a way to do this nicer: Good old C-style struct inheritance.
In short: Unless you're doing pointer arithmetic, you can just add additional
data at the end of a base struct, and the rest of the code won't care.
In this case, this means that we can have our own ShaderGlobals struct and
add more Cycles-specific data at the end. Additionally, we can replace the
generic opaque void pointers with ones of the correct type, which saves us
from needing to cast them back.
Since we have a copy of ShaderGlobals for GPU OSL anyways, it's just a matter
of refactoring the code a bit to make use of that.
The advantages of this are:
- Avoids casts all over the place, just needs one cast to turn our
ShaderGlobals into the "base" type that OSL expects and one to turn the
pointer that OSL gives us on callbacks back into our "derived" type.
- Removes indirection, all the relevant stuff (sd, kg, state) is now
directly in the ShaderGlobals
- Removes some OSL-specific state from ShaderData, which helps to keep
memory usage down
Pull Request: https://projects.blender.org/blender/blender/pulls/133689
2025-01-28 03:39:00 +01:00
|
|
|
const Transform itfm = object_get_inverse_transform(kg, sd);
|
2012-10-16 10:59:35 +00:00
|
|
|
#endif
|
Cycles: Refactor: Store Cycles-specific pointers in our own ShaderGlobals
OSL has OSL::ShaderGlobals, which contains all the state for OSL shader
execution. The renderer fills it out and hands a pointer to OSL, and any
callbacks (e.g. for querying attributes) get the pointer back.
In order to store renderer-specific data in it, there's a few opaque pointers
in the struct, but using those has led to a mess of reinterpret_cast<> and
pointer indirection in order to carry all the data around.
However, there is a way to do this nicer: Good old C-style struct inheritance.
In short: Unless you're doing pointer arithmetic, you can just add additional
data at the end of a base struct, and the rest of the code won't care.
In this case, this means that we can have our own ShaderGlobals struct and
add more Cycles-specific data at the end. Additionally, we can replace the
generic opaque void pointers with ones of the correct type, which saves us
from needing to cast them back.
Since we have a copy of ShaderGlobals for GPU OSL anyways, it's just a matter
of refactoring the code a bit to make use of that.
The advantages of this are:
- Avoids casts all over the place, just needs one cast to turn our
ShaderGlobals into the "base" type that OSL expects and one to turn the
pointer that OSL gives us on callbacks back into our "derived" type.
- Removes indirection, all the relevant stuff (sd, kg, state) is now
directly in the ShaderGlobals
- Removes some OSL-specific state from ShaderData, which helps to keep
memory usage down
Pull Request: https://projects.blender.org/blender/blender/pulls/133689
2025-01-28 03:39:00 +01:00
|
|
|
copy_matrix(result, itfm);
|
2011-04-27 11:58:34 +00:00
|
|
|
|
Cycles: Refactor: Store Cycles-specific pointers in our own ShaderGlobals
OSL has OSL::ShaderGlobals, which contains all the state for OSL shader
execution. The renderer fills it out and hands a pointer to OSL, and any
callbacks (e.g. for querying attributes) get the pointer back.
In order to store renderer-specific data in it, there's a few opaque pointers
in the struct, but using those has led to a mess of reinterpret_cast<> and
pointer indirection in order to carry all the data around.
However, there is a way to do this nicer: Good old C-style struct inheritance.
In short: Unless you're doing pointer arithmetic, you can just add additional
data at the end of a base struct, and the rest of the code won't care.
In this case, this means that we can have our own ShaderGlobals struct and
add more Cycles-specific data at the end. Additionally, we can replace the
generic opaque void pointers with ones of the correct type, which saves us
from needing to cast them back.
Since we have a copy of ShaderGlobals for GPU OSL anyways, it's just a matter
of refactoring the code a bit to make use of that.
The advantages of this are:
- Avoids casts all over the place, just needs one cast to turn our
ShaderGlobals into the "base" type that OSL expects and one to turn the
pointer that OSL gives us on callbacks back into our "derived" type.
- Removes indirection, all the relevant stuff (sd, kg, state) is now
directly in the ShaderGlobals
- Removes some OSL-specific state from ShaderData, which helps to keep
memory usage down
Pull Request: https://projects.blender.org/blender/blender/pulls/133689
2025-01-28 03:39:00 +01:00
|
|
|
return true;
|
|
|
|
|
}
|
2011-04-27 11:58:34 +00:00
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2014-07-24 23:07:49 +02:00
|
|
|
bool OSLRenderServices::get_matrix(OSL::ShaderGlobals *sg,
|
|
|
|
|
OSL::Matrix44 &result,
|
2023-08-10 20:01:09 +02:00
|
|
|
OSLUStringHash from,
|
2025-01-01 18:15:54 +01:00
|
|
|
const float time)
|
2011-04-27 11:58:34 +00:00
|
|
|
{
|
Cycles: Refactor: Store Cycles-specific pointers in our own ShaderGlobals
OSL has OSL::ShaderGlobals, which contains all the state for OSL shader
execution. The renderer fills it out and hands a pointer to OSL, and any
callbacks (e.g. for querying attributes) get the pointer back.
In order to store renderer-specific data in it, there's a few opaque pointers
in the struct, but using those has led to a mess of reinterpret_cast<> and
pointer indirection in order to carry all the data around.
However, there is a way to do this nicer: Good old C-style struct inheritance.
In short: Unless you're doing pointer arithmetic, you can just add additional
data at the end of a base struct, and the rest of the code won't care.
In this case, this means that we can have our own ShaderGlobals struct and
add more Cycles-specific data at the end. Additionally, we can replace the
generic opaque void pointers with ones of the correct type, which saves us
from needing to cast them back.
Since we have a copy of ShaderGlobals for GPU OSL anyways, it's just a matter
of refactoring the code a bit to make use of that.
The advantages of this are:
- Avoids casts all over the place, just needs one cast to turn our
ShaderGlobals into the "base" type that OSL expects and one to turn the
pointer that OSL gives us on callbacks back into our "derived" type.
- Removes indirection, all the relevant stuff (sd, kg, state) is now
directly in the ShaderGlobals
- Removes some OSL-specific state from ShaderData, which helps to keep
memory usage down
Pull Request: https://projects.blender.org/blender/blender/pulls/133689
2025-01-28 03:39:00 +01:00
|
|
|
ShaderGlobals *globals = reinterpret_cast<ShaderGlobals *>(sg);
|
|
|
|
|
const ThreadKernelGlobalsCPU *kg = globals->kg;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2015-03-28 00:15:15 +05:00
|
|
|
if (from == u_ndc) {
|
2018-03-08 05:33:55 +01:00
|
|
|
copy_matrix(result, kernel_data.cam.ndctoworld);
|
2011-04-27 11:58:34 +00:00
|
|
|
return true;
|
|
|
|
|
}
|
2024-12-26 17:53:59 +01:00
|
|
|
if (from == u_raster) {
|
2018-03-08 05:33:55 +01:00
|
|
|
copy_matrix(result, kernel_data.cam.rastertoworld);
|
2011-04-27 11:58:34 +00:00
|
|
|
return true;
|
|
|
|
|
}
|
2024-12-26 17:53:59 +01:00
|
|
|
if (from == u_screen) {
|
2018-03-08 05:33:55 +01:00
|
|
|
copy_matrix(result, kernel_data.cam.screentoworld);
|
2011-04-27 11:58:34 +00:00
|
|
|
return true;
|
|
|
|
|
}
|
2024-12-26 17:53:59 +01:00
|
|
|
if (from == u_camera) {
|
2018-03-08 05:33:55 +01:00
|
|
|
copy_matrix(result, kernel_data.cam.cameratoworld);
|
2011-04-27 11:58:34 +00:00
|
|
|
return true;
|
|
|
|
|
}
|
2024-12-26 17:53:59 +01:00
|
|
|
if (from == u_world) {
|
2014-05-06 16:39:28 +02:00
|
|
|
result.makeIdentity();
|
|
|
|
|
return true;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2011-04-27 11:58:34 +00:00
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2014-07-24 23:07:49 +02:00
|
|
|
bool OSLRenderServices::get_inverse_matrix(OSL::ShaderGlobals *sg,
|
|
|
|
|
OSL::Matrix44 &result,
|
2023-08-10 20:01:09 +02:00
|
|
|
OSLUStringHash to,
|
2025-01-01 18:15:54 +01:00
|
|
|
const float time)
|
2011-04-27 11:58:34 +00:00
|
|
|
{
|
Cycles: Refactor: Store Cycles-specific pointers in our own ShaderGlobals
OSL has OSL::ShaderGlobals, which contains all the state for OSL shader
execution. The renderer fills it out and hands a pointer to OSL, and any
callbacks (e.g. for querying attributes) get the pointer back.
In order to store renderer-specific data in it, there's a few opaque pointers
in the struct, but using those has led to a mess of reinterpret_cast<> and
pointer indirection in order to carry all the data around.
However, there is a way to do this nicer: Good old C-style struct inheritance.
In short: Unless you're doing pointer arithmetic, you can just add additional
data at the end of a base struct, and the rest of the code won't care.
In this case, this means that we can have our own ShaderGlobals struct and
add more Cycles-specific data at the end. Additionally, we can replace the
generic opaque void pointers with ones of the correct type, which saves us
from needing to cast them back.
Since we have a copy of ShaderGlobals for GPU OSL anyways, it's just a matter
of refactoring the code a bit to make use of that.
The advantages of this are:
- Avoids casts all over the place, just needs one cast to turn our
ShaderGlobals into the "base" type that OSL expects and one to turn the
pointer that OSL gives us on callbacks back into our "derived" type.
- Removes indirection, all the relevant stuff (sd, kg, state) is now
directly in the ShaderGlobals
- Removes some OSL-specific state from ShaderData, which helps to keep
memory usage down
Pull Request: https://projects.blender.org/blender/blender/pulls/133689
2025-01-28 03:39:00 +01:00
|
|
|
ShaderGlobals *globals = reinterpret_cast<ShaderGlobals *>(sg);
|
|
|
|
|
const ThreadKernelGlobalsCPU *kg = globals->kg;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2015-03-28 00:15:15 +05:00
|
|
|
if (to == u_ndc) {
|
2018-03-08 05:33:55 +01:00
|
|
|
copy_matrix(result, kernel_data.cam.worldtondc);
|
2011-04-27 11:58:34 +00:00
|
|
|
return true;
|
|
|
|
|
}
|
2024-12-26 17:53:59 +01:00
|
|
|
if (to == u_raster) {
|
2018-03-08 05:33:55 +01:00
|
|
|
copy_matrix(result, kernel_data.cam.worldtoraster);
|
2011-04-27 11:58:34 +00:00
|
|
|
return true;
|
|
|
|
|
}
|
2024-12-26 17:53:59 +01:00
|
|
|
if (to == u_screen) {
|
2018-03-08 05:33:55 +01:00
|
|
|
copy_matrix(result, kernel_data.cam.worldtoscreen);
|
2011-04-27 11:58:34 +00:00
|
|
|
return true;
|
|
|
|
|
}
|
2024-12-26 17:53:59 +01:00
|
|
|
if (to == u_camera) {
|
2018-03-08 05:33:55 +01:00
|
|
|
copy_matrix(result, kernel_data.cam.worldtocamera);
|
2011-04-27 11:58:34 +00:00
|
|
|
return true;
|
|
|
|
|
}
|
2024-12-26 17:53:59 +01:00
|
|
|
if (to == u_world) {
|
2014-05-06 16:39:28 +02:00
|
|
|
result.makeIdentity();
|
|
|
|
|
return true;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2011-04-27 11:58:34 +00:00
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2014-07-24 23:07:49 +02:00
|
|
|
bool OSLRenderServices::get_matrix(OSL::ShaderGlobals *sg,
|
|
|
|
|
OSL::Matrix44 &result,
|
|
|
|
|
OSL::TransformationPtr xform)
|
2012-09-02 01:10:31 +00:00
|
|
|
{
|
Cycles: Refactor: Store Cycles-specific pointers in our own ShaderGlobals
OSL has OSL::ShaderGlobals, which contains all the state for OSL shader
execution. The renderer fills it out and hands a pointer to OSL, and any
callbacks (e.g. for querying attributes) get the pointer back.
In order to store renderer-specific data in it, there's a few opaque pointers
in the struct, but using those has led to a mess of reinterpret_cast<> and
pointer indirection in order to carry all the data around.
However, there is a way to do this nicer: Good old C-style struct inheritance.
In short: Unless you're doing pointer arithmetic, you can just add additional
data at the end of a base struct, and the rest of the code won't care.
In this case, this means that we can have our own ShaderGlobals struct and
add more Cycles-specific data at the end. Additionally, we can replace the
generic opaque void pointers with ones of the correct type, which saves us
from needing to cast them back.
Since we have a copy of ShaderGlobals for GPU OSL anyways, it's just a matter
of refactoring the code a bit to make use of that.
The advantages of this are:
- Avoids casts all over the place, just needs one cast to turn our
ShaderGlobals into the "base" type that OSL expects and one to turn the
pointer that OSL gives us on callbacks back into our "derived" type.
- Removes indirection, all the relevant stuff (sd, kg, state) is now
directly in the ShaderGlobals
- Removes some OSL-specific state from ShaderData, which helps to keep
memory usage down
Pull Request: https://projects.blender.org/blender/blender/pulls/133689
2025-01-28 03:39:00 +01:00
|
|
|
ShaderGlobals *globals = reinterpret_cast<ShaderGlobals *>(sg);
|
|
|
|
|
|
|
|
|
|
if (globals == nullptr || globals->sd == nullptr) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2012-10-16 10:59:35 +00:00
|
|
|
/* this is only used for shader and object space, we don't really have
|
|
|
|
|
* a concept of shader space, so we just use object space for both. */
|
Cycles: Refactor: Store Cycles-specific pointers in our own ShaderGlobals
OSL has OSL::ShaderGlobals, which contains all the state for OSL shader
execution. The renderer fills it out and hands a pointer to OSL, and any
callbacks (e.g. for querying attributes) get the pointer back.
In order to store renderer-specific data in it, there's a few opaque pointers
in the struct, but using those has led to a mess of reinterpret_cast<> and
pointer indirection in order to carry all the data around.
However, there is a way to do this nicer: Good old C-style struct inheritance.
In short: Unless you're doing pointer arithmetic, you can just add additional
data at the end of a base struct, and the rest of the code won't care.
In this case, this means that we can have our own ShaderGlobals struct and
add more Cycles-specific data at the end. Additionally, we can replace the
generic opaque void pointers with ones of the correct type, which saves us
from needing to cast them back.
Since we have a copy of ShaderGlobals for GPU OSL anyways, it's just a matter
of refactoring the code a bit to make use of that.
The advantages of this are:
- Avoids casts all over the place, just needs one cast to turn our
ShaderGlobals into the "base" type that OSL expects and one to turn the
pointer that OSL gives us on callbacks back into our "derived" type.
- Removes indirection, all the relevant stuff (sd, kg, state) is now
directly in the ShaderGlobals
- Removes some OSL-specific state from ShaderData, which helps to keep
memory usage down
Pull Request: https://projects.blender.org/blender/blender/pulls/133689
2025-01-28 03:39:00 +01:00
|
|
|
const ShaderData *sd = globals->sd;
|
|
|
|
|
const ThreadKernelGlobalsCPU *kg = globals->kg;
|
|
|
|
|
const int object = sd->object;
|
2012-10-16 10:59:35 +00:00
|
|
|
|
Cycles: Refactor: Store Cycles-specific pointers in our own ShaderGlobals
OSL has OSL::ShaderGlobals, which contains all the state for OSL shader
execution. The renderer fills it out and hands a pointer to OSL, and any
callbacks (e.g. for querying attributes) get the pointer back.
In order to store renderer-specific data in it, there's a few opaque pointers
in the struct, but using those has led to a mess of reinterpret_cast<> and
pointer indirection in order to carry all the data around.
However, there is a way to do this nicer: Good old C-style struct inheritance.
In short: Unless you're doing pointer arithmetic, you can just add additional
data at the end of a base struct, and the rest of the code won't care.
In this case, this means that we can have our own ShaderGlobals struct and
add more Cycles-specific data at the end. Additionally, we can replace the
generic opaque void pointers with ones of the correct type, which saves us
from needing to cast them back.
Since we have a copy of ShaderGlobals for GPU OSL anyways, it's just a matter
of refactoring the code a bit to make use of that.
The advantages of this are:
- Avoids casts all over the place, just needs one cast to turn our
ShaderGlobals into the "base" type that OSL expects and one to turn the
pointer that OSL gives us on callbacks back into our "derived" type.
- Removes indirection, all the relevant stuff (sd, kg, state) is now
directly in the ShaderGlobals
- Removes some OSL-specific state from ShaderData, which helps to keep
memory usage down
Pull Request: https://projects.blender.org/blender/blender/pulls/133689
2025-01-28 03:39:00 +01:00
|
|
|
if (object != OBJECT_NONE) {
|
|
|
|
|
const Transform tfm = object_get_transform(kg, sd);
|
|
|
|
|
copy_matrix(result, tfm);
|
2012-10-16 10:59:35 +00:00
|
|
|
|
Cycles: Refactor: Store Cycles-specific pointers in our own ShaderGlobals
OSL has OSL::ShaderGlobals, which contains all the state for OSL shader
execution. The renderer fills it out and hands a pointer to OSL, and any
callbacks (e.g. for querying attributes) get the pointer back.
In order to store renderer-specific data in it, there's a few opaque pointers
in the struct, but using those has led to a mess of reinterpret_cast<> and
pointer indirection in order to carry all the data around.
However, there is a way to do this nicer: Good old C-style struct inheritance.
In short: Unless you're doing pointer arithmetic, you can just add additional
data at the end of a base struct, and the rest of the code won't care.
In this case, this means that we can have our own ShaderGlobals struct and
add more Cycles-specific data at the end. Additionally, we can replace the
generic opaque void pointers with ones of the correct type, which saves us
from needing to cast them back.
Since we have a copy of ShaderGlobals for GPU OSL anyways, it's just a matter
of refactoring the code a bit to make use of that.
The advantages of this are:
- Avoids casts all over the place, just needs one cast to turn our
ShaderGlobals into the "base" type that OSL expects and one to turn the
pointer that OSL gives us on callbacks back into our "derived" type.
- Removes indirection, all the relevant stuff (sd, kg, state) is now
directly in the ShaderGlobals
- Removes some OSL-specific state from ShaderData, which helps to keep
memory usage down
Pull Request: https://projects.blender.org/blender/blender/pulls/133689
2025-01-28 03:39:00 +01:00
|
|
|
return true;
|
|
|
|
|
}
|
2012-10-16 10:59:35 +00:00
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2014-07-24 23:07:49 +02:00
|
|
|
bool OSLRenderServices::get_inverse_matrix(OSL::ShaderGlobals *sg,
|
|
|
|
|
OSL::Matrix44 &result,
|
|
|
|
|
OSL::TransformationPtr xform)
|
2012-10-16 10:59:35 +00:00
|
|
|
{
|
Cycles: Refactor: Store Cycles-specific pointers in our own ShaderGlobals
OSL has OSL::ShaderGlobals, which contains all the state for OSL shader
execution. The renderer fills it out and hands a pointer to OSL, and any
callbacks (e.g. for querying attributes) get the pointer back.
In order to store renderer-specific data in it, there's a few opaque pointers
in the struct, but using those has led to a mess of reinterpret_cast<> and
pointer indirection in order to carry all the data around.
However, there is a way to do this nicer: Good old C-style struct inheritance.
In short: Unless you're doing pointer arithmetic, you can just add additional
data at the end of a base struct, and the rest of the code won't care.
In this case, this means that we can have our own ShaderGlobals struct and
add more Cycles-specific data at the end. Additionally, we can replace the
generic opaque void pointers with ones of the correct type, which saves us
from needing to cast them back.
Since we have a copy of ShaderGlobals for GPU OSL anyways, it's just a matter
of refactoring the code a bit to make use of that.
The advantages of this are:
- Avoids casts all over the place, just needs one cast to turn our
ShaderGlobals into the "base" type that OSL expects and one to turn the
pointer that OSL gives us on callbacks back into our "derived" type.
- Removes indirection, all the relevant stuff (sd, kg, state) is now
directly in the ShaderGlobals
- Removes some OSL-specific state from ShaderData, which helps to keep
memory usage down
Pull Request: https://projects.blender.org/blender/blender/pulls/133689
2025-01-28 03:39:00 +01:00
|
|
|
ShaderGlobals *globals = reinterpret_cast<ShaderGlobals *>(sg);
|
|
|
|
|
|
|
|
|
|
if (globals == nullptr || globals->sd == nullptr) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2012-10-16 10:59:35 +00:00
|
|
|
/* this is only used for shader and object space, we don't really have
|
|
|
|
|
* a concept of shader space, so we just use object space for both. */
|
Cycles: Refactor: Store Cycles-specific pointers in our own ShaderGlobals
OSL has OSL::ShaderGlobals, which contains all the state for OSL shader
execution. The renderer fills it out and hands a pointer to OSL, and any
callbacks (e.g. for querying attributes) get the pointer back.
In order to store renderer-specific data in it, there's a few opaque pointers
in the struct, but using those has led to a mess of reinterpret_cast<> and
pointer indirection in order to carry all the data around.
However, there is a way to do this nicer: Good old C-style struct inheritance.
In short: Unless you're doing pointer arithmetic, you can just add additional
data at the end of a base struct, and the rest of the code won't care.
In this case, this means that we can have our own ShaderGlobals struct and
add more Cycles-specific data at the end. Additionally, we can replace the
generic opaque void pointers with ones of the correct type, which saves us
from needing to cast them back.
Since we have a copy of ShaderGlobals for GPU OSL anyways, it's just a matter
of refactoring the code a bit to make use of that.
The advantages of this are:
- Avoids casts all over the place, just needs one cast to turn our
ShaderGlobals into the "base" type that OSL expects and one to turn the
pointer that OSL gives us on callbacks back into our "derived" type.
- Removes indirection, all the relevant stuff (sd, kg, state) is now
directly in the ShaderGlobals
- Removes some OSL-specific state from ShaderData, which helps to keep
memory usage down
Pull Request: https://projects.blender.org/blender/blender/pulls/133689
2025-01-28 03:39:00 +01:00
|
|
|
const ShaderData *sd = globals->sd;
|
|
|
|
|
const ThreadKernelGlobalsCPU *kg = globals->kg;
|
|
|
|
|
const int object = sd->object;
|
2012-10-16 10:59:35 +00:00
|
|
|
|
Cycles: Refactor: Store Cycles-specific pointers in our own ShaderGlobals
OSL has OSL::ShaderGlobals, which contains all the state for OSL shader
execution. The renderer fills it out and hands a pointer to OSL, and any
callbacks (e.g. for querying attributes) get the pointer back.
In order to store renderer-specific data in it, there's a few opaque pointers
in the struct, but using those has led to a mess of reinterpret_cast<> and
pointer indirection in order to carry all the data around.
However, there is a way to do this nicer: Good old C-style struct inheritance.
In short: Unless you're doing pointer arithmetic, you can just add additional
data at the end of a base struct, and the rest of the code won't care.
In this case, this means that we can have our own ShaderGlobals struct and
add more Cycles-specific data at the end. Additionally, we can replace the
generic opaque void pointers with ones of the correct type, which saves us
from needing to cast them back.
Since we have a copy of ShaderGlobals for GPU OSL anyways, it's just a matter
of refactoring the code a bit to make use of that.
The advantages of this are:
- Avoids casts all over the place, just needs one cast to turn our
ShaderGlobals into the "base" type that OSL expects and one to turn the
pointer that OSL gives us on callbacks back into our "derived" type.
- Removes indirection, all the relevant stuff (sd, kg, state) is now
directly in the ShaderGlobals
- Removes some OSL-specific state from ShaderData, which helps to keep
memory usage down
Pull Request: https://projects.blender.org/blender/blender/pulls/133689
2025-01-28 03:39:00 +01:00
|
|
|
if (object != OBJECT_NONE) {
|
|
|
|
|
const Transform tfm = object_get_inverse_transform(kg, sd);
|
|
|
|
|
copy_matrix(result, tfm);
|
2012-10-16 10:59:35 +00:00
|
|
|
|
Cycles: Refactor: Store Cycles-specific pointers in our own ShaderGlobals
OSL has OSL::ShaderGlobals, which contains all the state for OSL shader
execution. The renderer fills it out and hands a pointer to OSL, and any
callbacks (e.g. for querying attributes) get the pointer back.
In order to store renderer-specific data in it, there's a few opaque pointers
in the struct, but using those has led to a mess of reinterpret_cast<> and
pointer indirection in order to carry all the data around.
However, there is a way to do this nicer: Good old C-style struct inheritance.
In short: Unless you're doing pointer arithmetic, you can just add additional
data at the end of a base struct, and the rest of the code won't care.
In this case, this means that we can have our own ShaderGlobals struct and
add more Cycles-specific data at the end. Additionally, we can replace the
generic opaque void pointers with ones of the correct type, which saves us
from needing to cast them back.
Since we have a copy of ShaderGlobals for GPU OSL anyways, it's just a matter
of refactoring the code a bit to make use of that.
The advantages of this are:
- Avoids casts all over the place, just needs one cast to turn our
ShaderGlobals into the "base" type that OSL expects and one to turn the
pointer that OSL gives us on callbacks back into our "derived" type.
- Removes indirection, all the relevant stuff (sd, kg, state) is now
directly in the ShaderGlobals
- Removes some OSL-specific state from ShaderData, which helps to keep
memory usage down
Pull Request: https://projects.blender.org/blender/blender/pulls/133689
2025-01-28 03:39:00 +01:00
|
|
|
return true;
|
|
|
|
|
}
|
2012-10-16 10:59:35 +00:00
|
|
|
|
|
|
|
|
return false;
|
2012-09-02 01:10:31 +00:00
|
|
|
}
|
|
|
|
|
|
2023-08-10 20:01:09 +02:00
|
|
|
bool OSLRenderServices::get_matrix(OSL::ShaderGlobals *sg,
|
|
|
|
|
OSL::Matrix44 &result,
|
|
|
|
|
OSLUStringHash from)
|
2012-09-02 01:10:31 +00:00
|
|
|
{
|
Cycles: Refactor: Store Cycles-specific pointers in our own ShaderGlobals
OSL has OSL::ShaderGlobals, which contains all the state for OSL shader
execution. The renderer fills it out and hands a pointer to OSL, and any
callbacks (e.g. for querying attributes) get the pointer back.
In order to store renderer-specific data in it, there's a few opaque pointers
in the struct, but using those has led to a mess of reinterpret_cast<> and
pointer indirection in order to carry all the data around.
However, there is a way to do this nicer: Good old C-style struct inheritance.
In short: Unless you're doing pointer arithmetic, you can just add additional
data at the end of a base struct, and the rest of the code won't care.
In this case, this means that we can have our own ShaderGlobals struct and
add more Cycles-specific data at the end. Additionally, we can replace the
generic opaque void pointers with ones of the correct type, which saves us
from needing to cast them back.
Since we have a copy of ShaderGlobals for GPU OSL anyways, it's just a matter
of refactoring the code a bit to make use of that.
The advantages of this are:
- Avoids casts all over the place, just needs one cast to turn our
ShaderGlobals into the "base" type that OSL expects and one to turn the
pointer that OSL gives us on callbacks back into our "derived" type.
- Removes indirection, all the relevant stuff (sd, kg, state) is now
directly in the ShaderGlobals
- Removes some OSL-specific state from ShaderData, which helps to keep
memory usage down
Pull Request: https://projects.blender.org/blender/blender/pulls/133689
2025-01-28 03:39:00 +01:00
|
|
|
ShaderGlobals *globals = reinterpret_cast<ShaderGlobals *>(sg);
|
|
|
|
|
const ThreadKernelGlobalsCPU *kg = globals->kg;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2015-03-28 00:15:15 +05:00
|
|
|
if (from == u_ndc) {
|
2018-03-08 05:33:55 +01:00
|
|
|
copy_matrix(result, kernel_data.cam.ndctoworld);
|
2012-10-16 10:59:35 +00:00
|
|
|
return true;
|
|
|
|
|
}
|
2024-12-26 17:53:59 +01:00
|
|
|
if (from == u_raster) {
|
2018-03-08 05:33:55 +01:00
|
|
|
copy_matrix(result, kernel_data.cam.rastertoworld);
|
2012-10-16 10:59:35 +00:00
|
|
|
return true;
|
|
|
|
|
}
|
2024-12-26 17:53:59 +01:00
|
|
|
if (from == u_screen) {
|
2018-03-08 05:33:55 +01:00
|
|
|
copy_matrix(result, kernel_data.cam.screentoworld);
|
2012-10-16 10:59:35 +00:00
|
|
|
return true;
|
|
|
|
|
}
|
2024-12-26 17:53:59 +01:00
|
|
|
if (from == u_camera) {
|
2018-03-08 05:33:55 +01:00
|
|
|
copy_matrix(result, kernel_data.cam.cameratoworld);
|
2012-10-16 10:59:35 +00:00
|
|
|
return true;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-10-16 10:59:35 +00:00
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2014-07-24 23:07:49 +02:00
|
|
|
bool OSLRenderServices::get_inverse_matrix(OSL::ShaderGlobals *sg,
|
|
|
|
|
OSL::Matrix44 &result,
|
2023-08-10 20:01:09 +02:00
|
|
|
OSLUStringHash to)
|
2012-10-16 10:59:35 +00:00
|
|
|
{
|
Cycles: Refactor: Store Cycles-specific pointers in our own ShaderGlobals
OSL has OSL::ShaderGlobals, which contains all the state for OSL shader
execution. The renderer fills it out and hands a pointer to OSL, and any
callbacks (e.g. for querying attributes) get the pointer back.
In order to store renderer-specific data in it, there's a few opaque pointers
in the struct, but using those has led to a mess of reinterpret_cast<> and
pointer indirection in order to carry all the data around.
However, there is a way to do this nicer: Good old C-style struct inheritance.
In short: Unless you're doing pointer arithmetic, you can just add additional
data at the end of a base struct, and the rest of the code won't care.
In this case, this means that we can have our own ShaderGlobals struct and
add more Cycles-specific data at the end. Additionally, we can replace the
generic opaque void pointers with ones of the correct type, which saves us
from needing to cast them back.
Since we have a copy of ShaderGlobals for GPU OSL anyways, it's just a matter
of refactoring the code a bit to make use of that.
The advantages of this are:
- Avoids casts all over the place, just needs one cast to turn our
ShaderGlobals into the "base" type that OSL expects and one to turn the
pointer that OSL gives us on callbacks back into our "derived" type.
- Removes indirection, all the relevant stuff (sd, kg, state) is now
directly in the ShaderGlobals
- Removes some OSL-specific state from ShaderData, which helps to keep
memory usage down
Pull Request: https://projects.blender.org/blender/blender/pulls/133689
2025-01-28 03:39:00 +01:00
|
|
|
ShaderGlobals *globals = reinterpret_cast<ShaderGlobals *>(sg);
|
|
|
|
|
const ThreadKernelGlobalsCPU *kg = globals->kg;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2015-03-28 00:15:15 +05:00
|
|
|
if (to == u_ndc) {
|
2018-03-08 05:33:55 +01:00
|
|
|
copy_matrix(result, kernel_data.cam.worldtondc);
|
2012-10-16 10:59:35 +00:00
|
|
|
return true;
|
|
|
|
|
}
|
2024-12-26 17:53:59 +01:00
|
|
|
if (to == u_raster) {
|
2018-03-08 05:33:55 +01:00
|
|
|
copy_matrix(result, kernel_data.cam.worldtoraster);
|
2012-10-16 10:59:35 +00:00
|
|
|
return true;
|
|
|
|
|
}
|
2024-12-26 17:53:59 +01:00
|
|
|
if (to == u_screen) {
|
2018-03-08 05:33:55 +01:00
|
|
|
copy_matrix(result, kernel_data.cam.worldtoscreen);
|
2012-10-16 10:59:35 +00:00
|
|
|
return true;
|
|
|
|
|
}
|
2024-12-26 17:53:59 +01:00
|
|
|
if (to == u_camera) {
|
2018-03-08 05:33:55 +01:00
|
|
|
copy_matrix(result, kernel_data.cam.worldtocamera);
|
2012-10-16 10:59:35 +00:00
|
|
|
return true;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-10-16 10:59:35 +00:00
|
|
|
return false;
|
2012-09-02 01:10:31 +00:00
|
|
|
}
|
|
|
|
|
|
2018-07-06 10:17:58 +02:00
|
|
|
bool OSLRenderServices::get_array_attribute(OSL::ShaderGlobals *sg,
|
|
|
|
|
bool derivatives,
|
2023-08-10 20:01:09 +02:00
|
|
|
OSLUStringHash object,
|
2025-01-01 18:15:54 +01:00
|
|
|
const TypeDesc type,
|
2023-08-10 20:01:09 +02:00
|
|
|
OSLUStringHash name,
|
2025-01-01 18:15:54 +01:00
|
|
|
const int index,
|
2012-06-04 22:44:58 +00:00
|
|
|
void *val)
|
2011-04-27 11:58:34 +00:00
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2025-02-20 19:28:45 +01:00
|
|
|
template<typename T>
|
|
|
|
|
inline bool set_attribute(
|
|
|
|
|
const T v, const T dx, const T dy, TypeDesc type, bool derivatives, void *val);
|
2020-10-26 18:23:40 +01:00
|
|
|
|
2025-02-20 19:28:45 +01:00
|
|
|
inline void set_data_float(
|
|
|
|
|
const float v, const float dx, const float dy, bool derivatives, void *val)
|
|
|
|
|
{
|
|
|
|
|
float *fval = static_cast<float *>(val);
|
|
|
|
|
fval[0] = v;
|
|
|
|
|
if (derivatives) {
|
|
|
|
|
fval[1] = dx;
|
|
|
|
|
fval[2] = dy;
|
2020-10-26 18:23:40 +01:00
|
|
|
}
|
2025-02-20 19:28:45 +01:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2025-02-20 19:28:45 +01:00
|
|
|
inline void set_data_float3(
|
|
|
|
|
const float3 v, const float3 dx, const float3 dy, bool derivatives, void *val)
|
|
|
|
|
{
|
|
|
|
|
float *fval = static_cast<float *>(val);
|
|
|
|
|
fval[0] = v.x;
|
|
|
|
|
fval[1] = v.y;
|
|
|
|
|
fval[2] = v.z;
|
|
|
|
|
if (derivatives) {
|
|
|
|
|
fval[3] = dx.x;
|
|
|
|
|
fval[4] = dx.y;
|
|
|
|
|
fval[5] = dx.z;
|
|
|
|
|
fval[6] = dy.x;
|
|
|
|
|
fval[7] = dy.y;
|
|
|
|
|
fval[8] = dy.z;
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2025-02-20 19:28:45 +01:00
|
|
|
inline void set_data_float4(
|
|
|
|
|
const float4 v, const float4 dx, const float4 dy, bool derivatives, void *val)
|
|
|
|
|
{
|
|
|
|
|
float *fval = static_cast<float *>(val);
|
|
|
|
|
fval[0] = v.x;
|
|
|
|
|
fval[1] = v.y;
|
|
|
|
|
fval[2] = v.z;
|
|
|
|
|
fval[3] = v.w;
|
|
|
|
|
if (derivatives) {
|
|
|
|
|
fval[4] = dx.x;
|
|
|
|
|
fval[5] = dx.y;
|
|
|
|
|
fval[6] = dx.z;
|
|
|
|
|
fval[7] = dx.w;
|
|
|
|
|
fval[8] = dy.x;
|
|
|
|
|
fval[9] = dy.y;
|
|
|
|
|
fval[10] = dy.z;
|
|
|
|
|
fval[11] = dy.w;
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2025-02-20 19:28:45 +01:00
|
|
|
ccl_device_template_spec bool set_attribute(
|
|
|
|
|
const float v, const float dx, const float dy, TypeDesc type, bool derivatives, void *val)
|
|
|
|
|
{
|
|
|
|
|
if (type == TypeFloatArray4) {
|
|
|
|
|
set_data_float4(make_float4(v, v, v, 1.0f),
|
|
|
|
|
make_float4(dx, dx, dx, 0.0f),
|
|
|
|
|
make_float4(dy, dy, dy, 0.0f),
|
|
|
|
|
derivatives,
|
|
|
|
|
val);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
if (type == TypePoint || type == TypeVector || type == TypeNormal || type == TypeColor) {
|
|
|
|
|
set_data_float3(make_float3(v), make_float3(dx), make_float3(dy), derivatives, val);
|
2019-03-05 14:54:54 +01:00
|
|
|
return true;
|
|
|
|
|
}
|
2024-12-26 17:53:59 +01:00
|
|
|
if (type == TypeFloat) {
|
2025-02-20 19:28:45 +01:00
|
|
|
set_data_float(v, dx, dy, derivatives, val);
|
2019-03-05 14:54:54 +01:00
|
|
|
return true;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-03-05 14:54:54 +01:00
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2025-02-20 19:28:45 +01:00
|
|
|
ccl_device_template_spec bool set_attribute(
|
|
|
|
|
const float2 v, const float2 dx, const float2 dy, TypeDesc type, bool derivatives, void *val)
|
2011-04-27 11:58:34 +00:00
|
|
|
{
|
2020-10-26 18:23:40 +01:00
|
|
|
if (type == TypeFloatArray4) {
|
2025-02-20 19:28:45 +01:00
|
|
|
set_data_float4(make_float4(v.x, v.y, 0.0f, 1.0f),
|
|
|
|
|
make_float4(dx.x, dx.y, 0.0f, 0.0f),
|
|
|
|
|
make_float4(dy.x, dy.y, 0.0f, 0.0f),
|
|
|
|
|
derivatives,
|
|
|
|
|
val);
|
2020-10-26 18:23:40 +01:00
|
|
|
return true;
|
|
|
|
|
}
|
2024-12-26 17:53:59 +01:00
|
|
|
if (type == TypePoint || type == TypeVector || type == TypeNormal || type == TypeColor) {
|
2025-02-20 19:28:45 +01:00
|
|
|
set_data_float3(make_float3(v), make_float3(dx), make_float3(dy), derivatives, val);
|
Cycles OSL: support for the trace(point pos, vector dir, ...) function, to trace
rays from the OSL shader. The "shade" parameter is not supported currently, but
attributes can be retrieved from the object that was hit using the
getmessage("trace", ..) function.
As mentioned in the OSL specification, this function can't be used instead of
lighting, the main purpose is to allow shaders to "probe" nearby geometry, for
example to apply a projected texture that can be blocked by geometry, apply
more “wear” to exposed geometry, or make other ambient occlusion-like effects.
http://wiki.blender.org/index.php/Doc:2.6/Manual/Render/Cycles/Nodes/OSL#Trace
Example .blend and render:
http://www.pasteall.org/blend/17347
http://www.pasteall.org/pic/show.php?id=40066
2012-11-06 19:59:10 +00:00
|
|
|
return true;
|
2011-04-27 11:58:34 +00:00
|
|
|
}
|
2024-12-26 17:53:59 +01:00
|
|
|
if (type == TypeFloat) {
|
2025-02-20 19:28:45 +01:00
|
|
|
set_data_float(average(v), average(dx), average(dy), derivatives, val);
|
Cycles OSL: support for the trace(point pos, vector dir, ...) function, to trace
rays from the OSL shader. The "shade" parameter is not supported currently, but
attributes can be retrieved from the object that was hit using the
getmessage("trace", ..) function.
As mentioned in the OSL specification, this function can't be used instead of
lighting, the main purpose is to allow shaders to "probe" nearby geometry, for
example to apply a projected texture that can be blocked by geometry, apply
more “wear” to exposed geometry, or make other ambient occlusion-like effects.
http://wiki.blender.org/index.php/Doc:2.6/Manual/Render/Cycles/Nodes/OSL#Trace
Example .blend and render:
http://www.pasteall.org/blend/17347
http://www.pasteall.org/pic/show.php?id=40066
2012-11-06 19:59:10 +00:00
|
|
|
return true;
|
2011-04-27 11:58:34 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
Cycles OSL: support for the trace(point pos, vector dir, ...) function, to trace
rays from the OSL shader. The "shade" parameter is not supported currently, but
attributes can be retrieved from the object that was hit using the
getmessage("trace", ..) function.
As mentioned in the OSL specification, this function can't be used instead of
lighting, the main purpose is to allow shaders to "probe" nearby geometry, for
example to apply a projected texture that can be blocked by geometry, apply
more “wear” to exposed geometry, or make other ambient occlusion-like effects.
http://wiki.blender.org/index.php/Doc:2.6/Manual/Render/Cycles/Nodes/OSL#Trace
Example .blend and render:
http://www.pasteall.org/blend/17347
http://www.pasteall.org/pic/show.php?id=40066
2012-11-06 19:59:10 +00:00
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2025-02-20 19:28:45 +01:00
|
|
|
ccl_device_template_spec bool set_attribute(
|
|
|
|
|
const float3 v, const float3 dx, const float3 dy, TypeDesc type, bool derivatives, void *val)
|
Cycles OSL: support for the trace(point pos, vector dir, ...) function, to trace
rays from the OSL shader. The "shade" parameter is not supported currently, but
attributes can be retrieved from the object that was hit using the
getmessage("trace", ..) function.
As mentioned in the OSL specification, this function can't be used instead of
lighting, the main purpose is to allow shaders to "probe" nearby geometry, for
example to apply a projected texture that can be blocked by geometry, apply
more “wear” to exposed geometry, or make other ambient occlusion-like effects.
http://wiki.blender.org/index.php/Doc:2.6/Manual/Render/Cycles/Nodes/OSL#Trace
Example .blend and render:
http://www.pasteall.org/blend/17347
http://www.pasteall.org/pic/show.php?id=40066
2012-11-06 19:59:10 +00:00
|
|
|
{
|
2019-09-12 17:42:13 +02:00
|
|
|
if (type == TypeFloatArray4) {
|
2025-02-20 19:28:45 +01:00
|
|
|
set_data_float4(
|
|
|
|
|
make_float4(v, 1.0f), make_float4(dx, 0.0f), make_float4(dy, 0.0f), derivatives, val);
|
2019-09-12 17:42:13 +02:00
|
|
|
return true;
|
|
|
|
|
}
|
2024-12-26 17:53:59 +01:00
|
|
|
if (type == TypePoint || type == TypeVector || type == TypeNormal || type == TypeColor) {
|
2025-02-20 19:28:45 +01:00
|
|
|
set_data_float3(v, dx, dy, derivatives, val);
|
2019-09-12 17:42:13 +02:00
|
|
|
return true;
|
|
|
|
|
}
|
2024-12-26 17:53:59 +01:00
|
|
|
if (type == TypeFloat) {
|
2025-02-20 19:28:45 +01:00
|
|
|
set_data_float(average(v), average(dx), average(dy), derivatives, val);
|
2019-09-12 17:42:13 +02:00
|
|
|
return true;
|
|
|
|
|
}
|
2025-02-20 19:28:45 +01:00
|
|
|
|
2019-09-12 17:42:13 +02:00
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2025-02-20 19:28:45 +01:00
|
|
|
/* Attributes with the TypeRGBA type descriptor should be retrieved and stored
|
|
|
|
|
* in a float array of size 4 (e.g. node_vertex_color.osl), this array have
|
|
|
|
|
* a type descriptor TypeFloatArray4. If the storage is not a TypeFloatArray4,
|
|
|
|
|
* we either store the first three components in a vector, store the average of
|
|
|
|
|
* the components in a float, or fail the retrieval and do nothing. We allow
|
|
|
|
|
* this for the correct operation of the Attribute node.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
ccl_device_template_spec bool set_attribute(
|
|
|
|
|
const float4 v, const float4 dx, const float4 dy, TypeDesc type, bool derivatives, void *val)
|
2011-04-27 11:58:34 +00:00
|
|
|
{
|
2020-10-26 18:23:40 +01:00
|
|
|
if (type == TypeFloatArray4) {
|
2025-02-20 19:28:45 +01:00
|
|
|
set_data_float4(v, dx, dy, derivatives, val);
|
2020-10-26 18:23:40 +01:00
|
|
|
return true;
|
|
|
|
|
}
|
2024-12-26 17:53:59 +01:00
|
|
|
if (type == TypePoint || type == TypeVector || type == TypeNormal || type == TypeColor) {
|
2025-02-20 19:28:45 +01:00
|
|
|
set_data_float3(make_float3(v), make_float3(dx), make_float3(dy), derivatives, val);
|
Cycles OSL: support for the trace(point pos, vector dir, ...) function, to trace
rays from the OSL shader. The "shade" parameter is not supported currently, but
attributes can be retrieved from the object that was hit using the
getmessage("trace", ..) function.
As mentioned in the OSL specification, this function can't be used instead of
lighting, the main purpose is to allow shaders to "probe" nearby geometry, for
example to apply a projected texture that can be blocked by geometry, apply
more “wear” to exposed geometry, or make other ambient occlusion-like effects.
http://wiki.blender.org/index.php/Doc:2.6/Manual/Render/Cycles/Nodes/OSL#Trace
Example .blend and render:
http://www.pasteall.org/blend/17347
http://www.pasteall.org/pic/show.php?id=40066
2012-11-06 19:59:10 +00:00
|
|
|
return true;
|
2011-04-27 11:58:34 +00:00
|
|
|
}
|
2024-12-26 17:53:59 +01:00
|
|
|
if (type == TypeFloat) {
|
2025-02-20 19:28:45 +01:00
|
|
|
set_data_float(average(make_float3(v)),
|
|
|
|
|
average(make_float3(dx)),
|
|
|
|
|
average(make_float3(dy)),
|
|
|
|
|
derivatives,
|
|
|
|
|
val);
|
Cycles OSL: support for the trace(point pos, vector dir, ...) function, to trace
rays from the OSL shader. The "shade" parameter is not supported currently, but
attributes can be retrieved from the object that was hit using the
getmessage("trace", ..) function.
As mentioned in the OSL specification, this function can't be used instead of
lighting, the main purpose is to allow shaders to "probe" nearby geometry, for
example to apply a projected texture that can be blocked by geometry, apply
more “wear” to exposed geometry, or make other ambient occlusion-like effects.
http://wiki.blender.org/index.php/Doc:2.6/Manual/Render/Cycles/Nodes/OSL#Trace
Example .blend and render:
http://www.pasteall.org/blend/17347
http://www.pasteall.org/pic/show.php?id=40066
2012-11-06 19:59:10 +00:00
|
|
|
return true;
|
2012-09-14 18:10:54 +00:00
|
|
|
}
|
Cycles OSL: support for the trace(point pos, vector dir, ...) function, to trace
rays from the OSL shader. The "shade" parameter is not supported currently, but
attributes can be retrieved from the object that was hit using the
getmessage("trace", ..) function.
As mentioned in the OSL specification, this function can't be used instead of
lighting, the main purpose is to allow shaders to "probe" nearby geometry, for
example to apply a projected texture that can be blocked by geometry, apply
more “wear” to exposed geometry, or make other ambient occlusion-like effects.
http://wiki.blender.org/index.php/Doc:2.6/Manual/Render/Cycles/Nodes/OSL#Trace
Example .blend and render:
http://www.pasteall.org/blend/17347
http://www.pasteall.org/pic/show.php?id=40066
2012-11-06 19:59:10 +00:00
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2025-02-20 19:28:45 +01:00
|
|
|
template<typename T>
|
|
|
|
|
ccl_device_inline bool set_attribute(const T f, const TypeDesc type, bool derivatives, void *val)
|
Cycles OSL: support for the trace(point pos, vector dir, ...) function, to trace
rays from the OSL shader. The "shade" parameter is not supported currently, but
attributes can be retrieved from the object that was hit using the
getmessage("trace", ..) function.
As mentioned in the OSL specification, this function can't be used instead of
lighting, the main purpose is to allow shaders to "probe" nearby geometry, for
example to apply a projected texture that can be blocked by geometry, apply
more “wear” to exposed geometry, or make other ambient occlusion-like effects.
http://wiki.blender.org/index.php/Doc:2.6/Manual/Render/Cycles/Nodes/OSL#Trace
Example .blend and render:
http://www.pasteall.org/blend/17347
http://www.pasteall.org/pic/show.php?id=40066
2012-11-06 19:59:10 +00:00
|
|
|
{
|
2025-02-20 19:28:45 +01:00
|
|
|
return set_attribute(f, make_zero<T>(), make_zero<T>(), type, derivatives, val);
|
2012-09-14 18:10:54 +00:00
|
|
|
}
|
2011-04-27 11:58:34 +00:00
|
|
|
|
2025-02-20 19:28:45 +01:00
|
|
|
ccl_device_template_spec bool set_attribute(const int i,
|
|
|
|
|
const TypeDesc type,
|
|
|
|
|
bool derivatives,
|
|
|
|
|
void *val)
|
2012-11-03 14:32:13 +00:00
|
|
|
{
|
|
|
|
|
if (type.basetype == TypeDesc::INT && type.aggregate == TypeDesc::SCALAR && type.arraylen == 0) {
|
|
|
|
|
int *ival = (int *)val;
|
|
|
|
|
ival[0] = i;
|
|
|
|
|
|
2015-03-28 00:15:15 +05:00
|
|
|
if (derivatives) {
|
2012-11-03 14:32:13 +00:00
|
|
|
ival[1] = 0;
|
|
|
|
|
ival[2] = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2025-02-20 19:28:45 +01:00
|
|
|
ccl_device_template_spec bool set_attribute(ustring str,
|
|
|
|
|
const TypeDesc type,
|
|
|
|
|
bool derivatives,
|
|
|
|
|
void *val)
|
Cycles OSL: support for the trace(point pos, vector dir, ...) function, to trace
rays from the OSL shader. The "shade" parameter is not supported currently, but
attributes can be retrieved from the object that was hit using the
getmessage("trace", ..) function.
As mentioned in the OSL specification, this function can't be used instead of
lighting, the main purpose is to allow shaders to "probe" nearby geometry, for
example to apply a projected texture that can be blocked by geometry, apply
more “wear” to exposed geometry, or make other ambient occlusion-like effects.
http://wiki.blender.org/index.php/Doc:2.6/Manual/Render/Cycles/Nodes/OSL#Trace
Example .blend and render:
http://www.pasteall.org/blend/17347
http://www.pasteall.org/pic/show.php?id=40066
2012-11-06 19:59:10 +00:00
|
|
|
{
|
2014-08-05 17:53:00 +06:00
|
|
|
if (type.basetype == TypeDesc::STRING && type.aggregate == TypeDesc::SCALAR &&
|
2024-01-02 18:12:54 +01:00
|
|
|
type.arraylen == 0)
|
|
|
|
|
{
|
Cycles OSL: support for the trace(point pos, vector dir, ...) function, to trace
rays from the OSL shader. The "shade" parameter is not supported currently, but
attributes can be retrieved from the object that was hit using the
getmessage("trace", ..) function.
As mentioned in the OSL specification, this function can't be used instead of
lighting, the main purpose is to allow shaders to "probe" nearby geometry, for
example to apply a projected texture that can be blocked by geometry, apply
more “wear” to exposed geometry, or make other ambient occlusion-like effects.
http://wiki.blender.org/index.php/Doc:2.6/Manual/Render/Cycles/Nodes/OSL#Trace
Example .blend and render:
http://www.pasteall.org/blend/17347
http://www.pasteall.org/pic/show.php?id=40066
2012-11-06 19:59:10 +00:00
|
|
|
ustring *sval = (ustring *)val;
|
|
|
|
|
sval[0] = str;
|
|
|
|
|
|
2015-03-28 00:15:15 +05:00
|
|
|
if (derivatives) {
|
Cycles OSL: support for the trace(point pos, vector dir, ...) function, to trace
rays from the OSL shader. The "shade" parameter is not supported currently, but
attributes can be retrieved from the object that was hit using the
getmessage("trace", ..) function.
As mentioned in the OSL specification, this function can't be used instead of
lighting, the main purpose is to allow shaders to "probe" nearby geometry, for
example to apply a projected texture that can be blocked by geometry, apply
more “wear” to exposed geometry, or make other ambient occlusion-like effects.
http://wiki.blender.org/index.php/Doc:2.6/Manual/Render/Cycles/Nodes/OSL#Trace
Example .blend and render:
http://www.pasteall.org/blend/17347
http://www.pasteall.org/pic/show.php?id=40066
2012-11-06 19:59:10 +00:00
|
|
|
sval[1] = OSLRenderServices::u_empty;
|
|
|
|
|
sval[2] = OSLRenderServices::u_empty;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2025-01-01 18:15:54 +01:00
|
|
|
static bool set_attribute_float3_3(const float3 P[3], TypeDesc type, bool derivatives, void *val)
|
2012-11-03 14:32:13 +00:00
|
|
|
{
|
|
|
|
|
if (type.vecsemantics == TypeDesc::POINT && type.arraylen >= 3) {
|
|
|
|
|
float *fval = (float *)val;
|
|
|
|
|
|
|
|
|
|
fval[0] = P[0].x;
|
|
|
|
|
fval[1] = P[0].y;
|
|
|
|
|
fval[2] = P[0].z;
|
|
|
|
|
|
|
|
|
|
fval[3] = P[1].x;
|
|
|
|
|
fval[4] = P[1].y;
|
|
|
|
|
fval[5] = P[1].z;
|
|
|
|
|
|
|
|
|
|
fval[6] = P[2].x;
|
|
|
|
|
fval[7] = P[2].y;
|
|
|
|
|
fval[8] = P[2].z;
|
|
|
|
|
|
2023-09-17 09:01:48 +10:00
|
|
|
if (type.arraylen > 3) {
|
2012-11-03 14:32:13 +00:00
|
|
|
memset(fval + 3 * 3, 0, sizeof(float) * 3 * (type.arraylen - 3));
|
2023-09-17 09:01:48 +10:00
|
|
|
}
|
|
|
|
|
if (derivatives) {
|
2012-11-03 14:32:13 +00:00
|
|
|
memset(fval + type.arraylen * 3, 0, sizeof(float) * 2 * 3 * type.arraylen);
|
2023-09-17 09:01:48 +10:00
|
|
|
}
|
2012-11-03 14:32:13 +00:00
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2025-01-01 18:15:54 +01:00
|
|
|
static bool set_attribute_matrix(const Transform &tfm, const TypeDesc type, void *val)
|
2013-12-31 17:33:55 +01:00
|
|
|
{
|
2024-10-17 19:48:38 +02:00
|
|
|
if (type == TypeMatrix) {
|
2018-03-08 06:48:14 +01:00
|
|
|
copy_matrix(*(OSL::Matrix44 *)val, tfm);
|
2013-12-31 17:33:55 +01:00
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2025-02-20 19:28:45 +01:00
|
|
|
template<typename T>
|
|
|
|
|
inline bool get_object_attribute_impl(const ThreadKernelGlobalsCPU *kg,
|
|
|
|
|
ShaderData *sd,
|
|
|
|
|
const AttributeDescriptor &desc,
|
|
|
|
|
const TypeDesc &type,
|
|
|
|
|
bool derivatives,
|
|
|
|
|
void *val)
|
|
|
|
|
{
|
|
|
|
|
T v;
|
|
|
|
|
T dx = make_zero<T>();
|
|
|
|
|
T dy = make_zero<T>();
|
|
|
|
|
#ifdef __VOLUME__
|
|
|
|
|
if (primitive_is_volume_attribute(sd, desc)) {
|
|
|
|
|
v = primitive_volume_attribute<T>(kg, sd, desc);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
#endif
|
|
|
|
|
{
|
|
|
|
|
v = primitive_surface_attribute<T>(
|
|
|
|
|
kg, sd, desc, derivatives ? &dx : nullptr, derivatives ? &dy : nullptr);
|
|
|
|
|
}
|
|
|
|
|
return set_attribute(v, dx, dy, type, derivatives, val);
|
|
|
|
|
}
|
|
|
|
|
|
2024-12-29 23:13:45 +01:00
|
|
|
static bool get_object_attribute(const ThreadKernelGlobalsCPU *kg,
|
2022-09-09 11:55:35 +02:00
|
|
|
ShaderData *sd,
|
|
|
|
|
const AttributeDescriptor &desc,
|
|
|
|
|
const TypeDesc &type,
|
|
|
|
|
bool derivatives,
|
|
|
|
|
void *val)
|
2012-09-14 18:10:54 +00:00
|
|
|
{
|
2025-02-20 19:28:45 +01:00
|
|
|
if (desc.type == NODE_ATTR_FLOAT) {
|
|
|
|
|
return get_object_attribute_impl<float>(kg, sd, desc, type, derivatives, val);
|
2011-04-27 11:58:34 +00:00
|
|
|
}
|
2025-02-20 19:28:45 +01:00
|
|
|
else if (desc.type == NODE_ATTR_FLOAT2) {
|
|
|
|
|
return get_object_attribute_impl<float2>(kg, sd, desc, type, derivatives, val);
|
2019-03-05 14:54:54 +01:00
|
|
|
}
|
2025-02-20 19:28:45 +01:00
|
|
|
else if (desc.type == NODE_ATTR_FLOAT3) {
|
|
|
|
|
return get_object_attribute_impl<float3>(kg, sd, desc, type, derivatives, val);
|
2012-11-04 22:31:32 +00:00
|
|
|
}
|
2025-02-20 19:28:45 +01:00
|
|
|
else if (desc.type == NODE_ATTR_FLOAT4 || desc.type == NODE_ATTR_RGBA) {
|
|
|
|
|
return get_object_attribute_impl<float4>(kg, sd, desc, type, derivatives, val);
|
2019-09-12 17:42:13 +02:00
|
|
|
}
|
2025-02-20 19:28:45 +01:00
|
|
|
else if (desc.type == NODE_ATTR_MATRIX) {
|
2024-12-29 17:32:00 +01:00
|
|
|
const Transform tfm = primitive_attribute_matrix(kg, desc);
|
2013-12-31 17:33:55 +01:00
|
|
|
return set_attribute_matrix(tfm, type, val);
|
|
|
|
|
}
|
2024-12-26 17:53:59 +01:00
|
|
|
return false;
|
2013-12-31 17:33:55 +01:00
|
|
|
}
|
|
|
|
|
|
Cycles: Refactor: Store Cycles-specific pointers in our own ShaderGlobals
OSL has OSL::ShaderGlobals, which contains all the state for OSL shader
execution. The renderer fills it out and hands a pointer to OSL, and any
callbacks (e.g. for querying attributes) get the pointer back.
In order to store renderer-specific data in it, there's a few opaque pointers
in the struct, but using those has led to a mess of reinterpret_cast<> and
pointer indirection in order to carry all the data around.
However, there is a way to do this nicer: Good old C-style struct inheritance.
In short: Unless you're doing pointer arithmetic, you can just add additional
data at the end of a base struct, and the rest of the code won't care.
In this case, this means that we can have our own ShaderGlobals struct and
add more Cycles-specific data at the end. Additionally, we can replace the
generic opaque void pointers with ones of the correct type, which saves us
from needing to cast them back.
Since we have a copy of ShaderGlobals for GPU OSL anyways, it's just a matter
of refactoring the code a bit to make use of that.
The advantages of this are:
- Avoids casts all over the place, just needs one cast to turn our
ShaderGlobals into the "base" type that OSL expects and one to turn the
pointer that OSL gives us on callbacks back into our "derived" type.
- Removes indirection, all the relevant stuff (sd, kg, state) is now
directly in the ShaderGlobals
- Removes some OSL-specific state from ShaderData, which helps to keep
memory usage down
Pull Request: https://projects.blender.org/blender/blender/pulls/133689
2025-01-28 03:39:00 +01:00
|
|
|
bool OSLRenderServices::get_object_standard_attribute(
|
|
|
|
|
ShaderGlobals *globals, OSLUStringHash name, const TypeDesc type, bool derivatives, void *val)
|
2012-09-14 18:10:54 +00:00
|
|
|
{
|
Cycles: Refactor: Store Cycles-specific pointers in our own ShaderGlobals
OSL has OSL::ShaderGlobals, which contains all the state for OSL shader
execution. The renderer fills it out and hands a pointer to OSL, and any
callbacks (e.g. for querying attributes) get the pointer back.
In order to store renderer-specific data in it, there's a few opaque pointers
in the struct, but using those has led to a mess of reinterpret_cast<> and
pointer indirection in order to carry all the data around.
However, there is a way to do this nicer: Good old C-style struct inheritance.
In short: Unless you're doing pointer arithmetic, you can just add additional
data at the end of a base struct, and the rest of the code won't care.
In this case, this means that we can have our own ShaderGlobals struct and
add more Cycles-specific data at the end. Additionally, we can replace the
generic opaque void pointers with ones of the correct type, which saves us
from needing to cast them back.
Since we have a copy of ShaderGlobals for GPU OSL anyways, it's just a matter
of refactoring the code a bit to make use of that.
The advantages of this are:
- Avoids casts all over the place, just needs one cast to turn our
ShaderGlobals into the "base" type that OSL expects and one to turn the
pointer that OSL gives us on callbacks back into our "derived" type.
- Removes indirection, all the relevant stuff (sd, kg, state) is now
directly in the ShaderGlobals
- Removes some OSL-specific state from ShaderData, which helps to keep
memory usage down
Pull Request: https://projects.blender.org/blender/blender/pulls/133689
2025-01-28 03:39:00 +01:00
|
|
|
ShaderData *sd = globals->sd;
|
|
|
|
|
const ThreadKernelGlobalsCPU *kg = globals->kg;
|
2012-12-01 19:15:05 +00:00
|
|
|
/* todo: turn this into hash table? */
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-09-14 19:09:25 +00:00
|
|
|
/* Object Attributes */
|
2015-03-28 00:15:15 +05:00
|
|
|
if (name == u_object_location) {
|
2024-12-29 17:32:00 +01:00
|
|
|
const float3 f = object_location(kg, sd);
|
2025-02-20 19:28:45 +01:00
|
|
|
return set_attribute(f, type, derivatives, val);
|
2012-09-14 18:10:54 +00:00
|
|
|
}
|
2024-12-26 17:53:59 +01:00
|
|
|
if (name == u_object_color) {
|
2024-12-29 17:32:00 +01:00
|
|
|
const float3 f = object_color(kg, sd->object);
|
2025-02-20 19:28:45 +01:00
|
|
|
return set_attribute(f, type, derivatives, val);
|
2019-08-22 14:26:09 +02:00
|
|
|
}
|
2024-12-26 17:53:59 +01:00
|
|
|
if (name == u_object_alpha) {
|
2024-12-29 17:32:00 +01:00
|
|
|
const float f = object_alpha(kg, sd->object);
|
2025-02-20 19:28:45 +01:00
|
|
|
return set_attribute(f, type, derivatives, val);
|
2022-03-07 17:34:52 +01:00
|
|
|
}
|
2024-12-26 17:53:59 +01:00
|
|
|
if (name == u_object_index) {
|
2024-12-29 17:32:00 +01:00
|
|
|
const float f = object_pass_id(kg, sd->object);
|
2025-02-20 19:28:45 +01:00
|
|
|
return set_attribute(f, type, derivatives, val);
|
2012-09-14 18:10:54 +00:00
|
|
|
}
|
2024-12-26 17:53:59 +01:00
|
|
|
if (name == u_object_is_light) {
|
2024-12-29 17:32:00 +01:00
|
|
|
const float f = (sd->type & PRIMITIVE_LAMP) != 0;
|
2025-02-20 19:28:45 +01:00
|
|
|
return set_attribute(f, type, derivatives, val);
|
2024-07-24 12:16:44 +02:00
|
|
|
}
|
2024-12-26 17:53:59 +01:00
|
|
|
if (name == u_geom_dupli_generated) {
|
2024-12-29 17:32:00 +01:00
|
|
|
const float3 f = object_dupli_generated(kg, sd->object);
|
2025-02-20 19:28:45 +01:00
|
|
|
return set_attribute(f, type, derivatives, val);
|
2012-10-20 15:09:36 +00:00
|
|
|
}
|
2024-12-26 17:53:59 +01:00
|
|
|
if (name == u_geom_dupli_uv) {
|
2024-12-29 17:32:00 +01:00
|
|
|
const float3 f = object_dupli_uv(kg, sd->object);
|
2025-02-20 19:28:45 +01:00
|
|
|
return set_attribute(f, type, derivatives, val);
|
2012-10-20 15:09:36 +00:00
|
|
|
}
|
2024-12-26 17:53:59 +01:00
|
|
|
if (name == u_material_index) {
|
2024-12-29 17:32:00 +01:00
|
|
|
const float f = shader_pass_id(kg, sd);
|
2025-02-20 19:28:45 +01:00
|
|
|
return set_attribute(f, type, derivatives, val);
|
2012-09-14 18:10:54 +00:00
|
|
|
}
|
2024-12-26 17:53:59 +01:00
|
|
|
if (name == u_object_random) {
|
2024-12-29 17:32:00 +01:00
|
|
|
const float f = object_random_number(kg, sd->object);
|
2025-02-20 19:28:45 +01:00
|
|
|
return set_attribute(f, type, derivatives, val);
|
2012-09-14 19:09:25 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-09-14 19:09:25 +00:00
|
|
|
/* Particle Attributes */
|
2024-12-26 17:53:59 +01:00
|
|
|
if (name == u_particle_index) {
|
2024-12-29 17:32:00 +01:00
|
|
|
const int particle_id = object_particle_id(kg, sd->object);
|
|
|
|
|
const float f = particle_index(kg, particle_id);
|
2025-02-20 19:28:45 +01:00
|
|
|
return set_attribute(f, type, derivatives, val);
|
2018-02-14 17:02:28 +01:00
|
|
|
}
|
2024-12-26 17:53:59 +01:00
|
|
|
if (name == u_particle_random) {
|
2024-12-29 17:32:00 +01:00
|
|
|
const int particle_id = object_particle_id(kg, sd->object);
|
|
|
|
|
const float f = hash_uint2_to_float(particle_index(kg, particle_id), 0);
|
2025-02-20 19:28:45 +01:00
|
|
|
return set_attribute(f, type, derivatives, val);
|
2012-09-14 19:09:25 +00:00
|
|
|
}
|
2024-12-26 17:53:59 +01:00
|
|
|
if (name == u_particle_age) {
|
2024-12-29 17:32:00 +01:00
|
|
|
const int particle_id = object_particle_id(kg, sd->object);
|
|
|
|
|
const float f = particle_age(kg, particle_id);
|
2025-02-20 19:28:45 +01:00
|
|
|
return set_attribute(f, type, derivatives, val);
|
2012-09-14 19:09:25 +00:00
|
|
|
}
|
2024-12-26 17:53:59 +01:00
|
|
|
if (name == u_particle_lifetime) {
|
2024-12-29 17:32:00 +01:00
|
|
|
const int particle_id = object_particle_id(kg, sd->object);
|
|
|
|
|
const float f = particle_lifetime(kg, particle_id);
|
2025-02-20 19:28:45 +01:00
|
|
|
return set_attribute(f, type, derivatives, val);
|
2012-09-14 19:09:25 +00:00
|
|
|
}
|
2024-12-26 17:53:59 +01:00
|
|
|
if (name == u_particle_location) {
|
2024-12-29 17:32:00 +01:00
|
|
|
const int particle_id = object_particle_id(kg, sd->object);
|
|
|
|
|
const float3 f = particle_location(kg, particle_id);
|
2025-02-20 19:28:45 +01:00
|
|
|
return set_attribute(f, type, derivatives, val);
|
2012-09-14 19:09:25 +00:00
|
|
|
}
|
|
|
|
|
#if 0 /* unsupported */
|
2024-12-26 17:53:59 +01:00
|
|
|
if (name == u_particle_rotation) {
|
2014-05-05 01:30:02 +10:00
|
|
|
int particle_id = object_particle_id(kg, sd->object);
|
Cycles OSL: support for the trace(point pos, vector dir, ...) function, to trace
rays from the OSL shader. The "shade" parameter is not supported currently, but
attributes can be retrieved from the object that was hit using the
getmessage("trace", ..) function.
As mentioned in the OSL specification, this function can't be used instead of
lighting, the main purpose is to allow shaders to "probe" nearby geometry, for
example to apply a projected texture that can be blocked by geometry, apply
more “wear” to exposed geometry, or make other ambient occlusion-like effects.
http://wiki.blender.org/index.php/Doc:2.6/Manual/Render/Cycles/Nodes/OSL#Trace
Example .blend and render:
http://www.pasteall.org/blend/17347
http://www.pasteall.org/pic/show.php?id=40066
2012-11-06 19:59:10 +00:00
|
|
|
float4 f = particle_rotation(kg, particle_id);
|
2025-02-20 19:28:45 +01:00
|
|
|
return set_attribute(f, type, derivatives, val);
|
2012-09-14 19:09:25 +00:00
|
|
|
}
|
|
|
|
|
#endif
|
2024-12-26 17:53:59 +01:00
|
|
|
if (name == u_particle_size) {
|
2024-12-29 17:32:00 +01:00
|
|
|
const int particle_id = object_particle_id(kg, sd->object);
|
|
|
|
|
const float f = particle_size(kg, particle_id);
|
2025-02-20 19:28:45 +01:00
|
|
|
return set_attribute(f, type, derivatives, val);
|
2012-09-14 19:09:25 +00:00
|
|
|
}
|
2024-12-26 17:53:59 +01:00
|
|
|
if (name == u_particle_velocity) {
|
2024-12-29 17:32:00 +01:00
|
|
|
const int particle_id = object_particle_id(kg, sd->object);
|
|
|
|
|
const float3 f = particle_velocity(kg, particle_id);
|
2025-02-20 19:28:45 +01:00
|
|
|
return set_attribute(f, type, derivatives, val);
|
2012-09-14 19:09:25 +00:00
|
|
|
}
|
2024-12-26 17:53:59 +01:00
|
|
|
if (name == u_particle_angular_velocity) {
|
2024-12-29 17:32:00 +01:00
|
|
|
const int particle_id = object_particle_id(kg, sd->object);
|
|
|
|
|
const float3 f = particle_angular_velocity(kg, particle_id);
|
2025-02-20 19:28:45 +01:00
|
|
|
return set_attribute(f, type, derivatives, val);
|
2012-09-14 18:10:54 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-12-29 01:57:32 +00:00
|
|
|
/* Geometry Attributes */
|
2024-12-26 17:53:59 +01:00
|
|
|
if (name == u_geom_numpolyvertices) {
|
2025-02-20 19:28:45 +01:00
|
|
|
return set_attribute(3, type, derivatives, val);
|
2012-11-03 14:32:13 +00:00
|
|
|
}
|
2024-12-26 17:53:59 +01:00
|
|
|
if ((name == u_geom_trianglevertices || name == u_geom_polyvertices) &&
|
|
|
|
|
sd->type & PRIMITIVE_TRIANGLE)
|
2021-12-20 02:52:56 +01:00
|
|
|
{
|
2012-11-03 14:32:13 +00:00
|
|
|
float3 P[3];
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-12-20 02:52:56 +01:00
|
|
|
if (sd->type & PRIMITIVE_MOTION) {
|
2014-03-29 13:03:47 +01:00
|
|
|
motion_triangle_vertices(kg, sd->object, sd->prim, sd->time, P);
|
2021-12-20 02:52:56 +01:00
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
triangle_vertices(kg, sd->prim, P);
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2016-12-23 11:31:19 +01:00
|
|
|
if (!(sd->object_flag & SD_OBJECT_TRANSFORM_APPLIED)) {
|
2012-12-01 19:15:05 +00:00
|
|
|
object_position_transform(kg, sd, &P[0]);
|
|
|
|
|
object_position_transform(kg, sd, &P[1]);
|
|
|
|
|
object_position_transform(kg, sd, &P[2]);
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-11-03 14:32:13 +00:00
|
|
|
return set_attribute_float3_3(P, type, derivatives, val);
|
|
|
|
|
}
|
2024-12-26 17:53:59 +01:00
|
|
|
if (name == u_geom_name) {
|
2024-12-29 23:13:45 +01:00
|
|
|
const ustring object_name = kg->osl.globals->object_names[sd->object];
|
2025-02-20 19:28:45 +01:00
|
|
|
return set_attribute(object_name, type, derivatives, val);
|
Cycles OSL: support for the trace(point pos, vector dir, ...) function, to trace
rays from the OSL shader. The "shade" parameter is not supported currently, but
attributes can be retrieved from the object that was hit using the
getmessage("trace", ..) function.
As mentioned in the OSL specification, this function can't be used instead of
lighting, the main purpose is to allow shaders to "probe" nearby geometry, for
example to apply a projected texture that can be blocked by geometry, apply
more “wear” to exposed geometry, or make other ambient occlusion-like effects.
http://wiki.blender.org/index.php/Doc:2.6/Manual/Render/Cycles/Nodes/OSL#Trace
Example .blend and render:
http://www.pasteall.org/blend/17347
http://www.pasteall.org/pic/show.php?id=40066
2012-11-06 19:59:10 +00:00
|
|
|
}
|
2024-12-26 17:53:59 +01:00
|
|
|
if (name == u_is_smooth) {
|
2024-12-29 17:32:00 +01:00
|
|
|
const float f = ((sd->shader & SHADER_SMOOTH_NORMAL) != 0);
|
2025-02-20 19:28:45 +01:00
|
|
|
return set_attribute(f, type, derivatives, val);
|
2013-05-11 09:31:58 +00:00
|
|
|
}
|
2022-09-09 11:55:35 +02:00
|
|
|
#ifdef __HAIR__
|
2012-12-29 01:57:32 +00:00
|
|
|
/* Hair Attributes */
|
2024-12-26 17:53:59 +01:00
|
|
|
if (name == u_is_curve) {
|
2024-12-29 17:32:00 +01:00
|
|
|
const float f = (sd->type & PRIMITIVE_CURVE) != 0;
|
2025-02-20 19:28:45 +01:00
|
|
|
return set_attribute(f, type, derivatives, val);
|
2012-12-29 01:57:32 +00:00
|
|
|
}
|
2024-12-26 17:53:59 +01:00
|
|
|
if (name == u_curve_thickness) {
|
2024-12-29 17:32:00 +01:00
|
|
|
const float f = curve_thickness(kg, sd);
|
2025-02-20 19:28:45 +01:00
|
|
|
return set_attribute(f, type, derivatives, val);
|
2012-12-29 01:57:32 +00:00
|
|
|
}
|
2024-12-26 17:53:59 +01:00
|
|
|
if (name == u_curve_tangent_normal) {
|
2024-12-29 17:32:00 +01:00
|
|
|
const float3 f = curve_tangent_normal(kg, sd);
|
2025-02-20 19:28:45 +01:00
|
|
|
return set_attribute(f, type, derivatives, val);
|
2012-12-29 01:57:32 +00:00
|
|
|
}
|
2024-12-26 17:53:59 +01:00
|
|
|
if (name == u_curve_random) {
|
2024-12-29 17:32:00 +01:00
|
|
|
const float f = curve_random(kg, sd);
|
2025-02-20 19:28:45 +01:00
|
|
|
return set_attribute(f, type, derivatives, val);
|
2022-01-25 13:25:33 +01:00
|
|
|
}
|
2022-09-09 11:55:35 +02:00
|
|
|
#endif
|
|
|
|
|
#ifdef __POINTCLOUD__
|
2021-12-01 17:30:46 +01:00
|
|
|
/* point attributes */
|
2024-12-26 17:53:59 +01:00
|
|
|
if (name == u_is_point) {
|
2024-12-29 17:32:00 +01:00
|
|
|
const float f = (sd->type & PRIMITIVE_POINT) != 0;
|
2025-02-20 19:28:45 +01:00
|
|
|
return set_attribute(f, type, derivatives, val);
|
2021-12-01 17:30:46 +01:00
|
|
|
}
|
2024-12-26 17:53:59 +01:00
|
|
|
if (name == u_point_radius) {
|
2024-12-29 17:32:00 +01:00
|
|
|
const float f = point_radius(kg, sd);
|
2025-02-20 19:28:45 +01:00
|
|
|
return set_attribute(f, type, derivatives, val);
|
2021-12-01 17:30:46 +01:00
|
|
|
}
|
2024-12-26 17:53:59 +01:00
|
|
|
if (name == u_point_position) {
|
2024-12-29 17:32:00 +01:00
|
|
|
const float3 f = point_position(kg, sd);
|
2025-02-20 19:28:45 +01:00
|
|
|
return set_attribute(f, type, derivatives, val);
|
2022-01-25 13:25:33 +01:00
|
|
|
}
|
2024-12-26 17:53:59 +01:00
|
|
|
if (name == u_point_random) {
|
2024-12-29 17:32:00 +01:00
|
|
|
const float f = point_random(kg, sd);
|
2025-02-20 19:28:45 +01:00
|
|
|
return set_attribute(f, type, derivatives, val);
|
2022-01-25 13:25:33 +01:00
|
|
|
}
|
2022-09-09 11:55:35 +02:00
|
|
|
#endif
|
2024-12-26 17:53:59 +01:00
|
|
|
if (name == u_normal_map_normal) {
|
2021-12-20 02:52:56 +01:00
|
|
|
if (sd->type & PRIMITIVE_TRIANGLE) {
|
2024-12-29 17:32:00 +01:00
|
|
|
const float3 f = triangle_smooth_normal_unnormalized(kg, sd, sd->Ng, sd->prim, sd->u, sd->v);
|
2025-02-20 19:28:45 +01:00
|
|
|
return set_attribute(f, type, derivatives, val);
|
2021-10-04 12:19:18 +02:00
|
|
|
}
|
2024-12-26 17:53:59 +01:00
|
|
|
return false;
|
2021-10-04 12:19:18 +02:00
|
|
|
}
|
2025-02-06 16:22:19 +01:00
|
|
|
if (name == u_bump_map_normal) {
|
|
|
|
|
float3 f[3];
|
|
|
|
|
if (!attribute_bump_map_normal(kg, sd, f)) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2025-02-20 19:28:45 +01:00
|
|
|
return set_attribute(f[0], f[1], f[2], type, derivatives, val);
|
2025-02-06 16:22:19 +01:00
|
|
|
}
|
Cycles: Refactor: Store Cycles-specific pointers in our own ShaderGlobals
OSL has OSL::ShaderGlobals, which contains all the state for OSL shader
execution. The renderer fills it out and hands a pointer to OSL, and any
callbacks (e.g. for querying attributes) get the pointer back.
In order to store renderer-specific data in it, there's a few opaque pointers
in the struct, but using those has led to a mess of reinterpret_cast<> and
pointer indirection in order to carry all the data around.
However, there is a way to do this nicer: Good old C-style struct inheritance.
In short: Unless you're doing pointer arithmetic, you can just add additional
data at the end of a base struct, and the rest of the code won't care.
In this case, this means that we can have our own ShaderGlobals struct and
add more Cycles-specific data at the end. Additionally, we can replace the
generic opaque void pointers with ones of the correct type, which saves us
from needing to cast them back.
Since we have a copy of ShaderGlobals for GPU OSL anyways, it's just a matter
of refactoring the code a bit to make use of that.
The advantages of this are:
- Avoids casts all over the place, just needs one cast to turn our
ShaderGlobals into the "base" type that OSL expects and one to turn the
pointer that OSL gives us on callbacks back into our "derived" type.
- Removes indirection, all the relevant stuff (sd, kg, state) is now
directly in the ShaderGlobals
- Removes some OSL-specific state from ShaderData, which helps to keep
memory usage down
Pull Request: https://projects.blender.org/blender/blender/pulls/133689
2025-01-28 03:39:00 +01:00
|
|
|
return get_background_attribute(globals, name, type, derivatives, val);
|
2012-10-17 12:12:26 +00:00
|
|
|
}
|
2012-10-16 22:42:05 +00:00
|
|
|
|
Cycles: Refactor: Store Cycles-specific pointers in our own ShaderGlobals
OSL has OSL::ShaderGlobals, which contains all the state for OSL shader
execution. The renderer fills it out and hands a pointer to OSL, and any
callbacks (e.g. for querying attributes) get the pointer back.
In order to store renderer-specific data in it, there's a few opaque pointers
in the struct, but using those has led to a mess of reinterpret_cast<> and
pointer indirection in order to carry all the data around.
However, there is a way to do this nicer: Good old C-style struct inheritance.
In short: Unless you're doing pointer arithmetic, you can just add additional
data at the end of a base struct, and the rest of the code won't care.
In this case, this means that we can have our own ShaderGlobals struct and
add more Cycles-specific data at the end. Additionally, we can replace the
generic opaque void pointers with ones of the correct type, which saves us
from needing to cast them back.
Since we have a copy of ShaderGlobals for GPU OSL anyways, it's just a matter
of refactoring the code a bit to make use of that.
The advantages of this are:
- Avoids casts all over the place, just needs one cast to turn our
ShaderGlobals into the "base" type that OSL expects and one to turn the
pointer that OSL gives us on callbacks back into our "derived" type.
- Removes indirection, all the relevant stuff (sd, kg, state) is now
directly in the ShaderGlobals
- Removes some OSL-specific state from ShaderData, which helps to keep
memory usage down
Pull Request: https://projects.blender.org/blender/blender/pulls/133689
2025-01-28 03:39:00 +01:00
|
|
|
bool OSLRenderServices::get_background_attribute(
|
|
|
|
|
ShaderGlobals *globals, OSLUStringHash name, const TypeDesc type, bool derivatives, void *val)
|
2012-10-17 12:12:26 +00:00
|
|
|
{
|
Cycles: Refactor: Store Cycles-specific pointers in our own ShaderGlobals
OSL has OSL::ShaderGlobals, which contains all the state for OSL shader
execution. The renderer fills it out and hands a pointer to OSL, and any
callbacks (e.g. for querying attributes) get the pointer back.
In order to store renderer-specific data in it, there's a few opaque pointers
in the struct, but using those has led to a mess of reinterpret_cast<> and
pointer indirection in order to carry all the data around.
However, there is a way to do this nicer: Good old C-style struct inheritance.
In short: Unless you're doing pointer arithmetic, you can just add additional
data at the end of a base struct, and the rest of the code won't care.
In this case, this means that we can have our own ShaderGlobals struct and
add more Cycles-specific data at the end. Additionally, we can replace the
generic opaque void pointers with ones of the correct type, which saves us
from needing to cast them back.
Since we have a copy of ShaderGlobals for GPU OSL anyways, it's just a matter
of refactoring the code a bit to make use of that.
The advantages of this are:
- Avoids casts all over the place, just needs one cast to turn our
ShaderGlobals into the "base" type that OSL expects and one to turn the
pointer that OSL gives us on callbacks back into our "derived" type.
- Removes indirection, all the relevant stuff (sd, kg, state) is now
directly in the ShaderGlobals
- Removes some OSL-specific state from ShaderData, which helps to keep
memory usage down
Pull Request: https://projects.blender.org/blender/blender/pulls/133689
2025-01-28 03:39:00 +01:00
|
|
|
ShaderData *sd = globals->sd;
|
|
|
|
|
const ThreadKernelGlobalsCPU *kg = globals->kg;
|
|
|
|
|
const IntegratorStateCPU *state = globals->path_state;
|
|
|
|
|
const IntegratorShadowStateCPU *shadow_state = globals->shadow_path_state;
|
2015-03-28 00:15:15 +05:00
|
|
|
if (name == u_path_ray_length) {
|
2013-06-08 10:51:33 +00:00
|
|
|
/* Ray Length */
|
2024-12-29 17:32:00 +01:00
|
|
|
const float f = sd->ray_length;
|
2025-02-20 19:28:45 +01:00
|
|
|
return set_attribute(f, type, derivatives, val);
|
2012-10-16 22:42:05 +00:00
|
|
|
}
|
2025-01-28 03:48:14 +01:00
|
|
|
|
|
|
|
|
#define READ_PATH_STATE(elem) \
|
|
|
|
|
((state != nullptr) ? state->path.elem : \
|
|
|
|
|
(shadow_state != nullptr) ? shadow_state->shadow_path.elem : \
|
|
|
|
|
0)
|
|
|
|
|
|
2024-12-26 17:53:59 +01:00
|
|
|
if (name == u_path_ray_depth) {
|
2013-07-31 20:30:37 +00:00
|
|
|
/* Ray Depth */
|
2025-02-14 05:09:08 +01:00
|
|
|
int f = READ_PATH_STATE(bounce);
|
|
|
|
|
|
|
|
|
|
/* Read bounce from different locations depending on if this is a shadow path. For background,
|
|
|
|
|
* light emission and shadow evaluation from a surface or volume we are effectively one bounce
|
|
|
|
|
* further. */
|
|
|
|
|
if (globals->raytype & (PATH_RAY_SHADOW | PATH_RAY_EMISSION)) {
|
|
|
|
|
f += 1;
|
|
|
|
|
}
|
|
|
|
|
|
2025-02-20 19:28:45 +01:00
|
|
|
return set_attribute(f, type, derivatives, val);
|
2016-12-06 16:15:36 +01:00
|
|
|
}
|
2024-12-26 17:53:59 +01:00
|
|
|
if (name == u_path_diffuse_depth) {
|
2016-12-06 16:15:36 +01:00
|
|
|
/* Diffuse Ray Depth */
|
2025-01-28 03:48:14 +01:00
|
|
|
const int f = READ_PATH_STATE(diffuse_bounce);
|
2025-02-20 19:28:45 +01:00
|
|
|
return set_attribute(f, type, derivatives, val);
|
2016-12-06 16:15:36 +01:00
|
|
|
}
|
2024-12-26 17:53:59 +01:00
|
|
|
if (name == u_path_glossy_depth) {
|
2016-12-06 16:15:36 +01:00
|
|
|
/* Glossy Ray Depth */
|
2025-01-28 03:48:14 +01:00
|
|
|
const int f = READ_PATH_STATE(glossy_bounce);
|
2025-02-20 19:28:45 +01:00
|
|
|
return set_attribute(f, type, derivatives, val);
|
2016-12-06 16:15:36 +01:00
|
|
|
}
|
2024-12-26 17:53:59 +01:00
|
|
|
if (name == u_path_transmission_depth) {
|
2016-12-06 16:15:36 +01:00
|
|
|
/* Transmission Ray Depth */
|
2025-01-28 03:48:14 +01:00
|
|
|
const int f = READ_PATH_STATE(transmission_bounce);
|
2025-02-20 19:28:45 +01:00
|
|
|
return set_attribute(f, type, derivatives, val);
|
2013-07-31 20:30:37 +00:00
|
|
|
}
|
2024-12-26 17:53:59 +01:00
|
|
|
if (name == u_path_transparent_depth) {
|
2014-05-24 07:28:01 +02:00
|
|
|
/* Transparent Ray Depth */
|
2025-01-28 03:48:14 +01:00
|
|
|
const int f = READ_PATH_STATE(transparent_bounce);
|
2025-02-20 19:28:45 +01:00
|
|
|
return set_attribute(f, type, derivatives, val);
|
2014-04-21 14:20:29 +02:00
|
|
|
}
|
2025-01-28 03:48:14 +01:00
|
|
|
#undef READ_PATH_STATE
|
|
|
|
|
|
2024-12-26 17:53:59 +01:00
|
|
|
if (name == u_ndc) {
|
2021-02-05 16:23:34 +11:00
|
|
|
/* NDC coordinates with special exception for orthographic projection. */
|
2013-06-08 10:51:33 +00:00
|
|
|
float3 ndc[3];
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-03-29 13:03:47 +01:00
|
|
|
if ((globals->raytype & PATH_RAY_CAMERA) && sd->object == OBJECT_NONE &&
|
|
|
|
|
kernel_data.cam.type == CAMERA_ORTHOGRAPHIC)
|
|
|
|
|
{
|
2013-06-08 10:51:33 +00:00
|
|
|
ndc[0] = camera_world_to_ndc(kg, sd, sd->ray_P);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2013-06-08 10:51:33 +00:00
|
|
|
if (derivatives) {
|
2022-07-13 16:54:53 +02:00
|
|
|
ndc[1] = zero_float3();
|
|
|
|
|
ndc[2] = zero_float3();
|
2013-06-08 10:51:33 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
ndc[0] = camera_world_to_ndc(kg, sd, sd->P);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2013-06-08 10:51:33 +00:00
|
|
|
if (derivatives) {
|
2022-08-11 16:53:11 +02:00
|
|
|
const differential3 dP = differential_from_compact(sd->Ng, sd->dP);
|
|
|
|
|
ndc[1] = camera_world_to_ndc(kg, sd, sd->P + dP.dx) - ndc[0];
|
|
|
|
|
ndc[2] = camera_world_to_ndc(kg, sd, sd->P + dP.dy) - ndc[0];
|
2013-06-08 10:51:33 +00:00
|
|
|
}
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2025-02-20 19:28:45 +01:00
|
|
|
return set_attribute(ndc[0], ndc[1], ndc[2], type, derivatives, val);
|
2013-06-08 10:51:33 +00:00
|
|
|
}
|
2024-12-26 17:53:59 +01:00
|
|
|
|
|
|
|
|
return false;
|
2012-09-14 18:10:54 +00:00
|
|
|
}
|
|
|
|
|
|
2025-04-25 19:27:30 +02:00
|
|
|
bool OSLRenderServices::get_camera_attribute(
|
|
|
|
|
ShaderGlobals *globals, OSLUStringHash name, TypeDesc type, bool derivatives, void *val)
|
|
|
|
|
{
|
|
|
|
|
const ThreadKernelGlobalsCPU *kg = globals->kg;
|
|
|
|
|
if (name == u_sensor_size) {
|
|
|
|
|
const float2 sensor = make_float2(kernel_data.cam.sensorwidth, kernel_data.cam.sensorheight);
|
|
|
|
|
return set_attribute(sensor, type, derivatives, val);
|
|
|
|
|
}
|
|
|
|
|
else if (name == u_image_resolution) {
|
|
|
|
|
const float2 image = make_float2(kernel_data.cam.width, kernel_data.cam.height);
|
|
|
|
|
return set_attribute(image, type, derivatives, val);
|
|
|
|
|
}
|
|
|
|
|
else if (name == u_aperture_aspect_ratio) {
|
|
|
|
|
return set_attribute(1.0f / kernel_data.cam.inv_aperture_ratio, type, derivatives, val);
|
|
|
|
|
}
|
|
|
|
|
else if (name == u_aperture_size) {
|
|
|
|
|
return set_attribute(kernel_data.cam.aperturesize, type, derivatives, val);
|
|
|
|
|
}
|
|
|
|
|
else if (name == u_aperture_position) {
|
|
|
|
|
/* The random numbers for aperture sampling are packed into N. */
|
|
|
|
|
const float2 rand_lens = make_float2(globals->N.x, globals->N.y);
|
|
|
|
|
const float2 pos = camera_sample_aperture(&kernel_data.cam, rand_lens);
|
|
|
|
|
return set_attribute(pos * kernel_data.cam.aperturesize, type, derivatives, val);
|
|
|
|
|
}
|
|
|
|
|
else if (name == u_focal_distance) {
|
|
|
|
|
return set_attribute(kernel_data.cam.focaldistance, type, derivatives, val);
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2014-07-24 23:07:49 +02:00
|
|
|
bool OSLRenderServices::get_attribute(OSL::ShaderGlobals *sg,
|
|
|
|
|
bool derivatives,
|
2023-08-10 20:01:09 +02:00
|
|
|
OSLUStringHash object_name,
|
2025-01-01 18:15:54 +01:00
|
|
|
const TypeDesc type,
|
2023-08-10 20:01:09 +02:00
|
|
|
OSLUStringHash name,
|
2012-06-04 22:44:58 +00:00
|
|
|
void *val)
|
2011-04-27 11:58:34 +00:00
|
|
|
{
|
Cycles: Refactor: Store Cycles-specific pointers in our own ShaderGlobals
OSL has OSL::ShaderGlobals, which contains all the state for OSL shader
execution. The renderer fills it out and hands a pointer to OSL, and any
callbacks (e.g. for querying attributes) get the pointer back.
In order to store renderer-specific data in it, there's a few opaque pointers
in the struct, but using those has led to a mess of reinterpret_cast<> and
pointer indirection in order to carry all the data around.
However, there is a way to do this nicer: Good old C-style struct inheritance.
In short: Unless you're doing pointer arithmetic, you can just add additional
data at the end of a base struct, and the rest of the code won't care.
In this case, this means that we can have our own ShaderGlobals struct and
add more Cycles-specific data at the end. Additionally, we can replace the
generic opaque void pointers with ones of the correct type, which saves us
from needing to cast them back.
Since we have a copy of ShaderGlobals for GPU OSL anyways, it's just a matter
of refactoring the code a bit to make use of that.
The advantages of this are:
- Avoids casts all over the place, just needs one cast to turn our
ShaderGlobals into the "base" type that OSL expects and one to turn the
pointer that OSL gives us on callbacks back into our "derived" type.
- Removes indirection, all the relevant stuff (sd, kg, state) is now
directly in the ShaderGlobals
- Removes some OSL-specific state from ShaderData, which helps to keep
memory usage down
Pull Request: https://projects.blender.org/blender/blender/pulls/133689
2025-01-28 03:39:00 +01:00
|
|
|
ShaderGlobals *globals = reinterpret_cast<ShaderGlobals *>(sg);
|
2025-04-25 19:27:30 +02:00
|
|
|
if (globals == nullptr) {
|
2014-06-05 02:29:48 +06:00
|
|
|
return false;
|
2023-09-17 09:01:48 +10:00
|
|
|
}
|
2014-06-05 02:29:48 +06:00
|
|
|
|
Cycles: Refactor: Store Cycles-specific pointers in our own ShaderGlobals
OSL has OSL::ShaderGlobals, which contains all the state for OSL shader
execution. The renderer fills it out and hands a pointer to OSL, and any
callbacks (e.g. for querying attributes) get the pointer back.
In order to store renderer-specific data in it, there's a few opaque pointers
in the struct, but using those has led to a mess of reinterpret_cast<> and
pointer indirection in order to carry all the data around.
However, there is a way to do this nicer: Good old C-style struct inheritance.
In short: Unless you're doing pointer arithmetic, you can just add additional
data at the end of a base struct, and the rest of the code won't care.
In this case, this means that we can have our own ShaderGlobals struct and
add more Cycles-specific data at the end. Additionally, we can replace the
generic opaque void pointers with ones of the correct type, which saves us
from needing to cast them back.
Since we have a copy of ShaderGlobals for GPU OSL anyways, it's just a matter
of refactoring the code a bit to make use of that.
The advantages of this are:
- Avoids casts all over the place, just needs one cast to turn our
ShaderGlobals into the "base" type that OSL expects and one to turn the
pointer that OSL gives us on callbacks back into our "derived" type.
- Removes indirection, all the relevant stuff (sd, kg, state) is now
directly in the ShaderGlobals
- Removes some OSL-specific state from ShaderData, which helps to keep
memory usage down
Pull Request: https://projects.blender.org/blender/blender/pulls/133689
2025-01-28 03:39:00 +01:00
|
|
|
ShaderData *sd = globals->sd;
|
|
|
|
|
const ThreadKernelGlobalsCPU *kg = globals->kg;
|
2025-04-25 19:27:30 +02:00
|
|
|
if (sd == nullptr) {
|
|
|
|
|
/* Camera shader. */
|
|
|
|
|
return get_camera_attribute(globals, name, type, derivatives, val);
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2011-04-27 11:58:34 +00:00
|
|
|
/* lookup of attribute on another object */
|
2025-04-25 19:27:30 +02:00
|
|
|
int object;
|
2015-03-28 00:15:15 +05:00
|
|
|
if (object_name != u_empty) {
|
2024-12-29 23:13:45 +01:00
|
|
|
const OSLGlobals::ObjectNameMap::iterator it = kg->osl.globals->object_name_map.find(
|
|
|
|
|
object_name);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2024-12-29 23:13:45 +01:00
|
|
|
if (it == kg->osl.globals->object_name_map.end()) {
|
2011-04-27 11:58:34 +00:00
|
|
|
return false;
|
2023-09-17 09:01:48 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2011-04-27 11:58:34 +00:00
|
|
|
object = it->second;
|
|
|
|
|
}
|
2012-12-22 15:15:11 +00:00
|
|
|
else {
|
|
|
|
|
object = sd->object;
|
2011-04-27 11:58:34 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2011-04-27 11:58:34 +00:00
|
|
|
/* find attribute on object */
|
2025-03-09 03:07:29 +01:00
|
|
|
const AttributeDescriptor desc = find_attribute(kg, object, sd->prim, name.hash());
|
2022-09-09 11:55:35 +02:00
|
|
|
if (desc.offset != ATTR_STD_NOT_FOUND) {
|
|
|
|
|
return get_object_attribute(kg, sd, desc, type, derivatives, val);
|
2011-04-27 11:58:34 +00:00
|
|
|
}
|
2024-12-26 17:53:59 +01:00
|
|
|
|
|
|
|
|
/* not found in attribute, check standard object info */
|
Cycles: Refactor: Store Cycles-specific pointers in our own ShaderGlobals
OSL has OSL::ShaderGlobals, which contains all the state for OSL shader
execution. The renderer fills it out and hands a pointer to OSL, and any
callbacks (e.g. for querying attributes) get the pointer back.
In order to store renderer-specific data in it, there's a few opaque pointers
in the struct, but using those has led to a mess of reinterpret_cast<> and
pointer indirection in order to carry all the data around.
However, there is a way to do this nicer: Good old C-style struct inheritance.
In short: Unless you're doing pointer arithmetic, you can just add additional
data at the end of a base struct, and the rest of the code won't care.
In this case, this means that we can have our own ShaderGlobals struct and
add more Cycles-specific data at the end. Additionally, we can replace the
generic opaque void pointers with ones of the correct type, which saves us
from needing to cast them back.
Since we have a copy of ShaderGlobals for GPU OSL anyways, it's just a matter
of refactoring the code a bit to make use of that.
The advantages of this are:
- Avoids casts all over the place, just needs one cast to turn our
ShaderGlobals into the "base" type that OSL expects and one to turn the
pointer that OSL gives us on callbacks back into our "derived" type.
- Removes indirection, all the relevant stuff (sd, kg, state) is now
directly in the ShaderGlobals
- Removes some OSL-specific state from ShaderData, which helps to keep
memory usage down
Pull Request: https://projects.blender.org/blender/blender/pulls/133689
2025-01-28 03:39:00 +01:00
|
|
|
return get_object_standard_attribute(globals, name, type, derivatives, val);
|
2011-04-27 11:58:34 +00:00
|
|
|
}
|
|
|
|
|
|
2018-07-06 10:17:58 +02:00
|
|
|
bool OSLRenderServices::get_userdata(
|
2025-01-01 18:15:54 +01:00
|
|
|
bool derivatives, OSLUStringHash name, const TypeDesc type, OSL::ShaderGlobals *sg, void *val)
|
2011-04-27 11:58:34 +00:00
|
|
|
{
|
|
|
|
|
return false; /* disabled by lockgeom */
|
|
|
|
|
}
|
|
|
|
|
|
2024-12-26 17:53:58 +01:00
|
|
|
OSL::TextureSystem::TextureHandle *OSLRenderServices::get_texture_handle(
|
|
|
|
|
OSLUStringHash filename, OSL::ShadingContext *context, const OSL::TextureOpt *opt)
|
2023-12-10 17:08:47 +01:00
|
|
|
{
|
|
|
|
|
return get_texture_handle(to_ustring(filename), context, opt);
|
|
|
|
|
}
|
|
|
|
|
|
2024-12-26 17:53:58 +01:00
|
|
|
OSL::TextureSystem::TextureHandle *OSLRenderServices::get_texture_handle(
|
|
|
|
|
OSL::ustring filename, OSL::ShadingContext * /*context*/, const OSL::TextureOpt * /*options*/)
|
2018-10-26 19:26:06 +02:00
|
|
|
{
|
2019-05-14 12:13:43 +02:00
|
|
|
OSLTextureHandleMap::iterator it = textures.find(filename);
|
2019-05-02 12:40:24 +02:00
|
|
|
|
2022-11-09 14:25:32 +01:00
|
|
|
if (device_type_ == DEVICE_CPU) {
|
|
|
|
|
/* For non-OIIO textures, just return a pointer to our own OSLTextureHandle. */
|
|
|
|
|
if (it != textures.end()) {
|
2024-12-29 23:13:45 +01:00
|
|
|
if (it->second.type != OSLTextureHandle::OIIO) {
|
|
|
|
|
return (OSL::TextureSystem::TextureHandle *)(&it->second);
|
2022-11-09 14:25:32 +01:00
|
|
|
}
|
2019-05-02 12:40:24 +02:00
|
|
|
}
|
|
|
|
|
|
2022-11-09 14:25:32 +01:00
|
|
|
/* Get handle from OpenImageIO. */
|
|
|
|
|
OSL::TextureSystem *ts = m_texturesys;
|
2024-12-26 17:53:58 +01:00
|
|
|
OSL::TextureSystem::TextureHandle *handle = ts->get_texture_handle(to_ustring(filename));
|
2024-12-26 17:53:55 +01:00
|
|
|
if (handle == nullptr) {
|
|
|
|
|
return nullptr;
|
2022-11-09 14:25:32 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Insert new OSLTextureHandle if needed. */
|
|
|
|
|
if (it == textures.end()) {
|
2024-12-29 23:13:45 +01:00
|
|
|
textures.insert(filename, OSLTextureHandle(OSLTextureHandle::OIIO));
|
2022-11-09 14:25:32 +01:00
|
|
|
it = textures.find(filename);
|
|
|
|
|
}
|
2019-05-02 12:40:24 +02:00
|
|
|
|
2024-12-29 23:13:45 +01:00
|
|
|
/* Assign OIIO texture handle and return.
|
|
|
|
|
* OIIO::unordered_map_concurrent always returns a const handle even if the underlying
|
|
|
|
|
* std::unordered_map supports updating values just fine. */
|
|
|
|
|
const_cast<OSLTextureHandle &>(it->second).oiio_handle = handle;
|
|
|
|
|
return (OSL::TextureSystem::TextureHandle *)(&it->second);
|
2024-12-26 17:53:58 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Construct GPU texture handle for existing textures. */
|
|
|
|
|
if (it != textures.end()) {
|
2024-12-29 23:13:45 +01:00
|
|
|
switch (it->second.type) {
|
2024-12-26 17:53:58 +01:00
|
|
|
case OSLTextureHandle::OIIO:
|
|
|
|
|
return nullptr;
|
|
|
|
|
case OSLTextureHandle::SVM:
|
2024-12-29 23:13:45 +01:00
|
|
|
if (!it->second.handle.empty() && it->second.handle.get_manager() != image_manager) {
|
2024-12-26 17:53:58 +01:00
|
|
|
it.clear();
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
return reinterpret_cast<OSL::TextureSystem::TextureHandle *>(OSL_TEXTURE_HANDLE_TYPE_SVM |
|
2024-12-29 23:13:45 +01:00
|
|
|
it->second.svm_slots[0].y);
|
2024-12-26 17:53:58 +01:00
|
|
|
case OSLTextureHandle::IES:
|
2024-12-29 23:13:45 +01:00
|
|
|
if (!it->second.handle.empty() && it->second.handle.get_manager() != image_manager) {
|
2024-12-26 17:53:58 +01:00
|
|
|
it.clear();
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
return reinterpret_cast<OSL::TextureSystem::TextureHandle *>(OSL_TEXTURE_HANDLE_TYPE_IES |
|
2024-12-29 23:13:45 +01:00
|
|
|
it->second.svm_slots[0].y);
|
2024-12-26 17:53:58 +01:00
|
|
|
case OSLTextureHandle::AO:
|
|
|
|
|
return reinterpret_cast<OSL::TextureSystem::TextureHandle *>(
|
|
|
|
|
OSL_TEXTURE_HANDLE_TYPE_AO_OR_BEVEL | 1);
|
|
|
|
|
case OSLTextureHandle::BEVEL:
|
|
|
|
|
return reinterpret_cast<OSL::TextureSystem::TextureHandle *>(
|
|
|
|
|
OSL_TEXTURE_HANDLE_TYPE_AO_OR_BEVEL | 2);
|
2023-01-18 17:28:03 +01:00
|
|
|
}
|
2024-12-26 17:53:58 +01:00
|
|
|
}
|
2023-01-18 17:28:03 +01:00
|
|
|
|
2024-12-26 17:53:58 +01:00
|
|
|
if (!image_manager) {
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
2023-01-18 17:28:03 +01:00
|
|
|
|
2024-12-26 17:53:58 +01:00
|
|
|
/* Load new textures using SVM image manager. */
|
2024-12-29 17:32:00 +01:00
|
|
|
const ImageHandle handle = image_manager->add_image(filename.string(), ImageParams());
|
2024-12-26 17:53:58 +01:00
|
|
|
if (handle.empty()) {
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
2019-05-02 12:40:24 +02:00
|
|
|
|
2024-12-29 23:13:45 +01:00
|
|
|
if (!textures.insert(filename, OSLTextureHandle(handle))) {
|
2024-12-26 17:53:58 +01:00
|
|
|
return nullptr;
|
2022-11-09 14:25:32 +01:00
|
|
|
}
|
2024-12-26 17:53:58 +01:00
|
|
|
|
|
|
|
|
return reinterpret_cast<OSL::TextureSystem::TextureHandle *>(OSL_TEXTURE_HANDLE_TYPE_SVM |
|
|
|
|
|
handle.svm_slot());
|
2018-10-26 19:26:06 +02:00
|
|
|
}
|
|
|
|
|
|
2024-12-26 17:53:58 +01:00
|
|
|
bool OSLRenderServices::good(OSL::TextureSystem::TextureHandle *texture_handle)
|
2018-10-26 19:26:06 +02:00
|
|
|
{
|
2019-05-02 12:40:24 +02:00
|
|
|
OSLTextureHandle *handle = (OSLTextureHandle *)texture_handle;
|
|
|
|
|
|
|
|
|
|
if (handle->oiio_handle) {
|
2022-09-12 18:46:20 +02:00
|
|
|
OSL::TextureSystem *ts = m_texturesys;
|
2019-05-02 12:40:24 +02:00
|
|
|
return ts->good(handle->oiio_handle);
|
|
|
|
|
}
|
2024-12-26 17:53:59 +01:00
|
|
|
return true;
|
2018-10-26 19:26:06 +02:00
|
|
|
}
|
|
|
|
|
|
2023-08-10 20:01:09 +02:00
|
|
|
bool OSLRenderServices::texture(OSLUStringHash filename,
|
2015-12-18 21:42:04 +05:00
|
|
|
TextureHandle *texture_handle,
|
|
|
|
|
TexturePerthread *texture_thread_info,
|
2024-12-26 17:53:58 +01:00
|
|
|
OSL::TextureOpt &options,
|
2015-12-18 21:42:04 +05:00
|
|
|
OSL::ShaderGlobals *sg,
|
|
|
|
|
float s,
|
|
|
|
|
float t,
|
2025-01-01 18:15:54 +01:00
|
|
|
const float dsdx,
|
|
|
|
|
const float dtdx,
|
|
|
|
|
const float dsdy,
|
|
|
|
|
const float dtdy,
|
|
|
|
|
const int nchannels,
|
2015-12-18 21:42:04 +05:00
|
|
|
float *result,
|
|
|
|
|
float *dresultds,
|
2018-10-26 19:26:06 +02:00
|
|
|
float *dresultdt,
|
2023-08-10 20:01:09 +02:00
|
|
|
OSLUStringHash *errormessage)
|
2015-12-18 21:42:04 +05:00
|
|
|
{
|
2019-05-02 12:40:24 +02:00
|
|
|
OSLTextureHandle *handle = (OSLTextureHandle *)texture_handle;
|
2024-12-29 17:32:00 +01:00
|
|
|
const OSLTextureHandle::Type texture_type = (handle) ? handle->type : OSLTextureHandle::OIIO;
|
Cycles: Refactor: Store Cycles-specific pointers in our own ShaderGlobals
OSL has OSL::ShaderGlobals, which contains all the state for OSL shader
execution. The renderer fills it out and hands a pointer to OSL, and any
callbacks (e.g. for querying attributes) get the pointer back.
In order to store renderer-specific data in it, there's a few opaque pointers
in the struct, but using those has led to a mess of reinterpret_cast<> and
pointer indirection in order to carry all the data around.
However, there is a way to do this nicer: Good old C-style struct inheritance.
In short: Unless you're doing pointer arithmetic, you can just add additional
data at the end of a base struct, and the rest of the code won't care.
In this case, this means that we can have our own ShaderGlobals struct and
add more Cycles-specific data at the end. Additionally, we can replace the
generic opaque void pointers with ones of the correct type, which saves us
from needing to cast them back.
Since we have a copy of ShaderGlobals for GPU OSL anyways, it's just a matter
of refactoring the code a bit to make use of that.
The advantages of this are:
- Avoids casts all over the place, just needs one cast to turn our
ShaderGlobals into the "base" type that OSL expects and one to turn the
pointer that OSL gives us on callbacks back into our "derived" type.
- Removes indirection, all the relevant stuff (sd, kg, state) is now
directly in the ShaderGlobals
- Removes some OSL-specific state from ShaderData, which helps to keep
memory usage down
Pull Request: https://projects.blender.org/blender/blender/pulls/133689
2025-01-28 03:39:00 +01:00
|
|
|
ShaderGlobals *globals = reinterpret_cast<ShaderGlobals *>(sg);
|
|
|
|
|
ShaderData *sd = globals->sd;
|
|
|
|
|
const ThreadKernelGlobalsCPU *kernel_globals = globals->kg;
|
|
|
|
|
const IntegratorStateCPU *state = globals->path_state;
|
2017-08-18 18:37:05 +02:00
|
|
|
bool status = false;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-05-02 12:40:24 +02:00
|
|
|
switch (texture_type) {
|
|
|
|
|
case OSLTextureHandle::BEVEL: {
|
2024-06-13 18:11:30 +02:00
|
|
|
#ifdef __SHADER_RAYTRACE__
|
2017-08-18 18:37:05 +02:00
|
|
|
/* Bevel shader hack. */
|
Cycles: Refactor: Store Cycles-specific pointers in our own ShaderGlobals
OSL has OSL::ShaderGlobals, which contains all the state for OSL shader
execution. The renderer fills it out and hands a pointer to OSL, and any
callbacks (e.g. for querying attributes) get the pointer back.
In order to store renderer-specific data in it, there's a few opaque pointers
in the struct, but using those has led to a mess of reinterpret_cast<> and
pointer indirection in order to carry all the data around.
However, there is a way to do this nicer: Good old C-style struct inheritance.
In short: Unless you're doing pointer arithmetic, you can just add additional
data at the end of a base struct, and the rest of the code won't care.
In this case, this means that we can have our own ShaderGlobals struct and
add more Cycles-specific data at the end. Additionally, we can replace the
generic opaque void pointers with ones of the correct type, which saves us
from needing to cast them back.
Since we have a copy of ShaderGlobals for GPU OSL anyways, it's just a matter
of refactoring the code a bit to make use of that.
The advantages of this are:
- Avoids casts all over the place, just needs one cast to turn our
ShaderGlobals into the "base" type that OSL expects and one to turn the
pointer that OSL gives us on callbacks back into our "derived" type.
- Removes indirection, all the relevant stuff (sd, kg, state) is now
directly in the ShaderGlobals
- Removes some OSL-specific state from ShaderData, which helps to keep
memory usage down
Pull Request: https://projects.blender.org/blender/blender/pulls/133689
2025-01-28 03:39:00 +01:00
|
|
|
if (nchannels >= 3 && state != nullptr) {
|
|
|
|
|
const int num_samples = (int)s;
|
|
|
|
|
const float radius = t;
|
|
|
|
|
const float3 N = svm_bevel(kernel_globals, state, sd, radius, num_samples);
|
|
|
|
|
result[0] = N.x;
|
|
|
|
|
result[1] = N.y;
|
|
|
|
|
result[2] = N.z;
|
|
|
|
|
status = true;
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2024-06-13 18:11:30 +02:00
|
|
|
#endif
|
2019-05-02 12:40:24 +02:00
|
|
|
break;
|
2017-08-18 18:37:05 +02:00
|
|
|
}
|
2019-05-02 12:40:24 +02:00
|
|
|
case OSLTextureHandle::AO: {
|
2024-06-13 18:11:30 +02:00
|
|
|
#ifdef __SHADER_RAYTRACE__
|
2018-06-15 11:03:29 +02:00
|
|
|
/* AO shader hack. */
|
Cycles: Refactor: Store Cycles-specific pointers in our own ShaderGlobals
OSL has OSL::ShaderGlobals, which contains all the state for OSL shader
execution. The renderer fills it out and hands a pointer to OSL, and any
callbacks (e.g. for querying attributes) get the pointer back.
In order to store renderer-specific data in it, there's a few opaque pointers
in the struct, but using those has led to a mess of reinterpret_cast<> and
pointer indirection in order to carry all the data around.
However, there is a way to do this nicer: Good old C-style struct inheritance.
In short: Unless you're doing pointer arithmetic, you can just add additional
data at the end of a base struct, and the rest of the code won't care.
In this case, this means that we can have our own ShaderGlobals struct and
add more Cycles-specific data at the end. Additionally, we can replace the
generic opaque void pointers with ones of the correct type, which saves us
from needing to cast them back.
Since we have a copy of ShaderGlobals for GPU OSL anyways, it's just a matter
of refactoring the code a bit to make use of that.
The advantages of this are:
- Avoids casts all over the place, just needs one cast to turn our
ShaderGlobals into the "base" type that OSL expects and one to turn the
pointer that OSL gives us on callbacks back into our "derived" type.
- Removes indirection, all the relevant stuff (sd, kg, state) is now
directly in the ShaderGlobals
- Removes some OSL-specific state from ShaderData, which helps to keep
memory usage down
Pull Request: https://projects.blender.org/blender/blender/pulls/133689
2025-01-28 03:39:00 +01:00
|
|
|
if (state != nullptr) {
|
2024-12-29 17:32:00 +01:00
|
|
|
const int num_samples = (int)s;
|
|
|
|
|
const float radius = t;
|
|
|
|
|
const float3 N = make_float3(dsdx, dtdx, dsdy);
|
2021-10-17 16:22:20 +02:00
|
|
|
int flags = 0;
|
|
|
|
|
if ((int)dtdy) {
|
|
|
|
|
flags |= NODE_AO_INSIDE;
|
|
|
|
|
}
|
|
|
|
|
if ((int)options.sblur) {
|
|
|
|
|
flags |= NODE_AO_ONLY_LOCAL;
|
|
|
|
|
}
|
|
|
|
|
if ((int)options.tblur) {
|
|
|
|
|
flags |= NODE_AO_GLOBAL_RADIUS;
|
|
|
|
|
}
|
|
|
|
|
result[0] = svm_ao(kernel_globals, state, sd, N, radius, num_samples, flags);
|
|
|
|
|
status = true;
|
2018-06-15 11:03:29 +02:00
|
|
|
}
|
2024-06-13 18:11:30 +02:00
|
|
|
#endif
|
2019-05-02 12:40:24 +02:00
|
|
|
break;
|
Cycles: Add Support for IES files as textures for light strength
This patch adds support for IES files, a file format that is commonly used to store the directional intensity distribution of light sources.
The new IES node is supposed to be plugged into the Strength input of the Emission node of the lamp.
Since people generating IES files do not really seem to care about the standard, the parser is flexible enough to accept all test files I have tried.
Some common weirdnesses are distributing values over multiple lines that should go into one line, using commas instead of spaces as delimiters and adding various useless stuff at the end of the file.
The user interface of the node is similar to the script node, the user can either select an internal Text or load a file.
Internally, IES files are handled similar to Image textures: They are stored in slots by the LightManager and each unique IES is assigned to one slot.
The local coordinate system of the lamp is used, so that the direction of the light can be changed. For UI reasons, it's usually best to add an area light,
rotate it and then change its type, since especially the point light does not immediately show its local coordinate system in the viewport.
Reviewers: #cycles, dingto, sergey, brecht
Reviewed By: #cycles, dingto, brecht
Subscribers: OgDEV, crazyrobinhood, secundar, cardboard, pisuke, intrah, swerner, micah_denn, harvester, gottfried, disnel, campbellbarton, duarteframos, Lapineige, brecht, juicyfruit, dingto, marek, rickyblender, bliblubli, lockal, sergey
Differential Revision: https://developer.blender.org/D1543
2018-05-27 00:46:37 +02:00
|
|
|
}
|
2019-05-02 12:40:24 +02:00
|
|
|
case OSLTextureHandle::SVM: {
|
2022-05-11 20:11:44 -07:00
|
|
|
int id = -1;
|
|
|
|
|
if (handle->svm_slots[0].w == -1) {
|
|
|
|
|
/* Packed single texture. */
|
|
|
|
|
id = handle->svm_slots[0].y;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
/* Packed tiled texture. */
|
2024-12-29 17:32:00 +01:00
|
|
|
const int tx = (int)s;
|
|
|
|
|
const int ty = (int)t;
|
|
|
|
|
const int tile = 1001 + 10 * ty + tx;
|
|
|
|
|
for (const int4 &tile_node : handle->svm_slots) {
|
2022-05-11 20:11:44 -07:00
|
|
|
if (tile_node.x == tile) {
|
|
|
|
|
id = tile_node.y;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if (tile_node.z == tile) {
|
|
|
|
|
id = tile_node.w;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
s -= tx;
|
|
|
|
|
t -= ty;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
float4 rgba;
|
|
|
|
|
if (id == -1) {
|
|
|
|
|
rgba = make_float4(
|
|
|
|
|
TEX_IMAGE_MISSING_R, TEX_IMAGE_MISSING_G, TEX_IMAGE_MISSING_B, TEX_IMAGE_MISSING_A);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
rgba = kernel_tex_image_interp(kernel_globals, id, s, 1.0f - t);
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2017-08-18 18:37:05 +02:00
|
|
|
result[0] = rgba[0];
|
2023-09-17 09:01:48 +10:00
|
|
|
if (nchannels > 1) {
|
2017-08-18 18:37:05 +02:00
|
|
|
result[1] = rgba[1];
|
2023-09-17 09:01:48 +10:00
|
|
|
}
|
|
|
|
|
if (nchannels > 2) {
|
2017-08-18 18:37:05 +02:00
|
|
|
result[2] = rgba[2];
|
2023-09-17 09:01:48 +10:00
|
|
|
}
|
|
|
|
|
if (nchannels > 3) {
|
2017-08-18 18:37:05 +02:00
|
|
|
result[3] = rgba[3];
|
2023-09-17 09:01:48 +10:00
|
|
|
}
|
2017-08-18 18:37:05 +02:00
|
|
|
status = true;
|
2019-05-02 12:40:24 +02:00
|
|
|
break;
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2019-05-02 12:40:24 +02:00
|
|
|
case OSLTextureHandle::IES: {
|
|
|
|
|
/* IES light. */
|
2022-05-11 20:11:44 -07:00
|
|
|
result[0] = kernel_ies_interp(kernel_globals, handle->svm_slots[0].y, s, t);
|
2019-05-02 12:40:24 +02:00
|
|
|
status = true;
|
|
|
|
|
break;
|
2015-12-18 21:42:04 +05:00
|
|
|
}
|
2019-05-02 12:40:24 +02:00
|
|
|
case OSLTextureHandle::OIIO: {
|
|
|
|
|
/* OpenImageIO texture cache. */
|
2022-09-12 18:46:20 +02:00
|
|
|
OSL::TextureSystem *ts = m_texturesys;
|
2019-05-02 12:40:24 +02:00
|
|
|
|
|
|
|
|
if (handle && handle->oiio_handle) {
|
2024-12-26 17:53:55 +01:00
|
|
|
if (texture_thread_info == nullptr) {
|
2024-12-29 23:13:45 +01:00
|
|
|
texture_thread_info = kernel_globals->osl.oiio_thread_info;
|
2019-05-02 12:40:24 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
status = ts->texture(handle->oiio_handle,
|
|
|
|
|
texture_thread_info,
|
|
|
|
|
options,
|
|
|
|
|
s,
|
|
|
|
|
t,
|
|
|
|
|
dsdx,
|
|
|
|
|
dtdx,
|
|
|
|
|
dsdy,
|
|
|
|
|
dtdy,
|
|
|
|
|
nchannels,
|
|
|
|
|
result,
|
|
|
|
|
dresultds,
|
|
|
|
|
dresultdt);
|
|
|
|
|
}
|
|
|
|
|
else {
|
2023-08-10 20:01:09 +02:00
|
|
|
status = ts->texture(to_ustring(filename),
|
2019-05-02 12:40:24 +02:00
|
|
|
options,
|
|
|
|
|
s,
|
|
|
|
|
t,
|
|
|
|
|
dsdx,
|
|
|
|
|
dtdx,
|
|
|
|
|
dsdy,
|
|
|
|
|
dtdy,
|
|
|
|
|
nchannels,
|
|
|
|
|
result,
|
|
|
|
|
dresultds,
|
|
|
|
|
dresultdt);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!status) {
|
|
|
|
|
/* This might be slow, but prevents error messages leak and
|
|
|
|
|
* other nasty stuff happening. */
|
|
|
|
|
ts->geterror();
|
|
|
|
|
}
|
2019-05-02 15:45:31 +02:00
|
|
|
else if (handle && handle->processor) {
|
|
|
|
|
ColorSpaceManager::to_scene_linear(handle->processor, result, nchannels);
|
|
|
|
|
}
|
2019-05-02 12:40:24 +02:00
|
|
|
break;
|
2014-06-12 13:26:48 +06:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
|
2012-11-20 17:40:21 +00:00
|
|
|
if (!status) {
|
2014-11-04 15:49:28 +05:00
|
|
|
if (nchannels == 3 || nchannels == 4) {
|
2012-11-20 17:40:21 +00:00
|
|
|
result[0] = 1.0f;
|
|
|
|
|
result[1] = 0.0f;
|
|
|
|
|
result[2] = 1.0f;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2023-09-17 09:01:48 +10:00
|
|
|
if (nchannels == 4) {
|
2012-11-20 17:40:21 +00:00
|
|
|
result[3] = 1.0f;
|
2023-09-17 09:01:48 +10:00
|
|
|
}
|
2012-11-20 17:40:21 +00:00
|
|
|
}
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-11-20 17:40:21 +00:00
|
|
|
return status;
|
|
|
|
|
}
|
|
|
|
|
|
2023-08-10 20:01:09 +02:00
|
|
|
bool OSLRenderServices::texture3d(OSLUStringHash filename,
|
2015-12-18 21:42:04 +05:00
|
|
|
TextureHandle *texture_handle,
|
|
|
|
|
TexturePerthread *texture_thread_info,
|
2024-12-26 17:53:58 +01:00
|
|
|
OSL::TextureOpt &options,
|
2015-12-18 21:42:04 +05:00
|
|
|
OSL::ShaderGlobals *sg,
|
|
|
|
|
const OSL::Vec3 &P,
|
|
|
|
|
const OSL::Vec3 &dPdx,
|
|
|
|
|
const OSL::Vec3 &dPdy,
|
|
|
|
|
const OSL::Vec3 &dPdz,
|
2025-01-01 18:15:54 +01:00
|
|
|
const int nchannels,
|
2015-12-18 21:42:04 +05:00
|
|
|
float *result,
|
|
|
|
|
float *dresultds,
|
|
|
|
|
float *dresultdt,
|
2019-01-02 19:55:26 +01:00
|
|
|
float *dresultdr,
|
2023-08-10 20:01:09 +02:00
|
|
|
OSLUStringHash *errormessage)
|
2012-11-20 17:40:21 +00:00
|
|
|
{
|
2019-05-02 12:40:24 +02:00
|
|
|
OSLTextureHandle *handle = (OSLTextureHandle *)texture_handle;
|
2024-12-29 17:32:00 +01:00
|
|
|
const OSLTextureHandle::Type texture_type = (handle) ? handle->type : OSLTextureHandle::OIIO;
|
Cycles: Refactor: Store Cycles-specific pointers in our own ShaderGlobals
OSL has OSL::ShaderGlobals, which contains all the state for OSL shader
execution. The renderer fills it out and hands a pointer to OSL, and any
callbacks (e.g. for querying attributes) get the pointer back.
In order to store renderer-specific data in it, there's a few opaque pointers
in the struct, but using those has led to a mess of reinterpret_cast<> and
pointer indirection in order to carry all the data around.
However, there is a way to do this nicer: Good old C-style struct inheritance.
In short: Unless you're doing pointer arithmetic, you can just add additional
data at the end of a base struct, and the rest of the code won't care.
In this case, this means that we can have our own ShaderGlobals struct and
add more Cycles-specific data at the end. Additionally, we can replace the
generic opaque void pointers with ones of the correct type, which saves us
from needing to cast them back.
Since we have a copy of ShaderGlobals for GPU OSL anyways, it's just a matter
of refactoring the code a bit to make use of that.
The advantages of this are:
- Avoids casts all over the place, just needs one cast to turn our
ShaderGlobals into the "base" type that OSL expects and one to turn the
pointer that OSL gives us on callbacks back into our "derived" type.
- Removes indirection, all the relevant stuff (sd, kg, state) is now
directly in the ShaderGlobals
- Removes some OSL-specific state from ShaderData, which helps to keep
memory usage down
Pull Request: https://projects.blender.org/blender/blender/pulls/133689
2025-01-28 03:39:00 +01:00
|
|
|
ShaderGlobals *globals = reinterpret_cast<ShaderGlobals *>(sg);
|
|
|
|
|
const ThreadKernelGlobalsCPU *kernel_globals = globals->kg;
|
2019-05-02 12:40:24 +02:00
|
|
|
bool status = false;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-05-02 12:40:24 +02:00
|
|
|
switch (texture_type) {
|
|
|
|
|
case OSLTextureHandle::SVM: {
|
|
|
|
|
/* Packed texture. */
|
2024-12-29 17:32:00 +01:00
|
|
|
const int slot = handle->svm_slots[0].y;
|
|
|
|
|
const float3 P_float3 = make_float3(P.x, P.y, P.z);
|
2020-03-17 16:48:00 +01:00
|
|
|
float4 rgba = kernel_tex_image_interp_3d(kernel_globals, slot, P_float3, INTERPOLATION_NONE);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-05-02 12:40:24 +02:00
|
|
|
result[0] = rgba[0];
|
2023-09-17 09:01:48 +10:00
|
|
|
if (nchannels > 1) {
|
2019-05-02 12:40:24 +02:00
|
|
|
result[1] = rgba[1];
|
2023-09-17 09:01:48 +10:00
|
|
|
}
|
|
|
|
|
if (nchannels > 2) {
|
2019-05-02 12:40:24 +02:00
|
|
|
result[2] = rgba[2];
|
2023-09-17 09:01:48 +10:00
|
|
|
}
|
|
|
|
|
if (nchannels > 3) {
|
2019-05-02 12:40:24 +02:00
|
|
|
result[3] = rgba[3];
|
2023-09-17 09:01:48 +10:00
|
|
|
}
|
2019-05-02 12:40:24 +02:00
|
|
|
status = true;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case OSLTextureHandle::OIIO: {
|
|
|
|
|
/* OpenImageIO texture cache. */
|
2022-09-12 18:46:20 +02:00
|
|
|
OSL::TextureSystem *ts = m_texturesys;
|
2019-05-02 12:40:24 +02:00
|
|
|
|
|
|
|
|
if (handle && handle->oiio_handle) {
|
2024-12-26 17:53:55 +01:00
|
|
|
if (texture_thread_info == nullptr) {
|
2024-12-29 23:13:45 +01:00
|
|
|
texture_thread_info = kernel_globals->osl.oiio_thread_info;
|
2019-05-02 12:40:24 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
status = ts->texture3d(handle->oiio_handle,
|
|
|
|
|
texture_thread_info,
|
|
|
|
|
options,
|
|
|
|
|
P,
|
|
|
|
|
dPdx,
|
|
|
|
|
dPdy,
|
|
|
|
|
dPdz,
|
|
|
|
|
nchannels,
|
|
|
|
|
result,
|
|
|
|
|
dresultds,
|
|
|
|
|
dresultdt,
|
|
|
|
|
dresultdr);
|
|
|
|
|
}
|
|
|
|
|
else {
|
2023-08-10 20:01:09 +02:00
|
|
|
status = ts->texture3d(to_ustring(filename),
|
2019-05-02 12:40:24 +02:00
|
|
|
options,
|
|
|
|
|
P,
|
|
|
|
|
dPdx,
|
|
|
|
|
dPdy,
|
|
|
|
|
dPdz,
|
|
|
|
|
nchannels,
|
|
|
|
|
result,
|
|
|
|
|
dresultds,
|
|
|
|
|
dresultdt,
|
|
|
|
|
dresultdr);
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-05-02 12:40:24 +02:00
|
|
|
if (!status) {
|
|
|
|
|
/* This might be slow, but prevents error messages leak and
|
|
|
|
|
* other nasty stuff happening. */
|
|
|
|
|
ts->geterror();
|
|
|
|
|
}
|
2019-05-02 15:45:31 +02:00
|
|
|
else if (handle && handle->processor) {
|
|
|
|
|
ColorSpaceManager::to_scene_linear(handle->processor, result, nchannels);
|
|
|
|
|
}
|
2019-05-02 12:40:24 +02:00
|
|
|
break;
|
2015-12-18 21:42:04 +05:00
|
|
|
}
|
2019-05-02 12:40:24 +02:00
|
|
|
case OSLTextureHandle::IES:
|
|
|
|
|
case OSLTextureHandle::AO:
|
|
|
|
|
case OSLTextureHandle::BEVEL: {
|
|
|
|
|
status = false;
|
|
|
|
|
break;
|
2015-04-06 23:29:29 +05:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
|
2012-11-20 17:40:21 +00:00
|
|
|
if (!status) {
|
2014-11-04 15:49:28 +05:00
|
|
|
if (nchannels == 3 || nchannels == 4) {
|
2012-11-20 17:40:21 +00:00
|
|
|
result[0] = 1.0f;
|
|
|
|
|
result[1] = 0.0f;
|
|
|
|
|
result[2] = 1.0f;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2023-09-17 09:01:48 +10:00
|
|
|
if (nchannels == 4) {
|
2012-11-20 17:40:21 +00:00
|
|
|
result[3] = 1.0f;
|
2023-09-17 09:01:48 +10:00
|
|
|
}
|
2012-11-20 17:40:21 +00:00
|
|
|
}
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-11-20 17:40:21 +00:00
|
|
|
return status;
|
|
|
|
|
}
|
|
|
|
|
|
2023-08-10 20:01:09 +02:00
|
|
|
bool OSLRenderServices::environment(OSLUStringHash filename,
|
2019-05-02 12:40:24 +02:00
|
|
|
TextureHandle *texture_handle,
|
2019-01-02 19:55:26 +01:00
|
|
|
TexturePerthread *thread_info,
|
2024-12-26 17:53:58 +01:00
|
|
|
OSL::TextureOpt &options,
|
2019-01-02 19:55:26 +01:00
|
|
|
OSL::ShaderGlobals *sg,
|
|
|
|
|
const OSL::Vec3 &R,
|
|
|
|
|
const OSL::Vec3 &dRdx,
|
|
|
|
|
const OSL::Vec3 &dRdy,
|
2025-01-01 18:15:54 +01:00
|
|
|
const int nchannels,
|
2019-01-02 19:55:26 +01:00
|
|
|
float *result,
|
|
|
|
|
float *dresultds,
|
|
|
|
|
float *dresultdt,
|
2023-08-10 20:01:09 +02:00
|
|
|
OSLUStringHash *errormessage)
|
2012-11-20 17:40:21 +00:00
|
|
|
{
|
2019-05-02 12:40:24 +02:00
|
|
|
OSLTextureHandle *handle = (OSLTextureHandle *)texture_handle;
|
2022-09-12 18:46:20 +02:00
|
|
|
OSL::TextureSystem *ts = m_texturesys;
|
Cycles: Refactor: Store Cycles-specific pointers in our own ShaderGlobals
OSL has OSL::ShaderGlobals, which contains all the state for OSL shader
execution. The renderer fills it out and hands a pointer to OSL, and any
callbacks (e.g. for querying attributes) get the pointer back.
In order to store renderer-specific data in it, there's a few opaque pointers
in the struct, but using those has led to a mess of reinterpret_cast<> and
pointer indirection in order to carry all the data around.
However, there is a way to do this nicer: Good old C-style struct inheritance.
In short: Unless you're doing pointer arithmetic, you can just add additional
data at the end of a base struct, and the rest of the code won't care.
In this case, this means that we can have our own ShaderGlobals struct and
add more Cycles-specific data at the end. Additionally, we can replace the
generic opaque void pointers with ones of the correct type, which saves us
from needing to cast them back.
Since we have a copy of ShaderGlobals for GPU OSL anyways, it's just a matter
of refactoring the code a bit to make use of that.
The advantages of this are:
- Avoids casts all over the place, just needs one cast to turn our
ShaderGlobals into the "base" type that OSL expects and one to turn the
pointer that OSL gives us on callbacks back into our "derived" type.
- Removes indirection, all the relevant stuff (sd, kg, state) is now
directly in the ShaderGlobals
- Removes some OSL-specific state from ShaderData, which helps to keep
memory usage down
Pull Request: https://projects.blender.org/blender/blender/pulls/133689
2025-01-28 03:39:00 +01:00
|
|
|
ShaderGlobals *globals = reinterpret_cast<ShaderGlobals *>(sg);
|
2019-05-02 12:40:24 +02:00
|
|
|
bool status = false;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-05-02 12:40:24 +02:00
|
|
|
if (handle && handle->oiio_handle) {
|
2024-12-26 17:53:55 +01:00
|
|
|
if (thread_info == nullptr) {
|
Cycles: Refactor: Store Cycles-specific pointers in our own ShaderGlobals
OSL has OSL::ShaderGlobals, which contains all the state for OSL shader
execution. The renderer fills it out and hands a pointer to OSL, and any
callbacks (e.g. for querying attributes) get the pointer back.
In order to store renderer-specific data in it, there's a few opaque pointers
in the struct, but using those has led to a mess of reinterpret_cast<> and
pointer indirection in order to carry all the data around.
However, there is a way to do this nicer: Good old C-style struct inheritance.
In short: Unless you're doing pointer arithmetic, you can just add additional
data at the end of a base struct, and the rest of the code won't care.
In this case, this means that we can have our own ShaderGlobals struct and
add more Cycles-specific data at the end. Additionally, we can replace the
generic opaque void pointers with ones of the correct type, which saves us
from needing to cast them back.
Since we have a copy of ShaderGlobals for GPU OSL anyways, it's just a matter
of refactoring the code a bit to make use of that.
The advantages of this are:
- Avoids casts all over the place, just needs one cast to turn our
ShaderGlobals into the "base" type that OSL expects and one to turn the
pointer that OSL gives us on callbacks back into our "derived" type.
- Removes indirection, all the relevant stuff (sd, kg, state) is now
directly in the ShaderGlobals
- Removes some OSL-specific state from ShaderData, which helps to keep
memory usage down
Pull Request: https://projects.blender.org/blender/blender/pulls/133689
2025-01-28 03:39:00 +01:00
|
|
|
thread_info = globals->kg->osl.oiio_thread_info;
|
2019-05-02 12:40:24 +02:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-05-02 12:40:24 +02:00
|
|
|
status = ts->environment(handle->oiio_handle,
|
|
|
|
|
thread_info,
|
|
|
|
|
options,
|
|
|
|
|
R,
|
|
|
|
|
dRdx,
|
|
|
|
|
dRdy,
|
|
|
|
|
nchannels,
|
|
|
|
|
result,
|
|
|
|
|
dresultds,
|
|
|
|
|
dresultdt);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
status = ts->environment(
|
2023-08-10 20:01:09 +02:00
|
|
|
to_ustring(filename), options, R, dRdx, dRdy, nchannels, result, dresultds, dresultdt);
|
2019-01-02 19:55:26 +01:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-11-20 17:40:21 +00:00
|
|
|
if (!status) {
|
2014-11-04 15:49:28 +05:00
|
|
|
if (nchannels == 3 || nchannels == 4) {
|
2012-11-20 17:40:21 +00:00
|
|
|
result[0] = 1.0f;
|
|
|
|
|
result[1] = 0.0f;
|
|
|
|
|
result[2] = 1.0f;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2023-09-17 09:01:48 +10:00
|
|
|
if (nchannels == 4) {
|
2012-11-20 17:40:21 +00:00
|
|
|
result[3] = 1.0f;
|
2023-09-17 09:01:48 +10:00
|
|
|
}
|
2012-11-20 17:40:21 +00:00
|
|
|
}
|
|
|
|
|
}
|
2019-05-02 15:45:31 +02:00
|
|
|
else if (handle && handle->processor) {
|
|
|
|
|
ColorSpaceManager::to_scene_linear(handle->processor, result, nchannels);
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-11-20 17:40:21 +00:00
|
|
|
return status;
|
|
|
|
|
}
|
|
|
|
|
|
2023-12-10 17:08:47 +01:00
|
|
|
bool OSLRenderServices::get_texture_info(OSLUStringHash filename,
|
|
|
|
|
TextureHandle *texture_handle,
|
|
|
|
|
TexturePerthread *texture_thread_info,
|
2024-12-26 17:53:59 +01:00
|
|
|
OSL::ShaderGlobals * /*sg*/,
|
2025-01-01 18:15:54 +01:00
|
|
|
const int subimage,
|
2023-12-10 17:08:47 +01:00
|
|
|
OSLUStringHash dataname,
|
2025-01-01 18:15:54 +01:00
|
|
|
const TypeDesc datatype,
|
2023-12-10 17:08:47 +01:00
|
|
|
void *data,
|
2024-12-26 17:53:59 +01:00
|
|
|
OSLUStringHash * /*errormessage*/)
|
2012-11-20 17:40:21 +00:00
|
|
|
{
|
2019-05-02 12:40:24 +02:00
|
|
|
OSLTextureHandle *handle = (OSLTextureHandle *)texture_handle;
|
2025-03-17 16:18:31 +01:00
|
|
|
OSL::TextureSystem *ts = m_texturesys;
|
2019-05-02 12:40:24 +02:00
|
|
|
|
2025-03-17 16:18:31 +01:00
|
|
|
if (handle) {
|
|
|
|
|
/* No texture info for other texture types. */
|
|
|
|
|
if (handle->type != OSLTextureHandle::OIIO) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2019-05-02 12:40:24 +02:00
|
|
|
|
2025-03-17 16:18:31 +01:00
|
|
|
if (handle->oiio_handle) {
|
|
|
|
|
/* Get texture info from OpenImageIO. */
|
|
|
|
|
return ts->get_texture_info(handle->oiio_handle,
|
|
|
|
|
texture_thread_info,
|
|
|
|
|
subimage,
|
|
|
|
|
to_ustring(dataname),
|
|
|
|
|
datatype,
|
|
|
|
|
data);
|
|
|
|
|
}
|
2023-08-10 20:01:09 +02:00
|
|
|
}
|
2024-12-26 17:53:59 +01:00
|
|
|
|
2025-03-17 16:18:31 +01:00
|
|
|
/* Get texture info from OpenImageIO, slower using filename. */
|
2024-12-26 17:53:59 +01:00
|
|
|
return ts->get_texture_info(
|
|
|
|
|
to_ustring(filename), subimage, to_ustring(dataname), datatype, data);
|
2012-11-20 17:40:21 +00:00
|
|
|
}
|
|
|
|
|
|
2012-09-02 01:10:31 +00:00
|
|
|
int OSLRenderServices::pointcloud_search(OSL::ShaderGlobals *sg,
|
2023-08-10 20:01:09 +02:00
|
|
|
OSLUStringHash filename,
|
2012-09-02 01:10:31 +00:00
|
|
|
const OSL::Vec3 ¢er,
|
2025-01-01 18:15:54 +01:00
|
|
|
const float radius,
|
|
|
|
|
const int max_points,
|
2012-09-14 23:11:47 +00:00
|
|
|
bool sort,
|
2025-01-05 01:19:04 +01:00
|
|
|
#if OSL_LIBRARY_VERSION_CODE >= 11400
|
|
|
|
|
int *indices,
|
|
|
|
|
#else
|
2012-09-14 23:11:47 +00:00
|
|
|
size_t *out_indices,
|
2025-01-05 01:19:04 +01:00
|
|
|
#endif
|
2012-09-14 23:11:47 +00:00
|
|
|
float *out_distances,
|
2025-01-01 18:15:54 +01:00
|
|
|
const int derivs_offset)
|
2011-04-27 11:58:34 +00:00
|
|
|
{
|
2012-09-14 23:11:47 +00:00
|
|
|
return 0;
|
2011-04-27 11:58:34 +00:00
|
|
|
}
|
|
|
|
|
|
2014-02-04 22:48:32 +01:00
|
|
|
int OSLRenderServices::pointcloud_get(OSL::ShaderGlobals *sg,
|
2023-08-10 20:01:09 +02:00
|
|
|
OSLUStringHash filename,
|
2025-01-05 01:19:04 +01:00
|
|
|
#if OSL_LIBRARY_VERSION_CODE >= 11400
|
|
|
|
|
const int *indices,
|
|
|
|
|
#else
|
2014-02-04 22:48:32 +01:00
|
|
|
size_t *indices,
|
2025-01-05 01:19:04 +01:00
|
|
|
#endif
|
2025-01-01 18:15:54 +01:00
|
|
|
const int count,
|
2023-08-10 20:01:09 +02:00
|
|
|
OSLUStringHash attr_name,
|
2025-01-01 18:15:54 +01:00
|
|
|
const TypeDesc attr_type,
|
2012-09-14 23:11:47 +00:00
|
|
|
void *out_data)
|
2011-04-27 11:58:34 +00:00
|
|
|
{
|
2012-09-14 23:11:47 +00:00
|
|
|
return 0;
|
2011-04-27 11:58:34 +00:00
|
|
|
}
|
|
|
|
|
|
2014-02-04 22:48:32 +01:00
|
|
|
bool OSLRenderServices::pointcloud_write(OSL::ShaderGlobals *sg,
|
2023-08-10 20:01:09 +02:00
|
|
|
OSLUStringHash filename,
|
2014-02-04 22:48:32 +01:00
|
|
|
const OSL::Vec3 &pos,
|
2025-01-01 18:15:54 +01:00
|
|
|
const int nattribs,
|
2023-08-10 20:01:09 +02:00
|
|
|
const OSLUStringRep *names,
|
2014-02-04 22:48:32 +01:00
|
|
|
const TypeDesc *types,
|
|
|
|
|
const void **data)
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
Cycles OSL: support for the trace(point pos, vector dir, ...) function, to trace
rays from the OSL shader. The "shade" parameter is not supported currently, but
attributes can be retrieved from the object that was hit using the
getmessage("trace", ..) function.
As mentioned in the OSL specification, this function can't be used instead of
lighting, the main purpose is to allow shaders to "probe" nearby geometry, for
example to apply a projected texture that can be blocked by geometry, apply
more “wear” to exposed geometry, or make other ambient occlusion-like effects.
http://wiki.blender.org/index.php/Doc:2.6/Manual/Render/Cycles/Nodes/OSL#Trace
Example .blend and render:
http://www.pasteall.org/blend/17347
http://www.pasteall.org/pic/show.php?id=40066
2012-11-06 19:59:10 +00:00
|
|
|
bool OSLRenderServices::trace(TraceOpt &options,
|
|
|
|
|
OSL::ShaderGlobals *sg,
|
|
|
|
|
const OSL::Vec3 &P,
|
|
|
|
|
const OSL::Vec3 &dPdx,
|
|
|
|
|
const OSL::Vec3 &dPdy,
|
|
|
|
|
const OSL::Vec3 &R,
|
|
|
|
|
const OSL::Vec3 &dRdx,
|
|
|
|
|
const OSL::Vec3 &dRdy)
|
|
|
|
|
{
|
|
|
|
|
/* todo: options.shader support, maybe options.traceset */
|
Cycles: Refactor: Store Cycles-specific pointers in our own ShaderGlobals
OSL has OSL::ShaderGlobals, which contains all the state for OSL shader
execution. The renderer fills it out and hands a pointer to OSL, and any
callbacks (e.g. for querying attributes) get the pointer back.
In order to store renderer-specific data in it, there's a few opaque pointers
in the struct, but using those has led to a mess of reinterpret_cast<> and
pointer indirection in order to carry all the data around.
However, there is a way to do this nicer: Good old C-style struct inheritance.
In short: Unless you're doing pointer arithmetic, you can just add additional
data at the end of a base struct, and the rest of the code won't care.
In this case, this means that we can have our own ShaderGlobals struct and
add more Cycles-specific data at the end. Additionally, we can replace the
generic opaque void pointers with ones of the correct type, which saves us
from needing to cast them back.
Since we have a copy of ShaderGlobals for GPU OSL anyways, it's just a matter
of refactoring the code a bit to make use of that.
The advantages of this are:
- Avoids casts all over the place, just needs one cast to turn our
ShaderGlobals into the "base" type that OSL expects and one to turn the
pointer that OSL gives us on callbacks back into our "derived" type.
- Removes indirection, all the relevant stuff (sd, kg, state) is now
directly in the ShaderGlobals
- Removes some OSL-specific state from ShaderData, which helps to keep
memory usage down
Pull Request: https://projects.blender.org/blender/blender/pulls/133689
2025-01-28 03:39:00 +01:00
|
|
|
ShaderGlobals *globals = reinterpret_cast<ShaderGlobals *>(sg);
|
|
|
|
|
ShaderData *sd = globals->sd;
|
|
|
|
|
const ThreadKernelGlobalsCPU *kg = globals->kg;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2025-04-25 19:27:30 +02:00
|
|
|
if (sd == nullptr) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
Cycles OSL: support for the trace(point pos, vector dir, ...) function, to trace
rays from the OSL shader. The "shade" parameter is not supported currently, but
attributes can be retrieved from the object that was hit using the
getmessage("trace", ..) function.
As mentioned in the OSL specification, this function can't be used instead of
lighting, the main purpose is to allow shaders to "probe" nearby geometry, for
example to apply a projected texture that can be blocked by geometry, apply
more “wear” to exposed geometry, or make other ambient occlusion-like effects.
http://wiki.blender.org/index.php/Doc:2.6/Manual/Render/Cycles/Nodes/OSL#Trace
Example .blend and render:
http://www.pasteall.org/blend/17347
http://www.pasteall.org/pic/show.php?id=40066
2012-11-06 19:59:10 +00:00
|
|
|
/* setup ray */
|
|
|
|
|
Ray ray;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2022-09-08 19:31:44 +02:00
|
|
|
ray.P = make_float3(P.x, P.y, P.z);
|
|
|
|
|
ray.D = make_float3(R.x, R.y, R.z);
|
2022-07-13 16:54:53 +02:00
|
|
|
ray.tmin = 0.0f;
|
|
|
|
|
ray.tmax = (options.maxdist == 1.0e30f) ? FLT_MAX : options.maxdist - options.mindist;
|
Cycles OSL: support for the trace(point pos, vector dir, ...) function, to trace
rays from the OSL shader. The "shade" parameter is not supported currently, but
attributes can be retrieved from the object that was hit using the
getmessage("trace", ..) function.
As mentioned in the OSL specification, this function can't be used instead of
lighting, the main purpose is to allow shaders to "probe" nearby geometry, for
example to apply a projected texture that can be blocked by geometry, apply
more “wear” to exposed geometry, or make other ambient occlusion-like effects.
http://wiki.blender.org/index.php/Doc:2.6/Manual/Render/Cycles/Nodes/OSL#Trace
Example .blend and render:
http://www.pasteall.org/blend/17347
http://www.pasteall.org/pic/show.php?id=40066
2012-11-06 19:59:10 +00:00
|
|
|
ray.time = sd->time;
|
2022-02-23 18:38:51 +01:00
|
|
|
ray.self.object = OBJECT_NONE;
|
|
|
|
|
ray.self.prim = PRIM_NONE;
|
|
|
|
|
ray.self.light_object = OBJECT_NONE;
|
|
|
|
|
ray.self.light_prim = PRIM_NONE;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
Cycles OSL: support for the trace(point pos, vector dir, ...) function, to trace
rays from the OSL shader. The "shade" parameter is not supported currently, but
attributes can be retrieved from the object that was hit using the
getmessage("trace", ..) function.
As mentioned in the OSL specification, this function can't be used instead of
lighting, the main purpose is to allow shaders to "probe" nearby geometry, for
example to apply a projected texture that can be blocked by geometry, apply
more “wear” to exposed geometry, or make other ambient occlusion-like effects.
http://wiki.blender.org/index.php/Doc:2.6/Manual/Render/Cycles/Nodes/OSL#Trace
Example .blend and render:
http://www.pasteall.org/blend/17347
http://www.pasteall.org/pic/show.php?id=40066
2012-11-06 19:59:10 +00:00
|
|
|
if (options.mindist == 0.0f) {
|
|
|
|
|
/* avoid self-intersections */
|
|
|
|
|
if (ray.P == sd->P) {
|
2022-02-23 18:38:51 +01:00
|
|
|
ray.self.object = sd->object;
|
|
|
|
|
ray.self.prim = sd->prim;
|
Cycles OSL: support for the trace(point pos, vector dir, ...) function, to trace
rays from the OSL shader. The "shade" parameter is not supported currently, but
attributes can be retrieved from the object that was hit using the
getmessage("trace", ..) function.
As mentioned in the OSL specification, this function can't be used instead of
lighting, the main purpose is to allow shaders to "probe" nearby geometry, for
example to apply a projected texture that can be blocked by geometry, apply
more “wear” to exposed geometry, or make other ambient occlusion-like effects.
http://wiki.blender.org/index.php/Doc:2.6/Manual/Render/Cycles/Nodes/OSL#Trace
Example .blend and render:
http://www.pasteall.org/blend/17347
http://www.pasteall.org/pic/show.php?id=40066
2012-11-06 19:59:10 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
/* offset for minimum distance */
|
|
|
|
|
ray.P += options.mindist * ray.D;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
Cycles OSL: support for the trace(point pos, vector dir, ...) function, to trace
rays from the OSL shader. The "shade" parameter is not supported currently, but
attributes can be retrieved from the object that was hit using the
getmessage("trace", ..) function.
As mentioned in the OSL specification, this function can't be used instead of
lighting, the main purpose is to allow shaders to "probe" nearby geometry, for
example to apply a projected texture that can be blocked by geometry, apply
more “wear” to exposed geometry, or make other ambient occlusion-like effects.
http://wiki.blender.org/index.php/Doc:2.6/Manual/Render/Cycles/Nodes/OSL#Trace
Example .blend and render:
http://www.pasteall.org/blend/17347
http://www.pasteall.org/pic/show.php?id=40066
2012-11-06 19:59:10 +00:00
|
|
|
/* ray differentials */
|
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
|
|
|
differential3 dP;
|
2022-09-08 19:31:44 +02:00
|
|
|
dP.dx = make_float3(dPdx.x, dPdx.y, dPdx.z);
|
|
|
|
|
dP.dy = make_float3(dPdy.x, dPdy.y, dPdy.z);
|
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
|
|
|
ray.dP = differential_make_compact(dP);
|
|
|
|
|
differential3 dD;
|
2022-09-08 19:31:44 +02:00
|
|
|
dD.dx = make_float3(dRdx.x, dRdx.y, dRdx.z);
|
|
|
|
|
dD.dy = make_float3(dRdy.x, dRdy.y, dRdy.z);
|
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
|
|
|
ray.dD = differential_make_compact(dD);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
Cycles OSL: support for the trace(point pos, vector dir, ...) function, to trace
rays from the OSL shader. The "shade" parameter is not supported currently, but
attributes can be retrieved from the object that was hit using the
getmessage("trace", ..) function.
As mentioned in the OSL specification, this function can't be used instead of
lighting, the main purpose is to allow shaders to "probe" nearby geometry, for
example to apply a projected texture that can be blocked by geometry, apply
more “wear” to exposed geometry, or make other ambient occlusion-like effects.
http://wiki.blender.org/index.php/Doc:2.6/Manual/Render/Cycles/Nodes/OSL#Trace
Example .blend and render:
http://www.pasteall.org/blend/17347
http://www.pasteall.org/pic/show.php?id=40066
2012-11-06 19:59:10 +00:00
|
|
|
/* allocate trace data */
|
Cycles: Refactor: Store Cycles-specific pointers in our own ShaderGlobals
OSL has OSL::ShaderGlobals, which contains all the state for OSL shader
execution. The renderer fills it out and hands a pointer to OSL, and any
callbacks (e.g. for querying attributes) get the pointer back.
In order to store renderer-specific data in it, there's a few opaque pointers
in the struct, but using those has led to a mess of reinterpret_cast<> and
pointer indirection in order to carry all the data around.
However, there is a way to do this nicer: Good old C-style struct inheritance.
In short: Unless you're doing pointer arithmetic, you can just add additional
data at the end of a base struct, and the rest of the code won't care.
In this case, this means that we can have our own ShaderGlobals struct and
add more Cycles-specific data at the end. Additionally, we can replace the
generic opaque void pointers with ones of the correct type, which saves us
from needing to cast them back.
Since we have a copy of ShaderGlobals for GPU OSL anyways, it's just a matter
of refactoring the code a bit to make use of that.
The advantages of this are:
- Avoids casts all over the place, just needs one cast to turn our
ShaderGlobals into the "base" type that OSL expects and one to turn the
pointer that OSL gives us on callbacks back into our "derived" type.
- Removes indirection, all the relevant stuff (sd, kg, state) is now
directly in the ShaderGlobals
- Removes some OSL-specific state from ShaderData, which helps to keep
memory usage down
Pull Request: https://projects.blender.org/blender/blender/pulls/133689
2025-01-28 03:39:00 +01:00
|
|
|
OSLTraceData *tracedata = globals->tracedata;
|
Cycles OSL: support for the trace(point pos, vector dir, ...) function, to trace
rays from the OSL shader. The "shade" parameter is not supported currently, but
attributes can be retrieved from the object that was hit using the
getmessage("trace", ..) function.
As mentioned in the OSL specification, this function can't be used instead of
lighting, the main purpose is to allow shaders to "probe" nearby geometry, for
example to apply a projected texture that can be blocked by geometry, apply
more “wear” to exposed geometry, or make other ambient occlusion-like effects.
http://wiki.blender.org/index.php/Doc:2.6/Manual/Render/Cycles/Nodes/OSL#Trace
Example .blend and render:
http://www.pasteall.org/blend/17347
http://www.pasteall.org/pic/show.php?id=40066
2012-11-06 19:59:10 +00:00
|
|
|
tracedata->ray = ray;
|
|
|
|
|
tracedata->setup = false;
|
2012-12-15 10:18:42 +00:00
|
|
|
tracedata->init = true;
|
2020-08-24 14:30:54 +02:00
|
|
|
tracedata->hit = false;
|
2019-06-27 12:39:10 +02:00
|
|
|
|
2022-06-30 12:14:22 +10:00
|
|
|
/* Can't ray-trace from shaders like displacement, before BVH exists. */
|
2019-06-27 12:39:10 +02:00
|
|
|
if (kernel_data.bvh.bvh_layout == BVH_LAYOUT_NONE) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2022-06-30 12:14:22 +10:00
|
|
|
/* Ray-trace, leaving out shadow opaque to avoid early exit. */
|
2024-12-29 17:32:00 +01:00
|
|
|
const uint visibility = PATH_RAY_ALL_VISIBILITY - PATH_RAY_SHADOW_OPAQUE;
|
2020-08-24 14:30:54 +02:00
|
|
|
tracedata->hit = scene_intersect(kg, &ray, visibility, &tracedata->isect);
|
|
|
|
|
return tracedata->hit;
|
Cycles OSL: support for the trace(point pos, vector dir, ...) function, to trace
rays from the OSL shader. The "shade" parameter is not supported currently, but
attributes can be retrieved from the object that was hit using the
getmessage("trace", ..) function.
As mentioned in the OSL specification, this function can't be used instead of
lighting, the main purpose is to allow shaders to "probe" nearby geometry, for
example to apply a projected texture that can be blocked by geometry, apply
more “wear” to exposed geometry, or make other ambient occlusion-like effects.
http://wiki.blender.org/index.php/Doc:2.6/Manual/Render/Cycles/Nodes/OSL#Trace
Example .blend and render:
http://www.pasteall.org/blend/17347
http://www.pasteall.org/pic/show.php?id=40066
2012-11-06 19:59:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool OSLRenderServices::getmessage(OSL::ShaderGlobals *sg,
|
2023-08-10 20:01:09 +02:00
|
|
|
OSLUStringHash source,
|
|
|
|
|
OSLUStringHash name,
|
2025-01-01 18:15:54 +01:00
|
|
|
const TypeDesc type,
|
Cycles OSL: support for the trace(point pos, vector dir, ...) function, to trace
rays from the OSL shader. The "shade" parameter is not supported currently, but
attributes can be retrieved from the object that was hit using the
getmessage("trace", ..) function.
As mentioned in the OSL specification, this function can't be used instead of
lighting, the main purpose is to allow shaders to "probe" nearby geometry, for
example to apply a projected texture that can be blocked by geometry, apply
more “wear” to exposed geometry, or make other ambient occlusion-like effects.
http://wiki.blender.org/index.php/Doc:2.6/Manual/Render/Cycles/Nodes/OSL#Trace
Example .blend and render:
http://www.pasteall.org/blend/17347
http://www.pasteall.org/pic/show.php?id=40066
2012-11-06 19:59:10 +00:00
|
|
|
void *val,
|
|
|
|
|
bool derivatives)
|
|
|
|
|
{
|
Cycles: Refactor: Store Cycles-specific pointers in our own ShaderGlobals
OSL has OSL::ShaderGlobals, which contains all the state for OSL shader
execution. The renderer fills it out and hands a pointer to OSL, and any
callbacks (e.g. for querying attributes) get the pointer back.
In order to store renderer-specific data in it, there's a few opaque pointers
in the struct, but using those has led to a mess of reinterpret_cast<> and
pointer indirection in order to carry all the data around.
However, there is a way to do this nicer: Good old C-style struct inheritance.
In short: Unless you're doing pointer arithmetic, you can just add additional
data at the end of a base struct, and the rest of the code won't care.
In this case, this means that we can have our own ShaderGlobals struct and
add more Cycles-specific data at the end. Additionally, we can replace the
generic opaque void pointers with ones of the correct type, which saves us
from needing to cast them back.
Since we have a copy of ShaderGlobals for GPU OSL anyways, it's just a matter
of refactoring the code a bit to make use of that.
The advantages of this are:
- Avoids casts all over the place, just needs one cast to turn our
ShaderGlobals into the "base" type that OSL expects and one to turn the
pointer that OSL gives us on callbacks back into our "derived" type.
- Removes indirection, all the relevant stuff (sd, kg, state) is now
directly in the ShaderGlobals
- Removes some OSL-specific state from ShaderData, which helps to keep
memory usage down
Pull Request: https://projects.blender.org/blender/blender/pulls/133689
2025-01-28 03:39:00 +01:00
|
|
|
ShaderGlobals *globals = reinterpret_cast<ShaderGlobals *>(sg);
|
|
|
|
|
const ThreadKernelGlobalsCPU *kg = globals->kg;
|
|
|
|
|
OSLTraceData *tracedata = globals->tracedata;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-12-15 10:18:42 +00:00
|
|
|
if (source == u_trace && tracedata->init) {
|
2012-12-01 19:15:05 +00:00
|
|
|
if (name == u_hit) {
|
2025-02-20 19:28:45 +01:00
|
|
|
return set_attribute<int>(tracedata->hit, type, derivatives, val);
|
Cycles OSL: support for the trace(point pos, vector dir, ...) function, to trace
rays from the OSL shader. The "shade" parameter is not supported currently, but
attributes can be retrieved from the object that was hit using the
getmessage("trace", ..) function.
As mentioned in the OSL specification, this function can't be used instead of
lighting, the main purpose is to allow shaders to "probe" nearby geometry, for
example to apply a projected texture that can be blocked by geometry, apply
more “wear” to exposed geometry, or make other ambient occlusion-like effects.
http://wiki.blender.org/index.php/Doc:2.6/Manual/Render/Cycles/Nodes/OSL#Trace
Example .blend and render:
http://www.pasteall.org/blend/17347
http://www.pasteall.org/pic/show.php?id=40066
2012-11-06 19:59:10 +00:00
|
|
|
}
|
2024-12-26 17:53:59 +01:00
|
|
|
if (tracedata->hit) {
|
2012-12-01 19:15:05 +00:00
|
|
|
if (name == u_hitdist) {
|
2025-02-20 19:28:45 +01:00
|
|
|
return set_attribute(tracedata->isect.t, type, derivatives, val);
|
Cycles OSL: support for the trace(point pos, vector dir, ...) function, to trace
rays from the OSL shader. The "shade" parameter is not supported currently, but
attributes can be retrieved from the object that was hit using the
getmessage("trace", ..) function.
As mentioned in the OSL specification, this function can't be used instead of
lighting, the main purpose is to allow shaders to "probe" nearby geometry, for
example to apply a projected texture that can be blocked by geometry, apply
more “wear” to exposed geometry, or make other ambient occlusion-like effects.
http://wiki.blender.org/index.php/Doc:2.6/Manual/Render/Cycles/Nodes/OSL#Trace
Example .blend and render:
http://www.pasteall.org/blend/17347
http://www.pasteall.org/pic/show.php?id=40066
2012-11-06 19:59:10 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2024-12-26 17:53:59 +01:00
|
|
|
ShaderData *sd = &tracedata->sd;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2024-12-26 17:53:59 +01:00
|
|
|
if (!tracedata->setup) {
|
|
|
|
|
/* lazy shader data setup */
|
|
|
|
|
shader_setup_from_ray(kg, sd, &tracedata->ray, &tracedata->isect);
|
|
|
|
|
tracedata->setup = true;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2024-12-26 17:53:59 +01:00
|
|
|
if (name == u_N) {
|
2025-02-20 19:28:45 +01:00
|
|
|
return set_attribute(sd->N, type, derivatives, val);
|
2024-12-26 17:53:59 +01:00
|
|
|
}
|
|
|
|
|
if (name == u_Ng) {
|
2025-02-20 19:28:45 +01:00
|
|
|
return set_attribute(sd->Ng, type, derivatives, val);
|
2024-12-26 17:53:59 +01:00
|
|
|
}
|
|
|
|
|
if (name == u_P) {
|
|
|
|
|
const differential3 dP = differential_from_compact(sd->Ng, sd->dP);
|
2025-02-20 19:28:45 +01:00
|
|
|
return set_attribute(sd->P, dP.dx, dP.dy, type, derivatives, val);
|
Cycles OSL: support for the trace(point pos, vector dir, ...) function, to trace
rays from the OSL shader. The "shade" parameter is not supported currently, but
attributes can be retrieved from the object that was hit using the
getmessage("trace", ..) function.
As mentioned in the OSL specification, this function can't be used instead of
lighting, the main purpose is to allow shaders to "probe" nearby geometry, for
example to apply a projected texture that can be blocked by geometry, apply
more “wear” to exposed geometry, or make other ambient occlusion-like effects.
http://wiki.blender.org/index.php/Doc:2.6/Manual/Render/Cycles/Nodes/OSL#Trace
Example .blend and render:
http://www.pasteall.org/blend/17347
http://www.pasteall.org/pic/show.php?id=40066
2012-11-06 19:59:10 +00:00
|
|
|
}
|
2024-12-26 17:53:59 +01:00
|
|
|
if (name == u_I) {
|
|
|
|
|
const differential3 dI = differential_from_compact(sd->wi, sd->dI);
|
2025-02-20 19:28:45 +01:00
|
|
|
return set_attribute(sd->wi, dI.dx, dI.dy, type, derivatives, val);
|
2024-12-26 17:53:59 +01:00
|
|
|
}
|
|
|
|
|
if (name == u_u) {
|
2025-02-20 19:28:45 +01:00
|
|
|
return set_attribute(sd->u, sd->du.dx, sd->du.dy, type, derivatives, val);
|
2024-12-26 17:53:59 +01:00
|
|
|
}
|
|
|
|
|
if (name == u_v) {
|
2025-02-20 19:28:45 +01:00
|
|
|
return set_attribute(sd->v, sd->dv.dx, sd->dv.dy, type, derivatives, val);
|
2024-12-26 17:53:59 +01:00
|
|
|
}
|
|
|
|
|
|
Cycles: Refactor: Store Cycles-specific pointers in our own ShaderGlobals
OSL has OSL::ShaderGlobals, which contains all the state for OSL shader
execution. The renderer fills it out and hands a pointer to OSL, and any
callbacks (e.g. for querying attributes) get the pointer back.
In order to store renderer-specific data in it, there's a few opaque pointers
in the struct, but using those has led to a mess of reinterpret_cast<> and
pointer indirection in order to carry all the data around.
However, there is a way to do this nicer: Good old C-style struct inheritance.
In short: Unless you're doing pointer arithmetic, you can just add additional
data at the end of a base struct, and the rest of the code won't care.
In this case, this means that we can have our own ShaderGlobals struct and
add more Cycles-specific data at the end. Additionally, we can replace the
generic opaque void pointers with ones of the correct type, which saves us
from needing to cast them back.
Since we have a copy of ShaderGlobals for GPU OSL anyways, it's just a matter
of refactoring the code a bit to make use of that.
The advantages of this are:
- Avoids casts all over the place, just needs one cast to turn our
ShaderGlobals into the "base" type that OSL expects and one to turn the
pointer that OSL gives us on callbacks back into our "derived" type.
- Removes indirection, all the relevant stuff (sd, kg, state) is now
directly in the ShaderGlobals
- Removes some OSL-specific state from ShaderData, which helps to keep
memory usage down
Pull Request: https://projects.blender.org/blender/blender/pulls/133689
2025-01-28 03:39:00 +01:00
|
|
|
return get_attribute(sg, derivatives, u_empty, type, name, val);
|
Cycles OSL: support for the trace(point pos, vector dir, ...) function, to trace
rays from the OSL shader. The "shade" parameter is not supported currently, but
attributes can be retrieved from the object that was hit using the
getmessage("trace", ..) function.
As mentioned in the OSL specification, this function can't be used instead of
lighting, the main purpose is to allow shaders to "probe" nearby geometry, for
example to apply a projected texture that can be blocked by geometry, apply
more “wear” to exposed geometry, or make other ambient occlusion-like effects.
http://wiki.blender.org/index.php/Doc:2.6/Manual/Render/Cycles/Nodes/OSL#Trace
Example .blend and render:
http://www.pasteall.org/blend/17347
http://www.pasteall.org/pic/show.php?id=40066
2012-11-06 19:59:10 +00:00
|
|
|
}
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
Cycles OSL: support for the trace(point pos, vector dir, ...) function, to trace
rays from the OSL shader. The "shade" parameter is not supported currently, but
attributes can be retrieved from the object that was hit using the
getmessage("trace", ..) function.
As mentioned in the OSL specification, this function can't be used instead of
lighting, the main purpose is to allow shaders to "probe" nearby geometry, for
example to apply a projected texture that can be blocked by geometry, apply
more “wear” to exposed geometry, or make other ambient occlusion-like effects.
http://wiki.blender.org/index.php/Doc:2.6/Manual/Render/Cycles/Nodes/OSL#Trace
Example .blend and render:
http://www.pasteall.org/blend/17347
http://www.pasteall.org/pic/show.php?id=40066
2012-11-06 19:59:10 +00:00
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2011-04-27 11:58:34 +00:00
|
|
|
CCL_NAMESPACE_END
|