WIP: Brush assets project #106303
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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_;
|
||||||
|
|
|
@ -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
|
Loading…
Reference in New Issue