WIP: Brush assets project #106303

Draft
Julian Eisel wants to merge 370 commits from brush-assets-project into main

When changing the target branch, be careful to rebase the branch in your fork to match. See documentation.
8 changed files with 55 additions and 54 deletions
Showing only changes of commit ac78d7bb78 - Show all commits

View File

@ -492,13 +492,11 @@ ccl_device_forceinline bool area_light_tree_parameters(const ccl_global KernelLi
ccl_private float2 &distance, ccl_private float2 &distance,
ccl_private float3 &point_to_centroid) ccl_private float3 &point_to_centroid)
{ {
if (!in_volume_segment) { /* TODO: a cheap substitute for minimal distance between point and primitive. Does it worth the
/* TODO: a cheap substitute for minimal distance between point and primitive. Does it * overhead to compute the accurate minimal distance? */
* worth the overhead to compute the accurate minimal distance? */ float min_distance;
float min_distance; point_to_centroid = safe_normalize_len(centroid - P, &min_distance);
point_to_centroid = safe_normalize_len(centroid - P, &min_distance); distance = make_float2(min_distance, min_distance);
distance = make_float2(min_distance, min_distance);
}
cos_theta_u = FLT_MAX; cos_theta_u = FLT_MAX;

View File

@ -196,21 +196,22 @@ ccl_device_forceinline bool point_light_tree_parameters(const ccl_global KernelL
ccl_private float2 &distance, ccl_private float2 &distance,
ccl_private float3 &point_to_centroid) ccl_private float3 &point_to_centroid)
{ {
float min_distance;
point_to_centroid = safe_normalize_len(centroid - P, &min_distance);
distance = min_distance * one_float2();
if (in_volume_segment) { if (in_volume_segment) {
cos_theta_u = 1.0f; /* Any value in [-1, 1], irrelevant since theta = 0 */ cos_theta_u = 1.0f; /* Any value in [-1, 1], irrelevant since theta = 0 */
return true; return true;
} }
float dist_point_to_centroid;
point_to_centroid = safe_normalize_len(centroid - P, &dist_point_to_centroid);
const float radius = klight->spot.radius; const float radius = klight->spot.radius;
if (klight->spot.is_sphere) { if (klight->spot.is_sphere) {
if (dist_point_to_centroid > radius) { if (min_distance > radius) {
/* Equivalent to a disk light with the same angular span. */ /* Equivalent to a disk light with the same angular span. */
cos_theta_u = cos_from_sin(radius / dist_point_to_centroid); cos_theta_u = cos_from_sin(radius / min_distance);
distance = dist_point_to_centroid * make_float2(1.0f / cos_theta_u, 1.0f); distance.x = min_distance / cos_theta_u;
} }
else { else {
/* Similar to background light. */ /* Similar to background light. */
@ -220,10 +221,10 @@ ccl_device_forceinline bool point_light_tree_parameters(const ccl_global KernelL
} }
} }
else { else {
const float hypotenus = sqrtf(sqr(radius) + sqr(dist_point_to_centroid)); const float hypotenus = sqrtf(sqr(radius) + sqr(min_distance));
cos_theta_u = dist_point_to_centroid / hypotenus; cos_theta_u = min_distance / hypotenus;
distance = make_float2(hypotenus, dist_point_to_centroid); distance.x = hypotenus;
} }
return true; return true;

View File

@ -291,35 +291,32 @@ ccl_device_forceinline bool spot_light_tree_parameters(const ccl_global KernelLi
ccl_private float2 &distance, ccl_private float2 &distance,
ccl_private float3 &point_to_centroid) ccl_private float3 &point_to_centroid)
{ {
float dist_point_to_centroid; float min_distance;
const float3 point_to_centroid_ = safe_normalize_len(centroid - P, &dist_point_to_centroid); point_to_centroid = safe_normalize_len(centroid - P, &min_distance);
distance = min_distance * one_float2();
const float radius = klight->spot.radius; const float radius = klight->spot.radius;
if (klight->spot.is_sphere) { if (klight->spot.is_sphere) {
cos_theta_u = (dist_point_to_centroid > radius) ? cos_theta_u = (min_distance > radius) ? cos_from_sin(radius / min_distance) : -1.0f;
cos_from_sin(radius / dist_point_to_centroid) :
-1.0f;
if (in_volume_segment) { if (in_volume_segment) {
return true; return true;
} }
distance = (dist_point_to_centroid > radius) ? distance = (min_distance > radius) ? min_distance * make_float2(1.0f / cos_theta_u, 1.0f) :
dist_point_to_centroid * make_float2(1.0f / cos_theta_u, 1.0f) : one_float2() * radius / M_SQRT2_F;
one_float2() * radius / M_SQRT2_F;
} }
else { else {
const float hypotenus = sqrtf(sqr(radius) + sqr(dist_point_to_centroid)); const float hypotenus = sqrtf(sqr(radius) + sqr(min_distance));
cos_theta_u = dist_point_to_centroid / hypotenus; cos_theta_u = min_distance / hypotenus;
if (in_volume_segment) { if (in_volume_segment) {
return true; return true;
} }
distance = make_float2(hypotenus, dist_point_to_centroid); distance.x = hypotenus;
} }
point_to_centroid = point_to_centroid_;
return true; return true;
} }

View File

@ -333,14 +333,14 @@ ccl_device void light_tree_node_importance(KernelGlobals kg,
if (in_volume_segment) { if (in_volume_segment) {
const float3 D = N_or_D; const float3 D = N_or_D;
const float3 closest_point = P + dot(centroid - P, D) * D; const float closest_t = clamp(dot(centroid - P, D), 0.0f, t);
const float3 closest_point = P + D * closest_t;
/* Minimal distance of the ray to the cluster. */ /* Minimal distance of the ray to the cluster. */
distance = len(centroid - closest_point); distance = len(centroid - closest_point);
/* Vector that forms a minimal angle with the emitter centroid. */
point_to_centroid = -compute_v(centroid, P, D, bcone.axis, t); point_to_centroid = -compute_v(centroid, P, D, bcone.axis, t);
/* FIXME(weizhen): it is not clear from which point the `cos_theta_u` should be computed in cos_theta_u = light_tree_cos_bounding_box_angle(
* volume segment. We could use `closest_point` as a conservative measure, but then bbox, closest_point, normalize(centroid - closest_point));
* `point_to_centroid` should also use `closest_point`. */
cos_theta_u = light_tree_cos_bounding_box_angle(bbox, closest_point, point_to_centroid);
} }
else { else {
const float3 N = N_or_D; const float3 N = N_or_D;
@ -405,8 +405,8 @@ ccl_device void light_tree_emitter_importance(KernelGlobals kg,
bcone.theta_o = kemitter->theta_o; bcone.theta_o = kemitter->theta_o;
bcone.theta_e = kemitter->theta_e; bcone.theta_e = kemitter->theta_e;
float cos_theta_u; float cos_theta_u;
float2 distance; /* distance.x = max_distance, distance.y = mix_distance */ float2 distance; /* distance.x = max_distance, distance.y = min_distance */
float3 centroid, point_to_centroid, P_c; float3 centroid, point_to_centroid, P_c = P;
if (!compute_emitter_centroid_and_dir<in_volume_segment>(kg, kemitter, P, centroid, bcone.axis)) if (!compute_emitter_centroid_and_dir<in_volume_segment>(kg, kemitter, P, centroid, bcone.axis))
{ {
@ -415,15 +415,9 @@ ccl_device void light_tree_emitter_importance(KernelGlobals kg,
if (in_volume_segment) { if (in_volume_segment) {
const float3 D = N_or_D; const float3 D = N_or_D;
/* Closest point. */ /* Closest point from ray to the emitter centroid. */
P_c = P + dot(centroid - P, D) * D; const float closest_t = clamp(dot(centroid - P, D), 0.0f, t);
/* Minimal distance of the ray to the cluster. */ P_c += D * closest_t;
distance.x = len(centroid - P_c);
distance.y = distance.x;
point_to_centroid = -compute_v(centroid, P, D, bcone.axis, t);
}
else {
P_c = P;
} }
/* Early out if the emitter is guaranteed to be invisible. */ /* Early out if the emitter is guaranteed to be invisible. */
@ -457,6 +451,9 @@ ccl_device void light_tree_emitter_importance(KernelGlobals kg,
case LIGHT_DISTANT: case LIGHT_DISTANT:
is_visible = distant_light_tree_parameters( is_visible = distant_light_tree_parameters(
centroid, bcone.theta_e, cos_theta_u, distance, point_to_centroid); centroid, bcone.theta_e, cos_theta_u, distance, point_to_centroid);
if (in_volume_segment) {
centroid = P - bcone.axis;
}
break; break;
default: default:
return; return;
@ -468,6 +465,11 @@ ccl_device void light_tree_emitter_importance(KernelGlobals kg,
return; return;
} }
if (in_volume_segment) {
/* Vector that forms a minimal angle with the emitter centroid. */
point_to_centroid = -compute_v(centroid, P, N_or_D, bcone.axis, t);
}
light_tree_importance<in_volume_segment>(N_or_D, light_tree_importance<in_volume_segment>(N_or_D,
has_transmission, has_transmission,
point_to_centroid, point_to_centroid,

View File

@ -301,13 +301,11 @@ ccl_device_forceinline bool triangle_light_tree_parameters(
ccl_private float2 &distance, ccl_private float2 &distance,
ccl_private float3 &point_to_centroid) ccl_private float3 &point_to_centroid)
{ {
if (!in_volume_segment) { /* TODO: a cheap substitute for minimal distance between point and primitive. Does it worth the
/* TODO: a cheap substitute for minimal distance between point and primitive. Does it * overhead to compute the accurate minimal distance? */
* worth the overhead to compute the accurate minimal distance? */ float min_distance;
float min_distance; point_to_centroid = safe_normalize_len(centroid - P, &min_distance);
point_to_centroid = safe_normalize_len(centroid - P, &min_distance); distance = make_float2(min_distance, min_distance);
distance = make_float2(min_distance, min_distance);
}
cos_theta_u = FLT_MAX; cos_theta_u = FLT_MAX;

View File

@ -28,6 +28,10 @@ void Sampling::init(const Scene *scene)
{ {
sample_count_ = inst_.is_viewport() ? scene->eevee.taa_samples : scene->eevee.taa_render_samples; sample_count_ = inst_.is_viewport() ? scene->eevee.taa_samples : scene->eevee.taa_render_samples;
if (inst_.is_image_render()) {
sample_count_ = math::max(uint64_t(1), sample_count_);
}
if (sample_count_ == 0) { if (sample_count_ == 0) {
BLI_assert(inst_.is_viewport()); BLI_assert(inst_.is_viewport());
sample_count_ = infinite_sample_count_; sample_count_ = infinite_sample_count_;

View File

@ -3585,6 +3585,7 @@ static bool knife_snap_angle_relative(KnifeTool_OpData *kcd)
/* Choose best face for plane. */ /* Choose best face for plane. */
BMFace *fprev = nullptr; BMFace *fprev = nullptr;
int fprev_ob_index = kcd->prev.ob_index;
if (kcd->prev.vert && kcd->prev.vert->v) { if (kcd->prev.vert && kcd->prev.vert->v) {
LISTBASE_FOREACH (LinkData *, ref, &kcd->prev.vert->faces) { LISTBASE_FOREACH (LinkData *, ref, &kcd->prev.vert->faces) {
f = ((BMFace *)(ref->data)); f = ((BMFace *)(ref->data));
@ -3615,7 +3616,7 @@ static bool knife_snap_angle_relative(KnifeTool_OpData *kcd)
/* kcd->prev.face is usually not set. */ /* kcd->prev.face is usually not set. */
fprev = knife_bvh_raycast( fprev = knife_bvh_raycast(
kcd, prev_origin, prev_ray_normal, 0.0f, nullptr, prev_cage, nullptr); kcd, prev_origin, prev_ray_normal, 0.0f, nullptr, prev_cage, &fprev_ob_index);
} }
if (!fprev || fprev != fcurr) { if (!fprev || fprev != fcurr) {
@ -3623,7 +3624,7 @@ static bool knife_snap_angle_relative(KnifeTool_OpData *kcd)
} }
/* Use normal global direction. */ /* Use normal global direction. */
Object *ob = kcd->objects[kcd->curr.ob_index]; Object *ob = kcd->objects[fprev_ob_index];
float no_global[3]; float no_global[3];
copy_v3_v3(no_global, fprev->no); copy_v3_v3(no_global, fprev->no);
mul_transposed_mat3_m4_v3(ob->world_to_object().ptr(), no_global); mul_transposed_mat3_m4_v3(ob->world_to_object().ptr(), no_global);

@ -1 +1 @@
Subproject commit 5f22621489df3883cfeac7d49329ea3180a07250 Subproject commit 7d6518ef5fbada0da13736173b1b06e6fbd1941b