[Bf-blender-cvs] [b454416927f] master: Cycles: add non-uniform scaling to spot light size
Commit: b454416927f159f2397f1d4b0c12dab38e674a13 Author: Weizhen Huang Date: Thu Jan 26 16:17:08 2023 +0100 Branches: master https://developer.blender.org/rBb454416927f159f2397f1d4b0c12dab38e674a13 Cycles: add non-uniform scaling to spot light size Cycles ignores the size of spot lights, therefore the illuminated area doesn't match the gizmo. This patch resolves this discrepancy. | Before (Cycles) | After (Cycles) | Eevee |{F14200605}|{F14200595}|{F14200600}| This is done by scaling the ray direction by the size of the cone. The implementation of `spot_light_attenuation()` in `spot.h` matches `spot_attenuation()` in `lights_lib.glsl`. **Test file**: {F14200728} Differential Revision: https://developer.blender.org/D17129 === M intern/cycles/blender/light.cpp M intern/cycles/kernel/light/spot.h M intern/cycles/kernel/svm/brick.h M intern/cycles/kernel/types.h M intern/cycles/scene/light.cpp M intern/cycles/scene/light_tree.cpp M intern/cycles/util/math.h === diff --git a/intern/cycles/blender/light.cpp b/intern/cycles/blender/light.cpp index b8db4c24eb3..d5aba2041ad 100644 --- a/intern/cycles/blender/light.cpp +++ b/intern/cycles/blender/light.cpp @@ -48,6 +48,8 @@ void BlenderSync::sync_light(BL::Object _parent, case BL::Light::type_SPOT: { BL::SpotLight b_spot_light(b_light); light->set_size(b_spot_light.shadow_soft_size()); + light->set_axisu(transform_get_column(, 0)); + light->set_axisv(transform_get_column(, 1)); light->set_light_type(LIGHT_SPOT); light->set_spot_angle(b_spot_light.spot_size()); light->set_spot_smooth(b_spot_light.spot_blend()); diff --git a/intern/cycles/kernel/light/spot.h b/intern/cycles/kernel/light/spot.h index b1d652f13f9..1ffaebe7c17 100644 --- a/intern/cycles/kernel/light/spot.h +++ b/intern/cycles/kernel/light/spot.h @@ -7,24 +7,13 @@ CCL_NAMESPACE_BEGIN -ccl_device float spot_light_attenuation(float3 dir, -float cos_half_spot_angle, -float spot_smooth, -float3 N) +ccl_device float spot_light_attenuation(const ccl_global KernelSpotLight *spot, float3 ray) { - float attenuation = dot(dir, N); + const float3 scaled_ray = safe_normalize( + make_float3(dot(ray, spot->axis_u), dot(ray, spot->axis_v), dot(ray, spot->dir)) / + spot->len); - if (attenuation <= cos_half_spot_angle) { -attenuation = 0.0f; - } - else { -float t = attenuation - cos_half_spot_angle; - -if (t < spot_smooth && spot_smooth != 0.0f) - attenuation *= smoothstepf(t / spot_smooth); - } - - return attenuation; + return smoothstepf((scaled_ray.z - spot->cos_half_spot_angle) / spot->spot_smooth); } template @@ -57,8 +46,7 @@ ccl_device_inline bool spot_light_sample(const ccl_global KernelLight *klight, ls->eval_fac = (0.25f * M_1_PI_F) * invarea; /* spot light attenuation */ - ls->eval_fac *= spot_light_attenuation( - klight->spot.dir, klight->spot.cos_half_spot_angle, klight->spot.spot_smooth, -ls->D); + ls->eval_fac *= spot_light_attenuation(>spot, -ls->D); if (!in_volume_segment && ls->eval_fac == 0.0f) { return false; } @@ -87,8 +75,7 @@ ccl_device_forceinline void spot_light_update_position(const ccl_global KernelLi ls->pdf = invarea; /* spot light attenuation */ - ls->eval_fac *= spot_light_attenuation( - klight->spot.dir, klight->spot.cos_half_spot_angle, klight->spot.spot_smooth, ls->Ng); + ls->eval_fac *= spot_light_attenuation(>spot, ls->Ng); } ccl_device_inline bool spot_light_intersect(const ccl_global KernelLight *klight, @@ -129,8 +116,7 @@ ccl_device_inline bool spot_light_sample_from_intersection( ls->pdf = invarea; /* spot light attenuation */ - ls->eval_fac *= spot_light_attenuation( - klight->spot.dir, klight->spot.cos_half_spot_angle, klight->spot.spot_smooth, -ls->D); + ls->eval_fac *= spot_light_attenuation(>spot, -ls->D); if (ls->eval_fac == 0.0f) { return false; diff --git a/intern/cycles/kernel/svm/brick.h b/intern/cycles/kernel/svm/brick.h index f8fa4a4a84a..e64fc636334 100644 --- a/intern/cycles/kernel/svm/brick.h +++ b/intern/cycles/kernel/svm/brick.h @@ -46,17 +46,8 @@ ccl_device_noinline_cpu float2 svm_brick(float3 p, float tint = saturatef((brick_noise((rownum << 16) + (bricknum & 0x)) + bias)); float min_dist = min(min(x, y), min(brick_width - x, row_height - y)); - float mortar; - if (min_dist >= mortar_size) { -mortar = 0.0f; - } - else if (mortar_smooth == 0.0f) { -mortar = 1.0f; - } - else { -min_dist = 1.0f - min_dist / mor
[Bf-blender-cvs] [23506622a54] master: Gizmo: add central point to circular 2D cage
Commit: 23506622a5420e60701a237a61cdf5890fcd3f23 Author: Weizhen Huang Date: Fri Feb 3 18:30:51 2023 +0100 Branches: master https://developer.blender.org/rB23506622a5420e60701a237a61cdf5890fcd3f23 Gizmo: add central point to circular 2D cage === M source/blender/editors/gizmo_library/gizmo_types/cage2d_gizmo.c M source/blender/gpu/GPU_immediate_util.h M source/blender/gpu/intern/gpu_immediate_util.c === diff --git a/source/blender/editors/gizmo_library/gizmo_types/cage2d_gizmo.c b/source/blender/editors/gizmo_library/gizmo_types/cage2d_gizmo.c index 1b09d35c8b2..b1bf1a7b542 100644 --- a/source/blender/editors/gizmo_library/gizmo_types/cage2d_gizmo.c +++ b/source/blender/editors/gizmo_library/gizmo_types/cage2d_gizmo.c @@ -590,6 +590,20 @@ static void cage2d_draw_rect_handles(const rctf *r, immUnbindProgram(); } +static void cage2d_draw_central_handle(const float color[3], const float margin[2]) +{ + uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + + const float rad[2] = {margin[0] * 0.25f, margin[1] * 0.25f}; + + immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); + immUniformColor3fv(color); + + imm_draw_circle_fill_aspect_3d(pos, 0.0f, 0.0f, rad[0], rad[1], CIRCLE_RESOL); + + immUnbindProgram(); +} + /** \} */ static void gizmo_cage2d_draw_intern(wmGizmo *gz, @@ -636,6 +650,8 @@ static void gizmo_cage2d_draw_intern(wmGizmo *gz, GPU_select_load_id(select_id | ED_GIZMO_CAGE2D_PART_SCALE); cage2d_draw_circle_wire( gz->color, size_real, 0.5f * (margin[0] + margin[1]), gz->line_width); + + cage2d_draw_central_handle(gz->color, margin); } else { if (transform_flag & ED_GIZMO_CAGE_XFORM_FLAG_SCALE) { @@ -736,6 +752,8 @@ static void gizmo_cage2d_draw_intern(wmGizmo *gz, else if (draw_style == ED_GIZMO_CAGE2D_STYLE_CIRCLE) { cage2d_draw_circle_wire(black, size_real, 0.0f, outline_line_width); cage2d_draw_circle_wire(color, size_real, 0.0f, gz->line_width); + +cage2d_draw_central_handle(color, margin); } else { BLI_assert(0); diff --git a/source/blender/gpu/GPU_immediate_util.h b/source/blender/gpu/GPU_immediate_util.h index d12f950185b..d072f57ea27 100644 --- a/source/blender/gpu/GPU_immediate_util.h +++ b/source/blender/gpu/GPU_immediate_util.h @@ -76,6 +76,8 @@ void imm_draw_circle_wire_aspect_3d( uint pos, float x, float y, float radius_x, float radius_y, int nsegments); void imm_draw_circle_dashed_3d(uint pos, float x, float y, float radius, int nsegments); void imm_draw_circle_fill_3d(uint pos, float x, float y, float radius, int nsegments); +void imm_draw_circle_fill_aspect_3d( +uint pos, float x, float y, float radius_x, float radius_y, int nsegments); /** * Same as 'imm_draw_disk_partial_fill_2d', except it draws a wire arc. diff --git a/source/blender/gpu/intern/gpu_immediate_util.c b/source/blender/gpu/intern/gpu_immediate_util.c index b25fd04091a..14fb4dbc810 100644 --- a/source/blender/gpu/intern/gpu_immediate_util.c +++ b/source/blender/gpu/intern/gpu_immediate_util.c @@ -398,6 +398,12 @@ void imm_draw_circle_fill_3d(uint pos, float x, float y, float radius, int nsegm imm_draw_circle_3D(GPU_PRIM_TRI_FAN, pos, x, y, radius, radius, nsegments); } +void imm_draw_circle_fill_aspect_3d( +uint pos, float x, float y, float radius_x, float radius_y, int nsegments) +{ + imm_draw_circle_3D(GPU_PRIM_TRI_FAN, pos, x, y, radius_x, radius_y, nsegments); +} + void imm_draw_box_wire_2d(uint pos, float x1, float y1, float x2, float y2) { /* NOTE(Metal/AMD): For small primitives, line list more efficient than line-strip. */ ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [cc23b6abd68] master: Cleanup: rename cage2d draw style (`RECTANGLE` -> `BOX_TRANSFORM`)
Commit: cc23b6abd68d4979c38c076bced6cbed947d7220 Author: Weizhen Huang Date: Fri Feb 3 12:01:45 2023 +0100 Branches: master https://developer.blender.org/rBcc23b6abd68d4979c38c076bced6cbed947d7220 Cleanup: rename cage2d draw style (`RECTANGLE` -> `BOX_TRANSFORM`) === M source/blender/editors/gizmo_library/gizmo_types/cage2d_gizmo.c M source/blender/editors/include/ED_gizmo_library.h === diff --git a/source/blender/editors/gizmo_library/gizmo_types/cage2d_gizmo.c b/source/blender/editors/gizmo_library/gizmo_types/cage2d_gizmo.c index 5440498b8ba..1b09d35c8b2 100644 --- a/source/blender/editors/gizmo_library/gizmo_types/cage2d_gizmo.c +++ b/source/blender/editors/gizmo_library/gizmo_types/cage2d_gizmo.c @@ -725,7 +725,7 @@ static void gizmo_cage2d_draw_intern(wmGizmo *gz, float outline_line_width = gz->line_width + 3.0f; - if (draw_style == ED_GIZMO_CAGE2D_STYLE_RECTANGLE) { + if (draw_style == ED_GIZMO_CAGE2D_STYLE_BOX_TRANSFORM) { cage2d_draw_rect_wire(, margin, black, transform_flag, draw_options, outline_line_width); cage2d_draw_rect_wire(, margin, color, transform_flag, draw_options, gz->line_width); @@ -1223,7 +1223,7 @@ static void GIZMO_GT_cage_2d(wmGizmoType *gzt) /* rna */ static EnumPropertyItem rna_enum_draw_style[] = { {ED_GIZMO_CAGE2D_STYLE_BOX, "BOX", 0, "Box", ""}, - {ED_GIZMO_CAGE2D_STYLE_RECTANGLE, "RECTANGLE", 0, "Rectangle", ""}, + {ED_GIZMO_CAGE2D_STYLE_BOX_TRANSFORM, "BOX_TRANSFORM", 0, "Box Transform", ""}, {ED_GIZMO_CAGE2D_STYLE_CIRCLE, "CIRCLE", 0, "Circle", ""}, {0, NULL, 0, NULL, NULL}, }; @@ -1245,7 +1245,7 @@ static void GIZMO_GT_cage_2d(wmGizmoType *gzt) RNA_def_enum(gzt->srna, "draw_style", rna_enum_draw_style, - ED_GIZMO_CAGE2D_STYLE_RECTANGLE, + ED_GIZMO_CAGE2D_STYLE_BOX_TRANSFORM, "Draw Style", ""); RNA_def_enum_flag(gzt->srna, diff --git a/source/blender/editors/include/ED_gizmo_library.h b/source/blender/editors/include/ED_gizmo_library.h index ea844c25f8a..a4650126d85 100644 --- a/source/blender/editors/include/ED_gizmo_library.h +++ b/source/blender/editors/include/ED_gizmo_library.h @@ -106,16 +106,18 @@ enum { /* draw_style */ enum { - /** Display the hover region (edge or corner) of the underlying rectangle. */ + /* Display the hover region (edge or corner) of the underlying bounding box. */ ED_GIZMO_CAGE2D_STYLE_BOX = 0, - /** Display a rectangular wire plus dots on four corners while hovering. */ - ED_GIZMO_CAGE2D_STYLE_RECTANGLE, - /** Display a circular wire while hovering. */ + /* Display the bounding box plus dots on four corners while hovering, usually used for + transforming a 2D shape. */ + ED_GIZMO_CAGE2D_STYLE_BOX_TRANSFORM, + /* Display the bounding circle while hovering. */ ED_GIZMO_CAGE2D_STYLE_CIRCLE, }; enum { ED_GIZMO_CAGE3D_STYLE_BOX = 0, + /* TODO: rename */ ED_GIZMO_CAGE3D_STYLE_CIRCLE = 1, }; ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [3c8c0f1094a] master: Gizmo: add gizmo for adjusting spot light blend
Commit: 3c8c0f1094a3fad5ee47888ce0507c9707d71772 Author: Weizhen Huang Date: Tue Jan 31 18:04:15 2023 +0100 Branches: master https://developer.blender.org/rB3c8c0f1094a3fad5ee47888ce0507c9707d71772 Gizmo: add gizmo for adjusting spot light blend Ref T104280 Differential Revision: https://developer.blender.org/D17171 === M source/blender/editors/space_view3d/view3d_gizmo_light.c === diff --git a/source/blender/editors/space_view3d/view3d_gizmo_light.c b/source/blender/editors/space_view3d/view3d_gizmo_light.c index df601b4e73b..d967b950bc5 100644 --- a/source/blender/editors/space_view3d/view3d_gizmo_light.c +++ b/source/blender/editors/space_view3d/view3d_gizmo_light.c @@ -5,6 +5,7 @@ */ #include "BLI_math.h" +#include "BLI_math_base_safe.h" #include "BLI_utildefines.h" #include "BKE_context.h" @@ -34,6 +35,64 @@ /* */ /** \name Spot Light Gizmos * \{ */ +/* NOTE: scaling from `overlay_extra.cc`. */ +#define CONE_SCALE 10.0f +#define INV_CONE_SCALE 0.1f + +typedef struct LightSpotWidgetGroup { + wmGizmo *spot_angle; + wmGizmo *spot_blend; +} LightSpotWidgetGroup; + +static void gizmo_spot_blend_prop_matrix_get(const wmGizmo *UNUSED(gz), + wmGizmoProperty *gz_prop, + void *value_p) +{ + BLI_assert(gz_prop->type->array_length == 16); + float(*matrix)[4] = value_p; + + const bContext *C = gz_prop->custom_func.user_data; + ViewLayer *view_layer = CTX_data_view_layer(C); + BKE_view_layer_synced_ensure(CTX_data_scene(C), view_layer); + Light *la = BKE_view_layer_active_object_get(view_layer)->data; + + float a = cosf(la->spotsize * 0.5f); + float b = la->spotblend; + /* Cosine of the angle where spot attenuation == 1. */ + float c = (1.0f - a) * b + a; + /* Tangent. */ + float t = sqrtf(1.0f - c * c) / c; + + matrix[0][0] = 2.0f * CONE_SCALE * t * a; + matrix[1][1] = 2.0f * CONE_SCALE * t * a; +} + +static void gizmo_spot_blend_prop_matrix_set(const wmGizmo *UNUSED(gz), + wmGizmoProperty *gz_prop, + const void *value_p) +{ + const float(*matrix)[4] = value_p; + BLI_assert(gz_prop->type->array_length == 16); + + const bContext *C = gz_prop->custom_func.user_data; + Scene *scene = CTX_data_scene(C); + ViewLayer *view_layer = CTX_data_view_layer(C); + BKE_view_layer_synced_ensure(scene, view_layer); + Light *la = BKE_view_layer_active_object_get(view_layer)->data; + + float a = cosf(la->spotsize * 0.5f); + float t = matrix[0][0] * 0.5f * INV_CONE_SCALE / a; + float c = 1.0f / sqrt(t * t + 1.0f); + + float spot_blend = safe_divide(clamp_f(c - a, 0.0f, 1.0f - a), 1.0f - a); + + PointerRNA light_ptr; + RNA_pointer_create(>id, _Light, la, _ptr); + PropertyRNA *spot_blend_prop = RNA_struct_find_property(_ptr, "spot_blend"); + RNA_property_float_set(_ptr, spot_blend_prop, spot_blend); + + RNA_property_update_main(CTX_data_main(C), scene, _ptr, spot_blend_prop); +} static bool WIDGETGROUP_light_spot_poll(const bContext *C, wmGizmoGroupType *UNUSED(gzgt)) { @@ -59,42 +118,78 @@ static bool WIDGETGROUP_light_spot_poll(const bContext *C, wmGizmoGroupType *UNU return false; } -static void WIDGETGROUP_light_spot_setup(const bContext *UNUSED(C), wmGizmoGroup *gzgroup) +static void WIDGETGROUP_light_spot_setup(const bContext *C, wmGizmoGroup *gzgroup) { - wmGizmoWrapper *wwrapper = MEM_mallocN(sizeof(wmGizmoWrapper), __func__); + LightSpotWidgetGroup *ls_gzgroup = MEM_mallocN(sizeof(LightSpotWidgetGroup), __func__); - wwrapper->gizmo = WM_gizmo_new("GIZMO_GT_arrow_3d", gzgroup, NULL); - wmGizmo *gz = wwrapper->gizmo; - RNA_enum_set(gz->ptr, "transform", ED_GIZMO_ARROW_XFORM_FLAG_INVERTED); + gzgroup->customdata = ls_gzgroup; - gzgroup->customdata = wwrapper; - - ED_gizmo_arrow3d_set_range_fac(gz, 4.0f); + /* Spot angle gizmo. */ + { +ls_gzgroup->spot_angle = WM_gizmo_new("GIZMO_GT_arrow_3d", gzgroup, NULL); +wmGizmo *gz = ls_gzgroup->spot_angle; +RNA_enum_set(gz->ptr, "transform", ED_GIZMO_ARROW_XFORM_FLAG_INVERTED); +ED_gizmo_arrow3d_set_range_fac(gz, 4.0f); +UI_GetThemeColor3fv(TH_GIZMO_SECONDARY, gz->color); + } - UI_GetThemeColor3fv(TH_GIZMO_SECONDARY, gz->color); + /* Spot blend gizmo. */ + { +ls_gzgroup->spot_blend = WM_gizmo_new("GIZMO_GT_cage_2d", gzgroup, NULL); +wmGizmo *gz = ls_gzgroup->spot_blend; +RNA_enum_set(gz->ptr, + "transform", + ED_GIZMO_CAGE_XFORM_FLAG_SCALE | ED_GIZMO_CAGE_XFORM_FLAG_SCALE_UNIF
[Bf-blender-cvs] [fe5d54d3d0e] master: Gizmo: add new cage2d draw style for circular shapes
Commit: fe5d54d3d0ee328674caff7aa73180f7abfb85f6 Author: Weizhen Huang Date: Thu Feb 2 16:13:27 2023 +0100 Branches: master https://developer.blender.org/rBfe5d54d3d0ee328674caff7aa73180f7abfb85f6 Gizmo: add new cage2d draw style for circular shapes `ED_GIZMO_CAGE2D_STYLE_CIRCLE` now draw circles. The previous `ED_GIZMO_CAGE2D_STYLE_CIRCLE`, which drew rectangles, is renamed to `ED_GIZMO_CAGE2D_STYLE_RECTANGLE`. The meaning of `ED_GIZMO_CAGE2D_STYLE_BOX` is now unclear and probably needs to be renamed too. Ref T104280 Maniphest Tasks: T104280 Differential Revision: https://developer.blender.org/D17174 === M source/blender/editors/gizmo_library/gizmo_types/cage2d_gizmo.c M source/blender/editors/include/ED_gizmo_library.h M source/blender/gpu/GPU_immediate_util.h M source/blender/gpu/intern/gpu_immediate_util.c === diff --git a/source/blender/editors/gizmo_library/gizmo_types/cage2d_gizmo.c b/source/blender/editors/gizmo_library/gizmo_types/cage2d_gizmo.c index 22dd2a04f40..5440498b8ba 100644 --- a/source/blender/editors/gizmo_library/gizmo_types/cage2d_gizmo.c +++ b/source/blender/editors/gizmo_library/gizmo_types/cage2d_gizmo.c @@ -8,7 +8,7 @@ * * 2D Gizmo * - * \brief Rectangular gizmo acting as a 'cage' around its content. + * \brief Rectangular or circular gizmo acting as a 'cage' around its content. * Interacting scales or translates the gizmo. */ @@ -41,6 +41,8 @@ #include "../gizmo_library_intern.h" #define GIZMO_MARGIN_OFFSET_SCALE 1.5f +/* The same as in `draw_cache.c` */ +#define CIRCLE_RESOL 32 static bool gizmo_calc_rect_view_scale(const wmGizmo *gz, const float dims[2], float scale[2]) { @@ -472,12 +474,12 @@ static void imm_draw_point_aspect_2d( } } -static void cage2d_draw_circle_wire(const rctf *r, -const float margin[2], -const float color[3], -const int transform_flag, -const int draw_options, -const float line_width) +static void cage2d_draw_rect_wire(const rctf *r, + const float margin[2], + const float color[3], + const int transform_flag, + const int draw_options, + const float line_width) { /* NOTE(Metal): Prefer using 3D coordinates with 3D shader input, even if rendering 2D gizmo's. */ @@ -533,11 +535,31 @@ static void cage2d_draw_circle_wire(const rctf *r, immUnbindProgram(); } -static void cage2d_draw_circle_handles(const rctf *r, - const float margin[2], - const float color[3], - const int transform_flag, - bool solid) +static void cage2d_draw_circle_wire(const float color[3], +const float size[2], +const float margin, +const float line_width) +{ + uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); + + immBindBuiltinProgram(GPU_SHADER_3D_POLYLINE_UNIFORM_COLOR); + immUniformColor3fv(color); + + float viewport[4]; + GPU_viewport_size_get_f(viewport); + immUniform2fv("viewportSize", [2]); + immUniform1f("lineWidth", line_width * U.pixelsize + margin); + + imm_draw_circle_wire_aspect_3d(pos, 0.0f, 0.0f, size[0], size[1], CIRCLE_RESOL); + + immUnbindProgram(); +} + +static void cage2d_draw_rect_handles(const rctf *r, + const float margin[2], + const float color[3], + const int transform_flag, + bool solid) { uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); void (*circle_fn)(uint, float, float, float, float, int) = (solid) ? @@ -609,39 +631,46 @@ static void gizmo_cage2d_draw_intern(wmGizmo *gz, if (select) { /* Expand for hot-spot. */ const float size[2] = {size_real[0] + margin[0] / 2, size_real[1] + margin[1] / 2}; - -if (transform_flag & ED_GIZMO_CAGE_XFORM_FLAG_SCALE) { - int scale_parts[] = { - ED_GIZMO_CAGE2D_PART_SCALE_MIN_X, - ED_GIZMO_CAGE2D_PART_SCALE_MAX_X, - ED_GIZMO_CAGE2D_PART_SCALE_MIN_Y, - ED_GIZMO_CAGE2D_PART_SCALE_MAX_Y, - - ED_GIZMO_CAGE2D_PART_SCALE_MIN_X_MIN_Y, - ED_GIZMO_CAGE2D_PART_SCALE_MIN_X_MAX_Y, - ED_GIZMO_CAGE2D_PART_SCALE_MAX_X_MIN_Y, - ED_GIZMO_CAGE2D_PART
[Bf-blender-cvs] [c105c49407e] master: Cleanup: rename places where 3D cage gizmo uses 2D cage enums
Commit: c105c49407e1156b2e1c97048902a4e1d688fde9 Author: Weizhen Huang Date: Wed Feb 1 17:28:35 2023 +0100 Branches: master https://developer.blender.org/rBc105c49407e1156b2e1c97048902a4e1d688fde9 Cleanup: rename places where 3D cage gizmo uses 2D cage enums === M release/scripts/addons M source/blender/editors/gizmo_library/gizmo_types/cage2d_gizmo.c M source/blender/editors/gizmo_library/gizmo_types/cage3d_gizmo.c M source/blender/editors/include/ED_gizmo_library.h M source/blender/editors/mesh/editmesh_add_gizmo.c M source/blender/editors/space_node/node_gizmo.cc M source/blender/editors/space_view3d/view3d_gizmo_camera.c M source/blender/editors/space_view3d/view3d_gizmo_empty.c M source/blender/editors/space_view3d/view3d_gizmo_light.c M source/blender/editors/transform/transform_gizmo_2d.c M source/blender/editors/transform/transform_gizmo_3d.c === diff --git a/release/scripts/addons b/release/scripts/addons index fe59d382b4f..534bf3b76c3 16 --- a/release/scripts/addons +++ b/release/scripts/addons @@ -1 +1 @@ -Subproject commit fe59d382b4fd2047920208fa92d39fc1361d9242 +Subproject commit 534bf3b76c3b5f3bcd21641f1d53c1062bedcdbe diff --git a/source/blender/editors/gizmo_library/gizmo_types/cage2d_gizmo.c b/source/blender/editors/gizmo_library/gizmo_types/cage2d_gizmo.c index 4b78b122764..22dd2a04f40 100644 --- a/source/blender/editors/gizmo_library/gizmo_types/cage2d_gizmo.c +++ b/source/blender/editors/gizmo_library/gizmo_types/cage2d_gizmo.c @@ -345,7 +345,7 @@ static void cage2d_draw_box_interaction(const float color[4], } case ED_GIZMO_CAGE2D_PART_TRANSLATE: - if (draw_options & ED_GIZMO_CAGE2D_DRAW_FLAG_XFORM_CENTER_HANDLE) { + if (draw_options & ED_GIZMO_CAGE_DRAW_FLAG_XFORM_CENTER_HANDLE) { ARRAY_SET_ITEMS(verts[0], -margin[0] / 2, -margin[1] / 2); ARRAY_SET_ITEMS(verts[1], margin[0] / 2, margin[1] / 2); ARRAY_SET_ITEMS(verts[2], -margin[0] / 2, margin[1] / 2); @@ -506,7 +506,7 @@ static void cage2d_draw_circle_wire(const rctf *r, immVertex3f(pos, r->xmin, r->ymin, 0.0f); immEnd(); - if (transform_flag & ED_GIZMO_CAGE2D_XFORM_FLAG_ROTATE) { + if (transform_flag & ED_GIZMO_CAGE_XFORM_FLAG_ROTATE) { immBegin(GPU_PRIM_LINES, 4); immVertex3f(pos, BLI_rctf_cent_x(r), r->ymax, 0.0f); immVertex3f(pos, BLI_rctf_cent_x(r), r->ymax + margin[1], 0.0f); @@ -516,8 +516,8 @@ static void cage2d_draw_circle_wire(const rctf *r, immEnd(); } - if (transform_flag & ED_GIZMO_CAGE2D_XFORM_FLAG_TRANSLATE) { -if (draw_options & ED_GIZMO_CAGE2D_DRAW_FLAG_XFORM_CENTER_HANDLE) { + if (transform_flag & ED_GIZMO_CAGE_XFORM_FLAG_TRANSLATE) { +if (draw_options & ED_GIZMO_CAGE_DRAW_FLAG_XFORM_CENTER_HANDLE) { const float rad[2] = {margin[0] / 2, margin[1] / 2}; const float center[2] = {BLI_rctf_cent_x(r), BLI_rctf_cent_y(r)}; @@ -557,7 +557,7 @@ static void cage2d_draw_circle_handles(const rctf *r, imm_draw_point_aspect_2d(pos, r->xmin, r->ymax, rad[0], rad[1], solid); } - if (transform_flag & ED_GIZMO_CAGE2D_XFORM_FLAG_ROTATE) { + if (transform_flag & ED_GIZMO_CAGE_XFORM_FLAG_ROTATE) { const float handle[2] = { BLI_rctf_cent_x(r), r->ymax + (margin[1] * GIZMO_MARGIN_OFFSET_SCALE), @@ -610,7 +610,7 @@ static void gizmo_cage2d_draw_intern(wmGizmo *gz, /* Expand for hot-spot. */ const float size[2] = {size_real[0] + margin[0] / 2, size_real[1] + margin[1] / 2}; -if (transform_flag & ED_GIZMO_CAGE2D_XFORM_FLAG_SCALE) { +if (transform_flag & ED_GIZMO_CAGE_XFORM_FLAG_SCALE) { int scale_parts[] = { ED_GIZMO_CAGE2D_PART_SCALE_MIN_X, ED_GIZMO_CAGE2D_PART_SCALE_MAX_X, @@ -628,13 +628,13 @@ static void gizmo_cage2d_draw_intern(wmGizmo *gz, gz->color, scale_parts[i], size, margin, gz->line_width, true, draw_options); } } -if (transform_flag & ED_GIZMO_CAGE2D_XFORM_FLAG_TRANSLATE) { +if (transform_flag & ED_GIZMO_CAGE_XFORM_FLAG_TRANSLATE) { const int transform_part = ED_GIZMO_CAGE2D_PART_TRANSLATE; GPU_select_load_id(select_id | transform_part); cage2d_draw_box_interaction( gz->color, transform_part, size, margin, gz->line_width, true, draw_options); } -if (transform_flag & ED_GIZMO_CAGE2D_XFORM_FLAG_ROTATE) { +if (transform_flag & ED_GIZMO_CAGE_XFORM_FLAG_ROTATE) { cage2d_draw_box_interaction(gz->color, ED_GIZMO_CAGE2D_PART_ROTATE, size_real, @@ -665,7 +665,7 @@ static void gizmo_cage2d_draw_intern(wmGizmo *gz, if (gz->highlight_part == ED_GIZMO_CAGE2D_PART_TRANSLATE) {
[Bf-blender-cvs] [ce42906b896] master: Fix wrong spot light blend circle radius in viewport
Commit: ce42906b8962155b50cc043b3a0b5b24f191a41c Author: Weizhen Huang Date: Tue Jan 31 16:26:51 2023 +0100 Branches: master https://developer.blender.org/rBce42906b8962155b50cc043b3a0b5b24f191a41c Fix wrong spot light blend circle radius in viewport Was using squared cosine instead of cosine. The problem is obvious for large spread angles. |before|after |{F14220946}|{F14220948} The images are generating by returning `floor(spotmask)` in function `spot_attenuation()` in `lights_lib.glsl`. === M source/blender/draw/engines/overlay/overlay_extra.cc === diff --git a/source/blender/draw/engines/overlay/overlay_extra.cc b/source/blender/draw/engines/overlay/overlay_extra.cc index c366e64347c..2bb3bb5f8d8 100644 --- a/source/blender/draw/engines/overlay/overlay_extra.cc +++ b/source/blender/draw/engines/overlay/overlay_extra.cc @@ -649,16 +649,19 @@ void OVERLAY_light_cache_populate(OVERLAY_Data *vedata, Object *ob) const float3 scale_vec = {10.0f, 10.0f, 10.0f}; rescale_m4(instdata.mat, scale_vec); /* For cycles and eevee the spot attenuation is - * y = (1/(1 + x^2) - a)/((1 - a) b) + * y = (1/sqrt(1 + x^2) - a)/((1 - a) b) + * x being the tangent of the angle between the light direction and the generatrix of the cone. * We solve the case where spot attenuation y = 1 and y = 0 - * root for y = 1 is (-1 - c) / c - * root for y = 0 is (1 - a) / a + * root for y = 1 is sqrt(1/c^2 - 1) + * root for y = 0 is sqrt(1/a^2 - 1) * and use that to position the blend circle. */ float a = cosf(la->spotsize * 0.5f); float b = la->spotblend; float c = a * b - a - b; +float a2 = a * a; +float c2 = c * c; /* Optimized version or root1 / root0 */ -instdata.spot_blend = sqrtf((-a - c * a) / (c - c * a)); +instdata.spot_blend = sqrtf((a2 - a2 * c2) / (c2 - a2 * c2)); instdata.spot_cosine = a; /* HACK: We pack the area size in alpha color. This is decoded by the shader. */ color[3] = -max_ff(la->radius, FLT_MIN); ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [b898e00edce] master: Cleanup: remove unused KernelGlobals in microfacet BSDF
Commit: b898e00edce795d5b7414eb312503e7be5433ac3 Author: Weizhen Huang Date: Wed Jan 25 11:26:51 2023 +0100 Branches: master https://developer.blender.org/rBb898e00edce795d5b7414eb312503e7be5433ac3 Cleanup: remove unused KernelGlobals in microfacet BSDF === M intern/cycles/kernel/closure/bsdf.h M intern/cycles/kernel/closure/bsdf_microfacet.h === diff --git a/intern/cycles/kernel/closure/bsdf.h b/intern/cycles/kernel/closure/bsdf.h index 2f53454d7dd..b0d01c427de 100644 --- a/intern/cycles/kernel/closure/bsdf.h +++ b/intern/cycles/kernel/closure/bsdf.h @@ -170,7 +170,7 @@ ccl_device_inline int bsdf_sample(KernelGlobals kg, case CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID: case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID: label = bsdf_microfacet_ggx_sample( - kg, sc, Ng, sd->wi, randu, randv, eval, wo, pdf, sampled_roughness, eta); + sc, Ng, sd->wi, randu, randv, eval, wo, pdf, sampled_roughness, eta); break; case CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID: case CLOSURE_BSDF_MICROFACET_MULTI_GGX_FRESNEL_ID: @@ -185,7 +185,7 @@ ccl_device_inline int bsdf_sample(KernelGlobals kg, case CLOSURE_BSDF_MICROFACET_BECKMANN_ID: case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID: label = bsdf_microfacet_beckmann_sample( - kg, sc, Ng, sd->wi, randu, randv, eval, wo, pdf, sampled_roughness, eta); + sc, Ng, sd->wi, randu, randv, eval, wo, pdf, sampled_roughness, eta); break; case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID: label = bsdf_ashikhmin_shirley_sample( diff --git a/intern/cycles/kernel/closure/bsdf_microfacet.h b/intern/cycles/kernel/closure/bsdf_microfacet.h index 8cf4cfa244d..be21bcd720e 100644 --- a/intern/cycles/kernel/closure/bsdf_microfacet.h +++ b/intern/cycles/kernel/closure/bsdf_microfacet.h @@ -42,8 +42,7 @@ static_assert(sizeof(ShaderClosure) >= sizeof(MicrofacetBsdf), "MicrofacetBsdf i * Eric Heitz and Eugene d'Eon, EGSR 2014. * https://hal.inria.fr/hal-00996995v2/document */ -ccl_device_forceinline float3 microfacet_beckmann_sample_vndf(KernelGlobals kg, - const float3 wi, +ccl_device_forceinline float3 microfacet_beckmann_sample_vndf(const float3 wi, const float alpha_x, const float alpha_y, const float randu, @@ -387,8 +386,7 @@ ccl_device Spectrum bsdf_microfacet_eval(ccl_private const ShaderClosure *sc, } template -ccl_device int bsdf_microfacet_sample(KernelGlobals kg, - ccl_private const ShaderClosure *sc, +ccl_device int bsdf_microfacet_sample(ccl_private const ShaderClosure *sc, float3 Ng, float3 wi, float randu, @@ -431,7 +429,7 @@ ccl_device int bsdf_microfacet_sample(KernelGlobals kg, } else { /* m_type == MicrofacetType::BECKMANN */ -local_H = microfacet_beckmann_sample_vndf(kg, local_I, alpha_x, alpha_y, randu, randv); +local_H = microfacet_beckmann_sample_vndf(local_I, alpha_x, alpha_y, randu, randv); } const float3 H = X * local_H.x + Y * local_H.y + N * local_H.z; @@ -616,8 +614,7 @@ ccl_device Spectrum bsdf_microfacet_ggx_eval(ccl_private const ShaderClosure *sc return bsdf_microfacet_eval(sc, Ng, wi, wo, pdf); } -ccl_device int bsdf_microfacet_ggx_sample(KernelGlobals kg, - ccl_private const ShaderClosure *sc, +ccl_device int bsdf_microfacet_ggx_sample(ccl_private const ShaderClosure *sc, float3 Ng, float3 wi, float randu, @@ -629,7 +626,7 @@ ccl_device int bsdf_microfacet_ggx_sample(KernelGlobals kg, ccl_private float *eta) { return bsdf_microfacet_sample( - kg, sc, Ng, wi, randu, randv, eval, wo, pdf, sampled_roughness, eta); + sc, Ng, wi, randu, randv, eval, wo, pdf, sampled_roughness, eta); } /* Beckmann microfacet with Smith shadow-masking from: @@ -680,8 +677,7 @@ ccl_device Spectrum bsdf_microfacet_beckmann_eval(ccl_private const ShaderClosur return bsdf_microfacet_eval(sc, Ng, wi, wo, pdf); } -ccl_device int bsdf_microfacet_beckmann_sample(KernelGlobals kg, - ccl_private const ShaderClosure *sc, +ccl_device int bsdf_microfacet_beckmann_sample(ccl_private const ShaderClosure *sc, float3 Ng,
[Bf-blender-cvs] [5926f69f392] microfacet_hair: Format comment
Commit: 5926f69f392f46b5af0f8858c8dc4c3b214f2619 Author: Weizhen Huang Date: Mon Jan 23 12:20:11 2023 +0100 Branches: microfacet_hair https://developer.blender.org/rB5926f69f392f46b5af0f8858c8dc4c3b214f2619 Format comment === M intern/cycles/kernel/closure/bsdf_hair_microfacet.h === diff --git a/intern/cycles/kernel/closure/bsdf_hair_microfacet.h b/intern/cycles/kernel/closure/bsdf_hair_microfacet.h index 4494a4d24e2..b5c1a6ab628 100644 --- a/intern/cycles/kernel/closure/bsdf_hair_microfacet.h +++ b/intern/cycles/kernel/closure/bsdf_hair_microfacet.h @@ -512,7 +512,7 @@ ccl_device float3 bsdf_microfacet_hair_eval_tt_trt(KernelGlobals kg, /* TRT */ if (bsdf->extra->TRT > 0.0f) { - /* sample wh2 */ + /* Sample wh2. */ const float2 sample2 = make_float2(lcg_step_float(_quadrature), lcg_step_float(_quadrature)); const float3 wh2 = sample_wh(kg, roughness, -wt, wmt, sample2); ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [167b3bb17d7] microfacet_hair: Add paper citation and format comments
Commit: 167b3bb17d7c67aa38826601f403f20e8571866c Author: Weizhen Huang Date: Mon Jan 23 12:15:22 2023 +0100 Branches: microfacet_hair https://developer.blender.org/rB167b3bb17d7c67aa38826601f403f20e8571866c Add paper citation and format comments === M intern/cycles/kernel/closure/bsdf_hair_microfacet.h === diff --git a/intern/cycles/kernel/closure/bsdf_hair_microfacet.h b/intern/cycles/kernel/closure/bsdf_hair_microfacet.h index 7fb803903cd..4494a4d24e2 100644 --- a/intern/cycles/kernel/closure/bsdf_hair_microfacet.h +++ b/intern/cycles/kernel/closure/bsdf_hair_microfacet.h @@ -1,6 +1,10 @@ /* SPDX-License-Identifier: Apache-2.0 * Copyright 2018-2022 Blender Foundation */ +/* This code implements the paper [A Microfacet-based Hair Scattering + * Model](https://onlinelibrary.wiley.com/doi/full/10./cgf.14588) by Weizhen Huang, Matthias B. + * Hullin and Johannes Hanika. */ + #pragma once #ifndef __KERNEL_GPU__ @@ -80,7 +84,6 @@ ccl_device int bsdf_microfacet_hair_setup(ccl_private ShaderData *sd, sd->dPdu, make_float3(bsdf->extra->geom.x, bsdf->extra->geom.y, bsdf->extra->geom.z))); const float3 major_axis = safe_normalize(cross(minor_axis, sd->dPdu)); - /* Local frame is independent of the ray direction for elliptical hairs. */ bsdf->extra->geom = make_float4(major_axis.x, major_axis.y, major_axis.z, h); } else { @@ -88,6 +91,7 @@ ccl_device int bsdf_microfacet_hair_setup(ccl_private ShaderData *sd, } } else { +/* Align local frame with the ray direction so that `phi_i == 0`. */ bsdf->extra->geom = make_float4(X.x, X.y, X.z, h); } @@ -226,9 +230,9 @@ ccl_device_inline float3 sample_wh( const float3 wi_wm = make_float3(dot(wi, s), dot(wi, t), dot(wi, n)); - float G1i; + float discard; const float3 wh_wm = microfacet_sample_stretched( - kg, wi_wm, roughness, roughness, rand.x, rand.y, ); + kg, wi_wm, roughness, roughness, rand.x, rand.y, ); const float3 wh = wh_wm.x * s + wh_wm.y * t + wh_wm.z * n; return wh; @@ -365,7 +369,7 @@ ccl_device float3 bsdf_microfacet_hair_eval_r(ccl_private const ShaderClosure *s /* Modified resolution based on numbers of intervals. */ res = (gamma_m_max - gamma_m_min) / float(intervals); - /* Integrate using Simpson's rule. */ + /* Integrate using Composite Simpson's 1/3 rule. */ float integral = 0.0f; for (size_t i = 0; i <= intervals; i++) { @@ -445,7 +449,7 @@ ccl_device float3 bsdf_microfacet_hair_eval_tt_trt(KernelGlobals kg, const float3 wmi = sphg_dir(tilt, gamma_mi, b); const float3 wmi_ = sphg_dir(0.0f, gamma_mi, b); -/* sample wh1 */ +/* Sample wh1. */ const float2 sample1 = make_float2(lcg_step_float(_quadrature), lcg_step_float(_quadrature)); @@ -473,7 +477,6 @@ ccl_device float3 bsdf_microfacet_hair_eval_tt_trt(KernelGlobals kg, continue; } -/* Simpson's rule weight */ const float weight = (i == 0 || i == intervals) ? 0.5f : (i % 2 + 1); const float3 A_t = exp(mu_a / cos_theta(wt) * @@ -626,7 +629,7 @@ ccl_device int bsdf_microfacet_hair_sample(const KernelGlobals kg, const float roughness = bsdf->roughness; const float roughness2 = sqr(roughness); - /* generate sample */ + /* Generate samples. */ float sample_lobe = randu; const float sample_h = randv; const float2 sample_h1 = make_float2(lcg_step_float(>lcg_state), @@ -655,7 +658,7 @@ ccl_device int bsdf_microfacet_hair_sample(const KernelGlobals kg, return LABEL_NONE; } - /* sample R lobe */ + /* Sample R lobe. */ const float3 wh1 = sample_wh(kg, roughness, wi, wmi, sample_h1); const float3 wr = -reflect(wi, wh1); @@ -669,7 +672,7 @@ ccl_device int bsdf_microfacet_hair_sample(const KernelGlobals kg, const float R1 = fresnel(dot(wi, wh1), *eta, _theta_t1); const float3 R = make_float3(bsdf->extra->R * R1); - /* sample TT lobe */ + /* Sample TT lobe. */ const float3 wt = -refract_angle(wi, wh1, cos_theta_t1, inv_eta); const float phi_t = dir_phi(wt); @@ -820,7 +823,7 @@ ccl_device Spectrum bsdf_microfacet_hair_eval(KernelGlobals kg, return zero_spectrum(); } - /* evaluate */ + /* Evaluate. */ float3 R; if (bsdf->distribution_type == NODE_MICROFACET_HAIR_BECKMANN) { R = bsdf_microfacet_hair_eval_r(sc, local_I, local_O) + @@ -868,8 +871,7 @@ ccl_device void bsdf_microfacet_hair_blur(ccl_private ShaderClosure *sc, float r bsdf->roughness = fmaxf(roughness, bsdf->roughness); } -/* Hair Albedo */ - +/* Hair Albedo. */ ccl_device float3 bsdf_microfacet_hair_albedo(ccl_private const ShaderClosure *sc) { ccl_private MicrofacetHairBSDF *bsdf = (ccl_private MicrofacetHairBSDF *)sc; __
[Bf-blender-cvs] [035ee375ac3] microfacet_hair: Use functions in `bsdf_microfacet.h`
Commit: 035ee375ac32ebfb761bfe35a89a7443ec95e9df Author: Weizhen Huang Date: Mon Jan 23 11:58:15 2023 +0100 Branches: microfacet_hair https://developer.blender.org/rB035ee375ac32ebfb761bfe35a89a7443ec95e9df Use functions in `bsdf_microfacet.h` === M intern/cycles/kernel/closure/bsdf_hair_microfacet.h === diff --git a/intern/cycles/kernel/closure/bsdf_hair_microfacet.h b/intern/cycles/kernel/closure/bsdf_hair_microfacet.h index d8e79739ffb..7fb803903cd 100644 --- a/intern/cycles/kernel/closure/bsdf_hair_microfacet.h +++ b/intern/cycles/kernel/closure/bsdf_hair_microfacet.h @@ -249,49 +249,6 @@ ccl_device_inline bool microfacet_visible(const float3 wi, return microfacet_visible(wi, m, h) && microfacet_visible(wo, m, h); } -/* Smith's separable shadowing/masking term. */ -ccl_device_inline float smith_g1( -const bool beckmann, const float roughness, const float3 v, const float3 m, const float3 h) -{ - /* Assume consistent orientation (can't see the back of the microfacet from the front and vice - * versa). */ - float cos_vm = dot(v, m); - if (dot(v, h) <= 0.0f || cos_vm <= 0.0f) { -return 0.0f; - } - - return beckmann ? bsdf_G1(sqr(roughness), cos_vm) : -2.0f / (1.0f + sqrtf(1.0f + sqr(roughness) * (1.0f / sqr(cos_vm) - 1.0f))); -} - -/* Geometry term. */ -ccl_device_inline float G(const bool beckmann, - const float roughness, - const float3 wi, - const float3 wo, - const float3 m, - const float3 h) -{ - return smith_g1(beckmann, roughness, wi, m, h) * smith_g1(beckmann, roughness, wo, m, h); -} - -/* Normal Distribution Function. */ -ccl_device float D(const bool beckmann, const float roughness, const float3 m, const float3 h) -{ - const float cos_theta = dot(h, m); - - const float roughness2 = sqr(roughness); - const float cos_theta2 = sqr(cos_theta); - - const float result = beckmann ? - expf((1.0f - 1.0f / cos_theta2) / roughness2) / - (M_PI_F * roughness2 * sqr(cos_theta2)) : - roughness2 / (M_PI_F * sqr(1.0f + (roughness2 - 1.0f) * cos_theta2)); - - /* Prevent potential numerical issues in other stages of the model. */ - return (result * cos_theta > 1e-20f) ? result : 0.0f; -} - /* Compute fresnel reflection. Also return the dot product of the refracted ray and the normal as * `cos_theta_t`, as it is used when computing the direction of the refracted ray. */ ccl_device float fresnel(float cos_theta_i, float eta, ccl_private float *cos_theta_t) @@ -345,12 +302,11 @@ ccl_device float3 bsdf_microfacet_hair_eval_r(ccl_private const ShaderClosure *s ccl_private MicrofacetHairBSDF *bsdf = (ccl_private MicrofacetHairBSDF *)sc; const float tilt = -bsdf->tilt; const float roughness = bsdf->roughness; + const float roughness2 = sqr(roughness); const float eta = bsdf->eta; - const bool beckmann = (bsdf->distribution_type == NODE_MICROFACET_HAIR_BECKMANN); - float3 R = zero_float3(); if (bsdf->extra->R <= 0.0f) { -return R; +return zero_float3(); } /* Get elliptical cross section characteristic. Assuming major axis is 1. */ @@ -366,14 +322,14 @@ ccl_device float3 bsdf_microfacet_hair_eval_r(ccl_private const ShaderClosure *s const float tan_tilt = tanf(tilt); float phi_m_max1 = acosf(fmaxf(-tan_tilt * tan_theta(wi), 0.0f)) + phi_i; if (isnan_safe(phi_m_max1)) { -return R; +return zero_float3(); } float phi_m_min1 = -phi_m_max1 + 2.0f * phi_i; /* dot(wo, wmi) > 0 */ float phi_m_max2 = acosf(fmaxf(-tan_tilt * tan_theta(wo), 0.0f)) + phi_o; if (isnan_safe(phi_m_max2)) { -return R; +return zero_float3(); } float phi_m_min2 = -phi_m_max2 + 2.0f * phi_o; @@ -392,7 +348,7 @@ ccl_device float3 bsdf_microfacet_hair_eval_r(ccl_private const ShaderClosure *s const float phi_m_min = fmaxf(phi_m_min1, phi_m_min2) + 1e-3f; const float phi_m_max = fminf(phi_m_max1, phi_m_max2) - 1e-3f; if (phi_m_min > phi_m_max) { -return R; +return zero_float3(); } const float gamma_m_min = to_gamma(phi_m_min, b); @@ -418,8 +374,8 @@ ccl_device float3 bsdf_microfacet_hair_eval_r(ccl_private const ShaderClosure *s if (microfacet_visible(wi, wo, make_float3(wm.x, 0.0f, wm.z), wh)) { const float weight = (i == 0 || i == intervals) ? 0.5f : (i % 2 + 1); - integral += weight * D(beckmann, roughness, wm, wh) * - G(beckmann, roughness, wi, wo, wm, wh) * arc_length(e2, gamma_m); + integral += weight * bsdf_D(roughness2, dot(wm, wh)) * + bsdf_G(roughness2, dot(wi, wm), dot(wo, wm)) * arc_length(e2, gamma_m); }
[Bf-blender-cvs] [05e7caed943] microfacet_hair: Merge branch 'master' into microfacet_hair
Commit: 05e7caed943e570fe92a0fd11f0d4b1a1110d7bf Author: Weizhen Huang Date: Mon Jan 23 10:22:28 2023 +0100 Branches: microfacet_hair https://developer.blender.org/rB05e7caed943e570fe92a0fd11f0d4b1a1110d7bf Merge branch 'master' into microfacet_hair === === ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [33ff1ce7b25] microfacet_hair: Merge code for circular and elliptical cross-sections
Commit: 33ff1ce7b25f2429c0b6c5769268733880cfab1f Author: Weizhen Huang Date: Fri Jan 20 20:11:30 2023 +0100 Branches: microfacet_hair https://developer.blender.org/rB33ff1ce7b25f2429c0b6c5769268733880cfab1f Merge code for circular and elliptical cross-sections === M intern/cycles/blender/shader.cpp M intern/cycles/kernel/closure/bsdf_hair_microfacet.h M intern/cycles/kernel/osl/closures_setup.h M intern/cycles/kernel/osl/closures_template.h M intern/cycles/kernel/osl/shaders/node_microfacet_hair_bsdf.osl M intern/cycles/kernel/osl/shaders/stdcycles.h M intern/cycles/kernel/svm/closure.h M intern/cycles/kernel/svm/types.h M intern/cycles/scene/shader_nodes.cpp M intern/cycles/scene/shader_nodes.h M source/blender/makesdna/DNA_node_types.h M source/blender/makesrna/intern/rna_nodetree.c M source/blender/nodes/shader/nodes/node_shader_bsdf_hair_microfacet.cc === diff --git a/intern/cycles/blender/shader.cpp b/intern/cycles/blender/shader.cpp index 266a5900837..015bdee59fb 100644 --- a/intern/cycles/blender/shader.cpp +++ b/intern/cycles/blender/shader.cpp @@ -668,11 +668,7 @@ static ShaderNode *add_node(Scene *scene, "parametrization", NODE_MICROFACET_HAIR_NUM, NODE_MICROFACET_HAIR_REFLECTANCE)); -microfacet_hair->set_cross_section( - (NodeMicrofacetHairCrossSectionType)get_enum(b_microfacet_hair_node.ptr, - "cross_section", - NODE_MICROFACET_HAIR_CROSS_SECTION_NUM, - NODE_MICROFACET_HAIR_CIRCULAR)); + microfacet_hair->set_distribution_type( (NodeMicrofacetHairDistributionType)get_enum(b_microfacet_hair_node.ptr, "distribution_type", diff --git a/intern/cycles/kernel/closure/bsdf_hair_microfacet.h b/intern/cycles/kernel/closure/bsdf_hair_microfacet.h index d9d9df942e6..d8e79739ffb 100644 --- a/intern/cycles/kernel/closure/bsdf_hair_microfacet.h +++ b/intern/cycles/kernel/closure/bsdf_hair_microfacet.h @@ -36,9 +36,6 @@ typedef struct MicrofacetHairBSDF { /* GGX/Beckmann. */ int distribution_type; - /* Circular/Elliptical */ - int cross_section; - /* The ratio of the minor axis to the major axis. */ float aspect_ratio; @@ -74,7 +71,7 @@ ccl_device int bsdf_microfacet_hair_setup(ccl_private ShaderData *sd, kernel_assert(isfinite_safe(X)); kernel_assert(isfinite_safe(h)); - if (bsdf->cross_section == NODE_MICROFACET_HAIR_ELLIPTIC) { + if (bsdf->aspect_ratio != 1.0f) { if (bsdf->aspect_ratio > 1.0f) { bsdf->aspect_ratio = 1.0f / bsdf->aspect_ratio; @@ -154,53 +151,67 @@ ccl_device_inline float2 dir_sph(const float3 w) return make_float2(dir_theta(w), dir_phi(w)); } -/* Compute the vector direction given spherical coordinates. */ -ccl_device_inline float3 sph_dir(float theta, float phi) -{ - float sin_theta, cos_theta, sin_phi, cos_phi; - fast_sincosf(theta, _theta, _theta); - fast_sincosf(phi, _phi, _phi); - return make_float3(sin_phi * cos_theta, sin_theta, cos_phi * cos_theta); -} - -/* Utility functions for elliptical cross-sections. */ - /* Conversion between gamma and phi. Notations see Figure 5 in the paper. */ -ccl_device float to_phi(float gamma, float a, float b) +ccl_device_inline float to_phi(float gamma, float b) { + if (b == 1.0f) { +return gamma; + } float sin_gamma, cos_gamma; fast_sincosf(gamma, _gamma, _gamma); - return atan2f(b * sin_gamma, a * cos_gamma); + return atan2f(b * sin_gamma, cos_gamma); } -ccl_device float to_gamma(float phi, float a, float b) +ccl_device_inline float to_gamma(float phi, float b) { + if (b == 1.0f) { +return phi; + } float sin_phi, cos_phi; fast_sincosf(phi, _phi, _phi); - return atan2f(a * sin_phi, b * cos_phi); + return atan2f(sin_phi, b * cos_phi); } -/* Compute the coordinate on the ellipse, given gamma, the semi-major and semi-minor axes. */ -ccl_device float2 to_point(float gamma, float a, float b) +/* Compute the coordinate on the ellipse, given gamma and the aspect ratio between the minor axis + * and the major axis. */ +ccl_device_inline float2 to_point(float gamma, float b) { float sin_gamma, cos_gamma; fast_sincosf(gamma, _gamma, _gamma); - return make_float2(a * sin_gamma, b * cos_gamma); + return make_float2(sin_gamma, b * cos_gamma); } /* Compute the vector direction given by theta and gamma. */ -ccl_device float3 sphg_dir(float theta, float gamma, float a, float b) +ccl_device_inline float3 s
[Bf-blender-cvs] [46bc834a3dd] microfacet_hair: Merge branch 'master' into microfacet_hair
Commit: 46bc834a3ddf39ef53ebfd221697ac26ad5c15d5 Author: Weizhen Huang Date: Fri Jan 20 15:18:29 2023 +0100 Branches: microfacet_hair https://developer.blender.org/rB46bc834a3ddf39ef53ebfd221697ac26ad5c15d5 Merge branch 'master' into microfacet_hair === === diff --cc intern/cycles/blender/curves.cpp index ce8a35fb61b,6158ed78598..0b06ab22bbc --- a/intern/cycles/blender/curves.cpp +++ b/intern/cycles/blender/curves.cpp @@@ -895,9 -885,6 +894,14 @@@ static void export_hair_curves(Scene *s float *attr_length = NULL; float *attr_random = NULL; + if (hair->need_attribute(scene, ATTR_STD_VERTEX_NORMAL)) { - attr_normal = hair->attributes.add(ATTR_STD_VERTEX_NORMAL)->data_float3(); ++/* Compute geometry normals. */ ++float3 *attr_normal = hair->attributes.add(ATTR_STD_VERTEX_NORMAL)->data_float3(); ++int i = 0; ++for (BL::FloatVectorValueReadOnly : b_curves.normals) { ++ attr_normal[i++] = get_float3(normal.vector()); ++} + } if (hair->need_attribute(scene, ATTR_STD_CURVE_INTERCEPT)) { attr_intercept = hair->attributes.add(ATTR_STD_CURVE_INTERCEPT)->data_float(); } diff --cc intern/cycles/kernel/closure/bsdf.h index cb797e284a4,2f53454d7dd..8ca750945ff --- a/intern/cycles/kernel/closure/bsdf.h +++ b/intern/cycles/kernel/closure/bsdf.h @@@ -242,14 -220,10 +221,14 @@@ ccl_device_inline int bsdf_sample(Kerne break; case CLOSURE_BSDF_HAIR_PRINCIPLED_ID: label = bsdf_principled_hair_sample( - kg, sc, sd, randu, randv, eval, omega_in, pdf, sampled_roughness, eta); + kg, sc, sd, randu, randv, eval, wo, pdf, sampled_roughness, eta); break; +case CLOSURE_BSDF_HAIR_MICROFACET_ID: + label = bsdf_microfacet_hair_sample( - kg, sc, sd, randu, randv, eval, omega_in, pdf, sampled_roughness, eta); ++ kg, sc, sd, randu, randv, eval, wo, pdf, sampled_roughness, eta); + break; case CLOSURE_BSDF_PRINCIPLED_DIFFUSE_ID: - label = bsdf_principled_diffuse_sample(sc, Ng, sd->I, randu, randv, eval, omega_in, pdf); + label = bsdf_principled_diffuse_sample(sc, Ng, sd->wi, randu, randv, eval, wo, pdf); *sampled_roughness = one_float2(); *eta = 1.0f; break; @@@ -514,8 -483,7 +493,8 @@@ ccl_device_inline int bsdf_label(const label = LABEL_TRANSMIT | LABEL_GLOSSY; break; case CLOSURE_BSDF_HAIR_PRINCIPLED_ID: +case CLOSURE_BSDF_HAIR_MICROFACET_ID: - if (bsdf_is_transmission(sc, omega_in)) + if (bsdf_is_transmission(sc, wo)) label = LABEL_TRANSMIT | LABEL_GLOSSY; else label = LABEL_REFLECT | LABEL_GLOSSY; @@@ -603,37 -571,34 +582,37 @@@ ccl_device_inlin break; case CLOSURE_BSDF_MICROFACET_BECKMANN_ID: case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID: - eval = bsdf_microfacet_beckmann_eval(sc, sd->N, sd->I, omega_in, pdf); + eval = bsdf_microfacet_beckmann_eval(sc, sd->N, sd->wi, wo, pdf); break; case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID: - eval = bsdf_ashikhmin_shirley_eval(sc, sd->N, sd->I, omega_in, pdf); + eval = bsdf_ashikhmin_shirley_eval(sc, sd->N, sd->wi, wo, pdf); break; case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID: - eval = bsdf_ashikhmin_velvet_eval(sc, sd->I, omega_in, pdf); + eval = bsdf_ashikhmin_velvet_eval(sc, sd->wi, wo, pdf); break; case CLOSURE_BSDF_DIFFUSE_TOON_ID: - eval = bsdf_diffuse_toon_eval(sc, sd->I, omega_in, pdf); + eval = bsdf_diffuse_toon_eval(sc, sd->wi, wo, pdf); break; case CLOSURE_BSDF_GLOSSY_TOON_ID: - eval = bsdf_glossy_toon_eval(sc, sd->I, omega_in, pdf); + eval = bsdf_glossy_toon_eval(sc, sd->wi, wo, pdf); break; case CLOSURE_BSDF_HAIR_PRINCIPLED_ID: - eval = bsdf_principled_hair_eval(kg, sd, sc, omega_in, pdf); + eval = bsdf_principled_hair_eval(kg, sd, sc, wo, pdf); break; +case CLOSURE_BSDF_HAIR_MICROFACET_ID: - eval = bsdf_microfacet_hair_eval(kg, sd, sc, omega_in, pdf); ++ eval = bsdf_microfacet_hair_eval(kg, sd, sc, wo, pdf); + break; case CLOSURE_BSDF_HAIR_REFLECTION_ID: - eval = bsdf_hair_reflection_eval(sc, sd->I, omega_in, pdf); + eval = bsdf_hair_reflection_eval(sc, sd->wi, wo, pdf); break; case CLOSURE_BSDF_HAIR_TRANSMISSION_ID: - eval = bsdf_hair_transmission_eval(sc, sd->I, omega_in, pdf); + eval = bsdf_hair_transmission_eval(sc, sd->wi, wo, pdf); break; case CLOSURE_BSDF_PRINCIPLED_DIFFUSE_ID: - eval = bsdf_principled_diffuse_eval(sc, sd->I, omega_in, pdf); + eval = bsdf_principled_diffuse_eval(sc, sd->wi, wo, pdf); break; case CLOSURE_BSDF_PRINCIPLED_S
[Bf-blender-cvs] [f71bfe46553] master: Fix anisotropic Beckmann regression test failing on Metal
Commit: f71bfe465538e6add595804f14fa2731fc8f7b64 Author: Weizhen Huang Date: Thu Jan 19 20:02:35 2023 +0100 Branches: master https://developer.blender.org/rBf71bfe465538e6add595804f14fa2731fc8f7b64 Fix anisotropic Beckmann regression test failing on Metal The lookup table method on CPU and the numerical root finding method on GPU give quite different results. This commit deletes the Beckmann lookup table and uses numerical root finding on all devices. For the numerical root finding, a combined bisection-Newton method with precision control is used. Differential Revision: https://developer.blender.org/D17050 === M intern/cycles/kernel/closure/bsdf_microfacet.h M intern/cycles/kernel/types.h M intern/cycles/scene/shader.cpp M intern/cycles/scene/shader.h M release/scripts/addons M release/scripts/addons_contrib === diff --git a/intern/cycles/kernel/closure/bsdf_microfacet.h b/intern/cycles/kernel/closure/bsdf_microfacet.h index 25238698614..83051f08f40 100644 --- a/intern/cycles/kernel/closure/bsdf_microfacet.h +++ b/intern/cycles/kernel/closure/bsdf_microfacet.h @@ -71,7 +71,6 @@ ccl_device_inline void microfacet_beckmann_sample_slopes(KernelGlobals kg, *G1i = G1; -#if defined(__KERNEL_GPU__) /* Based on paper from Wenzel Jakob * An Improved Visible Normal Sampling Routine for the Beckmann Distribution * @@ -87,38 +86,38 @@ ccl_device_inline void microfacet_beckmann_sample_slopes(KernelGlobals kg, * exp(-ierf(x)^2) ~= 1 - x * x * solve y = 1 + b + K * (1 - b * b) */ - float K = tan_theta_i * SQRT_PI_INV; - float y_approx = randu * (1.0f + erf_a + K * (1 - erf_a * erf_a)); - float y_exact = randu * (1.0f + erf_a + K * exp_a2); + const float K = tan_theta_i * SQRT_PI_INV; + const float y_approx = randu * (1.0f + erf_a + K * (1 - erf_a * erf_a)); + const float y_exact = randu * (1.0f + erf_a + K * exp_a2); float b = K > 0 ? (0.5f - sqrtf(K * (K - y_approx + 1.0f) + 0.25f)) / K : y_approx - 1.0f; - /* Perform newton step to refine toward the true root. */ float inv_erf = fast_ierff(b); - float value = 1.0f + b + K * expf(-inv_erf * inv_erf) - y_exact; - /* Check if we are close enough already, - * this also avoids NaNs as we get close to the root. - */ - if (fabsf(value) > 1e-6f) { -b -= value / (1.0f - inv_erf * tan_theta_i); /* newton step 1. */ -inv_erf = fast_ierff(b); -value = 1.0f + b + K * expf(-inv_erf * inv_erf) - y_exact; -b -= value / (1.0f - inv_erf * tan_theta_i); /* newton step 2. */ -/* Compute the slope from the refined value. */ -*slope_x = fast_ierff(b); - } - else { -/* We are close enough already. */ -*slope_x = inv_erf; + float2 begin = make_float2(-1.0f, -y_exact); + float2 end = make_float2(erf_a, 1.0f + erf_a + K * exp_a2 - y_exact); + float2 current = make_float2(b, 1.0f + b + K * expf(-sqr(inv_erf)) - y_exact); + + /* Find root in a monotonic interval using newton method, under given precision and maximal + * iterations. Falls back to bisection if newton step produces results outside of the valid + * interval.*/ + const float precision = 1e-6f; + const int max_iter = 3; + int iter = 0; + while (fabsf(current.y) > precision && iter++ < max_iter) { +if (signf(begin.y) == signf(current.y)) { + begin.x = current.x; + begin.y = current.y; +} +else { + end.x = current.x; +} +const float newton_x = current.x - current.y / (1.0f - inv_erf * tan_theta_i); +current.x = (newton_x >= begin.x && newton_x <= end.x) ? newton_x : 0.5f * (begin.x + end.x); +inv_erf = fast_ierff(current.x); +current.y = 1.0f + current.x + K * expf(-sqr(inv_erf)) - y_exact; } - *slope_y = fast_ierff(2.0f * randv - 1.0f); -#else - /* Use precomputed table on CPU, it gives better performance. */ - int beckmann_table_offset = kernel_data.tables.beckmann_offset; - *slope_x = lookup_table_read_2D( - kg, randu, cos_theta_i, beckmann_table_offset, BECKMANN_TABLE_SIZE, BECKMANN_TABLE_SIZE); + *slope_x = inv_erf; *slope_y = fast_ierff(2.0f * randv - 1.0f); -#endif } /* GGX microfacet importance sampling from: diff --git a/intern/cycles/kernel/types.h b/intern/cycles/kernel/types.h index 72a9c65f303..4075980076f 100644 --- a/intern/cycles/kernel/types.h +++ b/intern/cycles/kernel/types.h @@ -34,8 +34,6 @@ CCL_NAMESPACE_BEGIN #define VOLUME_BOUNDS_MAX 1024 -#define BECKMANN_TABLE_SIZE 256 - #define SHADER_NONE (~0) #define OBJECT_NONE (~0) #define PRIM_NONE (~0) @@ -1187,9 +1185,8 @@ typedef enum KernelBVHLayout { #include "kernel/data_template.h" typedef struct KernelTables { - int beckmann_offset; int filter_table_offset; - int pad1, pad2; + int pad1, pad2, pad3; } KernelTables; static_assert_align(KernelTables, 16);
[Bf-blender-cvs] [9b7c2cca3df] master: Refactor: replace `bool beckmann` with `enum MicrofacetType` for readability
Commit: 9b7c2cca3df808eb0948e0e7e24fb18b11cb7476 Author: Weizhen Huang Date: Thu Jan 19 12:48:29 2023 +0100 Branches: master https://developer.blender.org/rB9b7c2cca3df808eb0948e0e7e24fb18b11cb7476 Refactor: replace `bool beckmann` with `enum MicrofacetType` for readability Differential Revision: https://developer.blender.org/D17044 === M intern/cycles/kernel/closure/bsdf_microfacet.h M intern/cycles/kernel/integrator/mnee.h === diff --git a/intern/cycles/kernel/closure/bsdf_microfacet.h b/intern/cycles/kernel/closure/bsdf_microfacet.h index 377cf836fb8..25238698614 100644 --- a/intern/cycles/kernel/closure/bsdf_microfacet.h +++ b/intern/cycles/kernel/closure/bsdf_microfacet.h @@ -16,6 +16,11 @@ CCL_NAMESPACE_BEGIN +enum MicrofacetType { + BECKMANN, + GGX, +}; + typedef struct MicrofacetExtra { Spectrum color, cspec0; Spectrum fresnel_color; @@ -175,13 +180,13 @@ ccl_device_inline void microfacet_ggx_sample_slopes(const float cos_theta_i, *slope_y = S * z * safe_sqrtf(1.0f + (*slope_x) * (*slope_x)); } +template ccl_device_forceinline float3 microfacet_sample_stretched(KernelGlobals kg, const float3 wi, const float alpha_x, const float alpha_y, const float randu, const float randv, - bool beckmann, ccl_private float *G1i) { /* 1. stretch wi */ @@ -206,7 +211,7 @@ ccl_device_forceinline float3 microfacet_sample_stretched(KernelGlobals kg, /* 2. sample P22_{wi}(x_slope, y_slope, 1, 1) */ float slope_x, slope_y; - if (beckmann) { + if constexpr (m_type == MicrofacetType::BECKMANN) { microfacet_beckmann_sample_slopes( kg, costheta_, sintheta_, randu, randv, _x, _y, G1i); } @@ -268,45 +273,51 @@ ccl_device_forceinline float bsdf_clearcoat_D(float alpha2, float cos_NH) } /* Monodirectional shadowing-masking term. */ -template ccl_device_inline float bsdf_G1_from_sqr_alpha_tan_n(float sqr_alpha_tan_n) +template +ccl_device_inline float bsdf_G1_from_sqr_alpha_tan_n(float sqr_alpha_tan_n) { - if (!beckmann) { /* GGX. */ + if constexpr (m_type == MicrofacetType::GGX) { return 2.0f / (1.0f + sqrtf(1.0f + sqr_alpha_tan_n)); } + /* m_type == MicrofacetType::BECKMANN */ const float a = inversesqrtf(sqr_alpha_tan_n); return (a > 1.6f) ? 1.0f : ((2.181f * a + 3.535f) * a) / ((2.577f * a + 2.276f) * a + 1.0f); } -template ccl_device_inline float bsdf_G1(float alpha2, float cos_N) +template ccl_device_inline float bsdf_G1(float alpha2, float cos_N) { - return bsdf_G1_from_sqr_alpha_tan_n(alpha2 * -fmaxf(1.0f / (cos_N * cos_N) - 1.0f, 0.0f)); + return bsdf_G1_from_sqr_alpha_tan_n(alpha2 * fmaxf(1.0f / (cos_N * cos_N) - 1.0f, 0.0f)); } -template +template ccl_device_inline float bsdf_aniso_G1(float alpha_x, float alpha_y, float3 V) { - return bsdf_G1_from_sqr_alpha_tan_n((sqr(alpha_x * V.x) + sqr(alpha_y * V.y)) / -sqr(V.z)); + return bsdf_G1_from_sqr_alpha_tan_n((sqr(alpha_x * V.x) + sqr(alpha_y * V.y)) / + sqr(V.z)); } /* Smith's separable shadowing-masking term. */ -template ccl_device_inline float bsdf_G(float alpha2, float cos_NI, float cos_NO) +template +ccl_device_inline float bsdf_G(float alpha2, float cos_NI, float cos_NO) { - return bsdf_G1(alpha2, cos_NI) * bsdf_G1(alpha2, cos_NO); + return bsdf_G1(alpha2, cos_NI) * bsdf_G1(alpha2, cos_NO); } /* Normal distribution function. */ -template ccl_device_inline float bsdf_D(float alpha2, float cos_NH) +template ccl_device_inline float bsdf_D(float alpha2, float cos_NH) { const float cos_NH2 = sqr(cos_NH); - return beckmann ? expf((1.0f - 1.0f / cos_NH2) / alpha2) / (M_PI_F * alpha2 * sqr(cos_NH2)) : -alpha2 / (M_PI_F * sqr(1.0f + (alpha2 - 1.0f) * cos_NH2)); + if constexpr (m_type == MicrofacetType::BECKMANN) { +return expf((1.0f - 1.0f / cos_NH2) / alpha2) / (M_PI_F * alpha2 * sqr(cos_NH2)); + } + + /* m_type == MicrofacetType::GGX */ + return alpha2 / (M_PI_F * sqr(1.0f + (alpha2 - 1.0f) * cos_NH2)); } -template +template ccl_device_inline float bsdf_aniso_D(float alpha_x, float alpha_y, float3 H) { H /= make_float3(alpha_x, alpha_y, 1.0f); @@ -314,8 +325,12 @@ ccl_device_inline float bsdf_aniso_D(float alpha_x, float alpha_y, float3 H) const float cos_NH2 = sqr(H.z); const float alpha2 = alpha_x * alph
[Bf-blender-cvs] [320757bc611] master: Refactor microfacet BSDF to reduce repetition
Commit: 320757bc6111bf7c652068368b92312c994838f8 Author: Weizhen Huang Date: Thu Jan 19 12:06:14 2023 +0100 Branches: master https://developer.blender.org/rB320757bc6111bf7c652068368b92312c994838f8 Refactor microfacet BSDF to reduce repetition === M intern/cycles/kernel/closure/bsdf_microfacet.h M intern/cycles/kernel/integrator/mnee.h === diff --git a/intern/cycles/kernel/closure/bsdf_microfacet.h b/intern/cycles/kernel/closure/bsdf_microfacet.h index ed438b1f483..377cf836fb8 100644 --- a/intern/cycles/kernel/closure/bsdf_microfacet.h +++ b/intern/cycles/kernel/closure/bsdf_microfacet.h @@ -43,17 +43,18 @@ ccl_device_inline void microfacet_beckmann_sample_slopes(KernelGlobals kg, ccl_private float *slope_y, ccl_private float *G1i) { - /* special case (normal incidence) */ + /* Special case (normal incidence). */ if (cos_theta_i >= 0.9f) { const float r = sqrtf(-logf(randu)); const float phi = M_2PI_F * randv; *slope_x = r * cosf(phi); *slope_y = r * sinf(phi); *G1i = 1.0f; + return; } - /* precomputations */ + /* Precomputations. */ const float tan_theta_i = sin_theta_i / cos_theta_i; const float inv_a = tan_theta_i; const float cot_theta_i = 1.0f / tan_theta_i; @@ -129,7 +130,7 @@ ccl_device_inline void microfacet_ggx_sample_slopes(const float cos_theta_i, ccl_private float *slope_y, ccl_private float *G1i) { - /* special case (normal incidence) */ + /* Special case (normal incidence). */ if (cos_theta_i >= 0.9f) { const float r = sqrtf(randu / (1.0f - randu)); const float phi = M_2PI_F * randv; @@ -140,13 +141,13 @@ ccl_device_inline void microfacet_ggx_sample_slopes(const float cos_theta_i, return; } - /* precomputations */ + /* Precomputations. */ const float tan_theta_i = sin_theta_i / cos_theta_i; const float G1_inv = 0.5f * (1.0f + safe_sqrtf(1.0f + tan_theta_i * tan_theta_i)); *G1i = 1.0f / G1_inv; - /* sample slope_x */ + /* Sample slope_x. */ const float A = 2.0f * randu * G1_inv - 1.0f; const float AA = A * A; const float tmp = 1.0f / (AA - 1.0f); @@ -157,7 +158,7 @@ ccl_device_inline void microfacet_ggx_sample_slopes(const float cos_theta_i, const float slope_x_2 = B * tmp + D; *slope_x = (A < 0.0f || slope_x_2 * tan_theta_i > 1.0f) ? slope_x_1 : slope_x_2; - /* sample slope_y */ + /* Sample slope_y. */ float S; if (randv > 0.5f) { @@ -187,7 +188,7 @@ ccl_device_forceinline float3 microfacet_sample_stretched(KernelGlobals kg, float3 wi_ = make_float3(alpha_x * wi.x, alpha_y * wi.y, wi.z); wi_ = normalize(wi_); - /* get polar coordinates of wi_ */ + /* Compute polar coordinates of wi_. */ float costheta_ = 1.0f; float sintheta_ = 0.0f; float cosphi_ = 1.0f; @@ -238,26 +239,85 @@ ccl_device_forceinline Spectrum reflection_color(ccl_private const MicrofacetBsd float3 H) { Spectrum F = one_spectrum(); - bool use_fresnel = (bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_FRESNEL_ID || - bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID); + + bool use_clearcoat = bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID; + bool use_fresnel = (bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_FRESNEL_ID || use_clearcoat); + if (use_fresnel) { float F0 = fresnel_dielectric_cos(1.0f, bsdf->ior); F = interpolate_fresnel_color(L, H, bsdf->ior, F0, bsdf->extra->cspec0); } + if (use_clearcoat) { +F *= 0.25f * bsdf->extra->clearcoat; + } + return F; } -ccl_device_forceinline float D_GTR1(float NdotH, float alpha) +/* Generalized Trowbridge-Reitz for clearcoat. */ +ccl_device_forceinline float bsdf_clearcoat_D(float alpha2, float cos_NH) { - if (alpha >= 1.0f) + if (alpha2 >= 1.0f) { return M_1_PI_F; - float alpha2 = alpha * alpha; - float t = 1.0f + (alpha2 - 1.0f) * NdotH * NdotH; + } + + const float t = 1.0f + (alpha2 - 1.0f) * cos_NH * cos_NH; return (alpha2 - 1.0f) / (M_PI_F * logf(alpha2) * t); } +/* Monodirectional shadowing-masking term. */ +template ccl_device_inline float bsdf_G1_from_sqr_alpha_tan_n(float sqr_alpha_tan_n) +{ + if (!beckmann) { /* GGX. */ +return 2.0f / (1.0f + sqrtf(1.0f + sqr_alpha_tan_n)); + } + + const float a = inversesqrtf(sqr_alpha_tan_n); + return (a > 1.6f) ? 1.0f : ((2.181f * a + 3.535f) * a) / ((2.577f * a + 2.276f) * a + 1.0f); +} + +template ccl_device_inline float bsdf_G1(float alpha2, float cos_N) +{ + return bsdf_G1_from_sqr_alpha_tan_n(alpha2 * +
[Bf-blender-cvs] [eb657633ed8] master: Fix anisotropic Beckmann using isotropic sampling
Commit: eb657633ed85ba6eca16617ac579baf21a6824d5 Author: Weizhen Huang Date: Thu Jan 19 11:22:16 2023 +0100 Branches: master https://developer.blender.org/rBeb657633ed85ba6eca16617ac579baf21a6824d5 Fix anisotropic Beckmann using isotropic sampling === M intern/cycles/kernel/closure/bsdf_microfacet.h === diff --git a/intern/cycles/kernel/closure/bsdf_microfacet.h b/intern/cycles/kernel/closure/bsdf_microfacet.h index 90ae42dd7a6..ed438b1f483 100644 --- a/intern/cycles/kernel/closure/bsdf_microfacet.h +++ b/intern/cycles/kernel/closure/bsdf_microfacet.h @@ -1006,7 +1006,7 @@ ccl_device int bsdf_microfacet_beckmann_sample(KernelGlobals kg, float3 local_m; float G1i; -local_m = microfacet_sample_stretched(kg, local_I, alpha_x, alpha_x, randu, randv, true, ); +local_m = microfacet_sample_stretched(kg, local_I, alpha_x, alpha_y, randu, randv, true, ); float3 m = X * local_m.x + Y * local_m.y + Z * local_m.z; float cosThetaM = local_m.z; ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [6e6ae173357] master: Fix reversed `cosNI` and `cosNO` in Cycles anisotropic beckmann G1
Commit: 6e6ae1733579bf56ee6269ff25114ac1de46b44f Author: Weizhen Huang Date: Wed Jan 18 13:08:33 2023 +0100 Branches: master https://developer.blender.org/rB6e6ae1733579bf56ee6269ff25114ac1de46b44f Fix reversed `cosNI` and `cosNO` in Cycles anisotropic beckmann G1 === M intern/cycles/kernel/closure/bsdf_microfacet.h === diff --git a/intern/cycles/kernel/closure/bsdf_microfacet.h b/intern/cycles/kernel/closure/bsdf_microfacet.h index 611d45b73cc..90ae42dd7a6 100644 --- a/intern/cycles/kernel/closure/bsdf_microfacet.h +++ b/intern/cycles/kernel/closure/bsdf_microfacet.h @@ -871,8 +871,8 @@ ccl_device Spectrum bsdf_microfacet_beckmann_eval_reflect(ccl_private const Micr D = expf(-slope_x * slope_x - slope_y * slope_y) / (M_PI_F * alpha2 * cosThetaM4); /* G1(i,m) and G1(o,m) */ -G1i = bsdf_beckmann_aniso_G1(alpha_x, alpha_y, cosNO, dot(wi, X), dot(wi, Y)); -G1o = bsdf_beckmann_aniso_G1(alpha_x, alpha_y, cosNI, dot(wo, X), dot(wo, Y)); +G1i = bsdf_beckmann_aniso_G1(alpha_x, alpha_y, cosNI, dot(wi, X), dot(wi, Y)); +G1o = bsdf_beckmann_aniso_G1(alpha_x, alpha_y, cosNO, dot(wo, X), dot(wo, Y)); } float G = G1i * G1o; ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [543bf28fb1f] master: Refactor: renamed I -> wi, omega_in -> wo in Cycles
Commit: 543bf28fb1ff736293900d154dfb3a5da84df28a Author: Weizhen Huang Date: Tue Jan 17 17:19:20 2023 +0100 Branches: master https://developer.blender.org/rB543bf28fb1ff736293900d154dfb3a5da84df28a Refactor: renamed I -> wi, omega_in -> wo in Cycles wi is the viewing direction, and wo is the illumination direction. Under this notation, BSDF sampling always samples from wi and outputs wo, which is consistent with most of the papers and mitsuba. This order is reversed compared with PBRT, although PBRT also traces from the camera. === M intern/cycles/kernel/closure/bsdf.h M intern/cycles/kernel/closure/bsdf_ashikhmin_shirley.h M intern/cycles/kernel/closure/bsdf_ashikhmin_velvet.h M intern/cycles/kernel/closure/bsdf_diffuse.h M intern/cycles/kernel/closure/bsdf_diffuse_ramp.h M intern/cycles/kernel/closure/bsdf_hair.h M intern/cycles/kernel/closure/bsdf_hair_principled.h M intern/cycles/kernel/closure/bsdf_microfacet.h M intern/cycles/kernel/closure/bsdf_microfacet_multi.h M intern/cycles/kernel/closure/bsdf_oren_nayar.h M intern/cycles/kernel/closure/bsdf_phong_ramp.h M intern/cycles/kernel/closure/bsdf_principled_diffuse.h M intern/cycles/kernel/closure/bsdf_principled_sheen.h M intern/cycles/kernel/closure/bsdf_reflection.h M intern/cycles/kernel/closure/bsdf_refraction.h M intern/cycles/kernel/closure/bsdf_toon.h M intern/cycles/kernel/closure/bsdf_transparent.h M intern/cycles/kernel/closure/bssrdf.h M intern/cycles/kernel/closure/emissive.h M intern/cycles/kernel/closure/volume.h M intern/cycles/kernel/geom/curve.h M intern/cycles/kernel/geom/curve_intersect.h M intern/cycles/kernel/geom/shader_data.h M intern/cycles/kernel/integrator/guiding.h M intern/cycles/kernel/integrator/mnee.h M intern/cycles/kernel/integrator/shade_surface.h M intern/cycles/kernel/integrator/shade_volume.h M intern/cycles/kernel/integrator/surface_shader.h M intern/cycles/kernel/integrator/volume_shader.h M intern/cycles/kernel/light/triangle.h M intern/cycles/kernel/osl/closures_setup.h M intern/cycles/kernel/osl/osl.h M intern/cycles/kernel/osl/services.cpp M intern/cycles/kernel/osl/shaders/node_principled_bsdf.osl M intern/cycles/kernel/sample/mapping.h M intern/cycles/kernel/svm/closure.h M intern/cycles/kernel/svm/displace.h M intern/cycles/kernel/svm/fresnel.h M intern/cycles/kernel/svm/geometry.h M intern/cycles/kernel/svm/tex_coord.h M intern/cycles/kernel/svm/wireframe.h M intern/cycles/kernel/types.h M release/datafiles/locale M release/scripts/addons M release/scripts/addons_contrib M source/tools === diff --git a/intern/cycles/kernel/closure/bsdf.h b/intern/cycles/kernel/closure/bsdf.h index 6de645cd1fe..2f53454d7dd 100644 --- a/intern/cycles/kernel/closure/bsdf.h +++ b/intern/cycles/kernel/closure/bsdf.h @@ -102,10 +102,9 @@ ccl_device_inline float shift_cos_in(float cos_in, const float frequency_multipl return val; } -ccl_device_inline bool bsdf_is_transmission(ccl_private const ShaderClosure *sc, -const float3 omega_in) +ccl_device_inline bool bsdf_is_transmission(ccl_private const ShaderClosure *sc, const float3 wo) { - return dot(sc->N, omega_in) < 0.0f; + return dot(sc->N, wo) < 0.0f; } ccl_device_inline int bsdf_sample(KernelGlobals kg, @@ -114,7 +113,7 @@ ccl_device_inline int bsdf_sample(KernelGlobals kg, float randu, float randv, ccl_private Spectrum *eval, - ccl_private float3 *omega_in, + ccl_private float3 *wo, ccl_private float *pdf, ccl_private float2 *sampled_roughness, ccl_private float *eta) @@ -126,43 +125,43 @@ ccl_device_inline int bsdf_sample(KernelGlobals kg, switch (sc->type) { case CLOSURE_BSDF_DIFFUSE_ID: - label = bsdf_diffuse_sample(sc, Ng, sd->I, randu, randv, eval, omega_in, pdf); + label = bsdf_diffuse_sample(sc, Ng, sd->wi, randu, randv, eval, wo, pdf); *sampled_roughness = one_float2(); *eta = 1.0f; break; #if defined(__SVM__) || defined(__OSL__) case CLOSURE_BSDF_OREN_NAYAR_ID: - label = bsdf_oren_nayar_sample(sc, Ng, sd->I, randu, randv, eval, omega_in, pdf); + label = bsdf_oren_nayar_sample(sc, Ng, sd->wi, randu, randv, eval, wo, pdf); *sampled_roughness = one_float2(); *eta = 1.0f; break; # ifdef __OSL__ case CLOSURE
[Bf-blender-cvs] [0383da5f44a] microfacet_hair: Cleanup: unify notations: O for outgoing direction, I for incoming/viewing/camera direction
Commit: 0383da5f44a560db3f8e6fcabeee3fa9a7453066 Author: Weizhen Huang Date: Mon Jan 16 18:53:21 2023 +0100 Branches: microfacet_hair https://developer.blender.org/rB0383da5f44a560db3f8e6fcabeee3fa9a7453066 Cleanup: unify notations: O for outgoing direction, I for incoming/viewing/camera direction === M intern/cycles/kernel/closure/bsdf_hair_microfacet.h === diff --git a/intern/cycles/kernel/closure/bsdf_hair_microfacet.h b/intern/cycles/kernel/closure/bsdf_hair_microfacet.h index 25a0e3ca537..b00da5b872d 100644 --- a/intern/cycles/kernel/closure/bsdf_hair_microfacet.h +++ b/intern/cycles/kernel/closure/bsdf_hair_microfacet.h @@ -563,10 +563,10 @@ ccl_device float3 bsdf_microfacet_hair_eval_tt_trt_circular(KernelGlobals kg, ccl_device Spectrum bsdf_microfacet_hair_eval_circular(KernelGlobals kg, ccl_private const ShaderData *sd, ccl_private const ShaderClosure *sc, - const float3 omega_in, + const float3 O, ccl_private float *pdf) { - /* Define local coordinate system: + /* Get local coordinate system: * . X along the hair fiber width & perpendicular to the incoming ray (sd->I). * . Y along the hair fiber tangent. * . Z = X ^ Y (facing the incoming ray (sd->I) as much as possible). */ @@ -575,9 +575,9 @@ ccl_device Spectrum bsdf_microfacet_hair_eval_circular(KernelGlobals kg, const float3 Y = safe_normalize(sd->dPdu); const float3 Z = safe_normalize(cross(X, Y)); - /* Get local wi/wo (convention is reversed from other hair bcsdfs). */ + /* Transform wi/wo from global coordinate system to local. */ const float3 wi = make_float3(dot(sd->I, X), dot(sd->I, Y), dot(sd->I, Z)); - const float3 wo = make_float3(dot(omega_in, X), dot(omega_in, Y), dot(omega_in, Z)); + const float3 wo = make_float3(dot(O, X), dot(O, Y), dot(O, Z)); /* Evaluate R, TT, TRT terms. */ const float3 R = bsdf_microfacet_hair_eval_r_circular(sc, wi, wo) + @@ -595,7 +595,7 @@ ccl_device int bsdf_microfacet_hair_sample_circular(const KernelGlobals kg, float randu, float randv, ccl_private Spectrum *eval, -ccl_private float3 *omega_in, +ccl_private float3 *O, ccl_private float *pdf, ccl_private float2 *sampled_roughness, ccl_private float *eta) @@ -611,7 +611,7 @@ ccl_device int bsdf_microfacet_hair_sample_circular(const KernelGlobals kg, return LABEL_NONE; } - /* Define local coordinate system: + /* Get local coordinate system: * . X along the hair fiber width & perpendicular to the incoming ray (sd->I). * . Y along the hair fiber tangent. * . Z = X ^ Y (facing the incoming ray (sd->I) as much as possible). */ @@ -619,7 +619,7 @@ ccl_device int bsdf_microfacet_hair_sample_circular(const KernelGlobals kg, const float3 Y = safe_normalize(sd->dPdu); const float3 Z = safe_normalize(cross(X, Y)); - /* Get local wi (convention is reversed from other hair bcsdfs). */ + /* Transform wi from global coordinate system to local. */ const float3 wi = make_float3(dot(sd->I, X), dot(sd->I, Y), dot(sd->I, Z)); const float tilt = -bsdf->tilt; @@ -783,7 +783,7 @@ ccl_device int bsdf_microfacet_hair_sample_circular(const KernelGlobals kg, *eval *= visibility; - *omega_in = wo.x * X + wo.y * Y + wo.z * Z; + *O = wo.x * X + wo.y * Y + wo.z * Z; /* correction of the cosine foreshortening term *eval *= dot(wi, wmi) / dot(wi, wmi_); */ @@ -798,8 +798,8 @@ ccl_device int bsdf_microfacet_hair_sample_circular(const KernelGlobals kg, /* Elliptic specific */ ccl_device float3 bsdf_microfacet_hair_eval_r_elliptic(ccl_private const ShaderClosure *sc, - const float3 wi_, - const float3 wo_) + const float3 wi, + const float3 wo) { ccl_private MicrofacetHairBSDF *bsdf = (ccl_private MicrofacetHairBSDF *)sc; const float tilt = -bsdf->tilt; @@ -818,10 +818,6 @@ ccl_device float3 bsdf_microfacet_hair_eval_r_elliptic(ccl_private const ShaderC const float b = bs
[Bf-blender-cvs] [935f500501d] microfacet_hair: Reuse albedo functions in principled hair BSDF
Commit: 935f500501dbf004e89f5c86e1bbbf7a7927bf54 Author: Weizhen Huang Date: Mon Jan 16 16:49:52 2023 +0100 Branches: microfacet_hair https://developer.blender.org/rB935f500501dbf004e89f5c86e1bbbf7a7927bf54 Reuse albedo functions in principled hair BSDF === M intern/cycles/kernel/closure/bsdf_hair_microfacet.h M intern/cycles/kernel/closure/bsdf_hair_principled.h M intern/cycles/kernel/svm/closure.h === diff --git a/intern/cycles/kernel/closure/bsdf_hair_microfacet.h b/intern/cycles/kernel/closure/bsdf_hair_microfacet.h index be3d7d7e105..25a0e3ca537 100644 --- a/intern/cycles/kernel/closure/bsdf_hair_microfacet.h +++ b/intern/cycles/kernel/closure/bsdf_hair_microfacet.h @@ -1397,32 +1397,10 @@ ccl_device void bsdf_microfacet_hair_blur(ccl_private ShaderClosure *sc, float r /* Hair Albedo */ -ccl_device_inline float bsdf_microfacet_hair_albedo_roughness_scale( -const float azimuthal_roughness) -{ - const float x = azimuthal_roughness; - return (0.245f * x) + 5.574f) * x - 10.73f) * x + 2.532f) * x - 0.215f) * x + 5.969f; -} - ccl_device float3 bsdf_microfacet_hair_albedo(ccl_private const ShaderClosure *sc) { ccl_private MicrofacetHairBSDF *bsdf = (ccl_private MicrofacetHairBSDF *)sc; - return exp(-sqrt(bsdf->sigma) * bsdf_microfacet_hair_albedo_roughness_scale(bsdf->roughness)); -} - -ccl_device_inline float3 -bsdf_microfacet_hair_sigma_from_reflectance(const float3 color, const float azimuthal_roughness) -{ - const float3 sigma = log(color) / - bsdf_microfacet_hair_albedo_roughness_scale(azimuthal_roughness); - return sigma * sigma; -} - -ccl_device_inline float3 bsdf_microfacet_hair_sigma_from_concentration(const float eumelanin, - const float pheomelanin) -{ - return eumelanin * make_float3(0.506f, 0.841f, 1.653f) + - pheomelanin * make_float3(0.343f, 0.733f, 1.924f); + return exp(-sqrt(bsdf->sigma) * bsdf_hair_albedo_roughness_scale(bsdf->roughness)); } CCL_NAMESPACE_END diff --git a/intern/cycles/kernel/closure/bsdf_hair_principled.h b/intern/cycles/kernel/closure/bsdf_hair_principled.h index 5a6465c7af6..fbdf05a2790 100644 --- a/intern/cycles/kernel/closure/bsdf_hair_principled.h +++ b/intern/cycles/kernel/closure/bsdf_hair_principled.h @@ -473,10 +473,9 @@ ccl_device void bsdf_principled_hair_blur(ccl_private ShaderClosure *sc, float r bsdf->m0_roughness = fmaxf(roughness, bsdf->m0_roughness); } -/* Hair Albedo */ +/* Hair Albedo. Also used by `bsdf_hair_microfacet.h` */ -ccl_device_inline float bsdf_principled_hair_albedo_roughness_scale( -const float azimuthal_roughness) +ccl_device_inline float bsdf_hair_albedo_roughness_scale(const float azimuthal_roughness) { const float x = azimuthal_roughness; return (0.245f * x) + 5.574f) * x - 10.73f) * x + 2.532f) * x - 0.215f) * x + 5.969f; @@ -485,19 +484,18 @@ ccl_device_inline float bsdf_principled_hair_albedo_roughness_scale( ccl_device Spectrum bsdf_principled_hair_albedo(ccl_private const ShaderClosure *sc) { ccl_private PrincipledHairBSDF *bsdf = (ccl_private PrincipledHairBSDF *)sc; - return exp(-sqrt(bsdf->sigma) * bsdf_principled_hair_albedo_roughness_scale(bsdf->v)); + return exp(-sqrt(bsdf->sigma) * bsdf_hair_albedo_roughness_scale(bsdf->v)); } -ccl_device_inline Spectrum -bsdf_principled_hair_sigma_from_reflectance(const Spectrum color, const float azimuthal_roughness) +ccl_device_inline Spectrum bsdf_hair_sigma_from_reflectance(const Spectrum color, +const float azimuthal_roughness) { - const Spectrum sigma = log(color) / - bsdf_principled_hair_albedo_roughness_scale(azimuthal_roughness); + const Spectrum sigma = log(color) / bsdf_hair_albedo_roughness_scale(azimuthal_roughness); return sigma * sigma; } -ccl_device_inline Spectrum bsdf_principled_hair_sigma_from_concentration(const float eumelanin, - const float pheomelanin) +ccl_device_inline Spectrum bsdf_hair_sigma_from_concentration(const float eumelanin, + const float pheomelanin) { const float3 eumelanin_color = make_float3(0.506f, 0.841f, 1.653f); const float3 pheomelanin_color = make_float3(0.343f, 0.733f, 1.924f); diff --git a/intern/cycles/kernel/svm/closure.h b/intern/cycles/kernel/svm/closure.h index 42abbbdd3a3..582f1595cba 100644 --- a/intern/cycles/kernel/svm/closure.h +++ b/intern/cycles/kernel/svm/closure.h @@ -850,27 +850,26 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg, /* Benedikt Bitterli's melanin ratio remapping. */ flo
[Bf-blender-cvs] [9e5c1787a51] microfacet_hair: Remove empirical scaling to match microfacet and principled hair BSDF
Commit: 9e5c1787a51cdccbb8b0443fde1b1247c77c639b Author: Weizhen Huang Date: Mon Jan 16 16:20:00 2023 +0100 Branches: microfacet_hair https://developer.blender.org/rB9e5c1787a51cdccbb8b0443fde1b1247c77c639b Remove empirical scaling to match microfacet and principled hair BSDF === M intern/cycles/kernel/svm/closure.h === diff --git a/intern/cycles/kernel/svm/closure.h b/intern/cycles/kernel/svm/closure.h index f4953e8beee..42abbbdd3a3 100644 --- a/intern/cycles/kernel/svm/closure.h +++ b/intern/cycles/kernel/svm/closure.h @@ -940,14 +940,6 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg, bsdf->distribution_type = clamp( distribution_type, NODE_MICROFACET_HAIR_GGX, NODE_MICROFACET_HAIR_BECKMANN); -/* Empirical equivalences compared with principled hair BSDF. */ -if (bsdf->distribution_type == NODE_MICROFACET_HAIR_GGX) { - roughness *= 0.5f; -} -else { /* bsdf->distribution_type == NODE_MICROFACET_HAIR_BECKMANN*/ - roughness *= 2.f / 3.f; -} - bsdf->N = N; bsdf->roughness = roughness; bsdf->tilt = tilt; ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [f0529cfabc7] microfacet_hair: Add support for OSL shader to microfacet hair model
Commit: f0529cfabc759712dfe19a575f914aa1aca9c277 Author: Weizhen Huang Date: Mon Jan 16 16:16:58 2023 +0100 Branches: microfacet_hair https://developer.blender.org/rBf0529cfabc759712dfe19a575f914aa1aca9c277 Add support for OSL shader to microfacet hair model === M intern/cycles/kernel/closure/bsdf_hair_microfacet.h M intern/cycles/kernel/osl/closures_setup.h M intern/cycles/kernel/osl/closures_template.h M intern/cycles/kernel/osl/shaders/node_microfacet_hair_bsdf.osl M intern/cycles/kernel/osl/shaders/stdcycles.h M intern/cycles/kernel/svm/closure.h M intern/cycles/scene/shader_nodes.cpp === diff --git a/intern/cycles/kernel/closure/bsdf_hair_microfacet.h b/intern/cycles/kernel/closure/bsdf_hair_microfacet.h index ff372ab947b..be3d7d7e105 100644 --- a/intern/cycles/kernel/closure/bsdf_hair_microfacet.h +++ b/intern/cycles/kernel/closure/bsdf_hair_microfacet.h @@ -17,8 +17,6 @@ typedef struct MicrofacetHairExtra { float TT; float TRT; - float aspect_ratio; - /* Geometry data. */ float4 geom; } MicrofacetHairExtra; @@ -41,6 +39,9 @@ typedef struct MicrofacetHairBSDF { /* Circular/Elliptical */ int cross_section; + /* The ratio of the minor axis to the major axis. */ + float aspect_ratio; + /* Extra closure. */ ccl_private MicrofacetHairExtra *extra; } MicrofacetHairBSDF; @@ -74,8 +75,20 @@ ccl_device int bsdf_microfacet_hair_setup(ccl_private ShaderData *sd, kernel_assert(isfinite_safe(h)); if (bsdf->cross_section == NODE_MICROFACET_HAIR_ELLIPTIC) { -/* Local frame is independent of the ray direction for elliptical hairs. */ -bsdf->extra->geom.w = h; +if (bsdf->aspect_ratio > 1.0f) { + bsdf->aspect_ratio = 1.0f / bsdf->aspect_ratio; + + /* Switch major and minor axis. */ + const float3 minor_axis = safe_normalize(cross( + sd->dPdu, make_float3(bsdf->extra->geom.x, bsdf->extra->geom.y, bsdf->extra->geom.z))); + const float3 major_axis = safe_normalize(cross(minor_axis, sd->dPdu)); + + /* Local frame is independent of the ray direction for elliptical hairs. */ + bsdf->extra->geom = make_float4(major_axis.x, major_axis.y, major_axis.z, h); +} +else { + bsdf->extra->geom.w = h; +} } else { bsdf->extra->geom = make_float4(X.x, X.y, X.z, h); @@ -802,7 +815,7 @@ ccl_device float3 bsdf_microfacet_hair_eval_r_elliptic(ccl_private const ShaderC /* get elliptical cross section characteristic */ const float a = 1.0f; /* TODO: rename this as aspect ratio? e is in [0, 0.85], b is in [0.52, 1]. */ - const float b = bsdf->extra->aspect_ratio; + const float b = bsdf->aspect_ratio; const float e2 = 1.0f - sqr(b / a); /* this follows blender's convention (unlike the circular case?) */ @@ -898,7 +911,7 @@ ccl_device float3 bsdf_microfacet_hair_eval_tt_trt_elliptic(KernelGlobals kg, return zero_float3(); } - /* this follows blender's convention (unlike the circular case?) */ + /* TODO: switch wi and wo? */ const float3 wo = wi_; const float3 wi = wo_; @@ -923,7 +936,7 @@ ccl_device float3 bsdf_microfacet_hair_eval_tt_trt_elliptic(KernelGlobals kg, /* get elliptical cross section characteristic */ const float a = 1.0f; - const float b = bsdf->extra->aspect_ratio; + const float b = bsdf->aspect_ratio; const float e2 = 1.0f - sqr(b / a); /* Squared Eccentricity. */ const float gamma_m_min = to_gamma(phi_m_min, a, b) + 1e-3f; @@ -1094,7 +1107,7 @@ ccl_device Spectrum bsdf_microfacet_hair_eval_elliptic(KernelGlobals kg, const float3 wo = make_float3(dot(omega_in, X), dot(omega_in, Y), dot(omega_in, Z)); /* Treat as transparent material if intersection lies outside of the projected radius. */ - const float e2 = 1.0f - sqr(bsdf->extra->aspect_ratio); + const float e2 = 1.0f - sqr(bsdf->aspect_ratio); const float radius = sqrtf(1.0f - e2 * sqr(sin_phi(wi))); if (fabsf(bsdf->extra->geom.w) > radius) { *pdf = 0.0f; @@ -1136,7 +1149,7 @@ ccl_device int bsdf_microfacet_hair_sample_elliptic(const KernelGlobals kg, /* get elliptical cross section characteristic */ const float a = 1.0f; - const float b = bsdf->extra->aspect_ratio; + const float b = bsdf->aspect_ratio; const float e2 = 1.0f - sqr(b / a); /* macronormal */ @@ -1345,7 +1358,7 @@ ccl_device Spectrum bsdf_microfacet_hair_eval(KernelGlobals kg, { ccl_private MicrofacetHairBSDF *bsdf = (ccl_private MicrofacetHairBSDF *)sc; - if (bsdf->cross_section == NODE_MICROFACET_HAIR_CIRCULAR || bsdf->extra->aspect_ratio == 1.0f) { + if (bsdf->cross_section == NODE_MICROFACET_HAIR_CIRCULAR || bsdf->aspect_ratio == 1.0f) { return bsdf_microfacet_hair_eval_cir
[Bf-blender-cvs] [e69877c217d] microfacet_hair: Cleanup: renaming and formatting comments
Commit: e69877c217d9ef27a52f3f2bf07b46ee2cfd0ffd Author: Weizhen Huang Date: Thu Jan 12 19:52:24 2023 +0100 Branches: microfacet_hair https://developer.blender.org/rBe69877c217d9ef27a52f3f2bf07b46ee2cfd0ffd Cleanup: renaming and formatting comments === M intern/cycles/blender/shader.cpp M intern/cycles/kernel/closure/bsdf_hair_microfacet.h M intern/cycles/kernel/osl/shaders/node_microfacet_hair_bsdf.osl M intern/cycles/kernel/osl/shaders/stdcycles.h M intern/cycles/kernel/svm/closure.h M intern/cycles/kernel/svm/types.h M intern/cycles/scene/shader_nodes.cpp M intern/cycles/scene/shader_nodes.h M source/blender/makesrna/intern/rna_nodetree.c M source/blender/nodes/shader/nodes/node_shader_bsdf_hair_microfacet.cc === diff --git a/intern/cycles/blender/shader.cpp b/intern/cycles/blender/shader.cpp index 099a48af84d..2a697c1d50a 100644 --- a/intern/cycles/blender/shader.cpp +++ b/intern/cycles/blender/shader.cpp @@ -668,10 +668,10 @@ static ShaderNode *add_node(Scene *scene, "parametrization", NODE_MICROFACET_HAIR_NUM, NODE_MICROFACET_HAIR_REFLECTANCE)); -microfacet_hair->set_cross_section_type( +microfacet_hair->set_cross_section( (NodeMicrofacetHairCrossSectionType)get_enum(b_microfacet_hair_node.ptr, - "cross_section_type", - NODE_MICROFACET_HAIR_CROSS_SECTION_TYPE_NUM, + "cross_section", + NODE_MICROFACET_HAIR_CROSS_SECTION_NUM, NODE_MICROFACET_HAIR_CIRCULAR)); microfacet_hair->set_distribution_type( (NodeMicrofacetHairDistributionType)get_enum(b_microfacet_hair_node.ptr, diff --git a/intern/cycles/kernel/closure/bsdf_hair_microfacet.h b/intern/cycles/kernel/closure/bsdf_hair_microfacet.h index 2381d5a5239..ff372ab947b 100644 --- a/intern/cycles/kernel/closure/bsdf_hair_microfacet.h +++ b/intern/cycles/kernel/closure/bsdf_hair_microfacet.h @@ -12,6 +12,7 @@ CCL_NAMESPACE_BEGIN typedef struct MicrofacetHairExtra { + /* TODO: is this necessary? */ float R; float TT; float TRT; @@ -30,7 +31,7 @@ typedef struct MicrofacetHairBSDF { /* Microfacet distribution roughness. */ float roughness; /* Cuticle tilt angle. */ - float alpha; + float tilt; /* IOR. */ float eta; @@ -38,7 +39,7 @@ typedef struct MicrofacetHairBSDF { int distribution_type; /* Circular/Elliptical */ - int cross_section_type; + int cross_section; /* Extra closure. */ ccl_private MicrofacetHairExtra *extra; @@ -58,21 +59,21 @@ ccl_device int bsdf_microfacet_hair_setup(ccl_private ShaderData *sd, bsdf->roughness = clamp(bsdf->roughness, 0.001f, 1.0f); - /* Compute local frame, aligned to curve tangent and ray direction. */ - float3 Y = safe_normalize(sd->dPdu); - float3 X = safe_normalize(cross(Y, sd->I)); - - /* h -1..0..1 means the rays goes from grazing the hair, to hitting it at - * the center, to grazing the other edge. This is the sine of the angle - * between sd->Ng and Z, as seen from the tangent X. */ + /* Compute local frame. The Y axis is aligned with the curve tangent; the X axis is perpendicular + to the ray direction for circular cross-sections, or aligned with the major axis for elliptical + cross-sections. */ + const float3 Y = safe_normalize(sd->dPdu); + const float3 X = safe_normalize(cross(Y, sd->I)); - float h = (sd->type & PRIMITIVE_CURVE_RIBBON) ? -sd->v : -dot(X, sd->N); + /* h -1..0..1 means the rays goes from grazing the hair, to hitting it at the center, to grazing + * the other edge. This is the cosine of the angle between sd->N and X. */ + const float h = (sd->type & PRIMITIVE_CURVE_RIBBON) ? -sd->v : -dot(X, sd->N); kernel_assert(fabsf(h) < 1.0f + 1e-4f); kernel_assert(isfinite_safe(X)); kernel_assert(isfinite_safe(h)); - if (bsdf->cross_section_type == NODE_MICROFACET_HAIR_ELLIPTIC) { + if (bsdf->cross_section == NODE_MICROFACET_HAIR_ELLIPTIC) { /* Local frame is independent of the ray direction for elliptical hairs. */ bsdf->extra->geom.w = h; } @@ -140,13 +141,13 @@ ccl_device_inline float2 dir_sph(const float3 w) return make_float2(dir_theta(w), dir_phi(w)); } -/* Compute the vector direction given spherical coordinates */ -ccl_device_inline float3 sph_dir(float theta, float gamma) +/* Compute the vector direction given spherical coordinates.
[Bf-blender-cvs] [5c9581920e5] microfacet_hair: Remove node input "Blur"
Commit: 5c9581920e50dfe20303481eb89c86de6dfb3245 Author: Weizhen Huang Date: Thu Jan 12 18:40:43 2023 +0100 Branches: microfacet_hair https://developer.blender.org/rB5c9581920e50dfe20303481eb89c86de6dfb3245 Remove node input "Blur" === M intern/cycles/kernel/closure/bsdf_hair_microfacet.h M intern/cycles/kernel/svm/closure.h M intern/cycles/scene/shader_nodes.cpp M intern/cycles/scene/shader_nodes.h M source/blender/gpu/shaders/material/gpu_shader_material_hair.glsl M source/blender/nodes/shader/nodes/node_shader_bsdf_hair_microfacet.cc === diff --git a/intern/cycles/kernel/closure/bsdf_hair_microfacet.h b/intern/cycles/kernel/closure/bsdf_hair_microfacet.h index 90a9fec8295..2381d5a5239 100644 --- a/intern/cycles/kernel/closure/bsdf_hair_microfacet.h +++ b/intern/cycles/kernel/closure/bsdf_hair_microfacet.h @@ -34,9 +34,6 @@ typedef struct MicrofacetHairBSDF { /* IOR. */ float eta; - /* Blur. */ - float blur; - /* GGX/Beckmann. */ int distribution_type; @@ -1382,9 +1379,7 @@ ccl_device void bsdf_microfacet_hair_blur(ccl_private ShaderClosure *sc, float r { ccl_private MicrofacetHairBSDF *bsdf = (ccl_private MicrofacetHairBSDF *)sc; - if (bsdf->blur > 0) { -bsdf->roughness = fmaxf(roughness, bsdf->roughness); - } + bsdf->roughness = fmaxf(roughness, bsdf->roughness); } /* Hair Albedo */ diff --git a/intern/cycles/kernel/svm/closure.h b/intern/cycles/kernel/svm/closure.h index 1f28aac138d..7e4819a7271 100644 --- a/intern/cycles/kernel/svm/closure.h +++ b/intern/cycles/kernel/svm/closure.h @@ -892,12 +892,9 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg, float alpha = stack_load_float_default(stack, offset_ofs, data_node.z); float ior = stack_load_float_default(stack, ior_ofs, data_node.w); - uint Blur_ofs, melanin_ofs, melanin_redness_ofs, absorption_coefficient_ofs; - svm_unpack_node_uchar4(data_node2.x, - _ofs, - _ofs, - _redness_ofs, - _coefficient_ofs); + uint melanin_ofs, melanin_redness_ofs, absorption_coefficient_ofs, temp; + svm_unpack_node_uchar4( + data_node2.x, , _ofs, _redness_ofs, _coefficient_ofs); uint tint_ofs, random_ofs, random_color_ofs, cross_section_type; svm_unpack_node_uchar4( @@ -917,7 +914,6 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg, float R = stack_load_float_default(stack, R_ofs, data_node4.y); float TT = stack_load_float_default(stack, TT_ofs, data_node4.z); float TRT = stack_load_float_default(stack, TRT_ofs, data_node4.w); - float blur = stack_load_float_default(stack, Blur_ofs, data_node2.y); ccl_private MicrofacetHairBSDF *bsdf = (ccl_private MicrofacetHairBSDF *)bsdf_alloc( sd, sizeof(MicrofacetHairBSDF), weight); @@ -932,7 +928,6 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg, bsdf->extra->R = fmaxf(0.0f, R); bsdf->extra->TT = fmaxf(0.0f, TT); bsdf->extra->TRT = fmaxf(0.0f, TRT); -bsdf->blur = clamp(blur, 0.0f, 1.0f); /* Random factors range: [-randomization/2, +randomization/2]. */ float random_roughness = param2; diff --git a/intern/cycles/scene/shader_nodes.cpp b/intern/cycles/scene/shader_nodes.cpp index e130a51bc4b..3854f008d55 100644 --- a/intern/cycles/scene/shader_nodes.cpp +++ b/intern/cycles/scene/shader_nodes.cpp @@ -3680,8 +3680,6 @@ NODE_DEFINE(MicrofacetHairBsdfNode) SOCKET_IN_FLOAT(TT, "Transmission", 1.0f); SOCKET_IN_FLOAT(TRT, "Secondary Reflection", 1.0f); - SOCKET_IN_FLOAT(Blur, "Blur", 1.0f); - SOCKET_IN_FLOAT(random_roughness, "Random Roughness", 0.0f); SOCKET_IN_FLOAT(random_color, "Random Color", 0.0f); SOCKET_IN_FLOAT(random, "Random", 0.0f); @@ -3730,7 +3728,6 @@ void MicrofacetHairBsdfNode::compile(SVMCompiler ) ShaderInput *R_in = input("Reflection"); ShaderInput *TT_in = input("Transmission"); ShaderInput *TRT_in = input("Secondary Reflection"); - ShaderInput *Blur_in = input("Blur"); ShaderInput *aspect_ratio_in = input("Aspect Ratio"); @@ -3772,13 +3769,11 @@ void MicrofacetHairBsdfNode::compile(SVMCompiler ) __float_as_uint(ior)); /* data node 2 */ - compiler.add_node(compiler.encode_uchar4(compiler.stack_assign_if_linked(Blur_in), - melanin_ofs, - melanin_redness_ofs, - absorption_coefficient_ofs), -__float_as_uint(Blur), -
[Bf-blender-cvs] [0da0f29c171] microfacet_hair: Replace legacy custom fields with node storage struct
Commit: 0da0f29c1714db0001ea8c785fe2a625620db020 Author: Weizhen Huang Date: Thu Jan 12 17:55:01 2023 +0100 Branches: microfacet_hair https://developer.blender.org/rB0da0f29c1714db0001ea8c785fe2a625620db020 Replace legacy custom fields with node storage struct === M source/blender/makesdna/DNA_node_types.h M source/blender/makesrna/intern/rna_nodetree.c M source/blender/nodes/shader/nodes/node_shader_bsdf_hair_microfacet.cc === diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h index 11e44cbf6f6..23755425ddf 100644 --- a/source/blender/makesdna/DNA_node_types.h +++ b/source/blender/makesdna/DNA_node_types.h @@ -322,8 +322,10 @@ typedef struct bNode { */ int16_t type; + char _pad1[2]; + /** Used for some builtin nodes that store properties but don't have a storage struct . */ - int16_t custom0, custom1, custom2; + int16_t custom1, custom2; float custom3, custom4; /** Optional link to libdata. */ @@ -1146,6 +1148,13 @@ typedef struct NodeShaderPrincipled { char _pad[3]; } NodeShaderPrincipled; +typedef struct NodeShaderHairMicrofacet { + short parametrization; + short cross_section; + short distribution; + char _pad[2]; +} NodeShaderHairMicrofacet; + /** TEX_output. */ typedef struct TexNodeOutput { char name[64]; diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index 87231edabc1..a47251b9940 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -6224,34 +6224,27 @@ static void def_hair_microfacet(StructRNA *srna) { PropertyRNA *prop; + RNA_def_struct_sdna_from(srna, "NodeShaderHairMicrofacet", "storage"); + prop = RNA_def_property(srna, "parametrization", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_sdna(prop, NULL, "custom0"); + RNA_def_property_enum_sdna(prop, NULL, "parametrization"); RNA_def_property_ui_text( prop, "Color Parametrization", "Select the shader's color parametrization"); RNA_def_property_enum_items(prop, node_microfacet_hair_parametrization_items); - RNA_def_property_enum_default(prop, SHD_MICROFACET_HAIR_REFLECTANCE); - /* Upon editing, update both the node data AND the UI representation */ - /* (This effectively shows/hides the relevant sockets) */ RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_ShaderNode_socket_update"); prop = RNA_def_property(srna, "cross_section_type", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_sdna(prop, NULL, "custom1"); + RNA_def_property_enum_sdna(prop, NULL, "cross_section"); RNA_def_property_ui_text( prop, "Hair Cross Section Shape", "Select the hair's cross section shape"); RNA_def_property_enum_items(prop, node_microfacet_hair_cross_section_items); - RNA_def_property_enum_default(prop, SHD_MICROFACET_HAIR_CIRCULAR); - /* Upon editing, update both the node data AND the UI representation */ - /* (This effectively shows/hides the relevant sockets) */ RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_ShaderNode_socket_update"); prop = RNA_def_property(srna, "distribution_type", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_sdna(prop, NULL, "custom2"); + RNA_def_property_enum_sdna(prop, NULL, "distribution"); RNA_def_property_ui_text( prop, "Microfacet Distribution", "Select the microfacet distribution of the hair surface"); RNA_def_property_enum_items(prop, node_microfacet_hair_distribution_items); - RNA_def_property_enum_default(prop, SHD_MICROFACET_HAIR_GGX); - /* Upon editing, update both the node data AND the UI representation */ - /* (This effectively shows/hides the relevant sockets) */ RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_ShaderNode_socket_update"); } diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_hair_microfacet.cc b/source/blender/nodes/shader/nodes/node_shader_bsdf_hair_microfacet.cc index a6f08769d2f..d864dd2cf5c 100644 --- a/source/blender/nodes/shader/nodes/node_shader_bsdf_hair_microfacet.cc +++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_hair_microfacet.cc @@ -119,18 +119,22 @@ static void node_shader_buts_microfacet_hair(uiLayout *layout, bContext * /*C*/, /* Initialize the custom Parametrization property to Color. */ static void node_shader_init_hair_microfacet(bNodeTree * /*ntree*/, bNode *node) { - node->custom0 = SHD_MICROFACET_HAIR_REFLECTANCE; - node->custom1 = SHD_MICROFACET_HAIR_CIRCULAR; - node->custom2 = SHD_MICROFACET_HAIR_GGX; + NodeShaderHairMicrofacet *data = MEM_cnew(__func__); + + data->parametriz
[Bf-blender-cvs] [9b99cc216b4] microfacet_hair: Add description to shader node inputs
Commit: 9b99cc216b4f881834bf23cb566453138e044b15 Author: Weizhen Huang Date: Wed Jan 11 20:09:31 2023 +0100 Branches: microfacet_hair https://developer.blender.org/rB9b99cc216b4f881834bf23cb566453138e044b15 Add description to shader node inputs === M source/blender/nodes/shader/nodes/node_shader_bsdf_hair_microfacet.cc === diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_hair_microfacet.cc b/source/blender/nodes/shader/nodes/node_shader_bsdf_hair_microfacet.cc index 8a7cbed08eb..a6f08769d2f 100644 --- a/source/blender/nodes/shader/nodes/node_shader_bsdf_hair_microfacet.cc +++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_hair_microfacet.cc @@ -11,18 +11,26 @@ namespace blender::nodes::node_shader_bsdf_hair_microfacet_cc { /* Color, melanin and absorption coefficient default to approximately same brownish hair. */ static void node_declare(NodeDeclarationBuilder ) { - b.add_input(N_("Color")).default_value({0.017513f, 0.005763f, 0.002059f, 1.0f}); + b.add_input(N_("Color")) + .default_value({0.017513f, 0.005763f, 0.002059f, 1.0f}) + .description("The RGB color of the strand. Only used in Direct Coloring"); b.add_input(N_("Melanin")) .default_value(0.8f) .min(0.0f) .max(1.0f) - .subtype(PROP_FACTOR); + .subtype(PROP_FACTOR) + .description("Hair pigment. Specify its absolute quantity between 0 and 1"); b.add_input(N_("Melanin Redness")) .default_value(1.0f) .min(0.0f) .max(1.0f) - .subtype(PROP_FACTOR); - b.add_input(N_("Tint")).default_value({1.0f, 1.0f, 1.0f, 1.0f}); + .subtype(PROP_FACTOR) + .description( + "Fraction of pheomelanin in melanin, gives yellowish to reddish color, as opposed to " + "the brownish to black color of eumelanin"); + b.add_input(N_("Tint")) + .default_value({1.0f, 1.0f, 1.0f, 1.0f}) + .description("Additional color used for dyeing the hair."); b.add_input(N_("Absorption Coefficient")) .default_value({0.245531f, 0.52f, 1.365f}) .min(0.0f) @@ -31,33 +39,54 @@ static void node_declare(NodeDeclarationBuilder ) .default_value(0.85f) .min(0.0f) .max(1.0f) - .subtype(PROP_FACTOR); + .subtype(PROP_FACTOR) + .description( + "For elliptical hair cross-section, the aspect ratio is the ratio of the minor axis to " + "the major axis. Recommended values are 0.8~1 for Asian hair, 0.65~0.9 for Caucasian " + "hair, 0.5~0.65 for African hair"); b.add_input(N_("Roughness")) .default_value(0.3f) .min(0.0f) .max(1.0f) - .subtype(PROP_FACTOR); + .subtype(PROP_FACTOR) + .description("Microfacet roughness"); b.add_input(N_("Reflection")) .default_value(1.0f) .min(0.0f) .max(1.0f) - .subtype(PROP_FACTOR); + .subtype(PROP_FACTOR) + .description( + "The first light bounce off the hair surface. The color of this component is always " + "white"); b.add_input(N_("Transmission")) .default_value(1.0f) .min(0.0f) .max(1.0f) - .subtype(PROP_FACTOR); + .subtype(PROP_FACTOR) + .description( + "The component that is transmitted through the hair. Picks up the color of the pigment " + "inside the hair"); b.add_input(N_("Secondary Reflection")) .default_value(1.0f) .min(0.0f) .max(1.0f) - .subtype(PROP_FACTOR); - b.add_input(N_("IOR")).default_value(1.55f).min(0.0f).max(1000.0f); + .subtype(PROP_FACTOR) + .description( + "The component that is transmitted into the hair, reflected off the backside of the " + "hair and then transmitted out of the hair, oriented approximately around the incoming " + "direction. Picks up the color of the pigment inside the hair"); + b.add_input(N_("IOR")).default_value(1.55f).min(0.0f).max(1000.0f).description( + "Index of refraction determines how much the ray is bent. At 1.0 rays pass straight through " + "like in a transparent material; higher values cause larger deflection in angle. Default " + "value is 1.55 (the IOR of keratin)"); b.add_input(N_("Offset")) .default_value(2.0f * ((float)M_PI) / 180.0f) .min(-M_PI_2) .max(M_PI_2) - .subtype(PROP_ANGLE); + .subtype(PROP_ANGLE) + .description( + "The tilt angle of the cuticle scales (the outermost part of the hair). They are always " +
[Bf-blender-cvs] [f7f08886355] microfacet_hair: Renaming R lobe to Reflection
Commit: f7f088863553c9b0b0d190d3220350d777355d48 Author: Weizhen Huang Date: Wed Jan 11 18:42:52 2023 +0100 Branches: microfacet_hair https://developer.blender.org/rBf7f088863553c9b0b0d190d3220350d777355d48 Renaming R lobe to Reflection === M intern/cycles/scene/shader_nodes.cpp M source/blender/nodes/shader/nodes/node_shader_bsdf_hair_microfacet.cc === diff --git a/intern/cycles/scene/shader_nodes.cpp b/intern/cycles/scene/shader_nodes.cpp index 8ebca2bc406..e130a51bc4b 100644 --- a/intern/cycles/scene/shader_nodes.cpp +++ b/intern/cycles/scene/shader_nodes.cpp @@ -3676,9 +3676,9 @@ NODE_DEFINE(MicrofacetHairBsdfNode) SOCKET_IN_FLOAT(roughness, "Roughness", 0.3f); SOCKET_IN_FLOAT(ior, "IOR", 1.55f); - SOCKET_IN_FLOAT(R, "R lobe", 1.0f); - SOCKET_IN_FLOAT(TT, "TT lobe", 1.0f); - SOCKET_IN_FLOAT(TRT, "TRT lobe", 1.0f); + SOCKET_IN_FLOAT(R, "Reflection", 1.0f); + SOCKET_IN_FLOAT(TT, "Transmission", 1.0f); + SOCKET_IN_FLOAT(TRT, "Secondary Reflection", 1.0f); SOCKET_IN_FLOAT(Blur, "Blur", 1.0f); @@ -3727,9 +3727,9 @@ void MicrofacetHairBsdfNode::compile(SVMCompiler ) ShaderInput *melanin_redness_in = input("Melanin Redness"); ShaderInput *random_color_in = input("Random Color"); - ShaderInput *R_in = input("R lobe"); - ShaderInput *TT_in = input("TT lobe"); - ShaderInput *TRT_in = input("TRT lobe"); + ShaderInput *R_in = input("Reflection"); + ShaderInput *TT_in = input("Transmission"); + ShaderInput *TRT_in = input("Secondary Reflection"); ShaderInput *Blur_in = input("Blur"); ShaderInput *aspect_ratio_in = input("Aspect Ratio"); diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_hair_microfacet.cc b/source/blender/nodes/shader/nodes/node_shader_bsdf_hair_microfacet.cc index e6ebebb359f..8a7cbed08eb 100644 --- a/source/blender/nodes/shader/nodes/node_shader_bsdf_hair_microfacet.cc +++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_hair_microfacet.cc @@ -37,17 +37,17 @@ static void node_declare(NodeDeclarationBuilder ) .min(0.0f) .max(1.0f) .subtype(PROP_FACTOR); - b.add_input(N_("R lobe")) + b.add_input(N_("Reflection")) .default_value(1.0f) .min(0.0f) .max(1.0f) .subtype(PROP_FACTOR); - b.add_input(N_("TT lobe")) + b.add_input(N_("Transmission")) .default_value(1.0f) .min(0.0f) .max(1.0f) .subtype(PROP_FACTOR); - b.add_input(N_("TRT lobe")) + b.add_input(N_("Secondary Reflection")) .default_value(1.0f) .min(0.0f) .max(1.0f) ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [f88b91fe619] microfacet_hair: Split `model_type` into `cross_section_type` and `distribution_type` Also disable analytical GGX R because it seems confusing
Commit: f88b91fe6196b5069813e3d87373875a2ec4f169 Author: Weizhen Huang Date: Wed Jan 11 18:23:04 2023 +0100 Branches: microfacet_hair https://developer.blender.org/rBf88b91fe6196b5069813e3d87373875a2ec4f169 Split `model_type` into `cross_section_type` and `distribution_type` Also disable analytical GGX R because it seems confusing === M intern/cycles/blender/shader.cpp M intern/cycles/kernel/closure/bsdf_hair_microfacet.h M intern/cycles/kernel/osl/shaders/node_microfacet_hair_bsdf.osl M intern/cycles/kernel/svm/closure.h M intern/cycles/kernel/svm/types.h M intern/cycles/scene/shader_nodes.cpp M intern/cycles/scene/shader_nodes.h M release/datafiles/locale M release/scripts/addons M release/scripts/addons_contrib M source/blender/makesdna/DNA_node_types.h M source/blender/makesrna/intern/rna_nodetree.c M source/blender/nodes/shader/nodes/node_shader_bsdf_hair_microfacet.cc M source/tools === diff --git a/intern/cycles/blender/shader.cpp b/intern/cycles/blender/shader.cpp index 43bc5538628..099a48af84d 100644 --- a/intern/cycles/blender/shader.cpp +++ b/intern/cycles/blender/shader.cpp @@ -668,11 +668,16 @@ static ShaderNode *add_node(Scene *scene, "parametrization", NODE_MICROFACET_HAIR_NUM, NODE_MICROFACET_HAIR_REFLECTANCE)); -microfacet_hair->set_model_type( -(NodeMicrofacetHairModelType)get_enum(b_microfacet_hair_node.ptr, - "model_type", - NODE_MICROFACET_HAIR_MODEL_TYPE_NUM, - NODE_MICROFACET_HAIR_CIRCULAR_GGX)); +microfacet_hair->set_cross_section_type( + (NodeMicrofacetHairCrossSectionType)get_enum(b_microfacet_hair_node.ptr, + "cross_section_type", + NODE_MICROFACET_HAIR_CROSS_SECTION_TYPE_NUM, + NODE_MICROFACET_HAIR_CIRCULAR)); +microfacet_hair->set_distribution_type( + (NodeMicrofacetHairDistributionType)get_enum(b_microfacet_hair_node.ptr, + "distribution_type", + NODE_MICROFACET_HAIR_DISTRIBUTION_TYPE_NUM, + NODE_MICROFACET_HAIR_GGX)); node = microfacet_hair; } else if (b_node.is_a(_ShaderNodeBsdfPrincipled)) { diff --git a/intern/cycles/kernel/closure/bsdf_hair_microfacet.h b/intern/cycles/kernel/closure/bsdf_hair_microfacet.h index 3216511a26d..90a9fec8295 100644 --- a/intern/cycles/kernel/closure/bsdf_hair_microfacet.h +++ b/intern/cycles/kernel/closure/bsdf_hair_microfacet.h @@ -37,8 +37,11 @@ typedef struct MicrofacetHairBSDF { /* Blur. */ float blur; - /* Circular/Ellipitic and GGX/Beckmann. */ - int model_type; + /* GGX/Beckmann. */ + int distribution_type; + + /* Circular/Elliptical */ + int cross_section_type; /* Extra closure. */ ccl_private MicrofacetHairExtra *extra; @@ -72,8 +75,7 @@ ccl_device int bsdf_microfacet_hair_setup(ccl_private ShaderData *sd, kernel_assert(isfinite_safe(X)); kernel_assert(isfinite_safe(h)); - if (bsdf->model_type == NODE_MICROFACET_HAIR_ELLIPTIC_GGX || - bsdf->model_type == NODE_MICROFACET_HAIR_ELLIPTIC_BECKMANN) { + if (bsdf->cross_section_type == NODE_MICROFACET_HAIR_ELLIPTIC) { /* Local frame is independent of the ray direction for elliptical hairs. */ bsdf->extra->geom.w = h; } @@ -329,8 +331,7 @@ ccl_device float3 bsdf_microfacet_hair_eval_r_circular(ccl_private const ShaderC const float tilt = -bsdf->alpha; const float roughness = bsdf->roughness; const float eta = bsdf->eta; - const bool beckmann = (bsdf->model_type == NODE_MICROFACET_HAIR_CIRCULAR_BECKMANN); - const bool analytical_ggx = (bsdf->model_type == NODE_MICROFACET_HAIR_CIRCULAR_GGX_ANALYTIC); + const bool beckmann = (bsdf->distribution_type == NODE_MICROFACET_HAIR_BECKMANN); float3 R = zero_float3(); if (bsdf->extra->R <= 0.0f) @@ -359,68 +360,26 @@ ccl_device float3 bsdf_microfacet_hair_eval_r_circular(ccl_private const ShaderC float integral = 0.0f; - /* analytical for ggx (no masking term) */ - if (analytical_ggx) { -const float phi_h = dir_phi(wh); -const float d_max = phi_h - phi_m_max; -const float d_min = phi_h - phi_m_min; - -const float roughness_squared = roughness * roughness; - -float sm, cm; -fast_sincosf
[Bf-blender-cvs] [08684b2601c] microfacet_hair: Merge branch 'master' into microfacet_hair
Commit: 08684b2601c7c1826e9214d519670bebb0d6f527 Author: Weizhen Huang Date: Tue Jan 10 13:24:52 2023 +0100 Branches: microfacet_hair https://developer.blender.org/rB08684b2601c7c1826e9214d519670bebb0d6f527 Merge branch 'master' into microfacet_hair === === diff --cc source/blender/blenkernel/intern/geometry_component_curves.cc index 5a6551f0c8e,075a6838704..44f662300fc --- a/source/blender/blenkernel/intern/geometry_component_curves.cc +++ b/source/blender/blenkernel/intern/geometry_component_curves.cc @@@ -505,12 -501,12 +505,12 @@@ static ComponentAttributeProviders crea tag_component_topology_changed, AttributeValidator{_order_clamp}); - static const fn::CustomMF_SI_SO normal_mode_clamp{ + static const auto normal_mode_clamp = mf::build::SI1_SO( "Normal Mode Validate", [](int8_t value) { -return std::clamp(value, NORMAL_MODE_MINIMUM_TWIST, NORMAL_MODE_Z_UP); +return std::clamp(value, NORMAL_MODE_MINIMUM_TWIST, NORMAL_MODE_CURVATURE_VECTOR); }, - fn::CustomMF_presets::AllSpanOrSingle()}; + mf::build::exec_presets::AllSpanOrSingle()); static BuiltinCustomDataLayerProvider normal_mode("normal_mode", ATTR_DOMAIN_CURVE, CD_PROP_INT8, ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [c1413e64d1e] microfacet_hair: Deal with cases where derivatives = 0
Commit: c1413e64d1eb639c5737ef5502aa3af3fe4092c0 Author: Weizhen Huang Date: Mon Jan 9 18:26:53 2023 +0100 Branches: microfacet_hair https://developer.blender.org/rBc1413e64d1eb639c5737ef5502aa3af3fe4092c0 Deal with cases where derivatives = 0 === M source/blender/blenkernel/intern/curve_catmull_rom.cc === diff --git a/source/blender/blenkernel/intern/curve_catmull_rom.cc b/source/blender/blenkernel/intern/curve_catmull_rom.cc index fa2fe01c0b0..92514615875 100644 --- a/source/blender/blenkernel/intern/curve_catmull_rom.cc +++ b/source/blender/blenkernel/intern/curve_catmull_rom.cc @@ -226,7 +226,16 @@ static float find_root_newton_bisection(float x_begin, const float precision) { float x_mid = 0.5f * (x_begin + x_end); + float y_begin = eval(x_begin); + if (y_begin == 0.0f) { +return x_begin; + } + + float y_end = eval(x_end); + if (y_end == 0.0f) { +return x_end; + } BLI_assert(signf(y_begin) != signf(eval(x_end))); @@ -261,7 +270,6 @@ void calculate_normals(const Span positions, const float weight_twist = 1.0f - clamp_f(weight_bending, 0.0f, 1.0f); - /* TODO: check if derivatives == 0.*/ Vector first_derivatives_(evaluated_normals.size()); MutableSpan first_derivatives = first_derivatives_; interpolate_to_evaluated(1, positions, is_cyclic, resolution, first_derivatives); @@ -307,9 +315,12 @@ void calculate_normals(const Span positions, /* TODO: Catmull-Rom is not C2 continuous. Some smoothening maybe? */ float3 curvature_vector = math::normalize(math::cross(binormal, first_derivatives[i])); +const float first_derivative_norm = math::length(first_derivatives[i]); +const float curvature = math::length(binormal) / pow3f(first_derivative_norm); + if (i == 0) { /* TODO: Does it make sense to propogate from where the curvature is the largest? */ - evaluated_normals[i] = curvature_vector; + evaluated_normals[i] = curvature > 1e-4f ? curvature_vector : float3(1.0f, 0.0f, 0.0f); continue; } @@ -321,29 +332,27 @@ void calculate_normals(const Span positions, continue; } -const float first_derivative_norm = math::length(first_derivatives[i]); const float3 last_tangent = math::normalize(first_derivatives[i - 1]); const float3 current_tangent = first_derivatives[i] / first_derivative_norm; const float angle = angle_normalized_v3v3(last_tangent, current_tangent); const float3 last_normal = evaluated_normals[i - 1]; const float3 minimal_twist_normal = -angle > 0 ? +angle > 0 && first_derivative_norm > 0 ? math::rotate_direction_around_axis( last_normal, math::normalize(math::cross(last_tangent, current_tangent)), angle) : last_normal; -if (weight_twist == 1.0f) { - evaluated_normals[i] = minimal_twist_normal; - continue; -} - /* Arc length depends on the unit, assuming meter. */ const float arc_length = first_derivative_norm * dt; -const float curvature = math::length(binormal) / pow3f(first_derivative_norm); const float coefficient_twist = weight_twist / arc_length; const float coefficient_bending = weight_bending * arc_length * curvature * curvature; +if (weight_twist == 1.0f || !(coefficient_bending > 0)) { + evaluated_normals[i] = minimal_twist_normal; + continue; +} + /* Angle between the curvature vector and the minimal twist normal. */ float theta_t = angle_normalized_v3v3(curvature_vector, minimal_twist_normal); if (theta_t > M_PI_2) { @@ -368,7 +377,7 @@ void calculate_normals(const Span positions, [coefficient_bending, coefficient_twist](float t) -> float { return 2.0f * (coefficient_twist + coefficient_bending * cosf(2.0f * t)); }, -1e-5f); +1e-4f); const float3 axis = math::dot(current_tangent, math::cross(curvature_vector, minimal_twist_normal)) > 0 ? ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [8ee7e626a5a] microfacet_hair: Interpolate between the curvature vector and the minimal twist vector with custom weight
Commit: 8ee7e626a5a6e4b5471fc1bddb508d77f072e0c2 Author: Weizhen Huang Date: Mon Jan 9 17:32:17 2023 +0100 Branches: microfacet_hair https://developer.blender.org/rB8ee7e626a5a6e4b5471fc1bddb508d77f072e0c2 Interpolate between the curvature vector and the minimal twist vector with custom weight === M source/blender/blenkernel/BKE_curves.hh M source/blender/blenkernel/intern/curve_catmull_rom.cc M source/blender/blenkernel/intern/curves_geometry.cc M source/blender/makesrna/intern/rna_curves.c M source/blender/nodes/geometry/nodes/node_geo_set_curve_normal.cc === diff --git a/source/blender/blenkernel/BKE_curves.hh b/source/blender/blenkernel/BKE_curves.hh index 14aa854a4f2..2aa1e3b5156 100644 --- a/source/blender/blenkernel/BKE_curves.hh +++ b/source/blender/blenkernel/BKE_curves.hh @@ -242,6 +242,13 @@ class CurvesGeometry : public ::CurvesGeometry { VArray normal_mode() const; MutableSpan normal_mode_for_write(); + /** + * Used for normal mode curvature vector, specifying the weight as opposed to the minimal twist + * normal. + */ + VArray curvature_vector_weight() const; + MutableSpan curvature_vector_weight_for_write(); + /** * Handle types for Bezier control points. Call #tag_topology_changed after changes. */ @@ -707,6 +714,7 @@ void calculate_tangents(Span positions, void calculate_normals(Span positions, bool is_cyclic, int resolution, + float weight_bending, MutableSpan normals); /** diff --git a/source/blender/blenkernel/intern/curve_catmull_rom.cc b/source/blender/blenkernel/intern/curve_catmull_rom.cc index a93b90ea598..fa2fe01c0b0 100644 --- a/source/blender/blenkernel/intern/curve_catmull_rom.cc +++ b/source/blender/blenkernel/intern/curve_catmull_rom.cc @@ -251,6 +251,7 @@ static float find_root_newton_bisection(float x_begin, void calculate_normals(const Span positions, const bool is_cyclic, const int resolution, + const float weight_bending, MutableSpan evaluated_normals) { if (evaluated_normals.size() == 1) { @@ -258,6 +259,8 @@ void calculate_normals(const Span positions, return; } + const float weight_twist = 1.0f - clamp_f(weight_bending, 0.0f, 1.0f); + /* TODO: check if derivatives == 0.*/ Vector first_derivatives_(evaluated_normals.size()); MutableSpan first_derivatives = first_derivatives_; @@ -265,21 +268,35 @@ void calculate_normals(const Span positions, Vector second_derivatives_(evaluated_normals.size()); MutableSpan second_derivatives = second_derivatives_; - interpolate_to_evaluated(2, positions, is_cyclic, resolution, second_derivatives); - - /* TODO: below are hair-specific values, assuming elliptical cross-section. Maybe make them more - * general by specifying user-defined weight? */ - /* Values taken from Table 9.5 in book Chemical and Physical Behavior of Human Hair by Clarence - * R. Robbins, 5th edition. Unit: GPa. */ - const float youngs_modulus = 3.89f; - const float shear_modulus = 0.89f; - /* Assuming major axis a = 1. */ - const float aspect_ratio = 0.5f; /* Minimal realistic value. */ - const float aspect_ratio_squared = aspect_ratio * aspect_ratio; - const float torsion_constant = M_PI * aspect_ratio_squared * aspect_ratio / - (1.0f + aspect_ratio_squared); - const float moment_of_inertia_coefficient = M_PI * aspect_ratio * 0.25f * - (1.0f - aspect_ratio_squared); + if (weight_twist < 1.0f) { +interpolate_to_evaluated(2, positions, is_cyclic, resolution, second_derivatives); + } + else { +/* TODO: Actually only the first entry needs to be evaluated. */ +interpolate_to_evaluated( +2, +positions, +is_cyclic, +[resolution](const int segment_i) -> IndexRange { + return {segment_i * resolution, 1}; +}, +second_derivatives); + } + + /* Hair-specific values, taken from Table 9.5 in book Chemical and Physical Behavior of Human + * Hair by Clarence R. Robbins, 5th edition. Unit: GPa. */ + // const float youngs_modulus = 3.89f; + // const float shear_modulus = 0.89f; + // /* Assuming major axis a = 1. */ + // const float aspect_ratio = 0.5f; /* Minimal realistic value. */ + // const float aspect_ratio_squared = aspect_ratio * aspect_ratio; + // const float torsion_constant = M_PI * aspect_ratio_squared * aspect_ratio / + //(1.0f + aspect_ratio_squared); + // const float moment_of_inertia_coefficient = M_PI * aspect_ratio * 0.25f * + // (1.0f - aspect_ratio_squared); + + // const float weight_b
[Bf-blender-cvs] [74cab3ea05e] microfacet_hair: Cleanup: remove unneeded variable
Commit: 74cab3ea05e1dfe437a8265601c067e0318c58eb Author: Weizhen Huang Date: Fri Jan 6 14:26:13 2023 +0100 Branches: microfacet_hair https://developer.blender.org/rB74cab3ea05e1dfe437a8265601c067e0318c58eb Cleanup: remove unneeded variable === M source/blender/blenkernel/intern/curve_catmull_rom.cc === diff --git a/source/blender/blenkernel/intern/curve_catmull_rom.cc b/source/blender/blenkernel/intern/curve_catmull_rom.cc index b7930ade7fc..a93b90ea598 100644 --- a/source/blender/blenkernel/intern/curve_catmull_rom.cc +++ b/source/blender/blenkernel/intern/curve_catmull_rom.cc @@ -48,10 +48,9 @@ void calculate_basis_derivative(const float parameter, float4 _weights) void calculate_basis_derivative2(const float parameter, float4 _weights) { const float t = parameter; - const float s = 1.0f - parameter; r_weights[0] = -6.0f * t + 4.0f; r_weights[1] = 18.0f * t - 10.0f; - r_weights[2] = 18.0f * s - 10.0f; + r_weights[2] = -18.0f * t + 8.0f; r_weights[3] = 6.0f * t - 2.0f; } ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [148e954dbbb] microfacet_hair: Add comment to failed test
Commit: 148e954dbbbff811e92dd438556332d70e2fc5eb Author: Weizhen Huang Date: Fri Jan 6 13:04:53 2023 +0100 Branches: microfacet_hair https://developer.blender.org/rB148e954dbbbff811e92dd438556332d70e2fc5eb Add comment to failed test === M source/blender/blenkernel/intern/curves_geometry.cc === diff --git a/source/blender/blenkernel/intern/curves_geometry.cc b/source/blender/blenkernel/intern/curves_geometry.cc index 47eafb3f912..10325c0bed0 100644 --- a/source/blender/blenkernel/intern/curves_geometry.cc +++ b/source/blender/blenkernel/intern/curves_geometry.cc @@ -665,6 +665,7 @@ Span CurvesGeometry::evaluated_tangents() const const IndexRange evaluated_points = this->evaluated_points_for_curve(curve_index); switch (types[curve_index]) { case CURVE_TYPE_CATMULL_ROM: +/* NOTE: this causes test geo_node_curves_test_sample_curves to fail. */ curves::catmull_rom::calculate_tangents(positions.slice(points), cyclic[curve_index], resolution[curve_index], ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [b47fc535f12] microfacet_hair: Merge branch 'master' into microfacet_hair
Commit: b47fc535f12b8724fcb5b3ed0eced4d9a815f423 Author: Weizhen Huang Date: Fri Jan 6 11:44:26 2023 +0100 Branches: microfacet_hair https://developer.blender.org/rBb47fc535f12b8724fcb5b3ed0eced4d9a815f423 Merge branch 'master' into microfacet_hair === === diff --cc source/blender/geometry/intern/add_curves_on_mesh.cc index b1eaf43da5a,55f0398fd3c..7e034a4640e --- a/source/blender/geometry/intern/add_curves_on_mesh.cc +++ b/source/blender/geometry/intern/add_curves_on_mesh.cc @@@ -373,18 -365,14 +365,15 @@@ AddCurvesOnMeshOutputs add_curves_on_me } curves.fill_curve_types(new_curves_range, CURVE_TYPE_CATMULL_ROM); + curves.normal_mode_for_write().fill(NORMAL_MODE_CURVATURE_VECTOR); - /* Explicitly set all other attributes besides those processed above to default values. */ bke::MutableAttributeAccessor attributes = curves.attributes_for_write(); - Set attributes_to_skip{{"position", -"curve_type", -"surface_uv_coordinate", -".selection_point_float", -".selection_curve_float"}}; + + /* Explicitly set all other attributes besides those processed above to default values. */ + Set attributes_to_skip{{"position", "curve_type", "surface_uv_coordinate"}}; attributes.for_all( [&](const bke::AttributeIDRef , const bke::AttributeMetaData /*meta_data*/) { - if (id.is_named() && attributes_to_skip.contains(id.name())) { + if (attributes_to_skip.contains(id.name())) { return true; } bke::GSpanAttributeWriter attribute = attributes.lookup_for_write_span(id); diff --cc source/blender/makesdna/DNA_curves_types.h index f5afb4eb498,5ecc816f4ea..8849d137701 --- a/source/blender/makesdna/DNA_curves_types.h +++ b/source/blender/makesdna/DNA_curves_types.h @@@ -78,9 -78,13 +78,14 @@@ typedef enum KnotsMode /** Method used to calculate the normals of a curve's evaluated points. */ typedef enum NormalMode { + /** Calculate normals with the smallest twist around the curve tangent across the whole curve. */ NORMAL_MODE_MINIMUM_TWIST = 0, + /** +* Calculate normals perpendicular to the Z axis and the curve tangent. If a series of points +* is vertical, the X axis is used. +*/ NORMAL_MODE_Z_UP = 1, + NORMAL_MODE_CURVATURE_VECTOR = 2, } NormalMode; /** ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [6b5f323b901] microfacet_hair: Small modification to comment
Commit: 6b5f323b9015e6c08711f533b2d9b80dd057ea57 Author: Weizhen Huang Date: Thu Jan 5 18:27:57 2023 +0100 Branches: microfacet_hair https://developer.blender.org/rB6b5f323b9015e6c08711f533b2d9b80dd057ea57 Small modification to comment === M source/blender/blenkernel/intern/curve_catmull_rom.cc === diff --git a/source/blender/blenkernel/intern/curve_catmull_rom.cc b/source/blender/blenkernel/intern/curve_catmull_rom.cc index 9bf5a5f1708..b7930ade7fc 100644 --- a/source/blender/blenkernel/intern/curve_catmull_rom.cc +++ b/source/blender/blenkernel/intern/curve_catmull_rom.cc @@ -247,7 +247,7 @@ static float find_root_newton_bisection(float x_begin, } /* Calculate normals by minimizing the potential energy due to twist and bending. Global - * estimation involves integration and is thus too costly. Instead, we start with the first + * optimization would involve integration and is too costly. Instead, we start with the first * curvature vector and propogate it along the curve. */ void calculate_normals(const Span positions, const bool is_cyclic, ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [5015c8219b6] microfacet_hair: Compute hair normal with minimal total potential energy Although computed in the geometry node, this normal is specific for hairs is only implemented fo
Commit: 5015c8219b69e7f632ec966634b2b8e7749e6c90 Author: Weizhen Huang Date: Thu Jan 5 17:46:59 2023 +0100 Branches: microfacet_hair https://developer.blender.org/rB5015c8219b69e7f632ec966634b2b8e7749e6c90 Compute hair normal with minimal total potential energy Although computed in the geometry node, this normal is specific for hairs is only implemented for Catmull-Rom splines. Questions remain whether this should be generalized, also a few design ideas are obscure. {F14115834} === M source/blender/blenkernel/BKE_curves.hh M source/blender/blenkernel/intern/curve_catmull_rom.cc M source/blender/blenkernel/intern/curves_geometry.cc === diff --git a/source/blender/blenkernel/BKE_curves.hh b/source/blender/blenkernel/BKE_curves.hh index 44d0dd132aa..49d0ac96a35 100644 --- a/source/blender/blenkernel/BKE_curves.hh +++ b/source/blender/blenkernel/BKE_curves.hh @@ -710,7 +710,6 @@ void calculate_tangents(Span positions, void calculate_normals(Span positions, bool is_cyclic, int resolution, - Span tangents, MutableSpan normals); /** diff --git a/source/blender/blenkernel/intern/curve_catmull_rom.cc b/source/blender/blenkernel/intern/curve_catmull_rom.cc index d16b82ed1d4..9bf5a5f1708 100644 --- a/source/blender/blenkernel/intern/curve_catmull_rom.cc +++ b/source/blender/blenkernel/intern/curve_catmull_rom.cc @@ -6,6 +6,8 @@ #include "BKE_attribute_math.hh" #include "BKE_curves.hh" +#include "BLI_math_rotation_legacy.hh" +#include "BLI_math_vector.hh" namespace blender::bke::curves::catmull_rom { @@ -139,7 +141,8 @@ static void interpolate_to_evaluated(const int order, } template -static void interpolate_to_evaluated(const Span src, +static void interpolate_to_evaluated(const int order, + const Span src, const bool cyclic, const int resolution, MutableSpan dst) @@ -147,7 +150,7 @@ static void interpolate_to_evaluated(const Span src, { BLI_assert(dst.size() == calculate_evaluated_num(src.size(), cyclic, resolution)); interpolate_to_evaluated( - 0, + order, src, cyclic, [resolution](const int segment_i) -> IndexRange { @@ -180,7 +183,7 @@ void interpolate_to_evaluated(const GSpan src, { attribute_math::convert_to_static_type(src.type(), [&](auto dummy) { using T = decltype(dummy); -interpolate_to_evaluated(src.typed(), cyclic, resolution, dst.typed()); +interpolate_to_evaluated(0, src.typed(), cyclic, resolution, dst.typed()); }); } @@ -206,25 +209,49 @@ void calculate_tangents(const Span positions, return; } - interpolate_to_evaluated( - 1, - positions, - is_cyclic, - [resolution](const int segment_i) -> IndexRange { -return {segment_i * resolution, resolution}; - }, - evaluated_tangents); + interpolate_to_evaluated(1, positions, is_cyclic, resolution, evaluated_tangents); for (const int i : evaluated_tangents.index_range()) { evaluated_tangents[i] = math::normalize(evaluated_tangents[i]); } } -/* Calculate analytical normals from the first and the second derivative. */ +/* Use a combination of Newton iterations and bisection to find the root in the monotonic interval + * [x_begin, x_end], given precision. Idea taken from the paper High-Performance Polynomial Root + * Finding for Graphics by Cem Yuksel, HPG 2022. */ +/* TODO: move this function elsewhere as a utility function? Also test corner cases. */ +static float find_root_newton_bisection(float x_begin, +float x_end, +std::function eval, +std::function eval_derivative, +const float precision) +{ + float x_mid = 0.5f * (x_begin + x_end); + float y_begin = eval(x_begin); + + BLI_assert(signf(y_begin) != signf(eval(x_end))); + + while (x_mid - x_begin > precision) { +const float y_mid = eval(x_mid); +if (signf(y_begin) == signf(y_mid)) { + x_begin = x_mid; + y_begin = y_mid; +} +else { + x_end = x_mid; +} +const float x_newton = x_mid - y_mid / eval_derivative(x_mid); +x_mid = (x_newton > x_begin && x_newton < x_end) ? x_newton : 0.5f * (x_begin + x_end); + } + return x_mid; +} + +/* Calculate normals by minimizing the potential energy due to twist and bending. Global + * estimation involves integration and is thus too costly. Instead, we start with the first + * curvature vector and propogate it along the curve. */ void calculate_normals
[Bf-blender-cvs] [8af16fd0877] microfacet_hair: Fix compiler error in the normal and tangent computation
Commit: 8af16fd08772ae25e33212c8a9774a5478e0d654 Author: Weizhen Huang Date: Mon Jan 2 16:14:42 2023 +0100 Branches: microfacet_hair https://developer.blender.org/rB8af16fd08772ae25e33212c8a9774a5478e0d654 Fix compiler error in the normal and tangent computation === M source/blender/blenkernel/intern/curve_catmull_rom.cc === diff --git a/source/blender/blenkernel/intern/curve_catmull_rom.cc b/source/blender/blenkernel/intern/curve_catmull_rom.cc index 7bd5db488f4..d16b82ed1d4 100644 --- a/source/blender/blenkernel/intern/curve_catmull_rom.cc +++ b/source/blender/blenkernel/intern/curve_catmull_rom.cc @@ -86,14 +86,11 @@ static void interpolate_to_evaluated(const int order, if (src.size() == 1) { switch (order) { - case 1: -dst.first() = float3(0.0f, 0.0f, 1.0f); -break; - case 2: -dst.first() = float3(1.0f, 0.0f, 0.0f); + case 0: +dst.first() = src.first(); break; default: -dst.first() = src.first(); +dst.first() = T(0); break; } return; @@ -204,6 +201,11 @@ void calculate_tangents(const Span positions, const int resolution, MutableSpan evaluated_tangents) { + if (evaluated_tangents.size() == 1) { +evaluated_tangents[0] = float3(0.0f, 0.0f, 1.0f); +return; + } + interpolate_to_evaluated( 1, positions, @@ -225,6 +227,11 @@ void calculate_normals(const Span positions, const Span evaluated_tangents, MutableSpan evaluated_normals) { + if (evaluated_normals.size() == 1) { +evaluated_normals[0] = float3(1.0f, 0.0f, 0.0f); +return; + } + /* Compute the second derivative (r'') of the control points, evaluated at t = 0. */ interpolate_to_evaluated( 2, ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [93e0559f54c] microfacet_hair: WIP: calculate normals aligned with the curvature vector Only works for Catmull-Rom and poly curve types for now
Commit: 93e0559f54c087a64121b4b30708be096a3d7c3e Author: Weizhen Huang Date: Mon Jan 2 15:49:28 2023 +0100 Branches: microfacet_hair https://developer.blender.org/rB93e0559f54c087a64121b4b30708be096a3d7c3e WIP: calculate normals aligned with the curvature vector Only works for Catmull-Rom and poly curve types for now === M release/datafiles/locale M release/scripts/addons M release/scripts/addons_contrib M source/blender/blenkernel/BKE_curves.hh M source/blender/blenkernel/intern/curve_catmull_rom.cc M source/blender/blenkernel/intern/curve_legacy_convert.cc M source/blender/blenkernel/intern/curve_poly.cc M source/blender/blenkernel/intern/curves_geometry.cc M source/blender/blenkernel/intern/geometry_component_curves.cc M source/blender/geometry/intern/add_curves_on_mesh.cc M source/blender/geometry/intern/trim_curves.cc M source/blender/makesdna/DNA_curves_types.h M source/blender/makesrna/intern/rna_curves.c M source/tools === diff --git a/release/datafiles/locale b/release/datafiles/locale index e398d3c4969..7084c4ecd97 16 --- a/release/datafiles/locale +++ b/release/datafiles/locale @@ -1 +1 @@ -Subproject commit e398d3c4969a37ae2ecff388344dd780bc1cfe82 +Subproject commit 7084c4ecd97d93459d9d23fd90f81589b09be5df diff --git a/release/scripts/addons b/release/scripts/addons index 90c87dd771e..042c799b7ae 16 --- a/release/scripts/addons +++ b/release/scripts/addons @@ -1 +1 @@ -Subproject commit 90c87dd771e027e0ffa157a0e294399bfd605d99 +Subproject commit 042c799b7aef9634a33d24e78d4922706aca9a2b diff --git a/release/scripts/addons_contrib b/release/scripts/addons_contrib index 96143b1a8b0..bdcfdd47ec3 16 --- a/release/scripts/addons_contrib +++ b/release/scripts/addons_contrib @@ -1 +1 @@ -Subproject commit 96143b1a8b037ea3c81f065f557025db9fe1ace3 +Subproject commit bdcfdd47ec3451822b21d1cff2ea2db751093c9a diff --git a/source/blender/blenkernel/BKE_curves.hh b/source/blender/blenkernel/BKE_curves.hh index 9382a912c02..44d0dd132aa 100644 --- a/source/blender/blenkernel/BKE_curves.hh +++ b/source/blender/blenkernel/BKE_curves.hh @@ -520,6 +520,13 @@ void calculate_tangents(Span positions, bool is_cyclic, MutableSpan tangents, bool cyclic, MutableSpan normals); +/** + * Calculate curvature vectors. TODO: more description. */ +void calculate_curvature_vectors(Span positions, + Span tangents, + bool cyclic, + MutableSpan normals); + /** * Calculate a vector perpendicular to every tangent on the X-Y plane (unless the tangent is * vertical, in that case use the X direction). @@ -696,6 +703,16 @@ void interpolate_to_evaluated(GSpan src, Span evaluated_offsets, GMutableSp namespace catmull_rom { +void calculate_tangents(Span positions, +bool is_cyclic, +int resolution, +MutableSpan tangents); +void calculate_normals(Span positions, + bool is_cyclic, + int resolution, + Span tangents, + MutableSpan normals); + /** * Calculate the number of evaluated points that #interpolate_to_evaluated is expected to produce. * \param points_num: The number of points in the curve. @@ -719,6 +736,8 @@ void interpolate_to_evaluated(const GSpan src, GMutableSpan dst); void calculate_basis(const float parameter, float4 _weights); +void calculate_basis_derivative(const float parameter, float4 _weights); +void calculate_basis_derivative2(const float parameter, float4 _weights); /** * Interpolate the control point values for the given parameter on the piecewise segment. @@ -727,11 +746,24 @@ void calculate_basis(const float parameter, float4 _weights); * \param parameter: Parameter in range [0, 1] to compute the interpolation for. */ template -T interpolate(const T , const T , const T , const T , const float parameter) +T interpolate( +const int order, const T , const T , const T , const T , const float parameter) { BLI_assert(0.0f <= parameter && parameter <= 1.0f); float4 n; - calculate_basis(parameter, n); + + switch (order) { +case 1: + calculate_basis_derivative(parameter, n); + break; +case 2: + calculate_basis_derivative2(parameter, n); + break; +default: + calculate_basis(parameter, n); + break; + } + if constexpr (is_same_any_v) { /* Save multiplications by adjusting weights after mix. */ return 0.5f * attribute_math::mix4(n, a, b, c, d); diff --git a/source/blender/blenkernel/intern/curve_catmull_rom.cc b/source/blender/blenkernel/intern/curve_catmull_rom.cc index 8247d9451e4..7bd5db488f4 10064
[Bf-blender-cvs] [c574ddc1044] microfacet_hair: Fix wrong interval numbers in composite Simpson's method
Commit: c574ddc10445d2dc5bc3984b3f356c501464bda3 Author: Weizhen Huang Date: Wed Dec 28 12:41:33 2022 +0100 Branches: microfacet_hair https://developer.blender.org/rBc574ddc10445d2dc5bc3984b3f356c501464bda3 Fix wrong interval numbers in composite Simpson's method === M intern/cycles/kernel/closure/bsdf_hair_microfacet.h === diff --git a/intern/cycles/kernel/closure/bsdf_hair_microfacet.h b/intern/cycles/kernel/closure/bsdf_hair_microfacet.h index 2392d03cbac..3216511a26d 100644 --- a/intern/cycles/kernel/closure/bsdf_hair_microfacet.h +++ b/intern/cycles/kernel/closure/bsdf_hair_microfacet.h @@ -398,23 +398,23 @@ ccl_device float3 bsdf_microfacet_hair_eval_r_circular(ccl_private const ShaderC integral = roughness_squared * M_1_PI_F * 0.5f * (temp1 + temp2 + temp3 + temp4); } - else { /* falls back to numerical integration */ -/* initial sample resolution */ + else { /* Falls back to numerical integration. */ +/* Maximal sample resolution. */ float res = roughness * 0.7f; -const float scale = (phi_m_max - phi_m_min) * 0.5f; -size_t intervals = 2 * (size_t)ceilf(scale / res) + 1; +/* Number of intervals should be even. */ +const size_t intervals = 2 * (size_t)ceilf((phi_m_max - phi_m_min) / res * 0.5f); -/* modified resolution based on integral domain */ +/* Modified resolution based on numbers of intervals. */ res = (phi_m_max - phi_m_min) / float(intervals); -/* integrate using Simpson's rule */ -for (size_t i = 0; i < intervals; i++) { +/* Integrate using Simpson's rule. */ +for (size_t i = 0; i <= intervals; i++) { const float phi_m = phi_m_min + i * res; const float3 wm = sph_dir(tilt, phi_m); if (microfacet_visible(wi, wo, make_float3(wm.x, 0.0f, wm.z), wh)) { -const float weight = (i == 0 || i == intervals - 1) ? 0.5f : (i % 2 + 1); +const float weight = (i == 0 || i == intervals) ? 0.5f : (i % 2 + 1); integral += weight * D(beckmann, roughness, wm, wh) * G(beckmann, roughness, wi, wo, wm, wh); } @@ -458,14 +458,13 @@ ccl_device float3 bsdf_microfacet_hair_eval_tt_trt_circular(KernelGlobals kg, const float3 mu_a = bsdf->sigma; const float inv_eta = 1.0f / eta; - float res = roughness * .8f; - const float scale = (phi_m_max - phi_m_min) * 0.5f; - size_t intervals = 2 * (size_t)ceilf(scale / res) + 1; + float res = roughness * 0.8f; + const size_t intervals = 2 * (size_t)ceilf((phi_m_max - phi_m_min) / res * 0.5f); res = (phi_m_max - phi_m_min) / intervals; float3 S_tt = zero_float3(); float3 S_trt = zero_float3(); - for (size_t i = 0; i < intervals; i++) { + for (size_t i = 0; i <= intervals; i++) { const float phi_mi = phi_m_min + i * res; const float3 wmi = sph_dir(tilt, phi_mi); @@ -495,7 +494,7 @@ ccl_device float3 bsdf_microfacet_hair_eval_tt_trt_circular(KernelGlobals kg, } /* Simpson's rule weight */ -float weight = (i == 0 || i == intervals - 1) ? 0.5f : (i % 2 + 1); +float weight = (i == 0 || i == intervals) ? 0.5f : (i % 2 + 1); float3 A_t = exp(mu_a * 2.0f * cosf(phi_t - phi_mi) / cos_theta(wt)); @@ -891,23 +890,23 @@ ccl_device float3 bsdf_microfacet_hair_eval_r_elliptic(ccl_private const ShaderC gamma_m_max += M_2PI_F; } - /* initial sample resolution */ + /* Maximal sample resolution. */ float res = roughness * .7f; - const float scale = (gamma_m_max - gamma_m_min) * 0.5f; - size_t intervals = 2 * (size_t)ceilf(scale / res) + 1; + /* Number of intervals should be even. */ + const size_t intervals = 2 * (size_t)ceilf((gamma_m_max - gamma_m_min) / res * 0.5f); - /* modified resolution based on integral domain */ + /* Modified resolution based on numbers of intervals. */ res = (gamma_m_max - gamma_m_min) / float(intervals); - /* integrate using Simpson's rule */ + /* Integrate using Simpson's rule. */ float integral = 0.0f; - for (size_t i = 0; i < intervals; i++) { + for (size_t i = 0; i <= intervals; i++) { const float gamma_m = gamma_m_min + i * res; const float3 wm = sphg_dir(tilt, gamma_m, a, b); if (microfacet_visible(wi, wo, make_float3(wm.x, 0.0f, wm.z), wh)) { - const float weight = (i == 0 || i == intervals - 1) ? 0.5f : (i % 2 + 1); + const float weight = (i == 0 || i == intervals) ? 0.5f : (i % 2 + 1); const float arc_length = sqrtf(1.0f - e2 * sqr(sinf(gamma_m))); integral += weight * D(beckmann, roughness, wm, wh) * @@ -976,13 +975,12 @@ ccl_device float3 bsdf_microfacet_hair_eval_tt_trt_elliptic(KernelGlobals kg, } float res = roughness * 0.8f; - const float scale = (gamma_m_max - gamma_m_min) * 0.5f; - size_t intervals = 2 * (size_t)ceilf(scale / res) + 1; + const size_t intervals = 2 * (size
[Bf-blender-cvs] [4990122abb7] microfacet_hair: Merge branch 'master' into microfacet_hair
Commit: 4990122abb71aafaca1aedd943846b90cd790a82 Author: Weizhen Huang Date: Tue Dec 27 11:07:13 2022 +0100 Branches: microfacet_hair https://developer.blender.org/rB4990122abb71aafaca1aedd943846b90cd790a82 Merge branch 'master' into microfacet_hair === === ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [767eb3cd6ad] microfacet_hair: Only add normal attributes for elliptical hairs
Commit: 767eb3cd6ad837f05eb93c6f42e7e73dda44eca0 Author: Weizhen Huang Date: Tue Dec 27 13:52:25 2022 +0100 Branches: microfacet_hair https://developer.blender.org/rB767eb3cd6ad837f05eb93c6f42e7e73dda44eca0 Only add normal attributes for elliptical hairs === M intern/cycles/scene/shader_nodes.cpp === diff --git a/intern/cycles/scene/shader_nodes.cpp b/intern/cycles/scene/shader_nodes.cpp index e1e602e240b..0f98c16b58e 100644 --- a/intern/cycles/scene/shader_nodes.cpp +++ b/intern/cycles/scene/shader_nodes.cpp @@ -3698,7 +3698,10 @@ MicrofacetHairBsdfNode::MicrofacetHairBsdfNode() : BsdfBaseNode(get_node_type()) void MicrofacetHairBsdfNode::attributes(Shader *shader, AttributeRequestSet *attributes) { /* Make sure we have the normal for elliptical cross section tracking */ - attributes->add(ATTR_STD_VERTEX_NORMAL); + if (model_type == NODE_MICROFACET_HAIR_ELLIPTIC_BECKMANN || + model_type == NODE_MICROFACET_HAIR_ELLIPTIC_GGX) { +attributes->add(ATTR_STD_VERTEX_NORMAL); + } if (!input("Random")->link) { attributes->add(ATTR_STD_CURVE_RANDOM); ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [8bad526d517] microfacet_hair: Fix normal attribute was defined per curve instead of per key
Commit: 8bad526d517404d491d824eff9e678c344ac2d44 Author: Weizhen Huang Date: Tue Dec 27 13:51:58 2022 +0100 Branches: microfacet_hair https://developer.blender.org/rB8bad526d517404d491d824eff9e678c344ac2d44 Fix normal attribute was defined per curve instead of per key === M intern/cycles/blender/curves.cpp === diff --git a/intern/cycles/blender/curves.cpp b/intern/cycles/blender/curves.cpp index eb064361cc8..ce8a35fb61b 100644 --- a/intern/cycles/blender/curves.cpp +++ b/intern/cycles/blender/curves.cpp @@ -326,12 +326,12 @@ static void ExportCurveSegments(Scene *scene, Hair *hair, ParticleCurveData *CDa if (attr_intercept) attr_intercept->add(time); -num_curve_keys++; - } +if (attr_normal) { + /* TODO: compute geometry normals. */ + attr_normal->add(make_float3(1.0f, 0.0f, 0.0f)); +} - if (attr_normal != NULL) { -/* TODO: compute geometry normals. */ -attr_normal->add(make_float3(1.0f, 0.0f, 0.0f)); +num_curve_keys++; } if (attr_length != NULL) { ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [b1c549059dc] microfacet_hair: Cleanup: remove unused variables
Commit: b1c549059dcb777ef02015ec8e1f7f2c0da99711 Author: Weizhen Huang Date: Thu Dec 22 18:49:09 2022 +0100 Branches: microfacet_hair https://developer.blender.org/rBb1c549059dcb777ef02015ec8e1f7f2c0da99711 Cleanup: remove unused variables === M intern/cycles/scene/shader_nodes.h M source/blender/gpu/shaders/material/gpu_shader_material_hair.glsl === diff --git a/intern/cycles/scene/shader_nodes.h b/intern/cycles/scene/shader_nodes.h index 8ba0b3e81f5..bab81cda1ac 100644 --- a/intern/cycles/scene/shader_nodes.h +++ b/intern/cycles/scene/shader_nodes.h @@ -909,10 +909,6 @@ class MicrofacetHairBsdfNode : public BsdfBaseNode { /* Aspect Ratio. */ NODE_SOCKET_API(float, aspect_ratio) - /* Randomization factor for axis rotation. */ - NODE_SOCKET_API(float, random_axis) - /* Twist rate. */ - NODE_SOCKET_API(float, twist_rate) NODE_SOCKET_API(float, R) NODE_SOCKET_API(float, TT) diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_hair.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_hair.glsl index b12346471cf..7342e6d29a3 100644 --- a/source/blender/gpu/shaders/material/gpu_shader_material_hair.glsl +++ b/source/blender/gpu/shaders/material/gpu_shader_material_hair.glsl @@ -57,8 +57,6 @@ void node_bsdf_hair_microfacet(vec4 color, float ior, float offset, float aspect_ratio, - float random_axis, - float twist_rate, float Blur, float random_color, float random_roughness, ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [4415ebc3365] microfacet_hair: Cleanup: rename eccentricity -> aspect ratio
Commit: 4415ebc336588dbbe4d9f41fb2b6297c997c773c Author: Weizhen Huang Date: Thu Dec 22 18:47:21 2022 +0100 Branches: microfacet_hair https://developer.blender.org/rB4415ebc336588dbbe4d9f41fb2b6297c997c773c Cleanup: rename eccentricity -> aspect ratio === M intern/cycles/kernel/closure/bsdf_hair_microfacet.h M intern/cycles/kernel/svm/closure.h M intern/cycles/scene/shader_nodes.cpp M intern/cycles/scene/shader_nodes.h M source/blender/gpu/shaders/material/gpu_shader_material_hair.glsl M source/blender/nodes/shader/nodes/node_shader_bsdf_hair_microfacet.cc === diff --git a/intern/cycles/kernel/closure/bsdf_hair_microfacet.h b/intern/cycles/kernel/closure/bsdf_hair_microfacet.h index 93f42b8f21a..2392d03cbac 100644 --- a/intern/cycles/kernel/closure/bsdf_hair_microfacet.h +++ b/intern/cycles/kernel/closure/bsdf_hair_microfacet.h @@ -16,7 +16,7 @@ typedef struct MicrofacetHairExtra { float TT; float TRT; - float eccentricity; + float aspect_ratio; /* Geometry data. */ float4 geom; @@ -844,7 +844,7 @@ ccl_device float3 bsdf_microfacet_hair_eval_r_elliptic(ccl_private const ShaderC /* get elliptical cross section characteristic */ const float a = 1.0f; /* TODO: rename this as aspect ratio? e is in [0, 0.85], b is in [0.52, 1]. */ - const float b = bsdf->extra->eccentricity; + const float b = bsdf->extra->aspect_ratio; const float e2 = 1.0f - sqr(b / a); /* this follows blender's convention (unlike the circular case?) */ @@ -966,8 +966,8 @@ ccl_device float3 bsdf_microfacet_hair_eval_tt_trt_elliptic(KernelGlobals kg, /* get elliptical cross section characteristic */ const float a = 1.0f; - const float b = bsdf->extra->eccentricity; - const float e2 = 1.0f - sqr(b / a); + const float b = bsdf->extra->aspect_ratio; + const float e2 = 1.0f - sqr(b / a); /* Squared Eccentricity. */ float gamma_m_min = to_gamma(phi_m_min, a, b) + 1e-3f; float gamma_m_max = to_gamma(phi_m_max, a, b) - 1e-3f; @@ -1138,7 +1138,7 @@ ccl_device Spectrum bsdf_microfacet_hair_eval_elliptic(KernelGlobals kg, const float3 wo = make_float3(dot(omega_in, X), dot(omega_in, Y), dot(omega_in, Z)); /* Treat as transparent material if intersection lies outside of the projected radius. */ - const float e2 = 1.0f - sqr(bsdf->extra->eccentricity); + const float e2 = 1.0f - sqr(bsdf->extra->aspect_ratio); const float radius = sqrtf(1.0f - e2 * sqr(sin_phi(wi))); if (fabsf(bsdf->extra->geom.w) > radius) { *pdf = 0.0f; @@ -1180,7 +1180,7 @@ ccl_device int bsdf_microfacet_hair_sample_elliptic(const KernelGlobals kg, /* get elliptical cross section characteristic */ const float a = 1.0f; - const float b = bsdf->extra->eccentricity; + const float b = bsdf->extra->aspect_ratio; const float e2 = 1.0f - sqr(b / a); /* macronormal */ diff --git a/intern/cycles/kernel/svm/closure.h b/intern/cycles/kernel/svm/closure.h index 8406b81b30a..cdf189ad2f9 100644 --- a/intern/cycles/kernel/svm/closure.h +++ b/intern/cycles/kernel/svm/closure.h @@ -1017,20 +1017,20 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg, if (model_type == NODE_MICROFACET_HAIR_ELLIPTIC_GGX || model_type == NODE_MICROFACET_HAIR_ELLIPTIC_BECKMANN) { - uint eccentricity_ofs, temp; - svm_unpack_node_uchar4(data_node5.x, _ofs, , , ); + uint aspect_ratio_ofs, temp; + svm_unpack_node_uchar4(data_node5.x, _ratio_ofs, , , ); - float eccentricity = stack_load_float_default(stack, eccentricity_ofs, data_node5.y); + float aspect_ratio = stack_load_float_default(stack, aspect_ratio_ofs, data_node5.y); - /* Eccentricity */ - bsdf->extra->eccentricity = (eccentricity > 1.0f) ? 1.0f / eccentricity : eccentricity; + /* Aspect Ratio */ + bsdf->extra->aspect_ratio = (aspect_ratio > 1.0f) ? 1.0f / aspect_ratio : aspect_ratio; const AttributeDescriptor attr_descr_normal = find_attribute(kg, sd, data_node5.z); const float3 normal = curve_attribute_float3(kg, sd, attr_descr_normal, NULL, NULL); const float3 binormal = safe_normalize(cross(sd->dPdu, normal)); /* Align X axis with the ellipse major axis. */ - if (eccentricity > 1.0f) { + if (aspect_ratio > 1.0f) { const float3 normal = safe_normalize(cross(binormal, sd->dPdu)); bsdf->extra->geom = make_float4(normal.x, normal.y, normal.z, 0.0f); } diff --git a/intern/cycles/scene/shader_nodes.cpp b/intern/cycles/scene/shader_nodes.cpp index b732825d96c..e1e602e240b 100644 --- a/intern/cycles/scene/shader_nodes.cpp +++ b/intern/cycles/scene/shader_nodes.cpp @@
[Bf-blender-cvs] [e73d4734f93] microfacet_hair: Switch normal and binormal if aspect ratio larger than 1
Commit: e73d4734f938722c352be1ba89ce06349e3c24e8 Author: Weizhen Huang Date: Thu Dec 22 18:32:40 2022 +0100 Branches: microfacet_hair https://developer.blender.org/rBe73d4734f938722c352be1ba89ce06349e3c24e8 Switch normal and binormal if aspect ratio larger than 1 === M intern/cycles/kernel/svm/closure.h === diff --git a/intern/cycles/kernel/svm/closure.h b/intern/cycles/kernel/svm/closure.h index a9a20b6ad7c..8406b81b30a 100644 --- a/intern/cycles/kernel/svm/closure.h +++ b/intern/cycles/kernel/svm/closure.h @@ -1023,12 +1023,20 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg, float eccentricity = stack_load_float_default(stack, eccentricity_ofs, data_node5.y); /* Eccentricity */ - bsdf->extra->eccentricity = (eccentricity > 1.f) ? 1.f / eccentricity : eccentricity; + bsdf->extra->eccentricity = (eccentricity > 1.0f) ? 1.0f / eccentricity : eccentricity; const AttributeDescriptor attr_descr_normal = find_attribute(kg, sd, data_node5.z); const float3 normal = curve_attribute_float3(kg, sd, attr_descr_normal, NULL, NULL); const float3 binormal = safe_normalize(cross(sd->dPdu, normal)); - bsdf->extra->geom = make_float4(binormal.x, binormal.y, binormal.z, 0.0f); + + /* Align X axis with the ellipse major axis. */ + if (eccentricity > 1.0f) { +const float3 normal = safe_normalize(cross(binormal, sd->dPdu)); +bsdf->extra->geom = make_float4(normal.x, normal.y, normal.z, 0.0f); + } + else { +bsdf->extra->geom = make_float4(binormal.x, binormal.y, binormal.z, 0.0f); + } } sd->flag |= bsdf_microfacet_hair_setup(sd, bsdf); ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [f4987bdb068] microfacet_hair: Treat hair as transparent if intersection lies outside of the radius
Commit: f4987bdb0683ca4dc1f85764ae90bc88a5b98cc3 Author: Weizhen Huang Date: Thu Dec 22 18:24:58 2022 +0100 Branches: microfacet_hair https://developer.blender.org/rBf4987bdb0683ca4dc1f85764ae90bc88a5b98cc3 Treat hair as transparent if intersection lies outside of the radius === M intern/cycles/kernel/closure/bsdf_hair_microfacet.h === diff --git a/intern/cycles/kernel/closure/bsdf_hair_microfacet.h b/intern/cycles/kernel/closure/bsdf_hair_microfacet.h index a037839c691..93f42b8f21a 100644 --- a/intern/cycles/kernel/closure/bsdf_hair_microfacet.h +++ b/intern/cycles/kernel/closure/bsdf_hair_microfacet.h @@ -66,7 +66,7 @@ ccl_device int bsdf_microfacet_hair_setup(ccl_private ShaderData *sd, * the center, to grazing the other edge. This is the sine of the angle * between sd->Ng and Z, as seen from the tangent X. */ - float h = (sd->type & PRIMITIVE_CURVE_RIBBON) ? -sd->v : -dot(X, sd->Ng); + float h = (sd->type & PRIMITIVE_CURVE_RIBBON) ? -sd->v : -dot(X, sd->N); kernel_assert(fabsf(h) < 1.0f + 1e-4f); kernel_assert(isfinite_safe(X)); @@ -109,6 +109,11 @@ ccl_device_inline float tan_theta(const float3 w) } /* Returns sin(phi) and cos(phi) of the given direction. */ +ccl_device float sin_phi(const float3 w) +{ + return w.x / cos_theta(w); +} + ccl_device float2 sincos_phi(const float3 w) { float c = cos_theta(w); @@ -1132,6 +1137,14 @@ ccl_device Spectrum bsdf_microfacet_hair_eval_elliptic(KernelGlobals kg, const float3 wi = make_float3(dot(sd->I, X), dot(sd->I, Y), dot(sd->I, Z)); const float3 wo = make_float3(dot(omega_in, X), dot(omega_in, Y), dot(omega_in, Z)); + /* Treat as transparent material if intersection lies outside of the projected radius. */ + const float e2 = 1.0f - sqr(bsdf->extra->eccentricity); + const float radius = sqrtf(1.0f - e2 * sqr(sin_phi(wi))); + if (fabsf(bsdf->extra->geom.w) > radius) { +*pdf = 0.0f; +return zero_spectrum(); + } + /* evaluate */ const float3 R = bsdf_microfacet_hair_eval_r_elliptic(sc, wi, wo) + bsdf_microfacet_hair_eval_tt_trt_elliptic(kg, sc, wi, wo, sd->lcg_state); @@ -1157,12 +1170,6 @@ ccl_device int bsdf_microfacet_hair_sample_elliptic(const KernelGlobals kg, *eta = bsdf->eta; const float inv_eta = 1.0f / *eta; - if (bsdf->extra->R <= 0.0f && bsdf->extra->TT <= 0.0f && bsdf->extra->TRT <= 0.0f) { -/* early out for inactive lobe */ -*pdf = 0.0f; -return LABEL_NONE; - } - /* get local wi (convention is reversed from other hair bcsdfs) */ const float3 X = float4_to_float3(bsdf->extra->geom); float3 Y = sd->dPdu; @@ -1171,6 +1178,31 @@ ccl_device int bsdf_microfacet_hair_sample_elliptic(const KernelGlobals kg, const float3 wi = make_float3(dot(sd->I, X), dot(sd->I, Y), dot(sd->I, Z)); + /* get elliptical cross section characteristic */ + const float a = 1.0f; + const float b = bsdf->extra->eccentricity; + const float e2 = 1.0f - sqr(b / a); + + /* macronormal */ + const float2 sincos_phi_i = sincos_phi(wi); + const float sin_phi_i = sincos_phi_i.x; + const float cos_phi_i = sincos_phi_i.y; + const float d_i = sqrtf(1.0f - e2 * sqr(sin_phi_i)); + + /* Treat as transparent material if intersection lies outside of the projected radius. */ + if (fabsf(bsdf->extra->geom.w) > d_i) { +*omega_in = -sd->I; +*pdf = 1; +*eval = one_spectrum(); +return LABEL_TRANSMIT | LABEL_TRANSPARENT; + } + + if (bsdf->extra->R <= 0.0f && bsdf->extra->TT <= 0.0f && bsdf->extra->TRT <= 0.0f) { +/* early out for inactive lobe */ +*pdf = 0.0f; +return LABEL_NONE; + } + const float tilt = -bsdf->alpha; const float roughness = bsdf->roughness; const bool beckmann = (bsdf->model_type == NODE_MICROFACET_HAIR_ELLIPTIC_BECKMANN); @@ -1185,16 +1217,6 @@ ccl_device int bsdf_microfacet_hair_sample_elliptic(const KernelGlobals kg, const float2 sample_h3 = make_float2(lcg_step_float(>lcg_state), lcg_step_float(>lcg_state)); - /* get elliptical cross section characteristic */ - const float a = 1.0f; - const float b = bsdf->extra->eccentricity; - const float e2 = 1.0f - sqr(b / a); - - /* macronormal */ - const float2 sincos_phi_i = sincos_phi(wi); - const float sin_phi_i = sincos_phi_i.x; - const float cos_phi_i = sincos_phi_i.y; - const float d_i = sqrtf(1.0f - e2 * sqr(sin_phi_i)); const float h = d_i * (sample_h * 2.0f - 1.0f); const float gamma_mi = atan2f(cos_phi_i, -b / a * sin_phi_i) - acosf(h / sqrtf(sqr(cos_phi_i) + sqr(b / a * sin_phi_i))); ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [9c59a200b50] microfacet_hair: Add TODO for curve API
Commit: 9c59a200b5069382fb6378a60e6d77b6a1c0e82c Author: Weizhen Huang Date: Thu Dec 22 15:55:04 2022 +0100 Branches: microfacet_hair https://developer.blender.org/rB9c59a200b5069382fb6378a60e6d77b6a1c0e82c Add TODO for curve API === M intern/cycles/blender/curves.cpp === diff --git a/intern/cycles/blender/curves.cpp b/intern/cycles/blender/curves.cpp index 48cee230770..eb064361cc8 100644 --- a/intern/cycles/blender/curves.cpp +++ b/intern/cycles/blender/curves.cpp @@ -912,6 +912,7 @@ static void export_hair_curves(Scene *scene, std::optional b_attr_radius = find_curves_radius_attribute(b_curves); /* Evaluate geometry normals. */ + /* TODO: implement proper RNA curves API. */ const Curves *curves = (Curves *)b_curves.ptr.owner_id; const auto curves_geometry = blender::bke::CurvesGeometry::wrap(curves->geometry); const blender::VArray resolutions = curves_geometry.resolution(); ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [c80ff8a39db] microfacet_hair: Add comments to normal computations
Commit: c80ff8a39db4e2f30b447d48fa6585235d938450 Author: Weizhen Huang Date: Thu Dec 22 15:21:39 2022 +0100 Branches: microfacet_hair https://developer.blender.org/rBc80ff8a39db4e2f30b447d48fa6585235d938450 Add comments to normal computations === M intern/cycles/blender/curves.cpp === diff --git a/intern/cycles/blender/curves.cpp b/intern/cycles/blender/curves.cpp index 3b1ccbc8c45..48cee230770 100644 --- a/intern/cycles/blender/curves.cpp +++ b/intern/cycles/blender/curves.cpp @@ -926,6 +926,8 @@ static void export_hair_curves(Scene *scene, float3 prev_co = zero_float3(); float length = 0.0f; +/* TODO: It seems a waste of time to compute the normals of the subdivided curve, but only use + * those of the control points. Maybe the API of `evaluated_normals()` should be changed. */ const int resolution = resolutions[i]; const int evaluated_offset = evaluated_offsets[i]; ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [8125657606d] microfacet_hair: Pass dummy normal to elliptical hairs
Commit: 8125657606d994e67c714a5c51dbf1925cc638cb Author: Weizhen Huang Date: Thu Dec 22 15:05:00 2022 +0100 Branches: microfacet_hair https://developer.blender.org/rB8125657606d994e67c714a5c51dbf1925cc638cb Pass dummy normal to elliptical hairs === M intern/cycles/blender/curves.cpp M intern/cycles/kernel/closure/bsdf_hair_microfacet.h M intern/cycles/kernel/svm/closure.h M intern/cycles/scene/attribute.cpp M intern/cycles/scene/shader_nodes.cpp === diff --git a/intern/cycles/blender/curves.cpp b/intern/cycles/blender/curves.cpp index 6158ed78598..ea9e50befbb 100644 --- a/intern/cycles/blender/curves.cpp +++ b/intern/cycles/blender/curves.cpp @@ -272,10 +272,13 @@ static void ExportCurveSegments(Scene *scene, Hair *hair, ParticleCurveData *CDa if (hair->num_curves()) return; + Attribute *attr_normal = NULL; Attribute *attr_intercept = NULL; Attribute *attr_length = NULL; Attribute *attr_random = NULL; + if (hair->need_attribute(scene, ATTR_STD_VERTEX_NORMAL)) +attr_normal = hair->attributes.add(ATTR_STD_VERTEX_NORMAL); if (hair->need_attribute(scene, ATTR_STD_CURVE_INTERCEPT)) attr_intercept = hair->attributes.add(ATTR_STD_CURVE_INTERCEPT); if (hair->need_attribute(scene, ATTR_STD_CURVE_LENGTH)) @@ -325,6 +328,11 @@ static void ExportCurveSegments(Scene *scene, Hair *hair, ParticleCurveData *CDa num_curve_keys++; } + if (attr_normal != NULL) { +/* TODO: compute geometry normals. */ +attr_normal->add(make_float3(1.0f, 0.0f, 0.0f)); + } + if (attr_length != NULL) { attr_length->add(CData->curve_length[curve]); } @@ -881,10 +889,14 @@ static void export_hair_curves(Scene *scene, int *curve_shader = hair->get_curve_shader().data(); /* Add requested attributes. */ + float3 *attr_normal = NULL; float *attr_intercept = NULL; float *attr_length = NULL; float *attr_random = NULL; + if (hair->need_attribute(scene, ATTR_STD_VERTEX_NORMAL)) { +attr_normal = hair->attributes.add(ATTR_STD_VERTEX_NORMAL)->data_float3(); + } if (hair->need_attribute(scene, ATTR_STD_CURVE_INTERCEPT)) { attr_intercept = hair->attributes.add(ATTR_STD_CURVE_INTERCEPT)->data_float(); } @@ -912,6 +924,11 @@ static void export_hair_curves(Scene *scene, const float3 co = get_float3(b_attr_position.data[point_offset].vector()); const float radius = b_attr_radius ? b_attr_radius->data[point_offset].value() : 0.005f; + if (attr_normal) { +/* TODO: compute geometry normals. */ +attr_normal[point_offset] = make_float3(1.0f, 0.0f, 0.0f); + } + curve_keys[point_offset] = co; curve_radius[point_offset] = radius; diff --git a/intern/cycles/kernel/closure/bsdf_hair_microfacet.h b/intern/cycles/kernel/closure/bsdf_hair_microfacet.h index 32a163eb846..a037839c691 100644 --- a/intern/cycles/kernel/closure/bsdf_hair_microfacet.h +++ b/intern/cycles/kernel/closure/bsdf_hair_microfacet.h @@ -17,13 +17,6 @@ typedef struct MicrofacetHairExtra { float TRT; float eccentricity; - float twist_rate; - float attr_descr_intercept; - float attr_descr_length; - - float axis_rot; - float diffraction_weight; - float pad1, pad2, pad3; /* Geometry data. */ float4 geom; @@ -73,15 +66,20 @@ ccl_device int bsdf_microfacet_hair_setup(ccl_private ShaderData *sd, * the center, to grazing the other edge. This is the sine of the angle * between sd->Ng and Z, as seen from the tangent X. */ - /* TODO: we convert this value to a cosine later and discard the sign, so - * we could probably save some operations. */ float h = (sd->type & PRIMITIVE_CURVE_RIBBON) ? -sd->v : -dot(X, sd->Ng); kernel_assert(fabsf(h) < 1.0f + 1e-4f); kernel_assert(isfinite_safe(X)); kernel_assert(isfinite_safe(h)); - bsdf->extra->geom = make_float4(X.x, X.y, X.z, h); + if (bsdf->model_type == NODE_MICROFACET_HAIR_ELLIPTIC_GGX || + bsdf->model_type == NODE_MICROFACET_HAIR_ELLIPTIC_BECKMANN) { +/* Local frame is independent of the ray direction for elliptical hairs. */ +bsdf->extra->geom.w = h; + } + else { +bsdf->extra->geom = make_float4(X.x, X.y, X.z, h); + } return SD_BSDF | SD_BSDF_HAS_EVAL | SD_BSDF_NEEDS_LCG | SD_BSDF_HAS_TRANSMISSION; } @@ -1126,23 +1124,10 @@ ccl_device Spectrum bsdf_microfacet_hair_eval_elliptic(KernelGlobals kg, { /* get local wi(convention is reversed from other hair bcsdfs) */ ccl_private MicrofacetHairBSDF *bsdf = (ccl_private MicrofacetHairBSDF *)sc; - const float3 X0 = float4_to_float3(bsdf->extra->geom); - const float3 Y = safe_normalize(sd->dPdu); - const float3 Z0 = safe_normalize(cross(X0, Y)); - - /* rotate (Z,X) arou
[Bf-blender-cvs] [ba62e31b45f] microfacet_hair: Compute normal for new hair system
Commit: ba62e31b45f7a13d17f662da3e5faf89ad2718e1 Author: Weizhen Huang Date: Thu Dec 22 15:13:07 2022 +0100 Branches: microfacet_hair https://developer.blender.org/rBba62e31b45f7a13d17f662da3e5faf89ad2718e1 Compute normal for new hair system === M intern/cycles/blender/curves.cpp === diff --git a/intern/cycles/blender/curves.cpp b/intern/cycles/blender/curves.cpp index ea9e50befbb..3b1ccbc8c45 100644 --- a/intern/cycles/blender/curves.cpp +++ b/intern/cycles/blender/curves.cpp @@ -3,6 +3,7 @@ #include +#include "BKE_curves.hh" #include "blender/sync.h" #include "blender/util.h" @@ -910,6 +911,13 @@ static void export_hair_curves(Scene *scene, BL::FloatVectorAttribute b_attr_position = find_curves_position_attribute(b_curves); std::optional b_attr_radius = find_curves_radius_attribute(b_curves); + /* Evaluate geometry normals. */ + const Curves *curves = (Curves *)b_curves.ptr.owner_id; + const auto curves_geometry = blender::bke::CurvesGeometry::wrap(curves->geometry); + const blender::VArray resolutions = curves_geometry.resolution(); + const auto evaluated_normals = curves_geometry.evaluated_normals(); + const auto evaluated_offsets = curves_geometry.evaluated_offsets(); + /* Export curves and points. */ for (int i = 0; i < num_curves; i++) { const int first_point_index = b_curves.curve_offset_data[i].value(); @@ -918,6 +926,9 @@ static void export_hair_curves(Scene *scene, float3 prev_co = zero_float3(); float length = 0.0f; +const int resolution = resolutions[i]; +const int evaluated_offset = evaluated_offsets[i]; + /* Position and radius. */ for (int j = 0; j < num_points; j++) { const int point_offset = first_point_index + j; @@ -925,8 +936,8 @@ static void export_hair_curves(Scene *scene, const float radius = b_attr_radius ? b_attr_radius->data[point_offset].value() : 0.005f; if (attr_normal) { -/* TODO: compute geometry normals. */ -attr_normal[point_offset] = make_float3(1.0f, 0.0f, 0.0f); +const blender::float3 normal = evaluated_normals[evaluated_offset + j * resolution]; +attr_normal[point_offset] = make_float3(normal.x, normal.y, normal.z); } curve_keys[point_offset] = co; ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [5e21a0909c7] microfacet_hair: Cleanup: formatting and `fast_sincosf()` call
Commit: 5e21a0909c7a9b0ba3201771ae25136db4a2438d Author: Weizhen Huang Date: Tue Dec 20 12:05:35 2022 +0100 Branches: microfacet_hair https://developer.blender.org/rB5e21a0909c7a9b0ba3201771ae25136db4a2438d Cleanup: formatting and `fast_sincosf()` call === M intern/cycles/kernel/closure/bsdf_hair_microfacet.h === diff --git a/intern/cycles/kernel/closure/bsdf_hair_microfacet.h b/intern/cycles/kernel/closure/bsdf_hair_microfacet.h index 05d9917dcd7..32a163eb846 100644 --- a/intern/cycles/kernel/closure/bsdf_hair_microfacet.h +++ b/intern/cycles/kernel/closure/bsdf_hair_microfacet.h @@ -141,10 +141,9 @@ ccl_device_inline float2 dir_sph(const float3 w) /* Compute the vector direction given spherical coordinates */ ccl_device_inline float3 sph_dir(float theta, float gamma) { - float sin_theta = sinf(theta); - float cos_theta = cosf(theta); - float sin_gamma = sinf(gamma); - float cos_gamma = cosf(gamma); + float sin_theta, cos_theta, sin_gamma, cos_gamma; + fast_sincosf(theta, _theta, _theta); + fast_sincosf(gamma, _gamma, _gamma); return make_float3(sin_gamma * cos_theta, sin_theta, cos_gamma * cos_theta); } @@ -153,38 +152,35 @@ ccl_device_inline float3 sph_dir(float theta, float gamma) /* Conversion between gamma and phi. Notations see Figure 5 in the paper. */ ccl_device float to_phi(float gamma, float a, float b) { - float sin_gamma = sinf(gamma); - float cos_gamma = cosf(gamma); + float sin_gamma, cos_gamma; + fast_sincosf(gamma, _gamma, _gamma); return atan2f(b * sin_gamma, a * cos_gamma); } ccl_device float to_gamma(float phi, float a, float b) { - float sin_phi = sinf(phi); - float cos_phi = cosf(phi); + float sin_phi, cos_phi; + fast_sincosf(phi, _phi, _phi); return atan2f(a * sin_phi, b * cos_phi); } /* Compute the coordinate on the ellipse, given gamma, the semi-major and semi-minor axes. */ ccl_device float2 to_point(float gamma, float a, float b) { - float sin_gamma = sinf(gamma); - float cos_gamma = cosf(gamma); + float sin_gamma, cos_gamma; + fast_sincosf(gamma, _gamma, _gamma); return make_float2(a * sin_gamma, b * cos_gamma); } /* Compute the vector direction given by theta and gamma. */ ccl_device float3 sphg_dir(float theta, float gamma, float a, float b) { - float sin_theta = sinf(theta); - float cos_theta = cosf(theta); - float sin_gamma = sinf(gamma); - float cos_gamma = cosf(gamma); + float sin_theta, cos_theta, sin_gamma, cos_gamma; + fast_sincosf(theta, _theta, _theta); + fast_sincosf(gamma, _gamma, _gamma); float tan_gamma = sin_gamma / cos_gamma; float tan_phi = b / a * tan_gamma; - float cos_phi = 1.0f / sqrtf(sqr(tan_phi) + 1.0f); - if (cos_gamma < 0.0f) -cos_phi = -cos_phi; + float cos_phi = signf(cos_gamma) / sqrtf(sqr(tan_phi) + 1.0f); float sin_phi = cos_phi * tan_phi; return make_float3(sin_phi * cos_theta, sin_theta, cos_phi * cos_theta); } @@ -368,8 +364,8 @@ ccl_device float3 bsdf_microfacet_hair_eval_r_circular(ccl_private const ShaderC const float roughness_squared = roughness * roughness; -const float sm = sinf(tilt); -const float cm = cosf(tilt); +float sm, cm; +fast_sincosf(tilt, , ); const float C = sqrtf(1.0f - roughness_squared); const float A = cm * cos_theta(wh) * C; @@ -379,10 +375,9 @@ ccl_device float3 bsdf_microfacet_hair_eval_r_circular(ccl_private const ShaderC const float tmp1 = 1.0f / sqrtf(sqr(B - 1.0f) - A2); const float tmp2 = 1.0f / sqrtf(sqr(B + 1.0f) - A2); -const float smax = sinf(d_max); -const float cmax = cosf(d_max); -const float smin = sinf(d_min); -const float cmin = cosf(d_min); +float smax, cmax, smin, cmin; +fast_sincosf(d_max, , ); +fast_sincosf(d_min, , ); const float tmax = smax / (1.0f + cmax); const float tmin = smin / (1.0f + cmin); @@ -492,8 +487,9 @@ ccl_device float3 bsdf_microfacet_hair_eval_tt_trt_circular(KernelGlobals kg, const float3 wmt = sph_dir(-tilt, phi_mt); const float G1 = G(beckmann, roughness, wi, -wt, wmi, wh1); -if (G1 == 0.0f || !microfacet_visible(wi, -wt, make_float3(wmi.x, 0.0f, wmi.z), wh1)) +if (G1 == 0.0f || !microfacet_visible(wi, -wt, make_float3(wmi.x, 0.0f, wmi.z), wh1)) { continue; +} /* Simpson's rule weight */ float weight = (i == 0 || i == intervals - 1) ? 0.5f : (i % 2 + 1); @@ -546,13 +542,14 @@ ccl_device float3 bsdf_microfacet_hair_eval_tt_trt_circular(KernelGlobals kg, float3 wtr = -reflect(wt, wh2); float G2 = G(beckmann, roughness, -wt, -wtr, wmt, wh2); - if (G2 == 0.0f || - microfacet_visible(-wt, -wtr, make_float3(wmt.x, 0.0f, wmt.z), wh2) == 0.0f) + if (G2 == 0.0f || !microfacet_visible(-wt, -wtr, make_float3(wmt.x, 0.0f, wmt.z), wh2)) { continue; + } /* total inter
[Bf-blender-cvs] [63d51d33050] microfacet_hair: Cleanup: formatting float
Commit: 63d51d33050f80be08564b8432acf5994be6898e Author: Weizhen Huang Date: Mon Dec 19 20:22:37 2022 +0100 Branches: microfacet_hair https://developer.blender.org/rB63d51d33050f80be08564b8432acf5994be6898e Cleanup: formatting float === M intern/cycles/kernel/closure/bsdf_hair_microfacet.h === diff --git a/intern/cycles/kernel/closure/bsdf_hair_microfacet.h b/intern/cycles/kernel/closure/bsdf_hair_microfacet.h index 04d9837365e..05d9917dcd7 100644 --- a/intern/cycles/kernel/closure/bsdf_hair_microfacet.h +++ b/intern/cycles/kernel/closure/bsdf_hair_microfacet.h @@ -182,8 +182,8 @@ ccl_device float3 sphg_dir(float theta, float gamma, float a, float b) float cos_gamma = cosf(gamma); float tan_gamma = sin_gamma / cos_gamma; float tan_phi = b / a * tan_gamma; - float cos_phi = 1.f / sqrtf(sqr(tan_phi) + 1.f); - if (cos_gamma < 0.f) + float cos_phi = 1.0f / sqrtf(sqr(tan_phi) + 1.0f); + if (cos_gamma < 0.0f) cos_phi = -cos_phi; float sin_phi = cos_phi * tan_phi; return make_float3(sin_phi * cos_theta, sin_theta, cos_phi * cos_theta); @@ -217,7 +217,7 @@ ccl_device_inline float3 sample_wh(KernelGlobals kg, /* Check micronormal/mesonormal direct visiblity from v */ ccl_device_inline bool microfacet_visible(const float3 v, const float3 m, const float3 h) { - return (dot(v, h) > 0.f && dot(v, m) > 0.f); + return (dot(v, h) > 0.0f && dot(v, m) > 0.0f); } /* Check micronormal/mesonormal direct visiblity from wi and wo */ @@ -237,11 +237,11 @@ ccl_device_inline float smith_g1( /* Assume consistent orientation (can't see the back of the microfacet from the front and vice * versa) */ float cos_vm = dot(v, m); - if (dot(v, h) <= 0.f || cos_vm <= 0.f) -return 0.f; + if (dot(v, h) <= 0.0f || cos_vm <= 0.0f) +return 0.0f; return beckmann ? bsdf_beckmann_G1(roughness, cos_vm) : -2.f / (1.f + sqrtf(1.0f + sqr(roughness) * (1.0f / sqr(cos_vm) - 1.0f))); +2.0f / (1.0f + sqrtf(1.0f + sqr(roughness) * (1.0f / sqr(cos_vm) - 1.0f))); } /* Smith's separable shadowing-masking approximation */ @@ -265,14 +265,15 @@ ccl_device float D(const bool beckmann, const float roughness, const float3 m, c const float cos_theta2 = sqr(cos_theta); if (beckmann) { -result = expf((1.f - 1.f / cos_theta2) / roughness2) / (M_PI_F * roughness2 * sqr(cos_theta2)); +result = expf((1.0f - 1.0f / cos_theta2) / roughness2) / + (M_PI_F * roughness2 * sqr(cos_theta2)); } else { /* GGX */ -result = roughness2 / (M_PI_F * sqr(1.f + (roughness2 - 1.f) * cos_theta2)); +result = roughness2 / (M_PI_F * sqr(1.0f + (roughness2 - 1.0f) * cos_theta2)); } /* Prevent potential numerical issues in other stages of the model */ - return (result * cos_theta > 1e-20f) ? result : 0.f; + return (result * cos_theta > 1e-20f) ? result : 0.0f; } /* Compute fresnel reflection. Also return the dot product of the refracted ray and the normal as @@ -282,18 +283,18 @@ ccl_device float fresnel(float cos_theta_i, float eta, ccl_private float *cos_th kernel_assert(!isnan_safe(cos_theta_i)); /* Special cases. */ - if (eta == 1.f) { -return 0.f; + if (eta == 1.0f) { +return 0.0f; } - if (cos_theta_i == 0.f) { -return 1.f; + if (cos_theta_i == 0.0f) { +return 1.0f; } cos_theta_i = fabsf(cos_theta_i); /* Using Snell's law, calculate the squared cosine of the angle between the surface normal and * the transmitted ray. */ - float cos_theta_t_sqr = 1.f - (1.f - cos_theta_i * cos_theta_i) / (eta * eta); + float cos_theta_t_sqr = 1.0f - (1.0f - cos_theta_i * cos_theta_i) / (eta * eta); *cos_theta_t = safe_sqrtf(cos_theta_t_sqr); if (cos_theta_t_sqr <= 0) { @@ -305,7 +306,7 @@ ccl_device float fresnel(float cos_theta_i, float eta, ccl_private float *cos_th float a_s = (cos_theta_i - eta * (*cos_theta_t)) / (cos_theta_i + eta * (*cos_theta_t)); float a_p = (*cos_theta_t - eta * cos_theta_i) / (*cos_theta_t + eta * cos_theta_i); - float r = .5f * (sqr(a_s) + sqr(a_p)); + float r = 0.5f * (sqr(a_s) + sqr(a_p)); /* Adjust the sign of the transmitted direction to be relative to the surface normal. */ *cos_theta_t = -(*cos_theta_t); @@ -333,7 +334,7 @@ ccl_device float3 bsdf_microfacet_hair_eval_r_circular(ccl_private const ShaderC const bool analytical_ggx = (bsdf->model_type == NODE_MICROFACET_HAIR_CIRCULAR_GGX_ANALYTIC); float3 R = zero_float3(); - if (bsdf->extra->R <= 0.f) + if (bsdf->extra->R <= 0.0f) return R; const float3 wh = normalize(wi + wo); @@ -341,23 +342,23 @@ ccl_device float3 bsdf_microfacet_hair_eval_r_circular(ccl_private const ShaderC /* dot(wi, wmi) > 0 */ const float tan_tilt
[Bf-blender-cvs] [b08064d8672] microfacet_hair: Start with less parameters
Commit: b08064d867255533ae243ee7945452adfea6fc97 Author: Weizhen Huang Date: Mon Dec 19 11:19:41 2022 +0100 Branches: microfacet_hair https://developer.blender.org/rBb08064d867255533ae243ee7945452adfea6fc97 Start with less parameters === M intern/cycles/kernel/closure/bsdf_hair_microfacet.h M intern/cycles/kernel/svm/closure.h M intern/cycles/scene/shader_nodes.cpp M source/blender/nodes/shader/nodes/node_shader_bsdf_hair_microfacet.cc === diff --git a/intern/cycles/kernel/closure/bsdf_hair_microfacet.h b/intern/cycles/kernel/closure/bsdf_hair_microfacet.h index 794c6930b96..92d32db6872 100644 --- a/intern/cycles/kernel/closure/bsdf_hair_microfacet.h +++ b/intern/cycles/kernel/closure/bsdf_hair_microfacet.h @@ -1169,14 +1169,11 @@ ccl_device int bsdf_microfacet_hair_sample_elliptic(const KernelGlobals kg, const float3 Y = safe_normalize(sd->dPdu); const float3 Z0 = safe_normalize(cross(X0, Y)); - /* rotate (Z,X) around Y */ - const float curve_parameter = bsdf->extra->attr_descr_intercept; - const float curve_length = bsdf->extra->attr_descr_length; - const float curve_twist_rate = bsdf->extra->twist_rate; - const float curve_twist_start = bsdf->extra->axis_rot; + /* const float curve_parameter = bsdf->extra->attr_descr_intercept; */ + /* const float curve_length = bsdf->extra->attr_descr_length; */ - const float twist_angle = M_2PI_F * (curve_twist_start + - curve_twist_rate * curve_parameter * curve_length); + /* TODO: compute the ellipse orientation based on the curve normal or user-defined normal? */ + const float twist_angle = 0.0f; const float sin_twist_angle = sinf(twist_angle); const float cos_twist_angle = cosf(twist_angle); diff --git a/intern/cycles/kernel/svm/closure.h b/intern/cycles/kernel/svm/closure.h index 55deefd136b..2db8ccbfeee 100644 --- a/intern/cycles/kernel/svm/closure.h +++ b/intern/cycles/kernel/svm/closure.h @@ -1023,20 +1023,14 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg, if (model_type == NODE_MICROFACET_HAIR_ELLIPTIC_GGX || model_type == NODE_MICROFACET_HAIR_ELLIPTIC_BECKMANN) { - uint eccentricity_ofs, twist_rate_ofs, axis_ofs; - svm_unpack_node_uchar4( - data_node7.x, _ofs, _rate_ofs, _ofs, ); + uint eccentricity_ofs; + svm_unpack_node_uchar4(data_node7.x, _ofs, , , ); float eccentricity = stack_load_float_default(stack, eccentricity_ofs, data_node7.y); - float twist_rate = stack_load_float_default(stack, twist_rate_ofs, data_node7.z); - float axis_rot = stack_load_float_default(stack, axis_ofs, data_node7.w); /* Eccentricity */ bsdf->extra->eccentricity = (eccentricity > 1.f) ? 1.f / eccentricity : eccentricity; - /* Angular twist rate per unit length */ - bsdf->extra->twist_rate = twist_rate; - const AttributeDescriptor attr_descr_intercept = find_attribute(kg, sd, data_node4.z); bsdf->extra->attr_descr_intercept = curve_attribute_float( kg, sd, attr_descr_intercept, NULL, NULL); @@ -1044,10 +1038,6 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg, const AttributeDescriptor attr_descr_length = find_attribute(kg, sd, data_node4.w); bsdf->extra->attr_descr_length = curve_attribute_float( kg, sd, attr_descr_length, NULL, NULL); - - bsdf->extra->axis_rot = axis_rot > 0.0f ? - random * axis_rot : - -axis_rot; // allowing this negative mode for debugging } sd->flag |= bsdf_microfacet_hair_setup(sd, bsdf); diff --git a/intern/cycles/scene/shader_nodes.cpp b/intern/cycles/scene/shader_nodes.cpp index 5b81c8dbe0c..345e8e8828b 100644 --- a/intern/cycles/scene/shader_nodes.cpp +++ b/intern/cycles/scene/shader_nodes.cpp @@ -3666,8 +3666,6 @@ NODE_DEFINE(MicrofacetHairBsdfNode) SocketType::VECTOR); SOCKET_IN_FLOAT(eccentricity, "Eccentricity", 0.85f); - SOCKET_IN_FLOAT(random_axis, "Random Axis", 0.0f); - SOCKET_IN_FLOAT(twist_rate, "Twist Rate", 0.0f); SOCKET_IN_FLOAT(offset, "Offset", 2.f * M_PI_F / 180.f); SOCKET_IN_FLOAT(roughness, "Roughness", 0.3f); @@ -3729,8 +3727,6 @@ void MicrofacetHairBsdfNode::compile(SVMCompiler ) ShaderInput *Blur_in = input("Blur"); ShaderInput *eccentricity_in = input("Eccentricity"); - ShaderInput *random_axis_in = input("Random Axis"); - ShaderInput *twist_rate_in = input("Twist Rate"); int color_ofs = compiler.stack_assign(
[Bf-blender-cvs] [d96320c2da6] microfacet_hair: Cleanup: pass pointer of variable that will be modified
Commit: d96320c2da6a20f332612220c69e2a13eaee3853 Author: Weizhen Huang Date: Mon Dec 19 20:08:36 2022 +0100 Branches: microfacet_hair https://developer.blender.org/rBd96320c2da6a20f332612220c69e2a13eaee3853 Cleanup: pass pointer of variable that will be modified === M intern/cycles/kernel/closure/bsdf_hair_microfacet.h === diff --git a/intern/cycles/kernel/closure/bsdf_hair_microfacet.h b/intern/cycles/kernel/closure/bsdf_hair_microfacet.h index 44755372159..04d9837365e 100644 --- a/intern/cycles/kernel/closure/bsdf_hair_microfacet.h +++ b/intern/cycles/kernel/closure/bsdf_hair_microfacet.h @@ -277,7 +277,7 @@ ccl_device float D(const bool beckmann, const float roughness, const float3 m, c /* Compute fresnel reflection. Also return the dot product of the refracted ray and the normal as * `cos_theta_t`, as it is used when computing the direction of the refracted ray. */ -ccl_device float fresnel(float cos_theta_i, float eta, ccl_private float _theta_t) +ccl_device float fresnel(float cos_theta_i, float eta, ccl_private float *cos_theta_t) { kernel_assert(!isnan_safe(cos_theta_i)); @@ -294,7 +294,7 @@ ccl_device float fresnel(float cos_theta_i, float eta, ccl_private float _th /* Using Snell's law, calculate the squared cosine of the angle between the surface normal and * the transmitted ray. */ float cos_theta_t_sqr = 1.f - (1.f - cos_theta_i * cos_theta_i) / (eta * eta); - cos_theta_t = safe_sqrtf(cos_theta_t_sqr); + *cos_theta_t = safe_sqrtf(cos_theta_t_sqr); if (cos_theta_t_sqr <= 0) { /* Total internal reflection. */ @@ -302,13 +302,13 @@ ccl_device float fresnel(float cos_theta_i, float eta, ccl_private float _th } /* Amplitudes of reflected waves. */ - float a_s = (cos_theta_i - eta * cos_theta_t) / (cos_theta_i + eta * cos_theta_t); - float a_p = (cos_theta_t - eta * cos_theta_i) / (cos_theta_t + eta * cos_theta_i); + float a_s = (cos_theta_i - eta * (*cos_theta_t)) / (cos_theta_i + eta * (*cos_theta_t)); + float a_p = (*cos_theta_t - eta * cos_theta_i) / (*cos_theta_t + eta * cos_theta_i); float r = .5f * (sqr(a_s) + sqr(a_p)); /* Adjust the sign of the transmitted direction to be relative to the surface normal. */ - cos_theta_t = -cos_theta_t; + *cos_theta_t = -(*cos_theta_t); return r; } @@ -480,7 +480,7 @@ ccl_device float3 bsdf_microfacet_hair_eval_tt_trt_circular(KernelGlobals kg, } float cos_theta_t1; -const float T1 = 1.f - fresnel(dot_wi_wh1, eta, cos_theta_t1); +const float T1 = 1.f - fresnel(dot_wi_wh1, eta, _theta_t1); /* refraction at the first interface */ const float3 wt = -refract_angle(wi, wh1, cos_theta_t1, inv_eta); @@ -689,7 +689,7 @@ ccl_device int bsdf_microfacet_hair_sample_circular(const KernelGlobals kg, float3 TRT = zero_float3(); float cos_theta_t1; - float R1 = fresnel(dot(wi, wh1), *eta, cos_theta_t1); + float R1 = fresnel(dot(wi, wh1), *eta, _theta_t1); float3 R = make_float3(bsdf->extra->R * R1); /* sample TT lobe */ @@ -718,7 +718,7 @@ ccl_device int bsdf_microfacet_hair_sample_circular(const KernelGlobals kg, const float3 A_t = exp(-mu_a * (2.f * cos_gamma_t / cos_theta_wt)); float cos_theta_t2; -const float R2 = fresnel(dot(-wt, wh2), inv_eta, cos_theta_t2); +const float R2 = fresnel(dot(-wt, wh2), inv_eta, _theta_t2); const float3 T1 = make_float3(1.f - R1); const float3 T2 = make_float3(1.f - R2); @@ -736,7 +736,7 @@ ccl_device int bsdf_microfacet_hair_sample_circular(const KernelGlobals kg, wh3 = sample_wh(kg, beckmann, roughness, wtr, wmtr, sample_h3); float cos_theta_t3; -const float R3 = fresnel(dot(wtr, wh3), inv_eta, cos_theta_t3); +const float R3 = fresnel(dot(wtr, wh3), inv_eta, _theta_t3); wtrt = -refract_angle(wtr, wh3, cos_theta_t3, *eta); @@ -983,7 +983,7 @@ ccl_device float3 bsdf_microfacet_hair_eval_tt_trt_elliptic(KernelGlobals kg, } float cos_theta_t1; -const float T1 = 1.f - fresnel(dot_wi_wh1, eta, cos_theta_t1); +const float T1 = 1.f - fresnel(dot_wi_wh1, eta, _theta_t1); /* refraction at the first interface */ const float3 wt = -refract_angle(wi, wh1, cos_theta_t1, inv_eta); @@ -1236,7 +1236,7 @@ ccl_device int bsdf_microfacet_hair_sample_elliptic(const KernelGlobals kg, float3 TRT = zero_float3(); float cos_theta_t1; - const float R1 = fresnel(dot(wi, wh1), *eta, cos_theta_t1); + const float R1 = fresnel(dot(wi, wh1), *eta, _theta_t1); float3 R = make_float3(bsdf->extra->R * R1); /* sample TT lobe */ @@ -1264,7 +1264,7 @@ ccl_device int bsdf_microfacet_hair_sample_elliptic(const KernelGlobals kg, const float3 A_t = exp(-mu_a * len(pi - pt) / cos_theta(wt)); float cos_theta_t2; -const float R2 = fresnel(dot(-wt, wh2), inv_et
[Bf-blender-cvs] [028918661a6] microfacet_hair: Fix variable passed to `fresnel()` being `NaN` sometimes
Commit: 028918661a6d36c95e607e5beafadfc4f57bff9a Author: Weizhen Huang Date: Mon Dec 19 20:03:03 2022 +0100 Branches: microfacet_hair https://developer.blender.org/rB028918661a6d36c95e607e5beafadfc4f57bff9a Fix variable passed to `fresnel()` being `NaN` sometimes === M intern/cycles/kernel/closure/bsdf_hair_microfacet.h === diff --git a/intern/cycles/kernel/closure/bsdf_hair_microfacet.h b/intern/cycles/kernel/closure/bsdf_hair_microfacet.h index 0f19cd83af6..44755372159 100644 --- a/intern/cycles/kernel/closure/bsdf_hair_microfacet.h +++ b/intern/cycles/kernel/closure/bsdf_hair_microfacet.h @@ -279,7 +279,7 @@ ccl_device float D(const bool beckmann, const float roughness, const float3 m, c * `cos_theta_t`, as it is used when computing the direction of the refracted ray. */ ccl_device float fresnel(float cos_theta_i, float eta, ccl_private float _theta_t) { - kernel_assert(cos_theta_i >= 0.f); /* FIXME: cos_theta_i could be NaN. */ + kernel_assert(!isnan_safe(cos_theta_i)); /* Special cases. */ if (eta == 1.f) { @@ -444,10 +444,10 @@ ccl_device float3 bsdf_microfacet_hair_eval_tt_trt_circular(KernelGlobals kg, /* dot(wi, wmi) > 0 */ const float tan_tilt = tanf(tilt); - float phi_m_max = acosf(fmaxf(-tan_tilt * tan_theta(wi), 0.f)); + const float phi_m_max = acosf(fmaxf(-tan_tilt * tan_theta(wi), 0.f)) - 1e-3f; if (isnan_safe(phi_m_max)) return zero_float3(); - float phi_m_min = -phi_m_max; + const float phi_m_min = -phi_m_max; /* dot(wo, wmo) < 0 */ float tmp1 = acosf(fminf(tan_tilt * tan_theta(wo), 0.f)); @@ -475,8 +475,9 @@ ccl_device float3 bsdf_microfacet_hair_eval_tt_trt_circular(KernelGlobals kg, const float3 wh1 = sample_wh(kg, beckmann, roughness, wi, wmi, sample1); const float dot_wi_wh1 = dot(wi, wh1); -if (dot_wi_wh1 <= 1e-5f) +if (!(dot_wi_wh1 > 0)) { continue; +} float cos_theta_t1; const float T1 = 1.f - fresnel(dot_wi_wh1, eta, cos_theta_t1); @@ -534,8 +535,9 @@ ccl_device float3 bsdf_microfacet_hair_eval_tt_trt_circular(KernelGlobals kg, float3 wh2 = sample_wh(kg, beckmann, roughness, -wt, wmt, sample2); const float cos_th2 = dot(-wt, wh2); - if (cos_th2 <= 1e-5f) + if (!(cos_th2 > 0)) { continue; + } const float R2 = fresnel_dielectric_cos(cos_th2, inv_eta); float3 wtr = -reflect(wt, wh2); @@ -678,7 +680,7 @@ ccl_device int bsdf_microfacet_hair_sample_circular(const KernelGlobals kg, const float3 wr = -reflect(wi, wh1); /* ensure that this is a valid sample */ - if (dot(wr, wh1) <= 0.f || dot(wr, wmi) <= 0.f || !microfacet_visible(wi, wr, wmi_, wh1)) { + if (!(dot(wr, wh1) > 0.f) || !(dot(wr, wmi) > 0.f) || !microfacet_visible(wi, wr, wmi_, wh1)) { *pdf = 0.f; return LABEL_NONE; } @@ -831,6 +833,7 @@ ccl_device float3 bsdf_microfacet_hair_eval_r_elliptic(ccl_private const ShaderC /* get elliptical cross section characteristic */ const float a = 1.f; + /* TODO: rename this as aspect ratio? e is in [0, 0.85], b is in [0.52, 1]. */ const float b = bsdf->extra->eccentricity; const float e2 = 1.f - sqr(b / a); @@ -865,8 +868,8 @@ ccl_device float3 bsdf_microfacet_hair_eval_r_elliptic(ccl_private const ShaderC phi_m_max1 -= M_2PI_F; } - const float phi_m_min = fmaxf(phi_m_min1, phi_m_min2) + .001f; - const float phi_m_max = fminf(phi_m_max1, phi_m_max2) - .001f; + const float phi_m_min = fmaxf(phi_m_min1, phi_m_min2) + 1e-3f; + const float phi_m_max = fminf(phi_m_max1, phi_m_max2) - 1e-3f; if (phi_m_min > phi_m_max) return R; @@ -950,8 +953,8 @@ ccl_device float3 bsdf_microfacet_hair_eval_tt_trt_elliptic(KernelGlobals kg, const float b = bsdf->extra->eccentricity; const float e2 = 1.f - sqr(b / a); - float gamma_m_min = to_gamma(phi_m_min, a, b); - float gamma_m_max = to_gamma(phi_m_max, a, b); + float gamma_m_min = to_gamma(phi_m_min, a, b) + 1e-3f; + float gamma_m_max = to_gamma(phi_m_max, a, b) - 1e-3f; if (gamma_m_max < gamma_m_min) gamma_m_max += M_2PI_F; @@ -975,8 +978,9 @@ ccl_device float3 bsdf_microfacet_hair_eval_tt_trt_elliptic(KernelGlobals kg, const float3 wh1 = sample_wh(kg, beckmann, roughness, wi, wmi, sample1); const float dot_wi_wh1 = dot(wi, wh1); -if (dot_wi_wh1 <= 1e-5f) +if (!(dot_wi_wh1 > 0)) { continue; +} float cos_theta_t1; const float T1 = 1.f - fresnel(dot_wi_wh1, eta, cos_theta_t1); @@ -997,12 +1001,14 @@ ccl_device float3 bsdf_microfacet_hair_eval_tt_trt_elliptic(KernelGlobals kg, const float2 pi = to_point(gamma_mi, a, b); const float2 pt = to_point(gamma_mt + M_PI_F, a, b); +/* TODO: check the definition of mu_a. */ +/* TODO: exp -> expf */ const float3 A
[Bf-blender-cvs] [a8608aab3da] microfacet_hair: Merge branch 'master' into microfacet_hair
Commit: a8608aab3da8b0d82376d9cdff4368fc1617ff4f Author: Weizhen Huang Date: Mon Dec 19 20:09:43 2022 +0100 Branches: microfacet_hair https://developer.blender.org/rBa8608aab3da8b0d82376d9cdff4368fc1617ff4f Merge branch 'master' into microfacet_hair === === ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [bf0075f8867] microfacet_hair: Cleanup: delete unused variables
Commit: bf0075f88670062e0858876d5f9e126dc48b37c4 Author: Weizhen Huang Date: Mon Dec 19 19:22:29 2022 +0100 Branches: microfacet_hair https://developer.blender.org/rBbf0075f88670062e0858876d5f9e126dc48b37c4 Cleanup: delete unused variables === M intern/cycles/kernel/closure/bsdf_hair_microfacet.h === diff --git a/intern/cycles/kernel/closure/bsdf_hair_microfacet.h b/intern/cycles/kernel/closure/bsdf_hair_microfacet.h index 6d754c533d1..0f19cd83af6 100644 --- a/intern/cycles/kernel/closure/bsdf_hair_microfacet.h +++ b/intern/cycles/kernel/closure/bsdf_hair_microfacet.h @@ -397,10 +397,7 @@ ccl_device float3 bsdf_microfacet_hair_eval_r_circular(ccl_private const ShaderC integral = roughness_squared * M_1_PI_F * 0.5f * (temp1 + temp2 + temp3 + temp4); } - else { -/* falls back to numerical integration */ -const float phi_i = dir_phi(wi); - + else { /* falls back to numerical integration */ /* initial sample resolution */ float res = roughness * .7f; const float scale = (phi_m_max - phi_m_min) * .5f; @@ -457,8 +454,6 @@ ccl_device float3 bsdf_microfacet_hair_eval_tt_trt_circular(KernelGlobals kg, if (isnan_safe(tmp1)) return zero_float3(); - const float phi_i = dir_phi(wi); - const float3 mu_a = bsdf->sigma; const float inv_eta = 1.f / eta; @@ -880,8 +875,6 @@ ccl_device float3 bsdf_microfacet_hair_eval_r_elliptic(ccl_private const ShaderC if (gamma_m_max < gamma_m_min) gamma_m_max += M_2PI_F; - const float gamma_i = to_gamma(phi_i, a, b); - /* initial sample resolution */ float res = roughness * .7f; const float scale = (gamma_m_max - gamma_m_min) * .5f; @@ -962,8 +955,6 @@ ccl_device float3 bsdf_microfacet_hair_eval_tt_trt_elliptic(KernelGlobals kg, if (gamma_m_max < gamma_m_min) gamma_m_max += M_2PI_F; - const float gamma_i = to_gamma(phi_i, a, b); - float res = roughness * .8f; const float scale = (gamma_m_max - gamma_m_min) * .5f; size_t intervals = 2 * (size_t)ceilf(scale / res) + 1; ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [0c075821693] microfacet_hair: Cleanup: minor API change for `sample_wh()``
Commit: 0c0758216933fbff816addafd2335ab54c89b27a Author: Weizhen Huang Date: Mon Dec 19 19:18:42 2022 +0100 Branches: microfacet_hair https://developer.blender.org/rB0c0758216933fbff816addafd2335ab54c89b27a Cleanup: minor API change for `sample_wh()`` === M intern/cycles/kernel/closure/bsdf_hair_microfacet.h === diff --git a/intern/cycles/kernel/closure/bsdf_hair_microfacet.h b/intern/cycles/kernel/closure/bsdf_hair_microfacet.h index 92d32db6872..6d754c533d1 100644 --- a/intern/cycles/kernel/closure/bsdf_hair_microfacet.h +++ b/intern/cycles/kernel/closure/bsdf_hair_microfacet.h @@ -197,8 +197,7 @@ ccl_device_inline float3 sample_wh(KernelGlobals kg, const float roughness, const float3 wi, const float3 wm, - const float randu, - const float randv) + const float2 rand) { /* Coordinate transformation for microfacet sampling */ float3 s, t; @@ -209,7 +208,7 @@ ccl_device_inline float3 sample_wh(KernelGlobals kg, float G1o; const float3 wh_wm = microfacet_sample_stretched( - kg, wi_wm, roughness, roughness, randu, randv, beckmann, ); + kg, wi_wm, roughness, roughness, rand.x, rand.y, beckmann, ); const float3 wh = wh_wm.x * s + wh_wm.y * t + wh_wm.z * n; return wh; @@ -479,7 +478,7 @@ ccl_device float3 bsdf_microfacet_hair_eval_tt_trt_circular(KernelGlobals kg, const float2 sample1 = make_float2(lcg_step_float(_quadrature), lcg_step_float(_quadrature)); -const float3 wh1 = sample_wh(kg, beckmann, roughness, wi, wmi, sample1.x, sample1.y); +const float3 wh1 = sample_wh(kg, beckmann, roughness, wi, wmi, sample1); const float dot_wi_wh1 = dot(wi, wh1); if (dot_wi_wh1 <= 1e-5f) continue; @@ -537,7 +536,7 @@ ccl_device float3 bsdf_microfacet_hair_eval_tt_trt_circular(KernelGlobals kg, const float2 sample2 = make_float2(lcg_step_float(_quadrature), lcg_step_float(_quadrature)); - float3 wh2 = sample_wh(kg, beckmann, roughness, -wt, wmt, sample2.x, sample2.y); + float3 wh2 = sample_wh(kg, beckmann, roughness, -wt, wmt, sample2); const float cos_th2 = dot(-wt, wh2); if (cos_th2 <= 1e-5f) @@ -680,7 +679,7 @@ ccl_device int bsdf_microfacet_hair_sample_circular(const KernelGlobals kg, } /* sample R lobe */ - const float3 wh1 = sample_wh(kg, beckmann, roughness, wi, wmi, sample_h1.x, sample_h1.y); + const float3 wh1 = sample_wh(kg, beckmann, roughness, wi, wmi, sample_h1); const float3 wr = -reflect(wi, wh1); /* ensure that this is a valid sample */ @@ -706,7 +705,7 @@ ccl_device int bsdf_microfacet_hair_sample_circular(const KernelGlobals kg, const float3 wmt = sph_dir(-tilt, phi_mt); const float3 wmt_ = sph_dir(0.f, phi_mt); - const float3 wh2 = sample_wh(kg, beckmann, roughness, -wt, wmt, sample_h2.x, sample_h2.y); + const float3 wh2 = sample_wh(kg, beckmann, roughness, -wt, wmt, sample_h2); const float3 wtr = -reflect(wt, wh2); float3 wh3; @@ -737,7 +736,7 @@ ccl_device int bsdf_microfacet_hair_sample_circular(const KernelGlobals kg, wmtr = sph_dir(-tilt, phi_mtr); wmtr_ = sph_dir(0.f, phi_mtr); -wh3 = sample_wh(kg, beckmann, roughness, wtr, wmtr, sample_h3.x, sample_h3.y); +wh3 = sample_wh(kg, beckmann, roughness, wtr, wmtr, sample_h3); float cos_theta_t3; const float R3 = fresnel(dot(wtr, wh3), inv_eta, cos_theta_t3); @@ -983,7 +982,7 @@ ccl_device float3 bsdf_microfacet_hair_eval_tt_trt_elliptic(KernelGlobals kg, const float2 sample1 = make_float2(lcg_step_float(_quadrature), lcg_step_float(_quadrature)); -const float3 wh1 = sample_wh(kg, beckmann, roughness, wi, wmi, sample1.x, sample1.y); +const float3 wh1 = sample_wh(kg, beckmann, roughness, wi, wmi, sample1); const float dot_wi_wh1 = dot(wi, wh1); if (dot_wi_wh1 <= 1e-5f) continue; @@ -1047,7 +1046,7 @@ ccl_device float3 bsdf_microfacet_hair_eval_tt_trt_elliptic(KernelGlobals kg, const float2 sample2 = make_float2(lcg_step_float(_quadrature), lcg_step_float(_quadrature)); - const float3 wh2 = sample_wh(kg, beckmann, roughness, -wt, wmt, sample2.x, sample2.y); + const float3 wh2 = sample_wh(kg, beckmann, roughness, -wt, wmt, sample2); const float cos_th2 = dot(-wt, wh2); if (cos_th2 <= 1e-5f) @@ -1225,7 +1224,7 @@ ccl_device int bsdf_microfacet_hair_sample_elliptic(const KernelGlobals kg, } /* sample R lobe */ - const float3 wh1 = sample_wh(kg, beckmann, roughness, wi, wmi, sample_h1.x,
[Bf-blender-cvs] [5be12da1890] microfacet_hair: Merge branch 'master' into microfacet_hair
Commit: 5be12da189015387223716193eb247dfe352e35e Author: Weizhen Huang Date: Fri Dec 16 15:43:44 2022 +0100 Branches: microfacet_hair https://developer.blender.org/rB5be12da189015387223716193eb247dfe352e35e Merge branch 'master' into microfacet_hair === === ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [f15010bbe65] microfacet_hair: Remove unnecessary Jacobians
Commit: f15010bbe65fee41306358b8405ba97bd244cdc8 Author: Weizhen Huang Date: Thu Dec 15 16:16:13 2022 +0100 Branches: microfacet_hair https://developer.blender.org/rBf15010bbe65fee41306358b8405ba97bd244cdc8 Remove unnecessary Jacobians === M intern/cycles/kernel/closure/bsdf_hair_microfacet.h === diff --git a/intern/cycles/kernel/closure/bsdf_hair_microfacet.h b/intern/cycles/kernel/closure/bsdf_hair_microfacet.h index b5e88464776..794c6930b96 100644 --- a/intern/cycles/kernel/closure/bsdf_hair_microfacet.h +++ b/intern/cycles/kernel/closure/bsdf_hair_microfacet.h @@ -415,12 +415,11 @@ ccl_device float3 bsdf_microfacet_hair_eval_r_circular(ccl_private const ShaderC const float phi_m = phi_m_min + i * res; const float3 wm = sph_dir(tilt, phi_m); - const float J = fmaxf(cos(phi_i - phi_m), 0.f); if (microfacet_visible(wi, wo, make_float3(wm.x, 0.f, wm.z), wh)) { const float weight = (i == 0 || i == intervals - 1) ? 0.5f : (i % 2 + 1); integral += weight * D(beckmann, roughness, wm, wh) * -G(beckmann, roughness, wi, wo, wm, wh) * J; +G(beckmann, roughness, wi, wo, wm, wh); } } integral *= (2.f / 3.f * res); @@ -475,7 +474,6 @@ ccl_device float3 bsdf_microfacet_hair_eval_tt_trt_circular(KernelGlobals kg, const float phi_mi = phi_m_min + i * res; const float3 wmi = sph_dir(tilt, phi_mi); -const float J = fmaxf(cos(phi_i - phi_mi), 0.f); /* sample wh1 */ const float2 sample1 = make_float2(lcg_step_float(_quadrature), @@ -524,7 +522,7 @@ ccl_device float3 bsdf_microfacet_hair_eval_tt_trt_circular(KernelGlobals kg, const float3 result = T1 * T2 * D2 * A_t * dot_wt_wh2 * dot(wo, wh2) * sqr(rcp_norm_wh2) / dot(wt, wmi) * weight * -smith_g1(beckmann, roughness, -wt, wmi, wh1) * dot(wi, wmi) * J; +smith_g1(beckmann, roughness, -wt, wmi, wh1) * dot(wi, wmi); if (isfinite_safe(result)) S_tt += bsdf->extra->TT * result; @@ -579,7 +577,7 @@ ccl_device float3 bsdf_microfacet_hair_eval_tt_trt_circular(KernelGlobals kg, A_tr * weight / (dot(wt, wmi) * dot(wtr, wmt)) * smith_g1(beckmann, roughness, -wt, wmi, wh1) * smith_g1(beckmann, roughness, -wtr, wmt, wh2) * dot(wi, wmi) * -dot(wt, wmt) * J; +dot(wt, wmt); if (isfinite_safe(result)) S_trt += bsdf->extra->TRT * result; @@ -615,13 +613,7 @@ ccl_device Spectrum bsdf_microfacet_hair_eval_circular(KernelGlobals kg, /* TODO: better estimation of the pdf */ *pdf = 1.f; - // original from Huang's EGSR 2022 return rgb_to_spectrum(R / cos_theta(wi)); - - // correction: the extra cos_theta(wo) corresponds to the lack of consideration of Zinke's - // cos_theta_i^2 in the BCSDF; for instance eq[2] in Huang's should include an extra cos_theta_i - // (plus here remember wi and wo meanings are flipped) - /* return rgb_to_spectrum(R / (cos_theta(wi) * cos_theta(wo))); */ } ccl_device int bsdf_microfacet_hair_sample_circular(const KernelGlobals kg, @@ -813,14 +805,8 @@ ccl_device int bsdf_microfacet_hair_sample_circular(const KernelGlobals kg, label |= LABEL_TRANSMIT; } - // original from Huang's EGSR 2022 *eval *= visibility; - // correction: the extra cos_theta(wo) corresponds to the lack of consideration of Zinke's - // cos_theta_i^2 in the BCSDF; for instance eq[2] in Huang's should include an extra cos_theta_i - // (plus here remember wi and wo meanings are flipped) - /* *eval *= visibility / cos_theta(wo); */ - *omega_in = wo.x * X + wo.y * Y + wo.z * Z; /* correction of the cosine foreshortening term @@ -911,14 +897,13 @@ ccl_device float3 bsdf_microfacet_hair_eval_r_elliptic(ccl_private const ShaderC const float gamma_m = gamma_m_min + i * res; const float3 wm = sphg_dir(tilt, gamma_m, a, b); -const float J = fmaxf(cos(gamma_i - gamma_m), 0.f); if (microfacet_visible(wi, wo, make_float3(wm.x, 0.f, wm.z), wh)) { const float weight = (i == 0 || i == intervals - 1) ? .5f : (i % 2 + 1); const float arc_length = sqrtf(1.f - e2 * sqr(sinf(gamma_m))); integral += weight * D(beckmann, roughness, wm, wh) * - G(beckmann, roughness, wi, wo, wm, wh) * arc_length * J; + G(beckmann, roughness, wi, wo, wm, wh) * arc_length; } } @@ -990,7 +975,6 @@ ccl_device float3 bsdf_microfacet_hair_eval_tt_trt_elliptic(KernelGlobals kg, for (size_t i = 0; i < intervals; i++) { const float gamma_mi = gamma_m_min + i * res; -const float J = fmaxf(cos(gamma_i -
[Bf-blender-cvs] [7bd7538b254] microfacet_hair: Revert to original implementation (needs investigation)
Commit: 7bd7538b2540e01b2885565215f520ea2bfd392a Author: Weizhen Huang Date: Wed Dec 14 15:18:43 2022 +0100 Branches: microfacet_hair https://developer.blender.org/rB7bd7538b2540e01b2885565215f520ea2bfd392a Revert to original implementation (needs investigation) === M intern/cycles/kernel/closure/bsdf_hair_microfacet.h === diff --git a/intern/cycles/kernel/closure/bsdf_hair_microfacet.h b/intern/cycles/kernel/closure/bsdf_hair_microfacet.h index 8cf39366111..b5e88464776 100644 --- a/intern/cycles/kernel/closure/bsdf_hair_microfacet.h +++ b/intern/cycles/kernel/closure/bsdf_hair_microfacet.h @@ -612,16 +612,16 @@ ccl_device Spectrum bsdf_microfacet_hair_eval_circular(KernelGlobals kg, const float3 R = bsdf_microfacet_hair_eval_r_circular(sc, wi, wo) + bsdf_microfacet_hair_eval_tt_trt_circular(kg, sc, wi, wo, sd->lcg_state); - /* This choice could be better */ + /* TODO: better estimation of the pdf */ *pdf = 1.f; // original from Huang's EGSR 2022 - // return rgb_to_spectrum(R / cos_theta(wi)); + return rgb_to_spectrum(R / cos_theta(wi)); // correction: the extra cos_theta(wo) corresponds to the lack of consideration of Zinke's // cos_theta_i^2 in the BCSDF; for instance eq[2] in Huang's should include an extra cos_theta_i // (plus here remember wi and wo meanings are flipped) - return rgb_to_spectrum(R / (cos_theta(wi) * cos_theta(wo))); + /* return rgb_to_spectrum(R / (cos_theta(wi) * cos_theta(wo))); */ } ccl_device int bsdf_microfacet_hair_sample_circular(const KernelGlobals kg, @@ -814,12 +814,12 @@ ccl_device int bsdf_microfacet_hair_sample_circular(const KernelGlobals kg, } // original from Huang's EGSR 2022 - //*eval *= visibility; + *eval *= visibility; // correction: the extra cos_theta(wo) corresponds to the lack of consideration of Zinke's // cos_theta_i^2 in the BCSDF; for instance eq[2] in Huang's should include an extra cos_theta_i // (plus here remember wi and wo meanings are flipped) - *eval *= visibility / cos_theta(wo); + /* *eval *= visibility / cos_theta(wo); */ *omega_in = wo.x * X + wo.y * Y + wo.z * Z; @@ -1155,8 +1155,8 @@ ccl_device Spectrum bsdf_microfacet_hair_eval_elliptic(KernelGlobals kg, *pdf = 1.f; - // return rgb_to_spectrum(R / cos_theta(wi)); // original from Huang's EGSR 2022 - return rgb_to_spectrum(R / (cos_theta(wi) * cos_theta(wo))); + return rgb_to_spectrum(R / cos_theta(wi)); // original from Huang's EGSR 2022 + /* return rgb_to_spectrum(R / (cos_theta(wi) * cos_theta(wo))); */ // correction: the extra cos_theta(wo) corresponds to the lack of consideration of Zinke's // cos_theta_i^2 in the BCSDF; for instance eq[2] in Huang's should include an extra cos_theta_i // (plus here remember wi and wo meanings are flipped) @@ -1373,8 +1373,8 @@ ccl_device int bsdf_microfacet_hair_sample_elliptic(const KernelGlobals kg, label |= LABEL_TRANSMIT; } - //*eval *= visibility; // original from Huang's EGSR 2022 - *eval *= visibility / cos_theta(wo); + *eval *= visibility; // original from Huang's EGSR 2022 + /* *eval *= visibility / cos_theta(wo); */ // correction: the extra cos_theta(wo) corresponds to the lack of consideration of Zinke's // cos_theta_i^2 in the BCSDF; for instance eq[2] in Huang's should include an extra cos_theta_i // (plus here remember wi and wo meanings are flipped) ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [1edaee99266] microfacet_hair: Cleanup: renaming a few functions and variables
Commit: 1edaee99266d9c0a3db34a12cc5c90bfbbc04900 Author: Weizhen Huang Date: Wed Dec 14 15:13:15 2022 +0100 Branches: microfacet_hair https://developer.blender.org/rB1edaee99266d9c0a3db34a12cc5c90bfbbc04900 Cleanup: renaming a few functions and variables === M intern/cycles/kernel/closure/bsdf_hair_microfacet.h === diff --git a/intern/cycles/kernel/closure/bsdf_hair_microfacet.h b/intern/cycles/kernel/closure/bsdf_hair_microfacet.h index cf87fa73e2d..8cf39366111 100644 --- a/intern/cycles/kernel/closure/bsdf_hair_microfacet.h +++ b/intern/cycles/kernel/closure/bsdf_hair_microfacet.h @@ -66,8 +66,8 @@ ccl_device int bsdf_microfacet_hair_setup(ccl_private ShaderData *sd, bsdf->roughness = clamp(bsdf->roughness, 0.001f, 1.0f); /* Compute local frame, aligned to curve tangent and ray direction. */ - float3 X = safe_normalize(sd->dPdu); - float3 Y = safe_normalize(cross(X, sd->I)); + float3 Y = safe_normalize(sd->dPdu); + float3 X = safe_normalize(cross(Y, sd->I)); /* h -1..0..1 means the rays goes from grazing the hair, to hitting it at * the center, to grazing the other edge. This is the sine of the angle @@ -75,13 +75,13 @@ ccl_device int bsdf_microfacet_hair_setup(ccl_private ShaderData *sd, /* TODO: we convert this value to a cosine later and discard the sign, so * we could probably save some operations. */ - float h = (sd->type & PRIMITIVE_CURVE_RIBBON) ? -sd->v : -dot(Y, sd->Ng); + float h = (sd->type & PRIMITIVE_CURVE_RIBBON) ? -sd->v : -dot(X, sd->Ng); kernel_assert(fabsf(h) < 1.0f + 1e-4f); - kernel_assert(isfinite_safe(Y)); + kernel_assert(isfinite_safe(X)); kernel_assert(isfinite_safe(h)); - bsdf->extra->geom = make_float4(Y.x, Y.y, Y.z, h); + bsdf->extra->geom = make_float4(X.x, X.y, X.z, h); return SD_BSDF | SD_BSDF_HAS_EVAL | SD_BSDF_NEEDS_LCG | SD_BSDF_HAS_TRANSMISSION; } @@ -216,15 +216,18 @@ ccl_device_inline float3 sample_wh(KernelGlobals kg, } /* Check micronormal/mesonormal direct visiblity from v */ -ccl_device_inline bool smith_g1_(const float3 v, const float3 m, const float3 h) +ccl_device_inline bool microfacet_visible(const float3 v, const float3 m, const float3 h) { return (dot(v, h) > 0.f && dot(v, m) > 0.f); } /* Check micronormal/mesonormal direct visiblity from wi and wo */ -ccl_device_inline bool G_(const float3 wi, const float3 wo, const float3 m, const float3 h) +ccl_device_inline bool microfacet_visible(const float3 wi, + const float3 wo, + const float3 m, + const float3 h) { - return smith_g1_(wi, m, h) && smith_g1_(wo, m, h); + return microfacet_visible(wi, m, h) && microfacet_visible(wo, m, h); } /* Check micronormal/mesonormal statistical visiblity from v: Smith's separable shadowing/masking @@ -238,23 +241,8 @@ ccl_device_inline float smith_g1( if (dot(v, h) <= 0.f || cos_vm <= 0.f) return 0.f; - const float roughness2 = sqr(roughness); - - float result; - if (beckmann) { -float tmp = fabsf(1.f / (sqr(cos_vm)) - 1.f); -float a_sqr = 1.f / (roughness2 * tmp); -float a = sqrtf(a_sqr); - -/* Use a fast and accurate (<0.35% rel. error) rational approximation to the shadowing-masking - * function */ -result = (a >= 1.6f) ? 1.f : - (3.535f * a + 2.181f * a_sqr) / (1.f + 2.276f * a + 2.577f * a_sqr); - } - else { -result = 2.f / (1.f + sqrtf(roughness2 / sqr(cos_vm) + 1.f - roughness2)); - } - return result; + return beckmann ? bsdf_beckmann_G1(roughness, cos_vm) : +2.f / (1.f + sqrtf(1.0f + sqr(roughness) * (1.0f / sqr(cos_vm) - 1.0f))); } /* Smith's separable shadowing-masking approximation */ @@ -326,10 +314,10 @@ ccl_device float fresnel(float cos_theta_i, float eta, ccl_private float _th return r; } -ccl_device_inline float3 refract(const float3 incident, - const float3 normal, - const float cos_theta_t, - const float inv_eta) +ccl_device_inline float3 refract_angle(const float3 incident, + const float3 normal, + const float cos_theta_t, + const float inv_eta) { return inv_eta * incident - (inv_eta * dot(normal, incident) + cos_theta_t) * normal; } @@ -429,7 +417,7 @@ ccl_device float3 bsdf_microfacet_hair_eval_r_circular(ccl_private const ShaderC const float3 wm = sph_dir(tilt, phi_m); const float J = fmaxf(cos(phi_i - phi_m), 0.f); - if (G_(wi, wo, make_float3(wm.x, 0.f, wm.z), wh)) { + if (
[Bf-blender-cvs] [4234a8017ec] microfacet_hair: Merge branch 'master' into microfacet_hair
Commit: 4234a8017ec6eb6708496b682aa8c6fcd7b3bd05 Author: Weizhen Huang Date: Tue Dec 13 11:47:00 2022 +0100 Branches: microfacet_hair https://developer.blender.org/rB4234a8017ec6eb6708496b682aa8c6fcd7b3bd05 Merge branch 'master' into microfacet_hair === === ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [f56488c20f4] master: Fix Cycles ellipse area light returns zero pdf in volume segment
Commit: f56488c20f44acaf31d75ba0a1e5dd2539c8f8a6 Author: Weizhen Huang Date: Mon Dec 12 21:38:23 2022 +0100 Branches: master https://developer.blender.org/rBf56488c20f44acaf31d75ba0a1e5dd2539c8f8a6 Fix Cycles ellipse area light returns zero pdf in volume segment === M intern/cycles/kernel/light/light.h === diff --git a/intern/cycles/kernel/light/light.h b/intern/cycles/kernel/light/light.h index d04bffe8f8b..fe1df22bd60 100644 --- a/intern/cycles/kernel/light/light.h +++ b/intern/cycles/kernel/light/light.h @@ -156,7 +156,7 @@ ccl_device_noinline bool light_sample(KernelGlobals kg, } ls->pdf *= ls->pdf_selection; - return (ls->pdf > 0.0f); + return in_volume_segment || (ls->pdf > 0.0f); } /* Intersect ray with individual light. */ ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [e378bd70ed6] master: Cleanup: remove code duplication in cycles light sampling
Commit: e378bd70ed6cb255f9a1cc092b88515bbf25d37c Author: Weizhen Huang Date: Thu Dec 8 12:56:49 2022 +0100 Branches: master https://developer.blender.org/rBe378bd70ed6cb255f9a1cc092b88515bbf25d37c Cleanup: remove code duplication in cycles light sampling There has been an attempt to reorganize this part, however, it seems that didn't compile on HIP, and is reverted in rBc2dc65dfa4ae60fa5d2c3b0cfe86f99dcb5bf16f. This is another attempt of refactoring. as I have no idea why some things don't work on HIP, it's best to check whether this compiles on other platforms. The main changes are creating a new struct named `MeshLight` that is shared between `KernelLightDistribution` and `KernelLightTreeEmitter`, and a bit of renaming, so that light sampling with or without light tree could call the same function. Also, I noticed a patch D16714 referring to HIP compilation error. Not sure if it's related, but browsing https://builder.blender.org/admin/#/builders/30/builds/7826/steps/7/logs/stdio, it didn't work on gfx1102, not gfx9*. Differential Revision: https://developer.blender.org/D16722 === M intern/cycles/kernel/light/distribution.h M intern/cycles/kernel/light/light.h M intern/cycles/kernel/light/tree.h M intern/cycles/kernel/light/triangle.h M intern/cycles/kernel/types.h M intern/cycles/scene/light.cpp === diff --git a/intern/cycles/kernel/light/distribution.h b/intern/cycles/kernel/light/distribution.h index 2f75a53ec2a..97c60376748 100644 --- a/intern/cycles/kernel/light/distribution.h +++ b/intern/cycles/kernel/light/distribution.h @@ -59,41 +59,9 @@ ccl_device_noinline bool light_distribution_sample(KernelGlobals kg, { /* Sample light index from distribution. */ const int index = light_distribution_sample(kg, ); - ccl_global const KernelLightDistribution *kdistribution = _data_fetch(light_distribution, - index); - const int prim = kdistribution->prim; - - if (prim >= 0) { -/* Mesh light. */ -const int object = kdistribution->mesh_light.object_id; - -/* Exclude synthetic meshes from shadow catcher pass. */ -if ((path_flag & PATH_RAY_SHADOW_CATCHER_PASS) && -!(kernel_data_fetch(object_flag, object) & SD_OBJECT_SHADOW_CATCHER)) { - return false; -} - -const int shader_flag = kdistribution->mesh_light.shader_flag; -if (!triangle_light_sample(kg, prim, object, randu, randv, time, ls, P)) { - return false; -} -ls->shader |= shader_flag; - } - else { -const int lamp = -prim - 1; - -if (UNLIKELY(light_select_reached_max_bounces(kg, lamp, bounce))) { - return false; -} - -if (!light_sample(kg, lamp, randu, randv, P, path_flag, ls)) { - return false; -} -ls->pdf_selection = kernel_data.integrator.distribution_pdf_lights; - } - - ls->pdf *= ls->pdf_selection; - return (ls->pdf > 0.0f); + const float pdf_selection = kernel_data.integrator.distribution_pdf_lights; + return light_sample( + kg, randu, randv, time, P, bounce, path_flag, index, pdf_selection, ls); } ccl_device_inline float light_distribution_pdf_lamp(KernelGlobals kg) diff --git a/intern/cycles/kernel/light/light.h b/intern/cycles/kernel/light/light.h index b33aecf8b62..d04bffe8f8b 100644 --- a/intern/cycles/kernel/light/light.h +++ b/intern/cycles/kernel/light/light.h @@ -14,6 +14,13 @@ CCL_NAMESPACE_BEGIN +/* Light info. */ + +ccl_device_inline bool light_select_reached_max_bounces(KernelGlobals kg, int index, int bounce) +{ + return (bounce > kernel_data_fetch(lights, index).max_bounces); +} + /* Sample point on an individual light. */ template @@ -90,6 +97,68 @@ ccl_device_inline bool light_sample(KernelGlobals kg, return in_volume_segment || (ls->pdf > 0.0f); } +/* Sample a point on the chosen emitter. */ + +template +ccl_device_noinline bool light_sample(KernelGlobals kg, + const float randu, + const float randv, + const float time, + const float3 P, + const int bounce, + const uint32_t path_flag, + const int emitter_index, + const float pdf_selection, + ccl_private LightSample *ls) +{ + int prim; + MeshLight mesh_light; + if (kernel_data.integrator.use_light_tree) { +ccl_global const KernelLightTreeEmitter *kemitter = _data_fetch(light_tree_emitters, + emitter_index); +prim = kemitter->
[Bf-blender-cvs] [014ffc4615b] master: Cycles: using concentric mapping when sampling disk
Commit: 014ffc4615b8fc04ef37e9147074c0c86e347b06 Author: Weizhen Huang Date: Mon Dec 12 17:07:57 2022 +0100 Branches: master https://developer.blender.org/rB014ffc4615b8fc04ef37e9147074c0c86e347b06 Cycles: using concentric mapping when sampling disk === M intern/cycles/kernel/light/common.h === diff --git a/intern/cycles/kernel/light/common.h b/intern/cycles/kernel/light/common.h index 9a08bbcf43a..bd2803eeade 100644 --- a/intern/cycles/kernel/light/common.h +++ b/intern/cycles/kernel/light/common.h @@ -30,8 +30,8 @@ typedef struct LightSample { ccl_device_inline float3 ellipse_sample(float3 ru, float3 rv, float randu, float randv) { - to_unit_disk(, ); - return ru * randu + rv * randv; + const float2 rand = concentric_sample_disk(randu, randv); + return ru * rand.x + rv * rand.y; } ccl_device_inline float3 rectangle_sample(float3 ru, float3 rv, float randu, float randv) ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [d17858cb370] master: Fix Cycles rectangular area light in volume segment sampled by ellipse
Commit: d17858cb37025c9732ef0987de5de884bd95 Author: Weizhen Huang Date: Mon Dec 12 15:56:50 2022 +0100 Branches: master https://developer.blender.org/rBd17858cb37025c9732ef0987de5de884bd95 Fix Cycles rectangular area light in volume segment sampled by ellipse === M intern/cycles/kernel/light/area.h M intern/cycles/kernel/light/common.h === diff --git a/intern/cycles/kernel/light/area.h b/intern/cycles/kernel/light/area.h index 69cf810f800..9c0ca0c8a70 100644 --- a/intern/cycles/kernel/light/area.h +++ b/intern/cycles/kernel/light/area.h @@ -255,8 +255,9 @@ ccl_device_inline bool area_light_sample(const ccl_global KernelLight *klight, float3 inplane; if (in_volume_segment) { -/* FIXME: handle rectangular light. */ -inplane = ellipse_sample(axis_u * len_u * 0.5f, axis_v * len_v * 0.5f, randu, randv); +inplane = sample_rectangle ? + rectangle_sample(axis_u * len_u * 0.5f, axis_v * len_v * 0.5f, randu, randv) : + ellipse_sample(axis_u * len_u * 0.5f, axis_v * len_v * 0.5f, randu, randv); ls->P += inplane; ls->pdf = invarea; } diff --git a/intern/cycles/kernel/light/common.h b/intern/cycles/kernel/light/common.h index 5f0a3218ae1..9a08bbcf43a 100644 --- a/intern/cycles/kernel/light/common.h +++ b/intern/cycles/kernel/light/common.h @@ -34,6 +34,11 @@ ccl_device_inline float3 ellipse_sample(float3 ru, float3 rv, float randu, float return ru * randu + rv * randv; } +ccl_device_inline float3 rectangle_sample(float3 ru, float3 rv, float randu, float randv) +{ + return ru * (2.0f * randu - 1.0f) + rv * (2.0f * randv - 1.0f); +} + ccl_device float3 disk_light_sample(float3 v, float randu, float randv) { float3 ru, rv; ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [009047ee0a0] master: Cleanup: remove unused variable and simplify computation in the light tree
Commit: 009047ee0a01d164fe9587671c0c4aeca0af8476 Author: Weizhen Huang Date: Thu Dec 8 18:24:49 2022 +0100 Branches: master https://developer.blender.org/rB009047ee0a01d164fe9587671c0c4aeca0af8476 Cleanup: remove unused variable and simplify computation in the light tree === M intern/cycles/kernel/light/tree.h === diff --git a/intern/cycles/kernel/light/tree.h b/intern/cycles/kernel/light/tree.h index 037a4a9f376..ad9fd3d10e4 100644 --- a/intern/cycles/kernel/light/tree.h +++ b/intern/cycles/kernel/light/tree.h @@ -58,9 +58,8 @@ ccl_device float3 compute_v( const float3 centroid, const float3 P, const float3 D, const float3 bcone_axis, const float t) { const float3 unnormalized_v0 = P - centroid; - float len_v0; const float3 unnormalized_v1 = unnormalized_v0 + D * fminf(t, 1e12f); - const float3 v0 = normalize_len(unnormalized_v0, _v0); + const float3 v0 = normalize(unnormalized_v0); const float3 v1 = normalize(unnormalized_v1); const float3 o0 = v0; @@ -69,10 +68,11 @@ ccl_device float3 compute_v( const float dot_o0_a = dot(o0, bcone_axis); const float dot_o1_a = dot(o1, bcone_axis); - const float cos_phi0 = dot_o0_a / sqrtf(sqr(dot_o0_a) + sqr(dot_o1_a)); + const float inv_len = inversesqrtf(sqr(dot_o0_a) + sqr(dot_o1_a)); + const float cos_phi0 = dot_o0_a * inv_len; return (dot_o1_a < 0 || dot(v0, v1) > cos_phi0) ? (dot_o0_a > dot(v1, bcone_axis) ? v0 : v1) : -cos_phi0 * o0 + sin_from_cos(cos_phi0) * o1; +cos_phi0 * o0 + dot_o1_a * inv_len * o1; } /* This is the general function for calculating the importance of either a cluster or an emitter. ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [bf180329773] master: Cycles: support spread angle 0 for area lights
Commit: bf180329773bbf961976b845ddd6e0257e44e7b6 Author: Weizhen Huang Date: Wed Dec 7 19:55:13 2022 +0100 Branches: master https://developer.blender.org/rBbf180329773bbf961976b845ddd6e0257e44e7b6 Cycles: support spread angle 0 for area lights Ref: T87053 === M intern/cycles/kernel/light/area.h M intern/cycles/scene/light.cpp M source/blender/makesrna/intern/rna_light.c === diff --git a/intern/cycles/kernel/light/area.h b/intern/cycles/kernel/light/area.h index 23c69bdac4e..69cf810f800 100644 --- a/intern/cycles/kernel/light/area.h +++ b/intern/cycles/kernel/light/area.h @@ -97,6 +97,11 @@ ccl_device float area_light_spread_attenuation(const float3 D, /* Model a soft-box grid, computing the ratio of light not hidden by the * slats of the grid at a given angle. (see D10594). */ const float cos_a = -dot(D, lightNg); + if (tan_half_spread == 0.0f) { +/* cos(0.05°) ≈ 0.997 */ +/* The factor M_PI_F comes from integrating the radiance over the hemisphere */ +return (cos_a > 0.997f) ? M_PI_F : 0.0f; + } const float sin_a = safe_sqrtf(1.0f - sqr(cos_a)); const float tan_a = sin_a / cos_a; return max((tan_half_spread - tan_a) * normalize_spread, 0.0f); @@ -128,8 +133,8 @@ ccl_device bool area_light_spread_clamp_light(const float3 P, const bool is_round = !(*sample_rectangle) && (*len_u == *len_v); /* Whether we should sample the spread circle. */ - bool sample_spread; - if (is_round) { + bool sample_spread = (r_spread == 0.0f); + if (is_round && !sample_spread) { /* Distance between the centers of the disk light and the valid region circle. */ const float dist = len(make_float2(spread_u, spread_v)); @@ -168,7 +173,7 @@ ccl_device bool area_light_spread_clamp_light(const float3 P, sample_spread = (spread_area < circle_area); } } - else { + else if (!is_round && !sample_spread) { /* Compute rectangle encompassing the circle that affects the shading point, * clamped to the bounds of the area light. */ const float min_u = max(spread_u - r_spread, -*len_u * 0.5f); @@ -210,6 +215,7 @@ ccl_device bool area_light_spread_clamp_light(const float3 P, } if (sample_spread) { +*sample_rectangle = false; *lightP = *lightP + *axis_u * spread_u + *axis_v * spread_v; *len_u = r_spread * 2.0f; *len_v = r_spread * 2.0f; @@ -280,9 +286,16 @@ ccl_device_inline bool area_light_sample(const ccl_global KernelLight *klight, P, >P, sample_axis_u, sample_len_u, sample_axis_v, sample_len_v, randu, randv, true); } else { - ls->P += ellipse_sample( - sample_axis_u * sample_len_u * 0.5f, sample_axis_v * sample_len_v * 0.5f, randu, randv); - ls->pdf = 4.0f * M_1_PI_F / (sample_len_u * sample_len_v); + if (klight->area.tan_half_spread == 0.0f) { +ls->pdf = 1.0f; + } + else { +ls->P += ellipse_sample(sample_axis_u * sample_len_u * 0.5f, +sample_axis_v * sample_len_v * 0.5f, +randu, +randv); +ls->pdf = 4.0f * M_1_PI_F / (sample_len_u * sample_len_v); + } } inplane = ls->P - old_P; } @@ -313,7 +326,7 @@ ccl_device_inline bool area_light_sample(const ccl_global KernelLight *klight, ls->D, ls->Ng, klight->area.tan_half_spread, klight->area.normalize_spread); } - if (!sample_rectangle) { + if (!sample_rectangle && klight->area.tan_half_spread > 0) { ls->pdf *= lamp_light_pdf(Ng, -ls->D, ls->t); } @@ -420,7 +433,10 @@ ccl_device_inline bool area_light_sample_from_intersection( ray_P, _P, sample_axis_u, sample_len_u, sample_axis_v, sample_len_v, 0, 0, false); } else { -ls->pdf = 4.0f * M_1_PI_F / (sample_len_u * sample_len_v) * lamp_light_pdf(Ng, -ray_D, ls->t); +ls->pdf = klight->area.tan_half_spread == 0.0f ? + 1.0f : + 4.0f * M_1_PI_F / (sample_len_u * sample_len_v) * + lamp_light_pdf(Ng, -ray_D, ls->t); } ls->eval_fac = 0.25f * invarea; @@ -429,12 +445,9 @@ ccl_device_inline bool area_light_sample_from_intersection( /* Area Light spread angle attenuation */ ls->eval_fac *= area_light_spread_attenuation( ls->D, ls->Ng, klight->area.tan_half_spread, klight->area.normalize_spread); -if (ls->eval_fac == 0.0f) { - return false; -} } - return true; + return ls->eval_fac > 0; } template diff --git a/intern/cycles/scene/light.cpp b/intern/cycles/scene/light.cpp index fa5affa8c68..c45e14bb1ad 100644 --- a/intern/cycles/scene/light.cpp +++ b/intern/cycles/scene/light.cpp @@ -1038,9 +1038,10 @@ vo
[Bf-blender-cvs] [f68634a3795] master: Cleanup: store tan instead of cot in area lights to increase precision
Commit: f68634a379519eba5da34f0876990615eb453596 Author: Weizhen Huang Date: Wed Dec 7 18:51:26 2022 +0100 Branches: master https://developer.blender.org/rBf68634a379519eba5da34f0876990615eb453596 Cleanup: store tan instead of cot in area lights to increase precision === M intern/cycles/kernel/light/area.h M intern/cycles/kernel/types.h M intern/cycles/scene/light.cpp === diff --git a/intern/cycles/kernel/light/area.h b/intern/cycles/kernel/light/area.h index 02cd22c543e..23c69bdac4e 100644 --- a/intern/cycles/kernel/light/area.h +++ b/intern/cycles/kernel/light/area.h @@ -91,7 +91,7 @@ ccl_device_inline float area_light_rect_sample(float3 P, ccl_device float area_light_spread_attenuation(const float3 D, const float3 lightNg, - const float cot_half_spread, + const float tan_half_spread, const float normalize_spread) { /* Model a soft-box grid, computing the ratio of light not hidden by the @@ -99,7 +99,7 @@ ccl_device float area_light_spread_attenuation(const float3 D, const float cos_a = -dot(D, lightNg); const float sin_a = safe_sqrtf(1.0f - sqr(cos_a)); const float tan_a = sin_a / cos_a; - return max((1.0f - (cot_half_spread * tan_a)) * normalize_spread, 0.0f); + return max((tan_half_spread - tan_a) * normalize_spread, 0.0f); } /* Compute the minimal rectangle, circle or ellipse that covers the valid sample region, to reduce @@ -111,7 +111,7 @@ ccl_device bool area_light_spread_clamp_light(const float3 P, ccl_private float *len_u, ccl_private float3 *axis_v, ccl_private float *len_v, - const float cot_half_spread, + const float tan_half_spread, ccl_private bool *sample_rectangle) { /* Closest point in area light plane and distance to that plane. */ @@ -119,7 +119,7 @@ ccl_device bool area_light_spread_clamp_light(const float3 P, const float t = len(closest_P - P); /* Radius of circle on area light that actually affects the shading point. */ - const float r_spread = t / cot_half_spread; + const float r_spread = t * tan_half_spread; /* Local uv coordinates of closest point. */ const float spread_u = dot(*axis_u, closest_P - *lightP); @@ -261,7 +261,7 @@ ccl_device_inline bool area_light_sample(const ccl_global KernelLight *klight, float sample_len_u = len_u; float sample_len_v = len_v; -if (klight->area.cot_half_spread > 0.0f) { +if (klight->area.normalize_spread > 0) { if (!area_light_spread_clamp_light(P, Ng, >P, @@ -269,7 +269,7 @@ ccl_device_inline bool area_light_sample(const ccl_global KernelLight *klight, _len_u, _axis_v, _len_v, - klight->area.cot_half_spread, + klight->area.tan_half_spread, _rectangle)) { return false; } @@ -307,10 +307,10 @@ ccl_device_inline bool area_light_sample(const ccl_global KernelLight *klight, ls->eval_fac = 0.25f * invarea; - if (klight->area.cot_half_spread > 0.0f) { + if (klight->area.normalize_spread > 0) { /* Area Light spread angle attenuation */ ls->eval_fac *= area_light_spread_attenuation( -ls->D, ls->Ng, klight->area.cot_half_spread, klight->area.normalize_spread); +ls->D, ls->Ng, klight->area.tan_half_spread, klight->area.normalize_spread); } if (!sample_rectangle) { @@ -328,10 +328,10 @@ ccl_device_forceinline void area_light_update_position(const ccl_global KernelLi ls->D = normalize_len(ls->P - P, >t); ls->pdf = invarea; - if (klight->area.cot_half_spread > 0.f) { + if (klight->area.tan_half_spread > 0) { ls->eval_fac = 0.25f * invarea; ls->eval_fac *= area_light_spread_attenuation( -ls->D, ls->Ng, klight->area.cot_half_spread, klight->area.normalize_spread); +ls->D, ls->Ng, klight->area.tan_half_spread, klight->area.normalize_spread); } } @@ -401,7 +401,7 @@ ccl_device_inline bool area_light_sample_from_intersection( bool is_ellipse = (klight->area.invarea < 0.0f); bool sample_rectangle = !is_ellipse; - if
[Bf-blender-cvs] [53ef52f1656] master: Cycles: improve sampling of ellipse area light with spread
Commit: 53ef52f1656939a9cadd61891a69c32ad9f96ea4 Author: Weizhen Huang Date: Mon Dec 5 14:35:25 2022 +0100 Branches: master https://developer.blender.org/rB53ef52f1656939a9cadd61891a69c32ad9f96ea4 Cycles: improve sampling of ellipse area light with spread **Problem**: Area lights in Cycles have spread angle, in which case some part of the area light might be invisible to a shading point. The current implementation samples the whole area light, resulting some samples invisible and thus simply discarded. A technique is applied on rectangular light to sample a subset of the area light that is potentially visible (rB3f24cfb9582e1c826406301d37808df7ca6aa64c), however, ellipse (including disk) area lights remained untreated. The purpose of this patch is to a [...] **Related Task**: T87053 **Results**: These are renderings before and after the patch: |16spp|Disk light|Ellipse light|Square light (for reference, no changes) |Before|{F13996789}|{F13996788}|{F13996822} |After|{F13996759}|{F13996787}|{F13996852} **Explanation**: The visible region on an area light is found by drawing a cone from the shading point to the plane where the area light lies, with the aperture of the cone being the light spread. {F13990078,height=200} Ideally, we would like to draw samples only from the intersection of the area light and the projection of the cone onto the plane (forming a circle). However, the shape of the intersection is often irregular and thus hard to sample from directly. {F13990104,height=200} Instead, the current implementation draws samples from the bounding rectangle of the intersection. In this case, we still end up with some invalid samples outside of the circle, but already much less than sampling the original area light, and the bounding rectangle is easy to sample from. {F13990125} The above technique is only applied to rectangle area lights, ellipse area light still suffers from poor sampling. We could apply a similar technique to ellipse area lights, that is, find the smallest regular shape (rectangle, circle, or ellipse) that covers the intersection (or maybe not the smallest but easy to compute). For disk area light, we consider the relative position of both circles. Denoting `dist` as the distance between the centre of two circles, and `r1`, `r2` their radii. If `dist > r1 + r2`, the area light is completely invisible, we directly return `false`. If `dist < abs(r1 - r2)`, the smaller circle lies inside the larger one, and we sample whichever circle is smaller. Otherwise, the two circles intersect, we compute the bounding rectangle of the intersection, in which case `axis_u`, `len [...] |{F13990211,height=195}|{F13990225,height=195}|{F13990274,height=195}|{F13990210,height=195} |`dist > r1 + r2`|`dist < abs(r1 - r2)`|`dist^2 < abs(r1^2 - r2^2)`|`dist^2 > abs(r1^2 - r2^2)` For ellipse area light, it's hard to find the smallest bounding shape of the intersection, therefore, we compute the bounding rectangle of the ellipse itself, then treat it as a rectangle light. |{F13990386,height=195}|{F13990385,height=195}|{F13990387,height=195} We also check the areas of the bounding rectangle of the intersection, the ellipse (disk) light, and the spread circle, then draw samples from the smallest shape of the three. For ellipse light, this also detects where one shape lies inside the other. I am not sure if we should add this measure to rectangle area light and sample from the spread circle when it has smaller area, as we seem to have a better sampling technique for rectangular (uniformly sample the solid angle). Maybe we could [...] ellipse](https://arxiv.org/pdf/1805.09048.pdf) in the future. **Limitation**: At some point we switch from sampling the ellipse to sampling the rectangle, depending on the area of the both, and there seems to be a visible line (with |slope| =1) on the final rendering which demonstrate at which point we switch between the two methods. We could see that the new sampling method clearly has lower variance near the boundaries, but close to that visible line, the rectangle sampling method seems to have larger variance. I could not spot any bug in the implementation, and I am not sure if this happens because different sampling patterns for ellipse and rectangle are used. |Before (256spp)|After (256spp) |{F13996995}|{F13996998} Differential Revision: https://developer.blender.org/D16694 === M intern/cycles/blender/light.cpp M intern/cycles/kernel/light/area.h M intern/cycles/scene/light.cpp M intern/cycles/scene/light.h M release/scripts/addons === diff --git a/intern/cycles/blender/light.cpp b/intern/cycles/blender/light.cpp index 5359fa13505..b8db4c24eb3 100644 --- a/intern/cycles/blender/light.cpp +++ b/intern/cycles/blender/light.cpp @@ -75,19 +75,19 @@ void BlenderS
[Bf-blender-cvs] [e5dc796da92] microfacet_hair: Cleanup: remove unused variables in `fresnel()`
Commit: e5dc796da921733a63aa635e713696233f1f5091 Author: Weizhen Huang Date: Wed Dec 7 18:08:09 2022 +0100 Branches: microfacet_hair https://developer.blender.org/rBe5dc796da921733a63aa635e713696233f1f5091 Cleanup: remove unused variables in `fresnel()` === M intern/cycles/kernel/closure/bsdf_hair_microfacet.h M intern/cycles/util/math_float3.h === diff --git a/intern/cycles/kernel/closure/bsdf_hair_microfacet.h b/intern/cycles/kernel/closure/bsdf_hair_microfacet.h index cd75d54d42b..cf87fa73e2d 100644 --- a/intern/cycles/kernel/closure/bsdf_hair_microfacet.h +++ b/intern/cycles/kernel/closure/bsdf_hair_microfacet.h @@ -288,50 +288,52 @@ ccl_device float D(const bool beckmann, const float roughness, const float3 m, c return (result * cos_theta > 1e-20f) ? result : 0.f; } -/* Fresnel */ -/* TODO: cleanup or refer to mitsuba */ -ccl_device float fresnel(float cos_theta_i, - float eta, - ccl_private float _theta_t, - ccl_private float _ti) +/* Compute fresnel reflection. Also return the dot product of the refracted ray and the normal as + * `cos_theta_t`, as it is used when computing the direction of the refracted ray. */ +ccl_device float fresnel(float cos_theta_i, float eta, ccl_private float _theta_t) { - const float rcp_eta = 1.f / eta; - float cos_theta_i_abs, eta_it; - if (cos_theta_i >= 0.f) { -eta_it = eta; -eta_ti = rcp_eta; -cos_theta_i_abs = cos_theta_i; + kernel_assert(cos_theta_i >= 0.f); /* FIXME: cos_theta_i could be NaN. */ + + /* Special cases. */ + if (eta == 1.f) { +return 0.f; } - else { -eta_it = rcp_eta; -eta_ti = eta; -cos_theta_i_abs = -cos_theta_i; + if (cos_theta_i == 0.f) { +return 1.f; } - /* Using Snell's law, calculate the squared sine of the angle between the surface normal and the - * transmitted ray */ - float cos_theta_t_sqr = 1.f - eta_ti * eta_ti * (1.f - cos_theta_i * cos_theta_i); - float cos_theta_t_abs = safe_sqrtf(cos_theta_t_sqr); + cos_theta_i = fabsf(cos_theta_i); - /* Adjust the sign of the transmitted direction */ - cos_theta_t = cos_theta_i > 0.f ? -cos_theta_t_abs : cos_theta_t_abs; - - if (eta == 1.f) -return 0.f; - if (cos_theta_i == 0.f) -return 1.f; + /* Using Snell's law, calculate the squared cosine of the angle between the surface normal and + * the transmitted ray. */ + float cos_theta_t_sqr = 1.f - (1.f - cos_theta_i * cos_theta_i) / (eta * eta); + cos_theta_t = safe_sqrtf(cos_theta_t_sqr); - /* Amplitudes of reflected waves */ - float a_s = (cos_theta_i_abs - eta_it * cos_theta_t_abs) / - (cos_theta_i_abs + eta_it * cos_theta_t_abs); + if (cos_theta_t_sqr <= 0) { +/* Total internal reflection. */ +return 1.0f; + } - float a_p = (cos_theta_t_abs - eta_it * cos_theta_i_abs) / - (cos_theta_t_abs + eta_it * cos_theta_i_abs); + /* Amplitudes of reflected waves. */ + float a_s = (cos_theta_i - eta * cos_theta_t) / (cos_theta_i + eta * cos_theta_t); + float a_p = (cos_theta_t - eta * cos_theta_i) / (cos_theta_t + eta * cos_theta_i); float r = .5f * (sqr(a_s) + sqr(a_p)); + + /* Adjust the sign of the transmitted direction to be relative to the surface normal. */ + cos_theta_t = -cos_theta_t; + return r; } +ccl_device_inline float3 refract(const float3 incident, + const float3 normal, + const float cos_theta_t, + const float inv_eta) +{ + return inv_eta * incident - (inv_eta * dot(normal, incident) + cos_theta_t) * normal; +} + ccl_device float3 bsdf_microfacet_hair_eval_r_circular(ccl_private const ShaderClosure *sc, const float3 wi, const float3 wo) @@ -496,11 +498,11 @@ ccl_device float3 bsdf_microfacet_hair_eval_tt_trt_circular(KernelGlobals kg, if (dot_wi_wh1 <= 1e-5f) continue; -float cos_theta_t1, eta_ti1; -const float T1 = 1.f - fresnel(dot_wi_wh1, eta, cos_theta_t1, eta_ti1); +float cos_theta_t1; +const float T1 = 1.f - fresnel(dot_wi_wh1, eta, cos_theta_t1); /* refraction at the first interface */ -const float3 wt = -refract(wi, wh1, cos_theta_t1, eta_ti1); +const float3 wt = -refract(wi, wh1, cos_theta_t1, inv_eta); const float phi_t = dir_phi(wt); const float phi_mt = 2.f * phi_t - phi_mi; const float3 wmt = sph_dir(-tilt, phi_mt); @@ -648,6 +650,7 @@ ccl_device int bsdf_microfacet_hair_sample_circular(const KernelGlobals kg, ccl_private MicrofacetHairBSDF *bsdf = (ccl_private MicrofacetHairBSDF *)sc; *sampled_roughness = make_float2(bsdf->roughness, bsdf->roughness); *eta = b
[Bf-blender-cvs] [cc7317af539] microfacet_hair: Cleanup: adjust the usage and naming of a few utility functions
Commit: cc7317af539206db8152128806141f4ec9fbf0c8 Author: Weizhen Huang Date: Wed Dec 7 17:20:15 2022 +0100 Branches: microfacet_hair https://developer.blender.org/rBcc7317af539206db8152128806141f4ec9fbf0c8 Cleanup: adjust the usage and naming of a few utility functions === M intern/cycles/kernel/closure/bsdf_hair_microfacet.h M intern/cycles/util/math_float3.h === diff --git a/intern/cycles/kernel/closure/bsdf_hair_microfacet.h b/intern/cycles/kernel/closure/bsdf_hair_microfacet.h index 6095ebcac41..cd75d54d42b 100644 --- a/intern/cycles/kernel/closure/bsdf_hair_microfacet.h +++ b/intern/cycles/kernel/closure/bsdf_hair_microfacet.h @@ -88,125 +88,109 @@ ccl_device int bsdf_microfacet_hair_setup(ccl_private ShaderData *sd, #endif /* __HAIR__ */ -ccl_device_inline float3 make_float3_from_float(const float f) +/* */ +/** \name Hair coordinate system utils. + * \{ */ + +/* Returns sin(theta) of the given direction. */ +ccl_device_inline float sin_theta(const float3 w) { - return make_float3(f, f, f); + return w.y; } -ccl_device_inline float3 reflect_vector(const float3 w, const float3 n) +/* Returns cos(theta) of the given direction. */ +ccl_device_inline float cos_theta(const float3 w) { - return 2.f * dot(w, n) * n - w; + return safe_sqrtf(sqr(w.x) + sqr(w.z)); } -ccl_device float3 refract_vector(const float3 w, - const float3 n, - const float cos_theta_t, - const float eta_ti) +/* Returns tan(theta) of the given direction. */ +ccl_device_inline float tan_theta(const float3 w) { - return n * (dot(w, n) * eta_ti + cos_theta_t) - w * eta_ti; + return sin_theta(w) / cos_theta(w); } -ccl_device_inline float3 microfacet_visible_normal_sample(KernelGlobals kg, - const bool beckmann, - const float roughness, - const float3 wi, - const float randu, - const float randv, - ccl_private float *G1i) +/* Returns sin(phi) and cos(phi) of the given direction. */ +ccl_device float2 sincos_phi(const float3 w) { - /* Step 1 : stretch wi */ - float3 omega_i_ = normalize(make_float3(roughness * wi.x, roughness * wi.y, wi.z)); - - /* get polar coordinates of omega_i_ */ - float costheta_ = 1.f; - float sintheta_ = 0.f; - float cosphi_ = 1.f; - float sinphi_ = 0.f; - - if (omega_i_.z < 0.9f) { -costheta_ = omega_i_.z; -sintheta_ = safe_sqrtf(1.f - costheta_ * costheta_); - -float invlen = 1.f / sintheta_; -cosphi_ = omega_i_.x * invlen; -sinphi_ = omega_i_.y * invlen; - } - - /* 2. sample P22_{omega_i}(x_slope, y_slope, 1, 1) */ - float slope_x, slope_y; - - if (beckmann) { -microfacet_beckmann_sample_slopes( -kg, costheta_, sintheta_, randu, randv, _x, _y, G1i); - } - else { -microfacet_ggx_sample_slopes(costheta_, sintheta_, randu, randv, _x, _y, G1i); - } - - /* 3. rotate */ - float tmp = cosphi_ * slope_x - sinphi_ * slope_y; - slope_y = sinphi_ * slope_x + cosphi_ * slope_y; - slope_x = tmp; - - /* 4. unstretch */ - slope_x = roughness * slope_x; - slope_y = roughness * slope_y; + float c = cos_theta(w); + return make_float2(w.x / c, w.z / c); +} - /* 5. compute normal */ - return normalize(make_float3(-slope_x, -slope_y, 1.f)); +/* Extract the theta coordinate from the given direction. + * -pi < theta < pi */ +ccl_device_inline float dir_theta(const float3 w) +{ + return atan2f(sin_theta(w), cos_theta(w)); } -/* returns sin_theta */ -ccl_device_inline float sintheta(const float3 w) +/* Extract the phi coordinate from the given direction, assuming phi(wi) = 0. + * -pi < phi < pi */ +ccl_device_inline float dir_phi(const float3 w) { - return w.y; + return atan2f(w.x, w.z); } -/* returns cos_theta */ -ccl_device_inline float costheta(const float3 w) +/* Extract theta and phi coordinates from the given direction, assuming phi(wi) = 0. + * -pi/2 < theta < pi/2, -pi < phi < pi */ +ccl_device_inline float2 dir_sph(const float3 w) { - return safe_sqrtf(sqr(w.x) + sqr(w.z)); + return make_float2(dir_theta(w), dir_phi(w)); } -/* returns tan_theta */ -ccl_device_inline float tantheta(const float3 w) +/* Compute the vector direction given spherical coordinates */ +ccl_device_inline float3 sph_dir(float theta, float gamma) { - return sintheta(w) / costheta(w); + float sin_theta = sinf(theta); + float cos_theta = cosf(theta); + float sin_gamma = sinf
[Bf-blender-cvs] [f423c4191f3] master: Cycles: credit the original light tree paper and explain modifications
Commit: f423c4191f3d744cc142ed61b217c2feaa5cb328 Author: Weizhen Huang Date: Wed Dec 7 15:36:56 2022 +0100 Branches: master https://developer.blender.org/rBf423c4191f3d744cc142ed61b217c2feaa5cb328 Cycles: credit the original light tree paper and explain modifications === M intern/cycles/kernel/light/tree.h === diff --git a/intern/cycles/kernel/light/tree.h b/intern/cycles/kernel/light/tree.h index 95a7fa0ed79..7429c29ea60 100644 --- a/intern/cycles/kernel/light/tree.h +++ b/intern/cycles/kernel/light/tree.h @@ -1,6 +1,17 @@ /* SPDX-License-Identifier: Apache-2.0 * Copyright 2011-2022 Blender Foundation */ +/* This code implements a modified version of the paper [Importance Sampling of Many Lights with + * Adaptive Tree Splitting](http://www.aconty.com/pdf/many-lights-hpg2018.pdf) by Alejandro Conty + * Estevez, Christopher Kulla. + * The original paper traverses both children when the variance of a node is too high (called + * splitting). However, Cycles does not support multiple lights per shading point. Therefore, we + * adjust the importance computation: instead of using a conservative measure (i.e., the maximal + * possible contribution a node could make to a shading point) as in the paper, we additionally + * compute the minimal possible contribution and choose uniformly between these two measures. Also, + * support for distant lights is added, which is not included in the paper. + */ + #pragma once #include "kernel/light/area.h" ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [4d05a000cb4] master: Fix light tree header file included while feature disabled
Commit: 4d05a000cb46f30750b1f2a259bc13d3f55ca33f Author: Weizhen Huang Date: Wed Dec 7 14:45:17 2022 +0100 Branches: master https://developer.blender.org/rB4d05a000cb46f30750b1f2a259bc13d3f55ca33f Fix light tree header file included while feature disabled === M intern/cycles/kernel/light/sample.h === diff --git a/intern/cycles/kernel/light/sample.h b/intern/cycles/kernel/light/sample.h index b71d6b8b63c..6a5219c3ae9 100644 --- a/intern/cycles/kernel/light/sample.h +++ b/intern/cycles/kernel/light/sample.h @@ -8,7 +8,10 @@ #include "kernel/light/distribution.h" #include "kernel/light/light.h" -#include "kernel/light/tree.h" + +#ifdef __LIGHT_TREE__ +# include "kernel/light/tree.h" +#endif #include "kernel/sample/mapping.h" #include "kernel/sample/mis.h" ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [68573757bc5] microfacet_hair: Cycles: initial commit of microfacet hair bsdf
Commit: 68573757bc5fb615f6bf2e27056f6e10a556bf70 Author: Weizhen Huang Date: Tue Dec 6 18:43:56 2022 +0100 Branches: microfacet_hair https://developer.blender.org/rB68573757bc5fb615f6bf2e27056f6e10a556bf70 Cycles: initial commit of microfacet hair bsdf This is an implementation of the paper [A Microfacet-based Hair Scattering Model](https://onlinelibrary.wiley.com/doi/full/10./cgf.14588) by Weizhen Huang, Matthias Hullin, and Johannes Hanika. Original implementation in [Mitsuba 2](https://github.com/RiverIntheSky/roughhair) by Weizhen Huang. Adapted to Cycles by Olivier Maury D16682 and Christophe Hery. === M intern/cycles/blender/shader.cpp M intern/cycles/kernel/CMakeLists.txt M intern/cycles/kernel/closure/bsdf.h A intern/cycles/kernel/closure/bsdf_hair_microfacet.h M intern/cycles/kernel/film/denoising_passes.h M intern/cycles/kernel/osl/shaders/CMakeLists.txt A intern/cycles/kernel/osl/shaders/node_microfacet_hair_bsdf.osl M intern/cycles/kernel/osl/shaders/stdcycles.h M intern/cycles/kernel/svm/closure.h M intern/cycles/kernel/svm/types.h M intern/cycles/scene/shader_graph.cpp M intern/cycles/scene/shader_nodes.cpp M intern/cycles/scene/shader_nodes.h M release/datafiles/locale M release/scripts/addons M source/blender/blenkernel/BKE_node.h M source/blender/gpu/shaders/material/gpu_shader_material_hair.glsl M source/blender/makesdna/DNA_node_types.h M source/blender/makesrna/intern/rna_nodetree.c M source/blender/nodes/NOD_static_types.h M source/blender/nodes/shader/CMakeLists.txt M source/blender/nodes/shader/node_shader_register.cc M source/blender/nodes/shader/node_shader_register.hh M source/blender/nodes/shader/node_shader_tree.cc A source/blender/nodes/shader/nodes/node_shader_bsdf_hair_microfacet.cc === diff --git a/intern/cycles/blender/shader.cpp b/intern/cycles/blender/shader.cpp index f25e98469fb..43bc5538628 100644 --- a/intern/cycles/blender/shader.cpp +++ b/intern/cycles/blender/shader.cpp @@ -660,6 +660,21 @@ static ShaderNode *add_node(Scene *scene, NODE_PRINCIPLED_HAIR_REFLECTANCE)); node = principled_hair; } + else if (b_node.is_a(_ShaderNodeBsdfHairMicrofacet)) { +BL::ShaderNodeBsdfHairMicrofacet b_microfacet_hair_node(b_node); +MicrofacetHairBsdfNode *microfacet_hair = graph->create_node(); +microfacet_hair->set_parametrization( +(NodeMicrofacetHairParametrization)get_enum(b_microfacet_hair_node.ptr, +"parametrization", +NODE_MICROFACET_HAIR_NUM, + NODE_MICROFACET_HAIR_REFLECTANCE)); +microfacet_hair->set_model_type( +(NodeMicrofacetHairModelType)get_enum(b_microfacet_hair_node.ptr, + "model_type", + NODE_MICROFACET_HAIR_MODEL_TYPE_NUM, + NODE_MICROFACET_HAIR_CIRCULAR_GGX)); +node = microfacet_hair; + } else if (b_node.is_a(_ShaderNodeBsdfPrincipled)) { BL::ShaderNodeBsdfPrincipled b_principled_node(b_node); PrincipledBsdfNode *principled = graph->create_node(); diff --git a/intern/cycles/kernel/CMakeLists.txt b/intern/cycles/kernel/CMakeLists.txt index 9dc343f597d..a203adda324 100644 --- a/intern/cycles/kernel/CMakeLists.txt +++ b/intern/cycles/kernel/CMakeLists.txt @@ -128,6 +128,7 @@ set(SRC_KERNEL_CLOSURE_HEADERS closure/bsdf_principled_diffuse.h closure/bsdf_principled_sheen.h closure/bsdf_hair_principled.h + closure/bsdf_hair_microfacet.h ) set(SRC_KERNEL_SVM_HEADERS diff --git a/intern/cycles/kernel/closure/bsdf.h b/intern/cycles/kernel/closure/bsdf.h index 2f5c5d7bd0c..23c64205c70 100644 --- a/intern/cycles/kernel/closure/bsdf.h +++ b/intern/cycles/kernel/closure/bsdf.h @@ -18,6 +18,7 @@ #include "kernel/closure/bsdf_toon.h" #include "kernel/closure/bsdf_hair.h" #include "kernel/closure/bsdf_hair_principled.h" +#include "kernel/closure/bsdf_hair_microfacet.h" #include "kernel/closure/bsdf_principled_diffuse.h" #include "kernel/closure/bsdf_principled_sheen.h" #include "kernel/closure/bssrdf.h" @@ -243,6 +244,10 @@ ccl_device_inline int bsdf_sample(KernelGlobals kg, label = bsdf_principled_hair_sample( kg, sc, sd, randu, randv, eval, omega_in, pdf, sampled_roughness, eta); break; +case CLOSURE_BSDF_HAIR_MICROFACET_ID: + label = bsdf_microfacet_hair_sample( + kg, sc, sd, randu, randv, eval, omega_in, p
[Bf-blender-cvs] [f646a4f22c4] master: Cleanup: renaming `tan_spread` to `cot_half_spread` to avoid ambiguity
Commit: f646a4f22c422689cf7cc9c0e62f02e2976989ac Author: Weizhen Huang Date: Mon Dec 5 17:02:52 2022 +0100 Branches: master https://developer.blender.org/rBf646a4f22c422689cf7cc9c0e62f02e2976989ac Cleanup: renaming `tan_spread` to `cot_half_spread` to avoid ambiguity Differential Revision: https://developer.blender.org/D16695 === M intern/cycles/kernel/light/area.h M intern/cycles/kernel/types.h M intern/cycles/scene/light.cpp === diff --git a/intern/cycles/kernel/light/area.h b/intern/cycles/kernel/light/area.h index 16d2e2c7d3a..6d2d6ace344 100644 --- a/intern/cycles/kernel/light/area.h +++ b/intern/cycles/kernel/light/area.h @@ -91,7 +91,7 @@ ccl_device_inline float area_light_rect_sample(float3 P, ccl_device float area_light_spread_attenuation(const float3 D, const float3 lightNg, - const float tan_spread, + const float cot_half_spread, const float normalize_spread) { /* Model a soft-box grid, computing the ratio of light not hidden by the @@ -99,7 +99,7 @@ ccl_device float area_light_spread_attenuation(const float3 D, const float cos_a = -dot(D, lightNg); const float sin_a = safe_sqrtf(1.0f - sqr(cos_a)); const float tan_a = sin_a / cos_a; - return max((1.0f - (tan_spread * tan_a)) * normalize_spread, 0.0f); + return max((1.0f - (cot_half_spread * tan_a)) * normalize_spread, 0.0f); } /* Compute subset of area light that actually has an influence on the shading point, to @@ -111,14 +111,14 @@ ccl_device bool area_light_spread_clamp_area_light(const float3 P, ccl_private float *len_u, const float3 axis_v, ccl_private float *len_v, - const float tan_spread) + const float cot_half_spread) { /* Closest point in area light plane and distance to that plane. */ const float3 closest_P = P - dot(lightNg, P - *lightP) * lightNg; const float t = len(closest_P - P); /* Radius of circle on area light that actually affects the shading point. */ - const float radius = t / tan_spread; + const float radius = t / cot_half_spread; /* Local uv coordinates of closest point. */ const float closest_u = dot(axis_u, closest_P - *lightP); @@ -186,7 +186,7 @@ ccl_device_inline bool area_light_sample(const ccl_global KernelLight *klight, float sample_len_u = len_u; float sample_len_v = len_v; -if (!in_volume_segment && klight->area.tan_spread > 0.0f) { +if (!in_volume_segment && klight->area.cot_half_spread > 0.0f) { if (!area_light_spread_clamp_area_light(P, Ng, >P, @@ -194,7 +194,7 @@ ccl_device_inline bool area_light_sample(const ccl_global KernelLight *klight, _len_u, axis_v, _len_v, - klight->area.tan_spread)) { + klight->area.cot_half_spread)) { return false; } } @@ -216,10 +216,10 @@ ccl_device_inline bool area_light_sample(const ccl_global KernelLight *klight, ls->eval_fac = 0.25f * invarea; - if (klight->area.tan_spread > 0.0f) { + if (klight->area.cot_half_spread > 0.0f) { /* Area Light spread angle attenuation */ ls->eval_fac *= area_light_spread_attenuation( -ls->D, ls->Ng, klight->area.tan_spread, klight->area.normalize_spread); +ls->D, ls->Ng, klight->area.cot_half_spread, klight->area.normalize_spread); } if (is_round) { @@ -237,10 +237,10 @@ ccl_device_forceinline void area_light_update_position(const ccl_global KernelLi ls->D = normalize_len(ls->P - P, >t); ls->pdf = invarea; - if (klight->area.tan_spread > 0.f) { + if (klight->area.cot_half_spread > 0.f) { ls->eval_fac = 0.25f * invarea; ls->eval_fac *= area_light_spread_attenuation( -ls->D, ls->Ng, klight->area.tan_spread, klight->area.normalize_spread); +ls->D, ls->Ng, klight->area.cot_half_spread, klight->area.normalize_spread); } } @@ -313,7 +313,7 @@ ccl_device_inline bool area_light_sample_from_intersection( float sample_len_u = klight->area.len_u; float sample_len_v = klight->area.len_v; -
[Bf-blender-cvs] [ee89f213de2] master: Cycles: improve many lights sampling using light tree
Commit: ee89f213de2ec810317141ed87b889981eb8c348 Author: Weizhen Huang Date: Fri Dec 2 19:04:00 2022 +0100 Branches: master https://developer.blender.org/rBee89f213de2ec810317141ed87b889981eb8c348 Cycles: improve many lights sampling using light tree Uses a light tree to more effectively sample scenes with many lights. This can significantly reduce noise, at the cost of a somewhat longer render time per sample. Light tree sampling is enabled by default. It can be disabled in the Sampling > Lights panel. Scenes using light clamping or ray visibility tricks may render different as these are biased techniques that depend on the sampling strategy. The implementation is currently disabled on AMD HIP. This is planned to be fixed before the release. Implementation by Jeffrey Liu, Weizhen Huang, Alaska and Brecht Van Lommel. Ref T77889 === M intern/cycles/blender/addon/properties.py M intern/cycles/blender/addon/ui.py M intern/cycles/blender/sync.cpp M intern/cycles/device/device.cpp M intern/cycles/device/device.h M intern/cycles/device/hip/device.cpp M intern/cycles/kernel/CMakeLists.txt M intern/cycles/kernel/data_arrays.h M intern/cycles/kernel/data_template.h M intern/cycles/kernel/integrator/shade_surface.h M intern/cycles/kernel/integrator/shade_volume.h M intern/cycles/kernel/integrator/state_template.h M intern/cycles/kernel/light/area.h M intern/cycles/kernel/light/background.h M intern/cycles/kernel/light/distant.h M intern/cycles/kernel/light/distribution.h M intern/cycles/kernel/light/point.h M intern/cycles/kernel/light/sample.h M intern/cycles/kernel/light/spot.h A intern/cycles/kernel/light/tree.h M intern/cycles/kernel/light/triangle.h M intern/cycles/kernel/types.h M intern/cycles/scene/CMakeLists.txt M intern/cycles/scene/integrator.cpp M intern/cycles/scene/integrator.h M intern/cycles/scene/light.cpp M intern/cycles/scene/light.h A intern/cycles/scene/light_tree.cpp A intern/cycles/scene/light_tree.h M intern/cycles/scene/object.cpp M intern/cycles/scene/scene.cpp M intern/cycles/scene/scene.h === diff --git a/intern/cycles/blender/addon/properties.py b/intern/cycles/blender/addon/properties.py index 3f3fae32f40..fe8a29200f0 100644 --- a/intern/cycles/blender/addon/properties.py +++ b/intern/cycles/blender/addon/properties.py @@ -503,6 +503,12 @@ class CyclesRenderSettings(bpy.types.PropertyGroup): default='MULTIPLE_IMPORTANCE_SAMPLING', ) +use_light_tree: BoolProperty( +name="Light Tree", +description="Sample multiple lights more efficiently based on estimated contribution at every shading point", +default=True, +) + min_light_bounces: IntProperty( name="Min Light Bounces", description="Minimum number of light bounces. Setting this higher reduces noise in the first bounces, " @@ -644,7 +650,7 @@ class CyclesRenderSettings(bpy.types.PropertyGroup): transparent_max_bounces: IntProperty( name="Transparent Max Bounces", -description="Maximum number of transparent bounces. This is independent of maximum number of other bounces ", +description="Maximum number of transparent bounces. This is independent of maximum number of other bounces", min=0, max=1024, default=8, ) diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py index 4f5edd469be..d0d66d09442 100644 --- a/intern/cycles/blender/addon/ui.py +++ b/intern/cycles/blender/addon/ui.py @@ -383,7 +383,6 @@ class CYCLES_RENDER_PT_sampling_advanced(CyclesButtonsPanel, Panel): col = layout.column(align=True) col.prop(cscene, "min_light_bounces") col.prop(cscene, "min_transparent_bounces") -col.prop(cscene, "light_sampling_threshold", text="Light Threshold") for view_layer in scene.view_layers: if view_layer.samples > 0: @@ -392,6 +391,31 @@ class CYCLES_RENDER_PT_sampling_advanced(CyclesButtonsPanel, Panel): break +class CYCLES_RENDER_PT_sampling_lights(CyclesButtonsPanel, Panel): +bl_label = "Lights" +bl_parent_id = "CYCLES_RENDER_PT_sampling" +bl_options = {'DEFAULT_CLOSED'} + +def draw_header(self, context): +layout = self.layout +scene = context.scene +cscene = scene.cycles + +def draw(self, context): +layout = self.layout +layout.use_property_split = True +layout.use_property_decorate = False + +scene = context.scene +cscene = scene.cycles
[Bf-blender-cvs] [e028662f78b] master: Cycles: store axis and length of an area light instead of their product
Commit: e028662f78bbbd642fb636a8d466c182a8e2841c Author: Weizhen Huang Date: Fri Dec 2 15:21:57 2022 +0100 Branches: master https://developer.blender.org/rBe028662f78bbbd642fb636a8d466c182a8e2841c Cycles: store axis and length of an area light instead of their product === M intern/cycles/kernel/light/area.h M intern/cycles/kernel/light/background.h M intern/cycles/kernel/types.h M intern/cycles/scene/light.cpp M intern/cycles/util/math_intersect.h === diff --git a/intern/cycles/kernel/light/area.h b/intern/cycles/kernel/light/area.h index 212631d363d..db8faf6ec10 100644 --- a/intern/cycles/kernel/light/area.h +++ b/intern/cycles/kernel/light/area.h @@ -15,18 +15,19 @@ CCL_NAMESPACE_BEGIN * NOTE: light_p is modified when sample_coord is true. */ ccl_device_inline float area_light_rect_sample(float3 P, ccl_private float3 *light_p, - float3 extentu, - float3 extentv, + const float3 axis_u, + const float len_u, + const float3 axis_v, + const float len_v, float randu, float randv, bool sample_coord) { /* In our name system we're using P for the center, which is o in the paper. */ - float3 corner = *light_p - extentu * 0.5f - extentv * 0.5f; - float extentu_len, extentv_len; + float3 corner = *light_p - axis_u * len_u * 0.5f - axis_v * len_v * 0.5f; /* Compute local reference system R. */ - float3 x = normalize_len(extentu, _len); - float3 y = normalize_len(extentv, _len); + float3 x = axis_u; + float3 y = axis_v; float3 z = cross(x, y); /* Compute rectangle coords in local reference system. */ float3 dir = corner - P; @@ -38,8 +39,8 @@ ccl_device_inline float area_light_rect_sample(float3 P, } float x0 = dot(dir, x); float y0 = dot(dir, y); - float x1 = x0 + extentu_len; - float y1 = y0 + extentv_len; + float x1 = x0 + len_u; + float y1 = y0 + len_v; /* Compute internal angles (gamma_i). */ float4 diff = make_float4(x0, y1, x1, y0) - make_float4(x1, y0, x0, y1); float4 nz = make_float4(y0, x1, y1, x0) * diff; @@ -106,8 +107,10 @@ ccl_device float area_light_spread_attenuation(const float3 D, ccl_device bool area_light_spread_clamp_area_light(const float3 P, const float3 lightNg, ccl_private float3 *lightP, - ccl_private float3 *extentu, - ccl_private float3 *extentv, + const float3 axis_u, + ccl_private float *len_u, + const float3 axis_v, + ccl_private float *len_v, const float tan_spread) { /* Closest point in area light plane and distance to that plane. */ @@ -117,22 +120,16 @@ ccl_device bool area_light_spread_clamp_area_light(const float3 P, /* Radius of circle on area light that actually affects the shading point. */ const float radius = t / tan_spread; - /* TODO: would be faster to store as normalized vector + length, also in area_light_rect_sample. - */ - float len_u, len_v; - const float3 u = normalize_len(*extentu, _u); - const float3 v = normalize_len(*extentv, _v); - /* Local uv coordinates of closest point. */ - const float closest_u = dot(u, closest_P - *lightP); - const float closest_v = dot(v, closest_P - *lightP); + const float closest_u = dot(axis_u, closest_P - *lightP); + const float closest_v = dot(axis_v, closest_P - *lightP); /* Compute rectangle encompassing the circle that affects the shading point, * clamped to the bounds of the area light. */ - const float min_u = max(closest_u - radius, -len_u * 0.5f); - const float max_u = min(closest_u + radius, len_u * 0.5f); - const float min_v = max(closest_v - radius, -len_v * 0.5f); - const float max_v = min(closest_v + radius, len_v * 0.5f); + const float min_u = max(closest_u - radius, -*len_u * 0.5f); + const float max_u = min(closest_u + radius, *len_u * 0.5f); + const float min_v = max(closest_v - radius, -*len_v * 0.5f); + const float max_v = min(closest_v + radius, *len_v * 0.5f); /* Skip if rectangle is empty. */ if (min_u >= max_u || min_v >= max_v) { @@ -
[Bf-blender-cvs] [f3fedfe2659] soc-2022-many-lights-sampling: Cleanup: delete a few outdated comments
Commit: f3fedfe26590835de443f23935293fc741e2f74e Author: Weizhen Huang Date: Wed Nov 30 14:21:02 2022 +0100 Branches: soc-2022-many-lights-sampling https://developer.blender.org/rBf3fedfe26590835de443f23935293fc741e2f74e Cleanup: delete a few outdated comments === M intern/cycles/kernel/light/tree.h M intern/cycles/scene/light_tree.h === diff --git a/intern/cycles/kernel/light/tree.h b/intern/cycles/kernel/light/tree.h index b68b7f2a32a..02897dfe2e2 100644 --- a/intern/cycles/kernel/light/tree.h +++ b/intern/cycles/kernel/light/tree.h @@ -515,7 +515,6 @@ ccl_device_inline bool get_left_probability(KernelGlobals kg, const int right_index, ccl_private float _probability) { - /* If we don't split, then we need to choose sampling between the left or right child. */ const ccl_global KernelLightTreeNode *left = _data_fetch(light_tree_nodes, left_index); const ccl_global KernelLightTreeNode *right = _data_fetch(light_tree_nodes, right_index); @@ -594,7 +593,6 @@ ccl_device bool light_tree_sample(KernelGlobals kg, pdf_leaf *= (node_index == left_index) ? left_prob : (1.0f - left_prob); } - /* TODO: check `spot_light_tree_weight()` and `area_light_tree_weight()` */ if (selected_light < 0) { return false; } diff --git a/intern/cycles/scene/light_tree.h b/intern/cycles/scene/light_tree.h index 4123a103116..2f12ad4f3f3 100644 --- a/intern/cycles/scene/light_tree.h +++ b/intern/cycles/scene/light_tree.h @@ -49,15 +49,14 @@ OrientationBounds merge(const OrientationBounds _a, const OrientationBounds /* * Light Tree Construction * - * The light tree construction is based off PBRT's BVH construction, - * which first uses build nodes before converting to a more compact structure. + * The light tree construction is based on PBRT's BVH construction. */ /* Light Tree Primitive * Struct that indexes into the scene's triangle and light arrays. */ struct LightTreePrimitive { - /* prim_id >= 0 is an index into an object's local triangle index, - * otherwise -prim_id-1 is an index into device lights array. */ + /* `prim_id >= 0` is an index into an object's local triangle index, + * otherwise `-prim_id-1`(`~prim`) is an index into device lights array. */ int prim_id; int object_id; ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [f4ab719f569] soc-2022-many-lights-sampling: Cleanup: unify variable names in function declaration and definition
Commit: f4ab719f569472aa48391488ddd4f90634569205 Author: Weizhen Huang Date: Wed Nov 30 14:21:42 2022 +0100 Branches: soc-2022-many-lights-sampling https://developer.blender.org/rBf4ab719f569472aa48391488ddd4f90634569205 Cleanup: unify variable names in function declaration and definition === M intern/cycles/scene/light_tree.h === diff --git a/intern/cycles/scene/light_tree.h b/intern/cycles/scene/light_tree.h index 2f12ad4f3f3..18f552924a9 100644 --- a/intern/cycles/scene/light_tree.h +++ b/intern/cycles/scene/light_tree.h @@ -144,13 +144,13 @@ class LightTree { private: int recursive_build( int start, int end, vector , uint bit_trail, int depth); - float min_split_saoh(const BoundBox _bounds, + float min_split_saoh(const BoundBox _bbox, int start, int end, const BoundBox , const OrientationBounds , - int _dim, - int _bucket, + int _dim, + int _bucket, int _left_prims, const vector ); }; ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [af00a73971e] soc-2022-many-lights-sampling: Cleanup: suppress some warnings
Commit: af00a73971ef6329b4b679f15915beb04f11b36c Author: Weizhen Huang Date: Wed Nov 30 13:35:29 2022 +0100 Branches: soc-2022-many-lights-sampling https://developer.blender.org/rBaf00a73971ef6329b4b679f15915beb04f11b36c Cleanup: suppress some warnings === M intern/cycles/kernel/light/tree.h M intern/cycles/scene/light_tree.cpp === diff --git a/intern/cycles/kernel/light/tree.h b/intern/cycles/kernel/light/tree.h index b35f76286b9..b68b7f2a32a 100644 --- a/intern/cycles/kernel/light/tree.h +++ b/intern/cycles/kernel/light/tree.h @@ -446,7 +446,7 @@ ccl_device int light_tree_cluster_select_emitter(KernelGlobals kg, kernel_assert(knode->num_prims <= sizeof(uint) * 8); uint has_importance = 0; - bool sample_max = (rand > 0.5f); /* sampling using the maximum importance */ + const bool sample_max = (rand > 0.5f); /* sampling using the maximum importance */ rand = rand * 2.0f - float(sample_max); for (int i = 0; i < knode->num_prims; i++) { diff --git a/intern/cycles/scene/light_tree.cpp b/intern/cycles/scene/light_tree.cpp index 6db2b29c4fd..121b5593bde 100644 --- a/intern/cycles/scene/light_tree.cpp +++ b/intern/cycles/scene/light_tree.cpp @@ -131,8 +131,8 @@ LightTreePrimitive::LightTreePrimitive(Scene *scene, int prim_id, int object_id) /* For an area light, sizeu and sizev determine the 2 dimensions of the area light, * while axisu and axisv determine the orientation of the 2 dimensions. * We want to add all 4 corners to our bounding box. */ - const float3 half_extentu = 0.5 * lamp->get_sizeu() * lamp->get_axisu() * size; - const float3 half_extentv = 0.5 * lamp->get_sizev() * lamp->get_axisv() * size; + const float3 half_extentu = 0.5f * lamp->get_sizeu() * lamp->get_axisu() * size; + const float3 half_extentv = 0.5f * lamp->get_sizev() * lamp->get_axisv() * size; bbox.grow(centroid + half_extentu + half_extentv); bbox.grow(centroid + half_extentu - half_extentv); bbox.grow(centroid - half_extentu + half_extentv); @@ -272,7 +272,7 @@ int LightTree::recursive_build( middle = (start + end) / 2; } -int left_index = recursive_build(start, middle, prims, bit_trail, depth + 1); +[[maybe_unused]] int left_index = recursive_build(start, middle, prims, bit_trail, depth + 1); int right_index = recursive_build(middle, end, prims, bit_trail | (1u << depth), depth + 1); assert(left_index == current_index + 1); nodes_[current_index].make_interior(right_index); ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [1e277d8a554] soc-2022-many-lights-sampling: Cleanup: rearranging the order of some variables
Commit: 1e277d8a5545d126b90211eb27f5568cd1942f3c Author: Weizhen Huang Date: Wed Nov 30 13:23:34 2022 +0100 Branches: soc-2022-many-lights-sampling https://developer.blender.org/rB1e277d8a5545d126b90211eb27f5568cd1942f3c Cleanup: rearranging the order of some variables === M intern/cycles/kernel/light/tree.h === diff --git a/intern/cycles/kernel/light/tree.h b/intern/cycles/kernel/light/tree.h index 88729da8d48..b35f76286b9 100644 --- a/intern/cycles/kernel/light/tree.h +++ b/intern/cycles/kernel/light/tree.h @@ -83,14 +83,14 @@ ccl_device void light_tree_importance(const float3 N_or_D, min_importance = 0.0f; const float sin_theta_u = sin_from_cos(cos_theta_u); + /* cos(theta_i') in the paper, omitted for volume */ float cos_min_incidence_angle = 1.0f; float cos_max_incidence_angle = 1.0f; + /* when sampling the light tree for the second time in `shade_volume.h` and when query the pdf in * `sample.h` */ const bool in_volume = is_zero(N_or_D); - - const float cos_theta = dot(bcone.axis, -point_to_centroid); if (!in_volume_segment && !in_volume) { const float3 N = N_or_D; const float cos_theta_i = has_transmission ? fabsf(dot(point_to_centroid, N)) : @@ -102,9 +102,6 @@ ccl_device void light_tree_importance(const float3 N_or_D, 1.0f : cos_theta_i * cos_theta_u + sin_theta_i * sin_theta_u; -/* cos_max_incidence_angle = cos(min{theta_i + theta_u, pi}) */ -cos_max_incidence_angle = fmaxf(cos_theta_i * cos_theta_u - sin_theta_i * sin_theta_u, 0.0f); - /* If the node is guaranteed to be behind the surface we're sampling, and the surface is * opaque, then we can give the node an importance of 0 as it contributes nothing to the * surface. This is more accurate than the bbox test if we are calculating the importance of @@ -112,18 +109,22 @@ ccl_device void light_tree_importance(const float3 N_or_D, if (!has_transmission && cos_min_incidence_angle < 0) { return; } + +/* cos_max_incidence_angle = cos(min{theta_i + theta_u, pi}) */ +cos_max_incidence_angle = fmaxf(cos_theta_i * cos_theta_u - sin_theta_i * sin_theta_u, 0.0f); } - /* minimum angle an emitter’s axis would form with the direction to the shading point, - * cos(theta') in the paper */ - float cos_min_outgoing_angle; /* cos(theta - theta_u) */ + const float cos_theta = dot(bcone.axis, -point_to_centroid); const float sin_theta = sin_from_cos(cos_theta); const float cos_theta_minus_theta_u = cos_theta * cos_theta_u + sin_theta * sin_theta_u; float cos_theta_o, sin_theta_o; fast_sincosf(bcone.theta_o, _theta_o, _theta_o); + /* minimum angle an emitter’s axis would form with the direction to the shading point, + * cos(theta') in the paper */ + float cos_min_outgoing_angle; if ((cos_theta > cos_theta_u) || (cos_theta_minus_theta_u > cos_theta_o)) { /* theta - theta_o - theta_u < 0 */ kernel_assert((fast_acosf(cos_theta) - bcone.theta_o - fast_acosf(cos_theta_u)) < 5e-4f); ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [e1289a5f33e] soc-2022-many-lights-sampling: Cleanup: use existing functions when possible
Commit: e1289a5f33e5939065d278340bc74b58eabe9c81 Author: Weizhen Huang Date: Tue Nov 29 23:35:14 2022 +0100 Branches: soc-2022-many-lights-sampling https://developer.blender.org/rBe1289a5f33e5939065d278340bc74b58eabe9c81 Cleanup: use existing functions when possible === M intern/cycles/kernel/light/tree.h === diff --git a/intern/cycles/kernel/light/tree.h b/intern/cycles/kernel/light/tree.h index 7f78d96f3f6..cf8b14b8027 100644 --- a/intern/cycles/kernel/light/tree.h +++ b/intern/cycles/kernel/light/tree.h @@ -37,7 +37,7 @@ ccl_device float light_tree_cos_bounding_box_angle(const BoundingBox bbox, return cos_theta_u; } -ccl_device_inline float sin_from_cos(const float c) +ccl_device_forceinline float sin_from_cos(const float c) { return safe_sqrtf(1.0f - sqr(c)); } @@ -82,7 +82,7 @@ ccl_device void light_tree_cluster_importance(const float3 N_or_D, max_importance = 0.0f; min_importance = 0.0f; - const float sin_theta_u = safe_sqrtf(1.0f - sqr(cos_theta_u)); + const float sin_theta_u = sin_from_cos(cos_theta_u); float cos_theta, cos_theta_i, sin_theta_i; /* cos(theta_i') in the paper, omitted for volume */ float cos_min_incidence_angle = 1.0f; @@ -95,7 +95,7 @@ ccl_device void light_tree_cluster_importance(const float3 N_or_D, if (!in_volume_segment && !in_volume) { const float3 N = N_or_D; cos_theta_i = has_transmission ? fabsf(dot(point_to_centroid, N)) : dot(point_to_centroid, N); -sin_theta_i = safe_sqrtf(1.0f - sqr(cos_theta_i)); +sin_theta_i = sin_from_cos(cos_theta_i); /* cos_min_incidence_angle = cos(max{theta_i - theta_u, 0}) = cos(theta_i') in the paper */ cos_min_incidence_angle = cos_theta_i >= cos_theta_u ? @@ -118,7 +118,7 @@ ccl_device void light_tree_cluster_importance(const float3 N_or_D, * cos(theta') in the paper */ float cos_min_outgoing_angle; /* cos(theta - theta_u) */ - const float sin_theta = safe_sqrtf(1.0f - sqr(cos_theta)); + const float sin_theta = sin_from_cos(cos_theta); const float cos_theta_minus_theta_u = cos_theta * cos_theta_u + sin_theta * sin_theta_u; float cos_theta_o, sin_theta_o; @@ -134,7 +134,7 @@ ccl_device void light_tree_cluster_importance(const float3 N_or_D, /* theta' = theta - theta_o - theta_u < theta_e */ kernel_assert( (fast_acosf(cos_theta) - bcone.theta_o - fast_acosf(cos_theta_u) - bcone.theta_e) < 5e-4f); -const float sin_theta_minus_theta_u = safe_sqrtf(1.0f - sqr(cos_theta_minus_theta_u)); +const float sin_theta_minus_theta_u = sin_from_cos(cos_theta_minus_theta_u); cos_min_outgoing_angle = cos_theta_minus_theta_u * cos_theta_o + sin_theta_minus_theta_u * sin_theta_o; } @@ -163,7 +163,7 @@ ccl_device void light_tree_cluster_importance(const float3 N_or_D, min_importance = 0.0f; } else { -const float sin_theta_plus_theta_u = safe_sqrtf(1.0f - sqr(cos_theta_plus_theta_u)); +const float sin_theta_plus_theta_u = sin_from_cos(cos_theta_plus_theta_u); cos_max_outgoing_angle = cos_theta_plus_theta_u * cos_theta_o - sin_theta_plus_theta_u * sin_theta_o; min_importance = fabsf(f_a * cos_max_incidence_angle * energy * cos_max_outgoing_angle / @@ -580,26 +580,17 @@ ccl_device bool light_tree_sample(KernelGlobals kg, const int left_index = node_index + 1; const int right_index = knode->child_index; -float left_probability; +float left_prob; if (!get_left_probability( -kg, P, N_or_D, t, has_transmission, left_index, right_index, left_probability)) { +kg, P, N_or_D, t, has_transmission, left_index, right_index, left_prob)) { return false; /* both child nodes have zero importance */ } -if (randu < left_probability) { /* go left */ - kernel_assert(left_probability > 0.0f); - - node_index = left_index; - randu /= left_probability; - pdf_leaf *= left_probability; -} -else { - kernel_assert((1.0f - left_probability) > 0.0f); - - node_index = right_index; - randu = (randu - left_probability) / (1.0f - left_probability); - pdf_leaf *= (1.0f - left_probability); -} +float discard; +float total_prob = left_prob; +node_index = left_index; +sample_resevoir(right_index, 1.0f - left_prob, node_index, discard, total_prob, randu); +pdf_leaf *= (node_index == left_index) ? left_prob : (1.0f - left_prob); } /* TODO: check `spot_light_tree_weight()` and `area_light_tree_weight()` */ @@ -675,15 +666,15 @@ ccl_device float light_tree_pdf( const int left_index = node_index + 1; const int right_index = knode->child_index; -float left_probability; +float left_prob; if (!get_left_probability( -kg, P, N, 0, has_trans
[Bf-blender-cvs] [c387b5240aa] soc-2022-many-lights-sampling: Cleanup: reduce variable scope
Commit: c387b5240aad1f8a4f044543493a55f1f61322f7 Author: Weizhen Huang Date: Wed Nov 30 13:05:50 2022 +0100 Branches: soc-2022-many-lights-sampling https://developer.blender.org/rBc387b5240aad1f8a4f044543493a55f1f61322f7 Cleanup: reduce variable scope === M intern/cycles/kernel/light/tree.h === diff --git a/intern/cycles/kernel/light/tree.h b/intern/cycles/kernel/light/tree.h index e02fd033726..88729da8d48 100644 --- a/intern/cycles/kernel/light/tree.h +++ b/intern/cycles/kernel/light/tree.h @@ -83,7 +83,6 @@ ccl_device void light_tree_importance(const float3 N_or_D, min_importance = 0.0f; const float sin_theta_u = sin_from_cos(cos_theta_u); - float cos_theta, cos_theta_i, sin_theta_i; /* cos(theta_i') in the paper, omitted for volume */ float cos_min_incidence_angle = 1.0f; float cos_max_incidence_angle = 1.0f; @@ -91,11 +90,12 @@ ccl_device void light_tree_importance(const float3 N_or_D, * `sample.h` */ const bool in_volume = is_zero(N_or_D); - cos_theta = dot(bcone.axis, -point_to_centroid); + const float cos_theta = dot(bcone.axis, -point_to_centroid); if (!in_volume_segment && !in_volume) { const float3 N = N_or_D; -cos_theta_i = has_transmission ? fabsf(dot(point_to_centroid, N)) : dot(point_to_centroid, N); -sin_theta_i = sin_from_cos(cos_theta_i); +const float cos_theta_i = has_transmission ? fabsf(dot(point_to_centroid, N)) : + dot(point_to_centroid, N); +const float sin_theta_i = sin_from_cos(cos_theta_i); /* cos_min_incidence_angle = cos(max{theta_i - theta_u, 0}) = cos(theta_i') in the paper */ cos_min_incidence_angle = cos_theta_i >= cos_theta_u ? ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [45bb862493c] soc-2022-many-lights-sampling: Cleanup: renaming function
Commit: 45bb862493c9a6d6e9219637dc1eb85e3a2351b1 Author: Weizhen Huang Date: Wed Nov 30 13:00:26 2022 +0100 Branches: soc-2022-many-lights-sampling https://developer.blender.org/rB45bb862493c9a6d6e9219637dc1eb85e3a2351b1 Cleanup: renaming function === M intern/cycles/kernel/light/tree.h === diff --git a/intern/cycles/kernel/light/tree.h b/intern/cycles/kernel/light/tree.h index cf8b14b8027..e02fd033726 100644 --- a/intern/cycles/kernel/light/tree.h +++ b/intern/cycles/kernel/light/tree.h @@ -67,17 +67,17 @@ ccl_device float3 compute_v( /* This is the general function for calculating the importance of either a cluster or an emitter. * Both of the specialized functions obtain the necessary data before calling this function. */ template -ccl_device void light_tree_cluster_importance(const float3 N_or_D, - const bool has_transmission, - const float3 point_to_centroid, - const float cos_theta_u, - const BoundingCone bcone, - const float max_distance, - const float min_distance, - const float t, - const float energy, - ccl_private float _importance, - ccl_private float _importance) +ccl_device void light_tree_importance(const float3 N_or_D, + const bool has_transmission, + const float3 point_to_centroid, + const float cos_theta_u, + const BoundingCone bcone, + const float max_distance, + const float min_distance, + const float t, + const float energy, + ccl_private float _importance, + ccl_private float _importance) { max_importance = 0.0f; min_importance = 0.0f; @@ -309,17 +309,17 @@ ccl_device void light_tree_emitter_importance(KernelGlobals kg, return; } - light_tree_cluster_importance(N_or_D, - has_transmission, - point_to_centroid, - cos_theta_u, - bcone, - distance.x, - distance.y, - t, - kemitter->energy, - max_importance, - min_importance); + light_tree_importance(N_or_D, + has_transmission, + point_to_centroid, + cos_theta_u, + bcone, + distance.x, + distance.y, + t, + kemitter->energy, + max_importance, + min_importance); } template @@ -387,17 +387,17 @@ ccl_device void light_tree_node_importance(KernelGlobals kg, } /* TODO: currently max_distance = min_distance, max_importance = min_importance for the * nodes. Do we need better weights for complex scenes? */ -light_tree_cluster_importance(N_or_D, - has_transmission, - point_to_centroid, - cos_theta_u, - bcone, - distance, - distance, - t, - knode->energy, - max_importance, - min_importance); +light_tree_importance(N_or_D, + has_tra
[Bf-blender-cvs] [e46c6650e34] soc-2022-many-lights-sampling: Fix access before initialization error in last fix
Commit: e46c6650e3465e4647351d22ffc91940362f3782 Author: Weizhen Huang Date: Tue Nov 29 18:50:09 2022 +0100 Branches: soc-2022-many-lights-sampling https://developer.blender.org/rBe46c6650e3465e4647351d22ffc91940362f3782 Fix access before initialization error in last fix === M intern/cycles/kernel/light/point.h === diff --git a/intern/cycles/kernel/light/point.h b/intern/cycles/kernel/light/point.h index bf85877e373..e88a8ecbaa0 100644 --- a/intern/cycles/kernel/light/point.h +++ b/intern/cycles/kernel/light/point.h @@ -125,8 +125,8 @@ ccl_device_forceinline bool point_light_tree_parameters(const ccl_global KernelL point_to_centroid = safe_normalize_len(centroid - P, _distance); const float radius = klight->spot.radius; - const float hypotenus = sqrtf(sqr(radius) + sqr(distance.y)); - cos_theta_u = distance.y / hypotenus; + const float hypotenus = sqrtf(sqr(radius) + sqr(min_distance)); + cos_theta_u = min_distance / hypotenus; distance = make_float2(hypotenus, min_distance); ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [e9918d67e2e] soc-2022-many-lights-sampling: Fix address of vector element requested error
Commit: e9918d67e2e09226636cdeae300ad4f73fb6fb8f Author: Weizhen Huang Date: Tue Nov 29 18:43:43 2022 +0100 Branches: soc-2022-many-lights-sampling https://developer.blender.org/rBe9918d67e2e09226636cdeae300ad4f73fb6fb8f Fix address of vector element requested error === M intern/cycles/kernel/light/area.h M intern/cycles/kernel/light/point.h M intern/cycles/kernel/light/triangle.h === diff --git a/intern/cycles/kernel/light/area.h b/intern/cycles/kernel/light/area.h index 8daadebe67d..2108073c199 100644 --- a/intern/cycles/kernel/light/area.h +++ b/intern/cycles/kernel/light/area.h @@ -335,8 +335,9 @@ ccl_device_forceinline bool area_light_tree_parameters(const ccl_global KernelLi if (!in_volume_segment) { /* TODO: a cheap substitute for minimal distance between point and primitive. Does it * worth the overhead to compute the accurate minimal distance? */ -point_to_centroid = safe_normalize_len(centroid - P, ); -distance.x = distance.y; +float min_distance; +point_to_centroid = safe_normalize_len(centroid - P, _distance); +distance = make_float2(min_distance, min_distance); } const float3 extentu = klight->area.extentu; diff --git a/intern/cycles/kernel/light/point.h b/intern/cycles/kernel/light/point.h index 7597bc12b84..bf85877e373 100644 --- a/intern/cycles/kernel/light/point.h +++ b/intern/cycles/kernel/light/point.h @@ -121,13 +121,14 @@ ccl_device_forceinline bool point_light_tree_parameters(const ccl_global KernelL cos_theta_u = 1.0f; /* Any value in [-1, 1], irrelevant since theta = 0 */ return true; } - point_to_centroid = safe_normalize_len(centroid - P, ); + float min_distance; + point_to_centroid = safe_normalize_len(centroid - P, _distance); const float radius = klight->spot.radius; const float hypotenus = sqrtf(sqr(radius) + sqr(distance.y)); cos_theta_u = distance.y / hypotenus; - distance.x = hypotenus; + distance = make_float2(hypotenus, min_distance); return true; } diff --git a/intern/cycles/kernel/light/triangle.h b/intern/cycles/kernel/light/triangle.h index af40b05e70b..fa9327b8ac6 100644 --- a/intern/cycles/kernel/light/triangle.h +++ b/intern/cycles/kernel/light/triangle.h @@ -298,8 +298,9 @@ ccl_device_forceinline bool triangle_light_tree_parameters( if (!in_volume_segment) { /* TODO: a cheap substitute for minimal distance between point and primitive. Does it * worth the overhead to compute the accurate minimal distance? */ -point_to_centroid = safe_normalize_len(centroid - P, ); -distance.x = distance.y; +float min_distance; +point_to_centroid = safe_normalize_len(centroid - P, _distance); +distance = make_float2(min_distance, min_distance); } const int object = kemitter->mesh_light.object_id; ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [9a97eb549c4] soc-2022-many-lights-sampling: Refactor: move light tree parameters computation to light type header files
Commit: 9a97eb549c4c0c8c1064f11d7c9c6d57decef4be Author: Weizhen Huang Date: Tue Nov 29 17:01:32 2022 +0100 Branches: soc-2022-many-lights-sampling https://developer.blender.org/rB9a97eb549c4c0c8c1064f11d7c9c6d57decef4be Refactor: move light tree parameters computation to light type header files === M intern/cycles/kernel/light/area.h M intern/cycles/kernel/light/background.h M intern/cycles/kernel/light/distant.h M intern/cycles/kernel/light/point.h M intern/cycles/kernel/light/spot.h M intern/cycles/kernel/light/tree.h M intern/cycles/kernel/light/triangle.h === diff --git a/intern/cycles/kernel/light/area.h b/intern/cycles/kernel/light/area.h index f7c52db1692..8daadebe67d 100644 --- a/intern/cycles/kernel/light/area.h +++ b/intern/cycles/kernel/light/area.h @@ -322,31 +322,42 @@ ccl_device_inline bool area_light_sample_from_intersection( return true; } -ccl_device_inline float area_light_tree_weight(const ccl_global KernelLight *klight, - const float3 P, - const float3 N) +template +ccl_device_forceinline bool area_light_tree_parameters(const ccl_global KernelLight *klight, + const float3 centroid, + const float3 P, + const float3 N, + const float3 bcone_axis, + ccl_private float _theta_u, + ccl_private float2 , + ccl_private float3 _to_centroid) { - float3 light_P = klight->co; - - float3 extentu = klight->area.extentu; - float3 extentv = klight->area.extentv; - float3 Ng = klight->area.dir; - bool is_round = (klight->area.invarea < 0.0f); - - if (dot(light_P - P, Ng) > 0.0f) { -return 0.0f; + if (!in_volume_segment) { +/* TODO: a cheap substitute for minimal distance between point and primitive. Does it + * worth the overhead to compute the accurate minimal distance? */ +point_to_centroid = safe_normalize_len(centroid - P, ); +distance.x = distance.y; } - if (!is_round) { -if (klight->area.tan_spread > 0.0f) { - if (!area_light_spread_clamp_area_light( - P, Ng, _P, , , klight->area.tan_spread)) { -return 0.0f; - } + const float3 extentu = klight->area.extentu; + const float3 extentv = klight->area.extentv; + for (int i = 0; i < 4; i++) { +const float3 corner = ((i & 1) - 0.5f) * extentu + 0.5f * ((i & 2) - 1) * extentv + centroid; +float distance_point_to_corner; +const float3 point_to_corner = safe_normalize_len(corner - P, _point_to_corner); +cos_theta_u = fminf(cos_theta_u, dot(point_to_centroid, point_to_corner)); +if (!in_volume_segment) { + distance.x = fmaxf(distance.x, distance_point_to_corner); } } - return 1.0f; + const bool front_facing = dot(bcone_axis, point_to_centroid) < 0; + const bool shape_above_surface = dot(N, centroid - P) + fabsf(dot(N, extentu)) + + fabsf(dot(N, extentv)) > + 0; + const bool in_volume = is_zero(N); + + return (front_facing && shape_above_surface) || in_volume; } CCL_NAMESPACE_END diff --git a/intern/cycles/kernel/light/background.h b/intern/cycles/kernel/light/background.h index 95bd5d47f9f..b37b4410ed4 100644 --- a/intern/cycles/kernel/light/background.h +++ b/intern/cycles/kernel/light/background.h @@ -430,4 +430,18 @@ ccl_device float background_light_pdf(KernelGlobals kg, float3 P, float3 directi return pdf; } +ccl_device_forceinline bool background_light_tree_parameters(const float3 centroid, + ccl_private float _theta_u, + ccl_private float2 , + ccl_private float3 _to_centroid) +{ + /* Cover the whole sphere */ + cos_theta_u = -1.0f; + + distance = make_float2(1.0f, 1.0f); + point_to_centroid = -centroid; + + return true; +} + CCL_NAMESPACE_END diff --git a/intern/cycles/kernel/light/distant.h b/intern/cycles/kernel/light/distant.h index c074a6bf097..3b6aa505fd2 100644 --- a/intern/cycles/kernel/light/distant.h +++ b/intern/cycles/kernel/light/distant.h @@ -108,4 +108,20 @@ ccl_device bool distant_light_sample_from_intersection(KernelGlobals kg, return true; } +ccl_device_forceinline bool distant_light_tree_parameters(const float3 centroid, +
[Bf-blender-cvs] [f1d33a4bb59] soc-2022-many-lights-sampling: Cycles: use closest point to conservatively compute the spreading angle
Commit: f1d33a4bb595a286f42e1c61044e9a99b2530a9c Author: Weizhen Huang Date: Tue Nov 29 12:56:36 2022 +0100 Branches: soc-2022-many-lights-sampling https://developer.blender.org/rBf1d33a4bb595a286f42e1c61044e9a99b2530a9c Cycles: use closest point to conservatively compute the spreading angle === M intern/cycles/kernel/light/tree.h === diff --git a/intern/cycles/kernel/light/tree.h b/intern/cycles/kernel/light/tree.h index 568ce51ce23..2ad37e046c4 100644 --- a/intern/cycles/kernel/light/tree.h +++ b/intern/cycles/kernel/light/tree.h @@ -43,18 +43,12 @@ ccl_device_inline float sin_from_cos(const float c) } /* Compute vector v as in Fig .8. P_v is the corresponding point along the ray ccl_device float3 */ -ccl_device float3 compute_v(const float3 centroid, -const float3 P, -const float3 D, -const float3 bcone_axis, -float t, -ccl_private float3 _v) +ccl_device float3 compute_v( +const float3 centroid, const float3 P, const float3 D, const float3 bcone_axis, const float t) { - t = fminf(t, 1e12f); - const float3 unnormalized_v0 = P - centroid; float len_v0; - const float3 unnormalized_v1 = unnormalized_v0 + D * t; + const float3 unnormalized_v1 = unnormalized_v0 + D * fminf(t, 1e12f); const float3 v0 = normalize_len(unnormalized_v0, _v0); const float3 v1 = normalize(unnormalized_v1); @@ -66,28 +60,8 @@ ccl_device float3 compute_v(const float3 centroid, const float dot_o1_a = dot(o1, bcone_axis); const float cos_phi0 = dot_o0_a / sqrtf(sqr(dot_o0_a) + sqr(dot_o1_a)); - float3 v; - float t_v; - if (dot_o1_a < 0 || dot(v0, v1) > cos_phi0) { -if (dot_o0_a > dot(v1, bcone_axis)) { - v = v0; - t_v = 0.0f; -} -else { - v = v1; - t_v = t; -} - } - else { -const float sin_phi0 = sin_from_cos(cos_phi0); -v = cos_phi0 * o0 + sin_phi0 * o1; -const float cos_phi1 = dot(-v0, D); -const float sin_phi1 = sin_from_cos(cos_phi1); -/* sin(phi_0) / t_v = sin(phi_0 + phi_1) / len_v0 */ -t_v = len_v0 / (cos_phi1 + cos_phi0 / sin_phi0 * sin_phi1); - } - P_v = P + D * t_v; - return v; + return (dot_o1_a < 0 || dot(v0, v1) > cos_phi0) ? (dot_o0_a > dot(v1, bcone_axis) ? v0 : v1) : +cos_phi0 * o0 + sin_from_cos(cos_phi0) * o1; } /* This is the general function for calculating the importance of either a cluster or an emitter. @@ -320,8 +294,7 @@ ccl_device void light_tree_emitter_importance(KernelGlobals kg, /* minimal distance of the ray to the cluster */ min_distance = len(centroid - closest_point); max_distance = min_distance; -float3 P_v; -point_to_centroid = -compute_v(centroid, P, D, bcone.axis, t, P_v); +point_to_centroid = -compute_v(centroid, P, D, bcone.axis, t); } light_tree_cluster_importance(N_or_D, @@ -378,9 +351,8 @@ ccl_device void light_tree_node_importance(KernelGlobals kg, const float3 closest_point = P + dot(centroid - P, D) * D; /* minimal distance of the ray to the cluster */ distance = len(centroid - closest_point); -float3 P_v; -point_to_centroid = -compute_v(centroid, P, D, bcone.axis, t, P_v); -cos_theta_u = light_tree_cos_bounding_box_angle(bbox, P_v, point_to_centroid); +point_to_centroid = -compute_v(centroid, P, D, bcone.axis, t); +cos_theta_u = light_tree_cos_bounding_box_angle(bbox, closest_point, point_to_centroid); } else { const float3 N = N_or_D; ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [b9fca048fc6] soc-2022-many-lights-sampling: Fix bounding cone angle not covering the whole sphere
Commit: b9fca048fc630874d35a9459685c9a6f12569aa1 Author: Weizhen Huang Date: Mon Nov 28 23:26:13 2022 +0100 Branches: soc-2022-many-lights-sampling https://developer.blender.org/rBb9fca048fc630874d35a9459685c9a6f12569aa1 Fix bounding cone angle not covering the whole sphere === M intern/cycles/kernel/light/tree.h === diff --git a/intern/cycles/kernel/light/tree.h b/intern/cycles/kernel/light/tree.h index de3eff956bc..568ce51ce23 100644 --- a/intern/cycles/kernel/light/tree.h +++ b/intern/cycles/kernel/light/tree.h @@ -18,6 +18,11 @@ ccl_device float light_tree_cos_bounding_box_angle(const BoundingBox bbox, const float3 P, const float3 point_to_centroid) { + if (P.x > bbox.min.x && P.y > bbox.min.y && P.z > bbox.min.z && P.x < bbox.max.x && + P.y < bbox.max.y && P.z < bbox.max.z) { +/* If P is inside the bbox, `theta_u` covers the whole sphere */ +return -1.0f; + } float cos_theta_u = 1.0f; /* Iterate through all 8 possible points of the bounding box. */ for (int i = 0; i < 8; ++i) { @@ -362,7 +367,7 @@ ccl_device void light_tree_node_importance(KernelGlobals kg, return; } point_to_centroid = -bcone.axis; - cos_theta_u = fmaxf(fast_cosf(bcone.theta_o), 0.0f); + cos_theta_u = fast_cosf(bcone.theta_o); distance = 1.0f; } else { ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [695eb4505cc] soc-2022-many-lights-sampling: Cleanup: use `packed_float3` instead of `float[3]`
Commit: 695eb4505cc5bfe252c7a338cde6ebde32461401 Author: Weizhen Huang Date: Mon Nov 28 22:16:19 2022 +0100 Branches: soc-2022-many-lights-sampling https://developer.blender.org/rB695eb4505cc5bfe252c7a338cde6ebde32461401 Cleanup: use `packed_float3` instead of `float[3]` === M intern/cycles/kernel/light/area.h M intern/cycles/kernel/light/background.h M intern/cycles/kernel/light/distant.h M intern/cycles/kernel/light/point.h M intern/cycles/kernel/light/spot.h M intern/cycles/kernel/light/tree.h M intern/cycles/kernel/types.h M intern/cycles/scene/light.cpp M release/datafiles/locale M release/scripts/addons M release/scripts/addons_contrib M source/tools === diff --git a/intern/cycles/kernel/light/area.h b/intern/cycles/kernel/light/area.h index 7d6f2a5bef9..f7c52db1692 100644 --- a/intern/cycles/kernel/light/area.h +++ b/intern/cycles/kernel/light/area.h @@ -162,13 +162,11 @@ ccl_device_inline bool area_light_sample(const ccl_global KernelLight *klight, const float3 P, ccl_private LightSample *ls) { - ls->P = make_float3(klight->co[0], klight->co[1], klight->co[2]); + ls->P = klight->co; - float3 extentu = make_float3( - klight->area.extentu[0], klight->area.extentu[1], klight->area.extentu[2]); - float3 extentv = make_float3( - klight->area.extentv[0], klight->area.extentv[1], klight->area.extentv[2]); - float3 Ng = make_float3(klight->area.dir[0], klight->area.dir[1], klight->area.dir[2]); + float3 extentu = klight->area.extentu; + float3 extentv = klight->area.extentv; + float3 Ng = klight->area.dir; float invarea = fabsf(klight->area.invarea); bool is_round = (klight->area.invarea < 0.0f); @@ -256,18 +254,16 @@ ccl_device_inline bool area_light_intersect(const ccl_global KernelLight *klight return false; } - const float3 extentu = make_float3( - klight->area.extentu[0], klight->area.extentu[1], klight->area.extentu[2]); - const float3 extentv = make_float3( - klight->area.extentv[0], klight->area.extentv[1], klight->area.extentv[2]); - const float3 Ng = make_float3(klight->area.dir[0], klight->area.dir[1], klight->area.dir[2]); + const float3 extentu = klight->area.extentu; + const float3 extentv = klight->area.extentv; + const float3 Ng = klight->area.dir; /* One sided. */ if (dot(ray->D, Ng) >= 0.0f) { return false; } - const float3 light_P = make_float3(klight->co[0], klight->co[1], klight->co[2]); + const float3 light_P = klight->co; float3 P; return ray_quad_intersect( @@ -285,12 +281,10 @@ ccl_device_inline bool area_light_sample_from_intersection( /* area light */ float invarea = fabsf(klight->area.invarea); - float3 extentu = make_float3( - klight->area.extentu[0], klight->area.extentu[1], klight->area.extentu[2]); - float3 extentv = make_float3( - klight->area.extentv[0], klight->area.extentv[1], klight->area.extentv[2]); - float3 Ng = make_float3(klight->area.dir[0], klight->area.dir[1], klight->area.dir[2]); - float3 light_P = make_float3(klight->co[0], klight->co[1], klight->co[2]); + float3 extentu = klight->area.extentu; + float3 extentv = klight->area.extentv; + float3 Ng = klight->area.dir; + float3 light_P = klight->co; ls->u = isect->u; ls->v = isect->v; @@ -332,13 +326,11 @@ ccl_device_inline float area_light_tree_weight(const ccl_global KernelLight *kli const float3 P, const float3 N) { - float3 light_P = make_float3(klight->co[0], klight->co[1], klight->co[2]); + float3 light_P = klight->co; - float3 extentu = make_float3( - klight->area.extentu[0], klight->area.extentu[1], klight->area.extentu[2]); - float3 extentv = make_float3( - klight->area.extentv[0], klight->area.extentv[1], klight->area.extentv[2]); - float3 Ng = make_float3(klight->area.dir[0], klight->area.dir[1], klight->area.dir[2]); + float3 extentu = klight->area.extentu; + float3 extentv = klight->area.extentv; + float3 Ng = klight->area.dir; bool is_round = (klight->area.invarea < 0.0f); if (dot(light_P - P, Ng) > 0.0f) { diff --git a/intern/cycles/kernel/light/background.h b/intern/cycles/kernel/light/background.h index 3fc9e0776a4..95bd5d47f9f 100644 --- a/intern/cycles/kernel/light/background.h +++ b/intern/cycles/kernel/light/background.h @@ -134,8 +134,8 @@ ccl_device_inline bool background_portal_data_fetch_and_check_side(
[Bf-blender-cvs] [2c7b7161f2d] soc-2022-many-lights-sampling: Fix wrong distant light bounding cone angles
Commit: 2c7b7161f2df0015b1ed63aee693983bf95d953c Author: Weizhen Huang Date: Mon Nov 28 18:13:24 2022 +0100 Branches: soc-2022-many-lights-sampling https://developer.blender.org/rB2c7b7161f2df0015b1ed63aee693983bf95d953c Fix wrong distant light bounding cone angles === M intern/cycles/kernel/light/tree.h M intern/cycles/scene/light_tree.cpp === diff --git a/intern/cycles/kernel/light/tree.h b/intern/cycles/kernel/light/tree.h index 9b4462387c3..9ffb4c22697 100644 --- a/intern/cycles/kernel/light/tree.h +++ b/intern/cycles/kernel/light/tree.h @@ -259,8 +259,7 @@ ccl_device void light_tree_emitter_importance(KernelGlobals kg, } if (klight->type == LIGHT_DISTANT) { /* Treating it as a disk light 1 unit away */ -cos_theta_u = fast_cosf(theta_o); -theta_o = 0.0f; +cos_theta_u = fast_cosf(kemitter->theta_e); max_distance = 1.0f / cos_theta_u; } else { diff --git a/intern/cycles/scene/light_tree.cpp b/intern/cycles/scene/light_tree.cpp index 90f5ae43260..6db2b29c4fd 100644 --- a/intern/cycles/scene/light_tree.cpp +++ b/intern/cycles/scene/light_tree.cpp @@ -173,8 +173,8 @@ LightTreePrimitive::LightTreePrimitive(Scene *scene, int prim_id, int object_id) strength *= lamp->get_average_radiance() * M_PI_F; } else if (type == LIGHT_DISTANT) { - bcone.theta_o = tanf(0.5f * lamp->get_angle()); - bcone.theta_e = 0; + bcone.theta_o = 0; + bcone.theta_e = 0.5f * lamp->get_angle(); } if (lamp->get_shader()) { ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [7151bb54a4f] soc-2022-many-lights-sampling: Refactor: move visibility test outside of spread angle function
Commit: 7151bb54a4f629c6354fac07df2471c4db9e3847 Author: Weizhen Huang Date: Mon Nov 28 14:06:05 2022 +0100 Branches: soc-2022-many-lights-sampling https://developer.blender.org/rB7151bb54a4f629c6354fac07df2471c4db9e3847 Refactor: move visibility test outside of spread angle function === M intern/cycles/kernel/light/tree.h === diff --git a/intern/cycles/kernel/light/tree.h b/intern/cycles/kernel/light/tree.h index 48225d45554..9b4462387c3 100644 --- a/intern/cycles/kernel/light/tree.h +++ b/intern/cycles/kernel/light/tree.h @@ -17,9 +17,7 @@ CCL_NAMESPACE_BEGIN ccl_device float light_tree_cos_bounding_box_angle(const float3 bbox_min, const float3 bbox_max, const float3 P, - const float3 N, - const float3 point_to_centroid, - ccl_private bool _is_visible) + const float3 point_to_centroid) { float cos_theta_u = 1.0f; /* Iterate through all 8 possible points of the bounding box. */ @@ -31,9 +29,6 @@ ccl_device float light_tree_cos_bounding_box_angle(const float3 bbox_min, /* Caculate the bounding box angle. */ float3 point_to_corner = normalize(corner - P); cos_theta_u = fminf(cos_theta_u, dot(point_to_centroid, point_to_corner)); - -/* Figure out whether or not the bounding box is in front or behind the shading point. */ -bbox_is_visible |= dot(point_to_corner, N) > 0; } return cos_theta_u; } @@ -386,18 +381,6 @@ ccl_device void light_tree_node_importance(KernelGlobals kg, const float3 centroid = 0.5f * (bbox_min + bbox_max); - point_to_centroid = normalize_len(centroid - P, ); - bool bbox_is_visible = has_transmission; - cos_theta_u = light_tree_cos_bounding_box_angle( - bbox_min, bbox_max, P, N_or_D, point_to_centroid, bbox_is_visible); - - /* If the node is guaranteed to be behind the surface we're sampling, and the surface is - * opaque, then we can give the node an importance of 0 as it contributes nothing to the - * surface. */ - if (!bbox_is_visible) { -return; - } - if (in_volume_segment) { const float3 D = N_or_D; const float3 closest_point = P + dot(centroid - P, D) * D; @@ -406,7 +389,23 @@ ccl_device void light_tree_node_importance(KernelGlobals kg, float3 P_v; point_to_centroid = -compute_v(centroid, P, D, bcone_axis, t, P_v); cos_theta_u = light_tree_cos_bounding_box_angle( -bbox_min, bbox_max, P_v, D, point_to_centroid, bbox_is_visible); +bbox_min, bbox_max, P_v, point_to_centroid); + } + else { +const float3 N = N_or_D; +const float3 bbox_extent = bbox_max - centroid; +const bool bbox_is_visible = has_transmission | + (dot(N, centroid - P) + dot(fabs(N), fabs(bbox_extent)) > 0); + +/* If the node is guaranteed to be behind the surface we're sampling, and the surface is + * opaque, then we can give the node an importance of 0 as it contributes nothing to the + * surface. */ +if (!bbox_is_visible) { + return; +} + +point_to_centroid = normalize_len(centroid - P, ); +cos_theta_u = light_tree_cos_bounding_box_angle(bbox_min, bbox_max, P, point_to_centroid); } /* clamp distance to half the radius of the cluster when splitting is disabled */ distance = fmaxf(0.5f * len(centroid - bbox_max), distance); ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [1ce158c8297] soc-2022-many-lights-sampling: Cleanup: remove unused variable
Commit: 1ce158c829756806a64ec829f272908d5342c454 Author: Weizhen Huang Date: Mon Nov 28 13:50:53 2022 +0100 Branches: soc-2022-many-lights-sampling https://developer.blender.org/rB1ce158c829756806a64ec829f272908d5342c454 Cleanup: remove unused variable === M intern/cycles/kernel/light/tree.h === diff --git a/intern/cycles/kernel/light/tree.h b/intern/cycles/kernel/light/tree.h index 17c1df99b34..48225d45554 100644 --- a/intern/cycles/kernel/light/tree.h +++ b/intern/cycles/kernel/light/tree.h @@ -327,7 +327,6 @@ ccl_device void light_tree_emitter_importance(KernelGlobals kg, min_distance = len(centroid - closest_point); max_distance = min_distance; float3 P_v; -float t_v; point_to_centroid = -compute_v(centroid, P, D, bcone_axis, t, P_v); } @@ -405,7 +404,6 @@ ccl_device void light_tree_node_importance(KernelGlobals kg, /* minimal distance of the ray to the cluster */ distance = len(centroid - closest_point); float3 P_v; -float t_v; point_to_centroid = -compute_v(centroid, P, D, bcone_axis, t, P_v); cos_theta_u = light_tree_cos_bounding_box_angle( bbox_min, bbox_max, P_v, D, point_to_centroid, bbox_is_visible); ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [6b0c235389d] soc-2022-many-lights-sampling: Merge branch 'master' into soc-2022-many-lights-sampling
Commit: 6b0c235389da85771589663cef16869d8469fafc Author: Weizhen Huang Date: Mon Nov 28 12:56:00 2022 +0100 Branches: soc-2022-many-lights-sampling https://developer.blender.org/rB6b0c235389da85771589663cef16869d8469fafc Merge branch 'master' into soc-2022-many-lights-sampling === === diff --cc intern/cycles/kernel/data_template.h index 994e7f7446c,c7b50b20c70..081af4437ad --- a/intern/cycles/kernel/data_template.h +++ b/intern/cycles/kernel/data_template.h @@@ -205,10 -206,11 +206,10 @@@ KERNEL_STRUCT_MEMBER(integrator, int, u KERNEL_STRUCT_MEMBER(integrator, int, use_volume_guiding) KERNEL_STRUCT_MEMBER(integrator, int, use_guiding_direct_light) KERNEL_STRUCT_MEMBER(integrator, int, use_guiding_mis_weights) - /* Padding */ + + /* Padding. */ KERNEL_STRUCT_MEMBER(integrator, int, pad1) KERNEL_STRUCT_MEMBER(integrator, int, pad2) --KERNEL_STRUCT_MEMBER(integrator, int, pad3) KERNEL_STRUCT_END(KernelIntegrator) /* SVM. For shader specialization. */ diff --cc intern/cycles/kernel/integrator/shade_volume.h index 6889e01f517,46d13f59c6a..a23efd5738b --- a/intern/cycles/kernel/integrator/shade_volume.h +++ b/intern/cycles/kernel/integrator/shade_volume.h @@@ -697,18 -702,10 +703,18 @@@ ccl_device_forceinline bool integrate_v /* Sample position on a light. */ const uint32_t path_flag = INTEGRATOR_STATE(state, path, flag); const uint bounce = INTEGRATOR_STATE(state, path, bounce); - float2 rand_light = path_state_rng_2D(kg, rng_state, PRNG_VOLUME_SEGMENT_LIGHT); + const float2 rand_light = path_state_rng_2D(kg, rng_state, PRNG_LIGHT); - if (!light_distribution_sample_from_volume_segment( - kg, rand_light.x, rand_light.y, sd->time, sd->P, bounce, path_flag, ls)) { + if (!light_sample_from_volume_segment(kg, +rand_light.x, +rand_light.y, +sd->time, +sd->P, +ray->D, +ray->tmax - ray->tmin, +bounce, +path_flag, +ls)) { return false; } ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [762aa998f3d] soc-2022-many-lights-sampling: Recompute theta_u from the point of theta_min for interior nodes in volume
Commit: 762aa998f3d05958519124f1c11f2c74e6184f2f Author: Weizhen Huang Date: Fri Nov 25 18:30:44 2022 +0100 Branches: soc-2022-many-lights-sampling https://developer.blender.org/rB762aa998f3d05958519124f1c11f2c74e6184f2f Recompute theta_u from the point of theta_min for interior nodes in volume === M intern/cycles/kernel/light/tree.h === diff --git a/intern/cycles/kernel/light/tree.h b/intern/cycles/kernel/light/tree.h index fff73a1392c..17c1df99b34 100644 --- a/intern/cycles/kernel/light/tree.h +++ b/intern/cycles/kernel/light/tree.h @@ -38,6 +38,59 @@ ccl_device float light_tree_cos_bounding_box_angle(const float3 bbox_min, return cos_theta_u; } +ccl_device_inline float sin_from_cos(const float c) +{ + return safe_sqrtf(1.0f - sqr(c)); +} + +/* Compute vector v as in Fig .8. P_v is the corresponding point along the ray ccl_device float3 */ +ccl_device float3 compute_v(const float3 centroid, +const float3 P, +const float3 D, +const float3 bcone_axis, +float t, +ccl_private float3 _v) +{ + t = fminf(t, 1e12f); + + const float3 unnormalized_v0 = P - centroid; + float len_v0; + const float3 unnormalized_v1 = unnormalized_v0 + D * t; + const float3 v0 = normalize_len(unnormalized_v0, _v0); + const float3 v1 = normalize(unnormalized_v1); + + const float3 o0 = v0; + float3 o1, o2; + make_orthonormals_tangent(o0, v1, , ); + + const float dot_o0_a = dot(o0, bcone_axis); + const float dot_o1_a = dot(o1, bcone_axis); + const float cos_phi0 = dot_o0_a / sqrtf(sqr(dot_o0_a) + sqr(dot_o1_a)); + + float3 v; + float t_v; + if (dot_o1_a < 0 || dot(v0, v1) > cos_phi0) { +if (dot_o0_a > dot(v1, bcone_axis)) { + v = v0; + t_v = 0.0f; +} +else { + v = v1; + t_v = t; +} + } + else { +const float sin_phi0 = sin_from_cos(cos_phi0); +v = cos_phi0 * o0 + sin_phi0 * o1; +const float cos_phi1 = dot(-v0, D); +const float sin_phi1 = sin_from_cos(cos_phi1); +/* sin(phi_0) / t_v = sin(phi_0 + phi_1) / len_v0 */ +t_v = len_v0 / (cos_phi1 + cos_phi0 / sin_phi0 * sin_phi1); + } + P_v = P + D * t_v; + return v; +} + /* This is the general function for calculating the importance of either a cluster or an emitter. * Both of the specialized functions obtain the necessary data before calling this function. */ template @@ -68,47 +121,26 @@ ccl_device void light_tree_cluster_importance(const float3 N_or_D, * `sample.h` */ const bool in_volume = (dot(N_or_D, N_or_D) < 5e-4f); - if (in_volume_segment) { -const float3 D = N_or_D; -const float3 v0 = -normalize(point_to_centroid); -const float3 v1 = normalize(-point_to_centroid + D * fminf(t, 1e12f)); - -const float3 o0 = v0; -float3 o1, o2; -make_orthonormals_tangent(o0, v1, , ); - -const float dot_o0_a = dot(o0, bcone_axis); -const float dot_o1_a = dot(o1, bcone_axis); -const float cos_phi0 = dot_o0_a / sqrtf(sqr(dot_o0_a) + sqr(dot_o1_a)); - -/* Eq. (6) */ -cos_theta = (dot_o1_a < 0 || dot(v0, v1) > cos_phi0) ? -fmaxf(dot_o0_a, dot(v1, bcone_axis)) : /* b_max */ -dot(bcone_axis, cos_phi0 * o0 + safe_sqrtf(1.0f - sqr(cos_phi0)) * o1); - } - else { -cos_theta = dot(bcone_axis, -point_to_centroid); -if (!in_volume) { - const float3 N = N_or_D; - cos_theta_i = has_transmission ? fabsf(dot(point_to_centroid, N)) : - dot(point_to_centroid, N); - sin_theta_i = safe_sqrtf(1.0f - sqr(cos_theta_i)); - - /* cos_min_incidence_angle = cos(max{theta_i - theta_u, 0}) = cos(theta_i') in the paper */ - cos_min_incidence_angle = cos_theta_i > cos_theta_u ? -1.0f : -cos_theta_i * cos_theta_u + sin_theta_i * sin_theta_u; - - /* cos_max_incidence_angle = cos(min{theta_i + theta_u, pi}) */ - cos_max_incidence_angle = fmaxf(cos_theta_i * cos_theta_u - sin_theta_i * sin_theta_u, 0.0f); - - /* If the node is guaranteed to be behind the surface we're sampling, and the surface is - * opaque, then we can give the node an importance of 0 as it contributes nothing to the - * surface. This is more accurate than the bbox test if we are calculating the importance of - * an emitter with radius */ - if (!has_transmission && cos_min_incidence_angle < 0) { -return; - } + cos_theta = dot(bcone_axis, -point_to_centroid); + if (!in_volume_segment && !in_volume) { +const float3 N = N_or_D; +cos_theta_i = has_transmission ? fabsf(dot(point_to_centroid, N)) : dot(point_to_centroid, N); +sin_the
[Bf-blender-cvs] [5c718884b72] soc-2022-many-lights-sampling: Fix normalized vector used when computing `closest_point`
Commit: 5c718884b72b35e5350382f193d6883c4b87c2ec Author: Weizhen Huang Date: Thu Nov 24 17:04:38 2022 +0100 Branches: soc-2022-many-lights-sampling https://developer.blender.org/rB5c718884b72b35e5350382f193d6883c4b87c2ec Fix normalized vector used when computing `closest_point` === M intern/cycles/kernel/light/tree.h === diff --git a/intern/cycles/kernel/light/tree.h b/intern/cycles/kernel/light/tree.h index dc7c1b3219a..f80935efd58 100644 --- a/intern/cycles/kernel/light/tree.h +++ b/intern/cycles/kernel/light/tree.h @@ -290,7 +290,7 @@ ccl_device void light_tree_emitter_importance(KernelGlobals kg, /* TODO: better measure for single emitter */ if (in_volume_segment) { const float3 D = N_or_D; -const float3 closest_point = P + D * dot(point_to_centroid, D); +const float3 closest_point = P + distance * dot(point_to_centroid, D) * D; /* minimal distance of the ray to the cluster */ min_distance = len(centroid - closest_point); max_distance = min_distance; @@ -367,7 +367,7 @@ ccl_device void light_tree_node_importance(KernelGlobals kg, if (in_volume_segment) { const float3 D = N_or_D; -const float3 closest_point = P + D * dot(point_to_centroid, D); +const float3 closest_point = P + distance * dot(point_to_centroid, D) * D; /* minimal distance of the ray to the cluster */ distance = len(centroid - closest_point); point_to_centroid = centroid - P; ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs