diff options
Diffstat (limited to 'intern')
-rw-r--r-- | intern/cycles/blender/addon/properties.py | 7 | ||||
-rw-r--r-- | intern/cycles/blender/addon/ui.py | 24 | ||||
-rw-r--r-- | intern/cycles/blender/blender_object.cpp | 6 | ||||
-rw-r--r-- | intern/cycles/kernel/bvh/bvh.h | 8 | ||||
-rw-r--r-- | intern/cycles/kernel/closure/bsdf.h | 32 | ||||
-rw-r--r-- | intern/cycles/kernel/kernel_camera.h | 16 | ||||
-rw-r--r-- | intern/cycles/kernel/kernel_light.h | 8 | ||||
-rw-r--r-- | intern/cycles/kernel/kernel_passes.h | 2 | ||||
-rw-r--r-- | intern/cycles/kernel/kernel_types.h | 3 | ||||
-rw-r--r-- | intern/cycles/render/light.cpp | 22 | ||||
-rw-r--r-- | intern/cycles/render/light.h | 5 | ||||
-rw-r--r-- | intern/cycles/render/object.cpp | 2 | ||||
-rw-r--r-- | intern/cycles/render/object.h | 1 | ||||
-rw-r--r-- | intern/cycles/util/util_guarded_allocator.h | 1 | ||||
-rw-r--r-- | intern/ghost/intern/GHOST_SystemWayland.cpp | 3 | ||||
-rw-r--r-- | intern/ghost/intern/GHOST_WindowWayland.cpp | 9 | ||||
-rw-r--r-- | intern/ghost/intern/GHOST_WindowWayland.h | 3 | ||||
-rw-r--r-- | intern/opencolorio/ocio_impl_glsl.cc | 17 |
18 files changed, 144 insertions, 25 deletions
diff --git a/intern/cycles/blender/addon/properties.py b/intern/cycles/blender/addon/properties.py index c91e210bbd8..da18ac7c693 100644 --- a/intern/cycles/blender/addon/properties.py +++ b/intern/cycles/blender/addon/properties.py @@ -1205,6 +1205,13 @@ class CyclesObjectSettings(bpy.types.PropertyGroup): default=1.0, ) + shadow_terminator_offset: FloatProperty( + name="Shadow Terminator Offset", + description="Push the shadow terminator towards the light to hide artifacts on low poly geometry", + min=0.0, max=1.0, + default=0.0, + ) + is_shadow_catcher: BoolProperty( name="Shadow Catcher", description="Only render shadows on this object, for compositing renders into real footage", diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py index a15daee706f..78a44881743 100644 --- a/intern/cycles/blender/addon/ui.py +++ b/intern/cycles/blender/addon/ui.py @@ -1209,6 +1209,27 @@ def has_geometry_visibility(ob): return ob and ((ob.type in {'MESH', 'CURVE', 'SURFACE', 'FONT', 'META', 'LIGHT'}) or (ob.instance_type == 'COLLECTION' and ob.instance_collection)) +class CYCLES_OBJECT_PT_shading(CyclesButtonsPanel, Panel): + bl_label = "Shading" + bl_context = "object" + bl_options = {'DEFAULT_CLOSED'} + + @classmethod + def poll(cls, context): + return CyclesButtonsPanel.poll(context) and (context.object) + + def draw(self, context): + layout = self.layout + layout.use_property_split = True + + flow = layout.grid_flow(row_major=False, columns=0, even_columns=True, even_rows=False, align=False) + layout = self.layout + ob = context.object + cob = ob.cycles + + if has_geometry_visibility(ob): + col = flow.column() + col.prop(cob, "shadow_terminator_offset") class CYCLES_OBJECT_PT_visibility(CyclesButtonsPanel, Panel): bl_label = "Visibility" @@ -1367,7 +1388,7 @@ class CYCLES_LIGHT_PT_light(CyclesButtonsPanel, Panel): col.separator() if light.type in {'POINT', 'SPOT'}: - col.prop(light, "shadow_soft_size", text="Size") + col.prop(light, "shadow_soft_size", text="Radius") elif light.type == 'SUN': col.prop(light, "angle") elif light.type == 'AREA': @@ -2268,6 +2289,7 @@ classes = ( CYCLES_CAMERA_PT_dof_aperture, CYCLES_PT_context_material, CYCLES_OBJECT_PT_motion_blur, + CYCLES_OBJECT_PT_shading, CYCLES_OBJECT_PT_visibility, CYCLES_OBJECT_PT_visibility_ray_visibility, CYCLES_OBJECT_PT_visibility_culling, diff --git a/intern/cycles/blender/blender_object.cpp b/intern/cycles/blender/blender_object.cpp index a461982a538..c28586d0f63 100644 --- a/intern/cycles/blender/blender_object.cpp +++ b/intern/cycles/blender/blender_object.cpp @@ -238,6 +238,12 @@ Object *BlenderSync::sync_object(BL::Depsgraph &b_depsgraph, object_updated = true; } + float shadow_terminator_offset = get_float(cobject, "shadow_terminator_offset"); + if (shadow_terminator_offset != object->shadow_terminator_offset) { + object->shadow_terminator_offset = shadow_terminator_offset; + object_updated = true; + } + /* sync the asset name for Cryptomatte */ BL::Object parent = b_ob.parent(); ustring parent_name; diff --git a/intern/cycles/kernel/bvh/bvh.h b/intern/cycles/kernel/bvh/bvh.h index b3992c03a9a..9b9df883b62 100644 --- a/intern/cycles/kernel/bvh/bvh.h +++ b/intern/cycles/kernel/bvh/bvh.h @@ -300,7 +300,9 @@ ccl_device_intersect bool scene_intersect_local(KernelGlobals *kg, // Is set to zero on miss or if ray is aborted, so can be used as return value uint p5 = max_hits; - local_isect->num_hits = 0; // Initialize hit count to zero + if (local_isect) { + local_isect->num_hits = 0; // Initialize hit count to zero + } optixTrace(scene_intersect_valid(ray) ? kernel_data.bvh.scene : 0, ray->P, ray->D, @@ -323,7 +325,9 @@ ccl_device_intersect bool scene_intersect_local(KernelGlobals *kg, return p5; # else /* __KERNEL_OPTIX__ */ if (!scene_intersect_valid(ray)) { - local_isect->num_hits = 0; + if (local_isect) { + local_isect->num_hits = 0; + } return false; } diff --git a/intern/cycles/kernel/closure/bsdf.h b/intern/cycles/kernel/closure/bsdf.h index dc80e67a891..4cc61e8ee71 100644 --- a/intern/cycles/kernel/closure/bsdf.h +++ b/intern/cycles/kernel/closure/bsdf.h @@ -97,6 +97,18 @@ ccl_device_inline float bump_shadowing_term(float3 Ng, float3 N, float3 I) return -g2 * g + g2 + g; } +/* Shadow terminator workaround, taken from Appleseed. + * Original code is under the MIT License + * Copyright (c) 2019 Francois Beaune, The appleseedhq Organization */ +ccl_device_inline float shift_cos_in(float cos_in, const float frequency_multiplier) +{ + cos_in = min(cos_in, 1.0f); + + const float angle = fast_acosf(cos_in); + const float val = max(cosf(angle * frequency_multiplier), 0.0f) / cos_in; + return val; +} + ccl_device_inline int bsdf_sample(KernelGlobals *kg, ShaderData *sd, const ShaderClosure *sc, @@ -444,9 +456,17 @@ ccl_device_inline int bsdf_sample(KernelGlobals *kg, } } } - else if (label & LABEL_DIFFUSE) { - if (!isequal_float3(sc->N, sd->N)) { - *eval *= bump_shadowing_term((label & LABEL_TRANSMIT) ? -sd->N : sd->N, sc->N, *omega_in); + else { + /* Shadow terminator offset. */ + const float frequency_multiplier = + kernel_tex_fetch(__objects, sd->object).shadow_terminator_offset; + if (frequency_multiplier > 1.0f) { + *eval *= shift_cos_in(dot(*omega_in, sc->N), frequency_multiplier); + } + if (label & LABEL_DIFFUSE) { + if (!isequal_float3(sc->N, sd->N)) { + *eval *= bump_shadowing_term((label & LABEL_TRANSMIT) ? -sd->N : sd->N, sc->N, *omega_in); + } } } @@ -561,6 +581,12 @@ ccl_device_inline eval *= bump_shadowing_term(sd->N, sc->N, omega_in); } } + /* Shadow terminator offset. */ + const float frequency_multiplier = + kernel_tex_fetch(__objects, sd->object).shadow_terminator_offset; + if (frequency_multiplier > 1.0f) { + eval *= shift_cos_in(dot(omega_in, sc->N), frequency_multiplier); + } } else { switch (sc->type) { diff --git a/intern/cycles/kernel/kernel_camera.h b/intern/cycles/kernel/kernel_camera.h index 62ce04ba48f..445cf9eb44b 100644 --- a/intern/cycles/kernel/kernel_camera.h +++ b/intern/cycles/kernel/kernel_camera.h @@ -441,8 +441,22 @@ ccl_device_inline float camera_distance(KernelGlobals *kg, float3 P) float3 camD = make_float3(cameratoworld.x.z, cameratoworld.y.z, cameratoworld.z.z); return fabsf(dot((P - camP), camD)); } - else + else { return len(P - camP); + } +} + +ccl_device_inline float camera_z_depth(KernelGlobals *kg, float3 P) +{ + if (kernel_data.cam.type != CAMERA_PANORAMA) { + Transform worldtocamera = kernel_data.cam.worldtocamera; + return transform_point(&worldtocamera, P).z; + } + else { + Transform cameratoworld = kernel_data.cam.cameratoworld; + float3 camP = make_float3(cameratoworld.x.w, cameratoworld.y.w, cameratoworld.z.w); + return len(P - camP); + } } ccl_device_inline float3 camera_direction_from_point(KernelGlobals *kg, float3 P) diff --git a/intern/cycles/kernel/kernel_light.h b/intern/cycles/kernel/kernel_light.h index d918abed381..04472212d0c 100644 --- a/intern/cycles/kernel/kernel_light.h +++ b/intern/cycles/kernel/kernel_light.h @@ -249,13 +249,13 @@ ccl_device float3 background_map_sample(KernelGlobals *kg, float randu, float ra float u = (index_u + du) / res_x; /* compute pdf */ - float denom = cdf_last_u.x * cdf_last_v.x; float sin_theta = sinf(M_PI_F * v); + float denom = (M_2PI_F * M_PI_F * sin_theta) * cdf_last_u.x * cdf_last_v.x; if (sin_theta == 0.0f || denom == 0.0f) *pdf = 0.0f; else - *pdf = (cdf_u.x * cdf_v.x) / (M_2PI_F * M_PI_F * sin_theta * denom); + *pdf = (cdf_u.x * cdf_v.x) / denom; /* compute direction */ return equirectangular_to_direction(u, v); @@ -284,7 +284,7 @@ ccl_device float background_map_pdf(KernelGlobals *kg, float3 direction) index_v * cdf_width + res_x); float2 cdf_last_v = kernel_tex_fetch(__light_background_marginal_cdf, res_y); - float denom = cdf_last_u.x * cdf_last_v.x; + float denom = (M_2PI_F * M_PI_F * sin_theta) * cdf_last_u.x * cdf_last_v.x; if (denom == 0.0f) return 0.0f; @@ -294,7 +294,7 @@ ccl_device float background_map_pdf(KernelGlobals *kg, float3 direction) index_v * cdf_width + index_u); float2 cdf_v = kernel_tex_fetch(__light_background_marginal_cdf, index_v); - return (cdf_u.x * cdf_v.x) / (M_2PI_F * M_PI_F * sin_theta * denom); + return (cdf_u.x * cdf_v.x) / denom; } ccl_device_inline bool background_portal_data_fetch_and_check_side( diff --git a/intern/cycles/kernel/kernel_passes.h b/intern/cycles/kernel/kernel_passes.h index 7437e540a1f..753cf4561b2 100644 --- a/intern/cycles/kernel/kernel_passes.h +++ b/intern/cycles/kernel/kernel_passes.h @@ -194,7 +194,7 @@ ccl_device_inline void kernel_write_data_passes(KernelGlobals *kg, average(shader_bsdf_alpha(kg, sd)) >= kernel_data.film.pass_alpha_threshold) { if (state->sample == 0) { if (flag & PASSMASK(DEPTH)) { - float depth = camera_distance(kg, sd->P); + float depth = camera_z_depth(kg, sd->P); kernel_write_pass_float(buffer + kernel_data.film.pass_depth, depth); } if (flag & PASSMASK(OBJECT_ID)) { diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h index 304835a1685..630d00a4e71 100644 --- a/intern/cycles/kernel/kernel_types.h +++ b/intern/cycles/kernel/kernel_types.h @@ -1480,6 +1480,9 @@ typedef struct KernelObject { float cryptomatte_object; float cryptomatte_asset; + + float shadow_terminator_offset; + float pad1, pad2, pad3; } KernelObject; static_assert_align(KernelObject, 16); diff --git a/intern/cycles/render/light.cpp b/intern/cycles/render/light.cpp index cd19b03ac53..cb7474017fa 100644 --- a/intern/cycles/render/light.cpp +++ b/intern/cycles/render/light.cpp @@ -120,6 +120,7 @@ NODE_DEFINE(Light) SOCKET_VECTOR(dir, "Dir", make_float3(0.0f, 0.0f, 0.0f)); SOCKET_FLOAT(size, "Size", 0.0f); + SOCKET_FLOAT(angle, "Angle", 0.0f); SOCKET_VECTOR(axisu, "Axis U", make_float3(0.0f, 0.0f, 0.0f)); SOCKET_FLOAT(sizeu, "Size U", 1.0f); @@ -183,6 +184,8 @@ LightManager::LightManager() need_update = true; need_update_background = true; use_light_visibility = false; + last_background_enabled = false; + last_background_resolution = 0; } LightManager::~LightManager() @@ -202,7 +205,7 @@ bool LightManager::has_background_light(Scene *scene) return false; } -void LightManager::disable_ineffective_light(Scene *scene) +void LightManager::test_enabled_lights(Scene *scene) { /* Make all lights enabled by default, and perform some preliminary checks * needed for finer-tuning of settings (for example, check whether we've @@ -215,6 +218,9 @@ void LightManager::disable_ineffective_light(Scene *scene) has_background |= light->type == LIGHT_BACKGROUND; } + bool background_enabled = false; + int background_resolution = 0; + if (has_background) { /* Ignore background light if: * - If unsupported on a device @@ -226,9 +232,18 @@ void LightManager::disable_ineffective_light(Scene *scene) foreach (Light *light, scene->lights) { if (light->type == LIGHT_BACKGROUND) { light->is_enabled = !disable_mis; + background_enabled = !disable_mis; + background_resolution = light->map_resolution; } } } + + if (last_background_enabled != background_enabled || + last_background_resolution != background_resolution) { + last_background_enabled = background_enabled; + last_background_resolution = background_resolution; + need_update_background = true; + } } bool LightManager::object_usable_as_light(Object *object) @@ -902,12 +917,13 @@ void LightManager::device_update(Device *device, VLOG(1) << "Total " << scene->lights.size() << " lights."; + /* Detect which lights are enabled, also determins if we need to update the background. */ + test_enabled_lights(scene); + device_free(device, dscene, need_update_background); use_light_visibility = false; - disable_ineffective_light(scene); - device_update_points(device, dscene, scene); if (progress.get_cancel()) return; diff --git a/intern/cycles/render/light.h b/intern/cycles/render/light.h index 1a99b2b76ae..d136e8f1a08 100644 --- a/intern/cycles/render/light.h +++ b/intern/cycles/render/light.h @@ -112,7 +112,7 @@ class LightManager { * which doesn't contribute to the scene or which is only used for MIS * and scene doesn't need MIS. */ - void disable_ineffective_light(Scene *scene); + void test_enabled_lights(Scene *scene); void device_update_points(Device *device, DeviceScene *dscene, Scene *scene); void device_update_distribution(Device *device, @@ -136,6 +136,9 @@ class LightManager { vector<IESSlot *> ies_slots; thread_mutex ies_mutex; + + bool last_background_enabled; + int last_background_resolution; }; CCL_NAMESPACE_END diff --git a/intern/cycles/render/object.cpp b/intern/cycles/render/object.cpp index 90a1d90019d..61deef4cd76 100644 --- a/intern/cycles/render/object.cpp +++ b/intern/cycles/render/object.cpp @@ -101,6 +101,7 @@ NODE_DEFINE(Object) SOCKET_POINT(dupli_generated, "Dupli Generated", make_float3(0.0f, 0.0f, 0.0f)); SOCKET_POINT2(dupli_uv, "Dupli UV", make_float2(0.0f, 0.0f)); SOCKET_TRANSFORM_ARRAY(motion, "Motion", array<Transform>()); + SOCKET_FLOAT(shadow_terminator_offset, "Terminator Offset", 0.0f); SOCKET_BOOLEAN(is_shadow_catcher, "Shadow Catcher", false); @@ -534,6 +535,7 @@ void ObjectManager::device_update_object_transform(UpdateObjectTransformState *s uint32_t hash_asset = util_murmur_hash3(ob->asset_name.c_str(), ob->asset_name.length(), 0); kobject.cryptomatte_object = util_hash_to_float(hash_name); kobject.cryptomatte_asset = util_hash_to_float(hash_asset); + kobject.shadow_terminator_offset = 1.0f / (1.0f - 0.5f * ob->shadow_terminator_offset); /* Object flag. */ if (ob->use_holdout) { diff --git a/intern/cycles/render/object.h b/intern/cycles/render/object.h index 7c84c2de4fb..ac9b4c331f5 100644 --- a/intern/cycles/render/object.h +++ b/intern/cycles/render/object.h @@ -59,6 +59,7 @@ class Object : public Node { bool hide_on_missing_motion; bool use_holdout; bool is_shadow_catcher; + float shadow_terminator_offset; float3 dupli_generated; float2 dupli_uv; diff --git a/intern/cycles/util/util_guarded_allocator.h b/intern/cycles/util/util_guarded_allocator.h index 2d09326d2ca..f78cc5f5da9 100644 --- a/intern/cycles/util/util_guarded_allocator.h +++ b/intern/cycles/util/util_guarded_allocator.h @@ -18,6 +18,7 @@ #define __UTIL_GUARDED_ALLOCATOR_H__ #include <cstddef> +#include <cstdlib> #include <memory> #ifdef WITH_BLENDER_GUARDEDALLOC diff --git a/intern/ghost/intern/GHOST_SystemWayland.cpp b/intern/ghost/intern/GHOST_SystemWayland.cpp index 633451feb85..31110694ea6 100644 --- a/intern/ghost/intern/GHOST_SystemWayland.cpp +++ b/intern/ghost/intern/GHOST_SystemWayland.cpp @@ -1527,7 +1527,7 @@ GHOST_IWindow *GHOST_SystemWayland::createWindow(const char *title, GHOST_TDrawingContextType type, GHOST_GLSettings glSettings, const bool exclusive, - const bool /*is_dialog*/, + const bool is_dialog, const GHOST_IWindow *parentWindow) { GHOST_WindowWayland *window = new GHOST_WindowWayland( @@ -1540,6 +1540,7 @@ GHOST_IWindow *GHOST_SystemWayland::createWindow(const char *title, state, parentWindow, type, + is_dialog, ((glSettings.flags & GHOST_glStereoVisual) != 0), exclusive); diff --git a/intern/ghost/intern/GHOST_WindowWayland.cpp b/intern/ghost/intern/GHOST_WindowWayland.cpp index 0ea6f5f8ecb..ef02db7abc3 100644 --- a/intern/ghost/intern/GHOST_WindowWayland.cpp +++ b/intern/ghost/intern/GHOST_WindowWayland.cpp @@ -39,6 +39,7 @@ struct window_t { bool is_maximised; bool is_fullscreen; bool is_active; + bool is_dialog; int32_t width, height; }; @@ -144,6 +145,7 @@ GHOST_WindowWayland::GHOST_WindowWayland(GHOST_SystemWayland *system, GHOST_TWindowState state, const GHOST_IWindow *parentWindow, GHOST_TDrawingContextType type, + const bool is_dialog, const bool stereoVisual, const bool exclusive) : GHOST_Window(width, height, state, stereoVisual, exclusive), @@ -155,6 +157,8 @@ GHOST_WindowWayland::GHOST_WindowWayland(GHOST_SystemWayland *system, w->width = int32_t(width); w->height = int32_t(height); + w->is_dialog = is_dialog; + /* Window surfaces. */ w->surface = wl_compositor_create_surface(m_system->compositor()); w->egl_window = wl_egl_window_create(w->surface, int(width), int(height)); @@ -376,6 +380,11 @@ GHOST_TSuccess GHOST_WindowWayland::endFullScreen() const return GHOST_kSuccess; } +bool GHOST_WindowWayland::isDialog() const +{ + return w->is_dialog; +} + /** * \param type The type of rendering context create. * \return Indication of success. diff --git a/intern/ghost/intern/GHOST_WindowWayland.h b/intern/ghost/intern/GHOST_WindowWayland.h index 39c35f77d7d..23e55fcd6e4 100644 --- a/intern/ghost/intern/GHOST_WindowWayland.h +++ b/intern/ghost/intern/GHOST_WindowWayland.h @@ -42,6 +42,7 @@ class GHOST_WindowWayland : public GHOST_Window { GHOST_TWindowState state, const GHOST_IWindow *parentWindow, GHOST_TDrawingContextType type, + const bool is_dialog, const bool stereoVisual, const bool exclusive); @@ -106,6 +107,8 @@ class GHOST_WindowWayland : public GHOST_Window { GHOST_TSuccess endFullScreen() const override; + bool isDialog() const override; + private: GHOST_SystemWayland *m_system; struct window_t *w; diff --git a/intern/opencolorio/ocio_impl_glsl.cc b/intern/opencolorio/ocio_impl_glsl.cc index df6adc8f34b..43416f734c5 100644 --- a/intern/opencolorio/ocio_impl_glsl.cc +++ b/intern/opencolorio/ocio_impl_glsl.cc @@ -263,19 +263,20 @@ static void updateGLSLShader(OCIO_GLSLShader *shader, shader->curve_mapping_loc = glGetUniformLocation(shader->program, "curve_mapping"); glUseProgram(shader->program); - /* Set texture bind point uniform once. This is saved by the shader. */ - glUniform1i(glGetUniformLocation(shader->program, "image_texture"), 0); - glUniform1i(glGetUniformLocation(shader->program, "lut3d_texture"), 2); - glUniform1i(glGetUniformLocation(shader->program, "lut3d_display_texture"), 3); - glUniform1i(glGetUniformLocation(shader->program, "curve_mapping_texture"), 4); + + /* TODO(fclem) Remove this. Make caller always assume viewport space and + * specify texco via vertex attribs. */ + shader->interface = GPU_shaderinterface_create(shader->program); /* Set UBO binding location. */ GLuint index = glGetUniformBlockIndex(shader->program, "OCIO_GLSLCurveMappingParameters"); glUniformBlockBinding(shader->program, index, UBO_BIND_LOC); - /* TODO(fclem) Remove this. Make caller always assume viewport space and - * specify texco via vertex attribs. */ - shader->interface = GPU_shaderinterface_create(shader->program); + /* Set texture bind point uniform once. This is saved by the shader. */ + glUniform1i(glGetUniformLocation(shader->program, "image_texture"), 0); + glUniform1i(glGetUniformLocation(shader->program, "lut3d_texture"), 2); + glUniform1i(glGetUniformLocation(shader->program, "lut3d_display_texture"), 3); + glUniform1i(glGetUniformLocation(shader->program, "curve_mapping_texture"), 4); } shader->cacheId = cache_id; |