blender/intern/cycles/kernel/light/common.h
Sergey Sharybin fde6280480 Refactor: Cycles: Split off visibility from path flags
The issue this change aims to solve is the fact that we are out of bits
in the PathRayFlag. There is a TODO in the code about the fact that we
might need a flag to record primary scatter for volumes. Additionally,
there are plans to introduce visibility flags for the raycast node
rays.

The choice of the underlying type for the PathRayVisibilityFlag keeps
the raycast visibility in mind.

There is now a dedicated type alias to pass visiiblity around in the
kernel. Currently it is 32 bit, keeping in mind possibility of shift
introduced by the shadow catcher. It is possible to limit it to 16,
but then we'd be limited to only 8 visibility bits (which would be
fine until we introduce other flag after the raycast visibility).
Although, it is not really clear it will brings an actual performance
improvement.

The main path state is using 16 to store path visibility, as per the
underlying type of the PathRayVisibilityFlag. It is possible to limit
it to 8 bit to keep state size small until even more ray visibility
bits be needed in the future (the unaligned node bit is not used by the
path visibility).

The shadow path state also needs path visibility to check which path
type it deals with.

Ref !157822
2026-05-27 19:22:53 +02:00

96 lines
3.1 KiB
C

/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation
*
* SPDX-License-Identifier: Apache-2.0 */
#pragma once
#include "kernel/types.h"
#include "kernel/sample/mapping.h"
CCL_NAMESPACE_BEGIN
/* Result from light sampling with next event estimation.
*
* TODO: It may be possible to reduce the size of this struct now that shader evaluation
* no longer uses this. For example D, Ng or P, though it's not trivial. */
struct LightSample {
float3 P; /* position on light, or direction for distant light */
packed_float3 Ng; /* normal on light */
float t; /* distance to light (FLT_MAX for distant light) */
float3 D; /* direction from shading point to light */
float pdf; /* pdf for selecting light and point on light */
float pdf_selection; /* pdf for selecting light */
float eval_fac; /* intensity multiplier (normalization, spot falloff) */
int object; /* object id for triangle/curve lights */
int prim; /* lamp id for lights, primitive id for triangle/curve lights */
int shader; /* shader id */
int group; /* lightgroup */
LightType type; /* type of light */
int emitter_id; /* index in the emitter array */
};
/* Result of evaluating a light from an intersection. */
struct LightEval {
float eval_fac = 0.0f; /* Intensity multiplier (normalization, spot falloff) */
float pdf = 0.0f; /* PDF for light sampling with next event estimation sampling. */
};
/* Utilities */
ccl_device_inline float3 ellipse_sample(const float3 ru, const float3 rv, const float2 rand)
{
const float2 uv = sample_uniform_disk(rand);
return ru * uv.x + rv * uv.y;
}
ccl_device_inline float3 rectangle_sample(const float3 ru, const float3 rv, const float2 rand)
{
return ru * (2.0f * rand.x - 1.0f) + rv * (2.0f * rand.y - 1.0f);
}
ccl_device float3 disk_light_sample(const float3 n, const float2 rand)
{
float3 ru;
float3 rv;
make_orthonormals(n, &ru, &rv);
return ellipse_sample(ru, rv, rand);
}
ccl_device float light_pdf_area_to_solid_angle(const float3 Ng, const float3 I, const float t)
{
const float cos_pi = dot(Ng, I);
if (cos_pi <= 0.0f) {
return 0.0f;
}
return t * t / cos_pi;
}
/* Visibility flag om the light shader. */
ccl_device_inline bool is_light_shader_visible_to_path(const int shader,
const PathRayVisibility path_visibility,
const uint32_t path_flag)
{
if ((shader & SHADER_EXCLUDE_ANY) == 0) {
return true;
}
if (((shader & SHADER_EXCLUDE_DIFFUSE) && (path_visibility & PATH_RAY_VISIBILITY_DIFFUSE)) ||
((shader & SHADER_EXCLUDE_GLOSSY) &&
((path_visibility & PATH_RAY_VISIBILITY_GLOSSY) && (path_flag & PATH_RAY_REFLECT))) ||
((shader & SHADER_EXCLUDE_TRANSMIT) && (path_visibility & PATH_RAY_VISIBILITY_TRANSMIT)) ||
((shader & SHADER_EXCLUDE_CAMERA) && (path_visibility & PATH_RAY_VISIBILITY_CAMERA)) ||
((shader & SHADER_EXCLUDE_SCATTER) &&
(path_visibility & PATH_RAY_VISIBILITY_VOLUME_SCATTER)))
{
return false;
}
return true;
}
CCL_NAMESPACE_END