UI: Window Title With Version #111998

Merged
Harley Acheson merged 14 commits from Harley/blender:WindowTitle into main 2023-09-16 02:37:12 +02:00
232 changed files with 2706 additions and 2607 deletions
Showing only changes of commit 7e65a18b05 - Show all commits

View File

@ -514,7 +514,7 @@ check_spelling_shaders: .FORCE
PYTHONIOENCODING=utf_8 $(PYTHON) \
"$(BLENDER_DIR)/tools/check_source/check_spelling.py" \
--cache-file=$(CHECK_SPELLING_CACHE) \
--match=".*\.(osl|msl|glsl)$$" \
--match=".*\.(osl|metal|msl|glsl)$$" \
"$(BLENDER_DIR)/intern/" \
"$(BLENDER_DIR)/source/"

View File

@ -12,6 +12,9 @@ if(DEFINED HIP_ROOT_DIR AND HIP_ROOT_DIR)
# Pass.
elseif(DEFINED ENV{HIP_ROOT_DIR})
set(HIP_ROOT_DIR $ENV{HIP_ROOT_DIR})
elseif(DEFINED ENV{HIP_PATH})
# Built-in environment variable from SDK.
set(HIP_ROOT_DIR $ENV{HIP_PATH})
else()
set(HIP_ROOT_DIR "")
endif()

View File

@ -12,6 +12,9 @@ if(DEFINED HIPRT_ROOT_DIR AND HIPRT_ROOT_DIR)
# Pass.
elseif(DEFINED ENV{HIPRT_ROOT_DIR})
set(HIPRT_ROOT_DIR $ENV{HIPRT_ROOT_DIR})
elseif(DEFINED ENV{HIP_PATH})
# Built-in environment variable from SDK.
set(HIPRT_ROOT_DIR $ENV{HIP_PATH})
else()
set(HIPRT_ROOT_DIR "")
endif()
@ -24,6 +27,7 @@ find_path(HIPRT_INCLUDE_DIR
NAMES
hiprt/hiprt.h
HINTS
${_hiprt_SEARCH_DIRS}/include
${_hiprt_SEARCH_DIRS}
)
@ -36,6 +40,7 @@ if(HIPRT_INCLUDE_DIR)
NAMES
hiprt${_hiprt_version}_amd_lib_win.bc
HINTS
${HIPRT_ROOT_DIR}/bin
${HIPRT_ROOT_DIR}/dist/bin/Release
NO_DEFAULT_PATH
)

View File

@ -21,28 +21,28 @@ extern void *AUD_createSet(void);
/**
* Deletes a set.
* \param set The set to delete.
* \param set: The set to delete.
*/
extern void AUD_destroySet(void *set);
/**
* Removes an entry from a set.
* \param set The set work on.
* \param entry The entry to remove.
* \param set: The set work on.
* \param entry: The entry to remove.
* \return Whether the entry was in the set or not.
*/
extern char AUD_removeSet(void *set, void *entry);
/**
* Adds a new entry to a set.
* \param set The set work on.
* \param entry The entry to add.
* \param set: The set work on.
* \param entry: The entry to add.
*/
extern void AUD_addSet(void *set, void *entry);
/**
* Removes one entry from a set and returns it.
* \param set The set work on.
* \param set: The set work on.
* \return The entry or NULL if the set is empty.
*/
extern void *AUD_getSet(void *set);

View File

@ -55,6 +55,9 @@ bool device_oneapi_init()
if (getenv("SYCL_PI_LEVEL_ZERO_USE_COPY_ENGINE_FOR_IN_ORDER_QUEUE") == nullptr) {
_putenv_s("SYCL_PI_LEVEL_ZERO_USE_COPY_ENGINE_FOR_IN_ORDER_QUEUE", "0");
}
if (getenv("SYCL_PI_LEVEL_ZERO_USE_COPY_ENGINE") == nullptr) {
_putenv_s("SYCL_PI_LEVEL_ZERO_USE_COPY_ENGINE", "0");
}
# elif __linux__
setenv("SYCL_CACHE_PERSISTENT", "1", false);
setenv("SYCL_CACHE_THRESHOLD", "0", false);
@ -66,6 +69,7 @@ bool device_oneapi_init()
}
setenv("SYCL_ENABLE_PCI", "1", false);
setenv("SYCL_PI_LEVEL_ZERO_USE_COPY_ENGINE_FOR_IN_ORDER_QUEUE", "0", false);
setenv("SYCL_PI_LEVEL_ZERO_USE_COPY_ENGINE", "0", false);
# endif
return true;

View File

@ -1000,6 +1000,7 @@ if(WITH_CYCLES_DEVICE_ONEAPI)
-L"${WINDOWS_KIT_DIR}/ucrt/x64")
else() # Add Linux specific compiler flags.
list(APPEND sycl_compiler_flags -fPIC)
list(APPEND sycl_compiler_flags -fvisibility=hidden)
# We avoid getting __FAST_MATH__ to be defined when building on CentOS-7 and Rocky-8
# until the compilation issues it triggers at either AoT or JIT stages gets fixed.

View File

@ -459,6 +459,7 @@ ccl_device_inline
{
Spectrum eval = zero_spectrum();
*pdf = 0.f;
const float3 Ng = (sd->type & PRIMITIVE_CURVE) ? sc->N : sd->Ng;
switch (sc->type) {
case CLOSURE_BSDF_DIFFUSE_ID:
@ -486,15 +487,15 @@ ccl_device_inline
case CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID:
case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID:
case CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID:
eval = bsdf_microfacet_ggx_eval(sc, sd->N, sd->wi, wo, pdf);
eval = bsdf_microfacet_ggx_eval(sc, Ng, sd->wi, wo, pdf);
break;
case CLOSURE_BSDF_MICROFACET_BECKMANN_ID:
case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID:
case CLOSURE_BSDF_MICROFACET_BECKMANN_GLASS_ID:
eval = bsdf_microfacet_beckmann_eval(sc, sd->N, sd->wi, wo, pdf);
eval = bsdf_microfacet_beckmann_eval(sc, Ng, sd->wi, wo, pdf);
break;
case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID:
eval = bsdf_ashikhmin_shirley_eval(sc, sd->N, sd->wi, wo, pdf);
eval = bsdf_ashikhmin_shirley_eval(sc, Ng, sd->wi, wo, pdf);
break;
case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID:
eval = bsdf_ashikhmin_velvet_eval(sc, sd->wi, wo, pdf);

View File

@ -207,7 +207,7 @@ ccl_device int bsdf_ashikhmin_shirley_sample(ccl_private const ShaderClosure *sc
}
else {
/* leave the rest to eval */
*eval = bsdf_ashikhmin_shirley_eval(sc, N, wi, *wo, pdf);
*eval = bsdf_ashikhmin_shirley_eval(sc, Ng, wi, *wo, pdf);
}
return label;

View File

@ -329,7 +329,11 @@ ccl_device_inline void microfacet_ggx_preserve_energy(KernelGlobals kg,
* code for that), but e.g. a reflection-only closure with Fresnel applied can end up having
* a very low overall albedo.
* This is used to adjust the sample weight, as well as for the Diff/Gloss/Trans Color pass
* and the Denoising Albedo pass. */
* and the Denoising Albedo pass.
* Use lookup tables for generalized Schlick. Otherwise assuming that the surface is smooth. */
/* TODO: The Schlick LUT seems to assume energy preservation, which is not true for GGX. if
* energy-preserving then transmission should just be `1 - reflection`. For dielectric we could
* probably split the LUT for multiGGX if smooth assumption is not good enough. */
ccl_device Spectrum bsdf_microfacet_estimate_albedo(KernelGlobals kg,
ccl_private const ShaderData *sd,
ccl_private const MicrofacetBsdf *bsdf,
@ -362,8 +366,6 @@ ccl_device Spectrum bsdf_microfacet_estimate_albedo(KernelGlobals kg,
albedo += mix(fresnel->f0, fresnel->f90, s) * fresnel->reflection_tint;
}
else {
/* If we don't (yet) have a way to estimate albedo in a way that accounts for roughness,
* fall back to assuming that the surface is smooth. */
albedo += microfacet_fresnel(bsdf, sd->wi, bsdf->N, false);
}
}
@ -513,6 +515,9 @@ ccl_device Spectrum bsdf_microfacet_eval(ccl_private const ShaderClosure *sc,
}
/* Compute half vector. */
/* TODO: deal with the case when `bsdf->ior` is close to one. */
/* TODO: check if the refraction configuration is valid. See `btdf_ggx()` in
* `eevee_bxdf_lib.glsl`. */
float3 H = is_transmission ? -(bsdf->ior * wo + wi) : (wi + wo);
const float inv_len_H = 1.0f / len(H);
H *= inv_len_H;
@ -520,7 +525,8 @@ ccl_device Spectrum bsdf_microfacet_eval(ccl_private const ShaderClosure *sc,
const float cos_NH = dot(N, H);
float D, lambdaI, lambdaO;
/* TODO: add support for anisotropic transmission. */
/* NOTE: we could add support for anisotropic transmission, although it will make dispersion
* harder to compute. */
if (alpha_x == alpha_y || is_transmission) { /* Isotropic. */
float alpha2 = alpha_x * alpha_y;
@ -559,8 +565,7 @@ ccl_device Spectrum bsdf_microfacet_eval(ccl_private const ShaderClosure *sc,
float lobe_pdf = 1.0f;
if (m_glass) {
float fresnel = fresnel_dielectric_cos(dot(H, wi), bsdf->ior);
float reflect_pdf = (fresnel == 1.0f) ? 1.0f : clamp(fresnel, 0.125f, 0.875f);
lobe_pdf = is_transmission ? (1.0f - reflect_pdf) : reflect_pdf;
lobe_pdf = is_transmission ? (1.0f - fresnel) : fresnel;
}
*pdf = common * lobe_pdf / (1.0f + lambdaI);
@ -583,32 +588,29 @@ ccl_device int bsdf_microfacet_sample(ccl_private const ShaderClosure *sc,
{
ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc;
const float3 N = bsdf->N;
const float cos_NI = dot(N, wi);
if (cos_NI <= 0) {
/* Incident angle from the lower hemisphere is invalid. */
return LABEL_NONE;
}
const float m_eta = bsdf->ior;
const float m_inv_eta = 1.0f / bsdf->ior;
const bool m_refraction = CLOSURE_IS_REFRACTION(bsdf->type);
const bool m_glass = CLOSURE_IS_GLASS(bsdf->type);
const bool m_reflection = !(m_refraction || m_glass);
const float alpha_x = bsdf->alpha_x;
const float alpha_y = bsdf->alpha_y;
bool m_singular = !bsdf_microfacet_eval_flag(bsdf);
const float3 N = bsdf->N;
const float cos_NI = dot(N, wi);
if (cos_NI <= 0) {
*eval = zero_spectrum();
*pdf = 0.0f;
return (m_reflection ? LABEL_REFLECT : LABEL_TRANSMIT) |
(m_singular ? LABEL_SINGULAR : LABEL_GLOSSY);
}
float3 H;
float cos_NH, cos_HI;
float3 local_H, local_I, X, Y; /* Needed for anisotropic microfacets later. */
/* Needed for anisotropic microfacets later. */
float3 local_H, local_I;
if (m_singular) {
H = N;
cos_NH = 1.0f;
cos_HI = cos_NI;
}
else {
float3 X, Y;
if (alpha_x == alpha_y) {
make_orthonormals(N, &X, &Y);
}
@ -628,83 +630,63 @@ ccl_device int bsdf_microfacet_sample(ccl_private const ShaderClosure *sc,
}
H = X * local_H.x + Y * local_H.y + N * local_H.z;
cos_NH = local_H.z;
cos_HI = dot(H, wi);
}
const float cos_HI = dot(H, wi);
bool valid;
/* The angle between the half vector and the refracted ray. Not used when sampling reflection. */
float cos_HO;
bool do_refract;
float lobe_pdf;
if (m_refraction || m_glass) {
bool inside;
float fresnel = fresnel_dielectric(m_eta, H, wi, wo, &inside);
valid = !inside;
float fresnel = fresnel_dielectric(cos_HI, m_eta, &cos_HO);
/* For glass closures, we decide between reflection and refraction here. */
if (m_glass) {
if (fresnel == 1.0f) {
/* TIR, reflection is the only option. */
do_refract = false;
lobe_pdf = 1.0f;
}
else {
/* Decide between reflection and refraction, using defensive sampling to avoid
* excessive noise for reflection highlights. */
float reflect_pdf = (path_flag & PATH_RAY_CAMERA) ? clamp(fresnel, 0.125f, 0.875f) :
fresnel;
do_refract = (rand.z >= reflect_pdf);
lobe_pdf = do_refract ? (1.0f - reflect_pdf) : reflect_pdf;
}
do_refract = (rand.z >= fresnel);
lobe_pdf = do_refract ? (1.0f - fresnel) : fresnel;
}
else {
/* For pure refractive closures, refraction is the only option. */
if (fresnel == 1.0f) {
return LABEL_NONE;
}
do_refract = true;
lobe_pdf = 1.0f;
valid = valid && (fresnel != 1.0f);
}
}
else {
/* Pure reflective closure, reflection is the only option. */
valid = true;
lobe_pdf = 1.0f;
do_refract = false;
}
int label;
if (do_refract) {
/* wo was already set to the refracted direction by fresnel_dielectric. */
// valid = valid && (dot(Ng, *wo) < 0);
label = LABEL_TRANSMIT;
*wo = refract_angle(wi, H, cos_HO, m_inv_eta);
/* If the IOR is close enough to 1.0, just treat the interaction as specular. */
m_singular = m_singular || (fabsf(m_eta - 1.0f) < 1e-4f);
}
else {
/* Eq. 39 - compute actual reflected direction */
*wo = 2 * cos_HI * H - wi;
valid = valid && (dot(Ng, *wo) > 0);
label = LABEL_REFLECT;
}
if (!valid) {
*eval = zero_spectrum();
*pdf = 0.0f;
return label | (m_singular ? LABEL_SINGULAR : LABEL_GLOSSY);
if ((dot(Ng, *wo) < 0) != do_refract) {
return LABEL_NONE;
}
if (m_singular) {
label |= LABEL_SINGULAR;
/* Some high number for MIS. */
*pdf = lobe_pdf * 1e6f;
*eval = make_spectrum(1e6f) * microfacet_fresnel(bsdf, wi, H, do_refract);
}
else {
label |= LABEL_GLOSSY;
float cos_NO = dot(N, *wo);
float D, lambdaI, lambdaO;
/* TODO: add support for anisotropic transmission. */
if (alpha_x == alpha_y || do_refract) { /* Isotropic. */
float alpha2 = alpha_x * alpha_y;
const float cos_NH = dot(N, H);
const float cos_NO = dot(N, *wo);
if (bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID) {
D = bsdf_clearcoat_D(alpha2, cos_NH);
@ -721,7 +703,7 @@ ccl_device int bsdf_microfacet_sample(ccl_private const ShaderClosure *sc,
lambdaI = bsdf_lambda<m_type>(alpha2, cos_NI);
}
else { /* Anisotropic. */
const float3 local_O = make_float3(dot(X, *wo), dot(Y, *wo), cos_NO);
const float3 local_O = 2.0f * cos_HI * local_H - local_I;
D = bsdf_aniso_D<m_type>(alpha_x, alpha_y, local_H);
@ -729,9 +711,8 @@ ccl_device int bsdf_microfacet_sample(ccl_private const ShaderClosure *sc,
lambdaI = bsdf_aniso_lambda<m_type>(alpha_x, alpha_y, local_I);
}
const float cos_HO = dot(H, *wo);
const float common = D / cos_NI *
(do_refract ? fabsf(cos_HI * cos_HO) / sqr(cos_HO + cos_HI / m_eta) :
(do_refract ? fabsf(cos_HI * cos_HO) / sqr(cos_HO + cos_HI * m_inv_eta) :
0.25f);
*pdf = common * lobe_pdf / (1.0f + lambdaI);
@ -741,9 +722,10 @@ ccl_device int bsdf_microfacet_sample(ccl_private const ShaderClosure *sc,
}
*sampled_roughness = make_float2(alpha_x, alpha_y);
*eta = do_refract ? 1.0f / m_eta : m_eta;
*eta = do_refract ? m_inv_eta : m_eta;
return label;
return (do_refract ? LABEL_TRANSMIT : LABEL_REFLECT) |
(m_singular ? LABEL_SINGULAR : LABEL_GLOSSY);
}
/* Fresnel term setup functions. These get called after the distribution-specific setup functions

View File

@ -17,15 +17,15 @@ ccl_device float fresnel_dielectric(float cos_theta_i, float eta, ccl_private fl
/* Using Snell's law, calculate the squared cosine of the angle between the surface normal and
* the transmitted ray. */
const float cos_theta_t_sq = 1.0f - (1.0f - sqr(cos_theta_i)) / sqr(eta);
if (cos_theta_t_sq <= 0) {
const float eta_cos_theta_t_sq = sqr(eta) - (1.0f - sqr(cos_theta_i));
if (eta_cos_theta_t_sq <= 0) {
/* Total internal reflection. */
return 1.0f;
}
cos_theta_i = fabsf(cos_theta_i);
/* Relative to the surface normal. */
const float cos_theta_t = -safe_sqrtf(cos_theta_t_sq);
const float cos_theta_t = -safe_sqrtf(eta_cos_theta_t_sq) / eta;
if (r_cos_theta_t) {
*r_cos_theta_t = cos_theta_t;
@ -48,45 +48,6 @@ ccl_device_inline float3 refract_angle(const float3 incident,
return (inv_eta * dot(normal, incident) + cos_theta_t) * normal - inv_eta * incident;
}
ccl_device float fresnel_dielectric(
float eta, const float3 N, const float3 I, ccl_private float3 *T, ccl_private bool *is_inside)
{
float cos = dot(N, I), neta;
float3 Nn;
// check which side of the surface we are on
if (cos > 0) {
// we are on the outside of the surface, going in
neta = 1 / eta;
Nn = N;
*is_inside = false;
}
else {
// we are inside the surface
cos = -cos;
neta = eta;
Nn = -N;
*is_inside = true;
}
float arg = 1 - (neta * neta * (1 - (cos * cos)));
if (arg < 0) {
*T = make_float3(0.0f, 0.0f, 0.0f);
return 1; // total internal reflection
}
else {
float dnp = max(sqrtf(arg), 1e-7f);
float nK = (neta * cos) - dnp;
*T = -(neta * I) + (nK * Nn);
// compute Fresnel terms
float cosTheta1 = cos; // N.R
float cosTheta2 = -dot(Nn, *T);
float pPara = (cosTheta1 - eta * cosTheta2) / (cosTheta1 + eta * cosTheta2);
float pPerp = (eta * cosTheta1 - cosTheta2) / (eta * cosTheta1 + cosTheta2);
return 0.5f * (pPara * pPara + pPerp * pPerp);
}
}
ccl_device float fresnel_dielectric_cos(float cosi, float eta)
{
// compute fresnel reflectance without explicitly computing

View File

@ -202,7 +202,7 @@ bool metalrt_shadow_all_hit(constant KernelParamsMetal &launch_params_metal,
type = segment.type;
prim = segment.prim;
/* Filter out curve endcaps */
/* Filter out curve end-caps. */
if (u == 0.0f || u == 1.0f) {
/* continue search */
return true;
@ -349,7 +349,7 @@ inline TReturnType metalrt_visibility_test(
if (intersection_type == METALRT_HIT_BOUNDING_BOX &&
(type == PRIMITIVE_CURVE_THICK || type == PRIMITIVE_CURVE_RIBBON))
{
/* Filter out curve endcaps. */
/* Filter out curve end-caps. */
if (u == 0.0f || u == 1.0f) {
result.accept = false;
result.continue_search = true;

View File

@ -20,7 +20,7 @@ enum DeviceKernel : int;
# define CYCLES_KERNEL_ONEAPI_EXPORT extern __declspec(dllimport)
# endif
# else
# define CYCLES_KERNEL_ONEAPI_EXPORT
# define CYCLES_KERNEL_ONEAPI_EXPORT extern __attribute__((visibility("default")))
# endif
# endif

View File

@ -633,6 +633,7 @@ ccl_device_forceinline Spectrum mnee_eval_bsdf_contribution(ccl_private ShaderCl
* contribution = bsdf_do * |do/dh| * |n.wo / n.h| / pdf_dh
* = (1 - F) * G * |h.wi / (n.wi * n.h^2)|
*/
/* TODO: energy compensation for multi-GGX. */
return bsdf->weight * F * G * fabsf(cosHI / (cosNI * sqr(cosThetaM)));
}

View File

@ -176,32 +176,6 @@ ccl_device_inline void surface_shader_prepare_closures(KernelGlobals kg,
}
}
/* Defensive sampling.
*
* We can likely also do defensive sampling at deeper bounces, particularly
* for cases like a perfect mirror but possibly also others. This will need
* a good heuristic. */
if (INTEGRATOR_STATE(state, path, bounce) + INTEGRATOR_STATE(state, path, transparent_bounce) ==
0 &&
sd->num_closure > 1)
{
float sum = 0.0f;
for (int i = 0; i < sd->num_closure; i++) {
ccl_private ShaderClosure *sc = &sd->closure[i];
if (CLOSURE_IS_BSDF_OR_BSSRDF(sc->type)) {
sum += sc->sample_weight;
}
}
for (int i = 0; i < sd->num_closure; i++) {
ccl_private ShaderClosure *sc = &sd->closure[i];
if (CLOSURE_IS_BSDF_OR_BSSRDF(sc->type)) {
sc->sample_weight = max(sc->sample_weight, 0.125f * sum);
}
}
}
/* Filter glossy.
*
* Blurring of bsdf after bounces, for rays that have a small likelihood
@ -489,7 +463,7 @@ ccl_device int surface_shader_bsdf_guided_sample_closure_mis(KernelGlobals kg,
ccl_private float3 *wo,
ccl_private float *bsdf_pdf,
ccl_private float *unguided_bsdf_pdf,
ccl_private float2 *sampled_rougness,
ccl_private float2 *sampled_roughness,
ccl_private float *eta)
{
/* BSSRDF should already have been handled elsewhere. */
@ -560,7 +534,7 @@ ccl_device int surface_shader_bsdf_guided_sample_closure_mis(KernelGlobals kg,
kernel_assert(reduce_min(bsdf_eval_sum(bsdf_eval)) >= 0.0f);
*sampled_rougness = make_float2(1.0f, 1.0f);
*sampled_roughness = make_float2(1.0f, 1.0f);
*eta = 1.0f;
}
else {
@ -574,14 +548,14 @@ ccl_device int surface_shader_bsdf_guided_sample_closure_mis(KernelGlobals kg,
&eval,
wo,
unguided_bsdf_pdf,
sampled_rougness,
sampled_roughness,
eta);
# if 0
// Code path to validate the estimation of the label, sampled roughness and eta
// This should be activated from time to time when the BSDFs change to check if everything
// is still working correctly.
if (*unguided_bsdf_pdf > 0.0f) {
surface_shader_validate_bsdf_sample(kg, sc, *wo, label, sampled_roughness, eta);
surface_shader_validate_bsdf_sample(kg, sc, *wo, label, *sampled_roughness, *eta);
}
# endif
@ -824,7 +798,7 @@ ccl_device int surface_shader_bsdf_guided_sample_closure_ris(KernelGlobals kg,
// This should be activated from time to time when the BSDFs change to check if everything
// is still working correctly.
if (*unguided_bsdf_pdf > 0.0f) {
surface_shader_validate_bsdf_sample(kg, sc, *wo, label, sampled_roughness, eta);
surface_shader_validate_bsdf_sample(kg, sc, *wo, label, *sampled_roughness, *eta);
}
# endif

View File

@ -406,6 +406,11 @@ LightTreeNode *LightTree::build(Scene *scene, DeviceScene *dscene)
left, root_.get(), num_emissive_triangles, num_local_lights, emitters_.data(), 0, 1);
task_pool.wait_work();
if (progress_.get_cancel()) {
root_.reset();
return nullptr;
}
/* All distant lights are grouped to the right child as a leaf node. */
root_->get_inner().children[right] = create_node(LightTreeMeasure::empty, 1);
for (int i = 0; i < num_distant_lights; i++) {

View File

@ -473,7 +473,6 @@ class GHOST_ISystem {
/**
* Returns the selection buffer
* \return "unsigned char" from X11 XA_CUT_BUFFER0 buffer
*
*/
virtual char *getClipboard(bool selection) const = 0;

View File

@ -327,7 +327,6 @@ class GHOST_System : public GHOST_ISystem {
* Returns the selection buffer
* \param selection: Only used on X11.
* \return Returns the clipboard data
*
*/
virtual char *getClipboard(bool selection) const = 0;

View File

@ -19,7 +19,7 @@
47:Slovak (Slovenčina):sk_SK
#
0:In Progress:
11:Czech (Český):cs_CZ
11:Czech (Čeština):cs_CZ
5:German (Deutsch):de_DE
4:Italian (Italiano):it_IT
48:Georgian (ქართული):ka

View File

@ -44,7 +44,7 @@ LANGUAGES = (
(8, "French (Français)", "fr_FR"),
(9, "Spanish (Español)", "es"),
(10, "Catalan (Català)", "ca_AD"),
(11, "Czech (Český)", "cs_CZ"),
(11, "Czech (Čeština)", "cs_CZ"),
(12, "Portuguese (Português)", "pt_PT"),
(13, "Simplified Chinese (简体中文)", "zh_CN"),
(14, "Traditional Chinese (繁體中文)", "zh_TW"),

View File

@ -83,7 +83,7 @@ class _BPyOpsSubModOp:
return _op_poll(self.idname_py(), C_exec)
def idname(self):
# submod.foo -> SUBMOD_OT_foo
# `submod.foo` -> `SUBMOD_OT_foo`.
return self._module.upper() + "_OT_" + self._func
def idname_py(self):

View File

@ -199,8 +199,8 @@ def load_scripts(*, reload_scripts=False, refresh_scripts=False, extensions=True
:arg refresh_scripts: only load scripts which are not already loaded
as modules.
:type refresh_scripts: bool
:arg: extensions: Loads additional scripts (add-ons & app-templates).
:type: extensions: bool
:arg extensions: Loads additional scripts (add-ons & app-templates).
:type extensions: bool
"""
use_time = use_class_register_check = _bpy.app.debug_python
use_user = not _is_factory_startup

View File

@ -362,15 +362,15 @@ def _template_items_transform_actions(
("transform.translate", {"type": params.select_mouse, "value": 'CLICK_DRAG'}, None),
op_tool_optional(
("transform.translate", {"type": 'G', "value": 'PRESS'},
{"properties": [("alt_navigation", params.use_alt_navigation)]}),
{"properties": [("alt_navigation", params.use_alt_navigation)]}),
(op_tool_cycle, "builtin.move"), params),
op_tool_optional(
("transform.rotate", {"type": 'R', "value": 'PRESS'},
{"properties": [("alt_navigation", params.use_alt_navigation)]}),
{"properties": [("alt_navigation", params.use_alt_navigation)]}),
(op_tool_cycle, "builtin.rotate"), params),
op_tool_optional(
("transform.resize", {"type": 'S', "value": 'PRESS'},
{"properties": [("alt_navigation", params.use_alt_navigation)]}),
{"properties": [("alt_navigation", params.use_alt_navigation)]}),
(op_tool_cycle, "builtin.scale"), params),
]
@ -568,7 +568,6 @@ def _template_items_tool_select(
# Always use the cursor operator where possible,
# needed for time-line views where we always want to be able to scrub time.
cursor_prioritize=False,
operator_props=(),
fallback=False,
):
if not params.legacy and not fallback:
@ -585,11 +584,11 @@ def _template_items_tool_select(
if select_passthrough:
return [
(operator, {"type": 'LEFTMOUSE', "value": 'PRESS'},
{"properties": [("deselect_all", True), ("select_passthrough", True), *operator_props]}),
{"properties": [("deselect_all", True), ("select_passthrough", True)]}),
(operator, {"type": 'LEFTMOUSE', "value": 'CLICK'},
{"properties": [("deselect_all", True), *operator_props]}),
{"properties": [("deselect_all", True)]}),
(operator, {"type": 'LEFTMOUSE', "value": 'PRESS', "shift": True},
{"properties": [("deselect_all", False), ("toggle", True), *operator_props]}),
{"properties": [("deselect_all", False), ("toggle", True)]}),
("transform.translate", {"type": 'LEFTMOUSE', "value": 'CLICK_DRAG'},
{"properties": [("release_confirm", True)]}),
]
@ -600,9 +599,9 @@ def _template_items_tool_select(
# unless it is expected that the tool should operate on the selection (click-drag to rip for e.g.).
return [
(operator, {"type": 'LEFTMOUSE', "value": 'PRESS'},
{"properties": [("deselect_all", True), *operator_props]}),
{"properties": [("deselect_all", True)]}),
(operator, {"type": 'LEFTMOUSE', "value": 'PRESS', "shift": True},
{"properties": [("toggle", True), *operator_props]}),
{"properties": [("toggle", True)]}),
# Fallback key-map must transform as the primary tool is expected
# to be accessed via gizmos in this case. See: #96885.
@ -1895,7 +1894,7 @@ def km_graph_editor(params):
("graph.easing_type", {"type": 'E', "value": 'PRESS', "ctrl": True}, None),
("graph.smooth", {"type": 'O', "value": 'PRESS', "alt": True}, None),
("graph.sample", {"type": 'O', "value": 'PRESS', "shift": True, "alt": True}, None),
("graph.bake", {"type": 'C', "value": 'PRESS', "alt": True}, None),
("graph.keys_to_samples", {"type": 'C', "value": 'PRESS', "alt": True}, None),
op_menu("GRAPH_MT_delete", {"type": 'X', "value": 'PRESS'}),
("graph.delete", {"type": 'DEL', "value": 'PRESS'}, {"properties": [("confirm", False)]}),
("graph.duplicate_move", {"type": 'D', "value": 'PRESS', "shift": True}, None),
@ -2121,16 +2120,29 @@ def km_node_editor(params):
)
if not params.legacy:
items.extend(_template_node_select(type=params.select_mouse,
value=params.select_mouse_value, select_passthrough=True))
items.extend(_template_node_select(
type=params.select_mouse,
value=params.select_mouse_value,
select_passthrough=True,
))
# Allow node selection with both for RMB select.
if params.select_mouse == 'RIGHTMOUSE':
items.extend(_template_node_select(type='LEFTMOUSE', value='PRESS', select_passthrough=True))
else:
items.extend([
op_tool_cycle("builtin.select_box", {"type": 'W', "value": 'PRESS'}),
])
else:
items.extend(_template_node_select(
type='RIGHTMOUSE', value=params.select_mouse_value, select_passthrough=True))
type='RIGHTMOUSE',
value=params.select_mouse_value,
select_passthrough=True,
))
items.extend(_template_node_select(
type='LEFTMOUSE', value='PRESS', select_passthrough=True))
type='LEFTMOUSE',
value='PRESS',
select_passthrough=True,
))
items.extend([
("node.select_box", {"type": params.select_mouse, "value": 'CLICK_DRAG'},
@ -4043,8 +4055,10 @@ def km_grease_pencil_stroke_sculpt_mode(params):
# Context menu
*_template_items_context_panel("VIEW3D_PT_gpencil_sculpt_context_menu", params.context_menu_event),
# Auto-masking Pie menu.
op_menu_pie("VIEW3D_MT_sculpt_gpencil_automasking_pie", {
"type": 'A', "shift": True, "alt": True, "value": 'PRESS'}),
op_menu_pie(
"VIEW3D_MT_sculpt_gpencil_automasking_pie",
{"type": 'A', "shift": True, "alt": True, "value": 'PRESS'},
),
])
return keymap
@ -4882,10 +4896,6 @@ def _template_view3d_select(*, type, value, legacy, select_passthrough, exclude_
# NOTE: `exclude_mod` is needed since we don't want this tool to exclude Control-RMB actions when this is used
# as a tool key-map with RMB-select and `use_fallback_tool` is enabled with RMB select. See #92467.
props_vert_without_handles = ()
if select_passthrough:
props_vert_without_handles = ("vert_without_handles",)
# See: `use_tweak_select_passthrough` doc-string.
if select_passthrough and (value in {'CLICK', 'RELEASE'}):
select_passthrough = False
@ -4895,9 +4905,9 @@ def _template_view3d_select(*, type, value, legacy, select_passthrough, exclude_
{"type": type, "value": value, **{m: True for m in mods}},
{"properties": [(c, True) for c in props]},
) for props, mods in (
((("deselect_all", "select_passthrough", *props_vert_without_handles) if select_passthrough else
("deselect_all", *props_vert_without_handles)) if not legacy else (), ()),
(("toggle", *props_vert_without_handles), ("shift",)),
((("deselect_all", "select_passthrough") if select_passthrough else
("deselect_all",)) if not legacy else (), ()),
(("toggle",), ("shift",)),
(("center", "object"), ("ctrl",)),
(("enumerate",), ("alt",)),
(("toggle", "center"), ("shift", "ctrl")),
@ -4914,7 +4924,7 @@ def _template_view3d_select(*, type, value, legacy, select_passthrough, exclude_
{"type": type, "value": 'CLICK'},
{"properties": [
(c, True)
for c in ("deselect_all", *props_vert_without_handles)
for c in ("deselect_all",)
]},
))
@ -7070,17 +7080,12 @@ def km_3d_view_tool_text_select(_params):
def km_3d_view_tool_select(params, *, fallback):
if params.use_tweak_select_passthrough:
operator_props = (("vert_without_handles", True),)
else:
operator_props = ()
return (
_fallback_id("3D View Tool: Tweak", fallback),
{"space_type": 'VIEW_3D', "region_type": 'WINDOW'},
{"items": [
*([] if (fallback and (params.select_mouse == 'RIGHTMOUSE')) else _template_items_tool_select(
params, "view3d.select", "view3d.cursor3d", operator_props=operator_props, fallback=fallback)),
params, "view3d.select", "view3d.cursor3d", fallback=fallback)),
*([] if params.use_fallback_tool_select_handled else
_template_view3d_select(
type=params.select_mouse,
@ -7895,8 +7900,8 @@ def km_3d_view_tool_paint_gpencil_line(params):
("gpencil.primitive_line", {"type": 'LEFTMOUSE', "value": 'PRESS', "alt": True},
{"properties": [("wait_for_input", False)]}),
# Lasso select
("gpencil.select_lasso", {"type": params.action_mouse,
"value": 'CLICK_DRAG', "ctrl": True, "alt": True}, None),
("gpencil.select_lasso",
{"type": params.action_mouse, "value": 'CLICK_DRAG', "ctrl": True, "alt": True}, None),
]},
)
@ -7911,8 +7916,8 @@ def km_3d_view_tool_paint_gpencil_polyline(params):
("gpencil.primitive_polyline", {"type": 'LEFTMOUSE', "value": 'PRESS', "shift": True},
{"properties": [("wait_for_input", False)]}),
# Lasso select
("gpencil.select_lasso", {"type": params.action_mouse,
"value": 'CLICK_DRAG', "ctrl": True, "alt": True}, None),
("gpencil.select_lasso",
{"type": params.action_mouse, "value": 'CLICK_DRAG', "ctrl": True, "alt": True}, None),
]},
)
@ -7929,8 +7934,8 @@ def km_3d_view_tool_paint_gpencil_box(params):
("gpencil.primitive_box", {"type": 'LEFTMOUSE', "value": 'PRESS', "alt": True},
{"properties": [("wait_for_input", False)]}),
# Lasso select
("gpencil.select_lasso", {"type": params.action_mouse,
"value": 'CLICK_DRAG', "ctrl": True, "alt": True}, None),
("gpencil.select_lasso",
{"type": params.action_mouse, "value": 'CLICK_DRAG', "ctrl": True, "alt": True}, None),
]},
)
@ -7947,8 +7952,8 @@ def km_3d_view_tool_paint_gpencil_circle(params):
("gpencil.primitive_circle", {"type": 'LEFTMOUSE', "value": 'PRESS', "alt": True},
{"properties": [("wait_for_input", False)]}),
# Lasso select
("gpencil.select_lasso", {"type": params.action_mouse,
"value": 'CLICK_DRAG', "ctrl": True, "alt": True}, None),
("gpencil.select_lasso",
{"type": params.action_mouse, "value": 'CLICK_DRAG', "ctrl": True, "alt": True}, None),
]},
)
@ -7965,8 +7970,8 @@ def km_3d_view_tool_paint_gpencil_arc(params):
("gpencil.primitive_curve", {"type": 'LEFTMOUSE', "value": 'PRESS', "alt": True},
{"properties": [("type", 'ARC'), ("wait_for_input", False)]}),
# Lasso select
("gpencil.select_lasso", {"type": params.action_mouse,
"value": 'CLICK_DRAG', "ctrl": True, "alt": True}, None),
("gpencil.select_lasso",
{"type": params.action_mouse, "value": 'CLICK_DRAG', "ctrl": True, "alt": True}, None),
]},
)
@ -7979,8 +7984,8 @@ def km_3d_view_tool_paint_gpencil_curve(params):
("gpencil.primitive_curve", params.tool_maybe_tweak_event,
{"properties": [("type", 'CURVE'), ("wait_for_input", False)]}),
# Lasso select
("gpencil.select_lasso", {"type": params.action_mouse,
"value": 'CLICK_DRAG', "ctrl": True, "alt": True}, None),
("gpencil.select_lasso",
{"type": params.action_mouse, "value": 'CLICK_DRAG', "ctrl": True, "alt": True}, None),
]},
)
@ -7992,8 +7997,8 @@ def km_3d_view_tool_paint_gpencil_cutter(params):
{"items": [
("gpencil.stroke_cutter", {"type": params.tool_mouse, "value": 'PRESS'}, None),
# Lasso select
("gpencil.select_lasso", {"type": params.action_mouse,
"value": 'CLICK_DRAG', "ctrl": True, "alt": True}, None),
("gpencil.select_lasso",
{"type": params.action_mouse, "value": 'CLICK_DRAG', "ctrl": True, "alt": True}, None),
]},
)

View File

@ -35,6 +35,29 @@ def geometry_node_group_empty_new():
return group
def geometry_node_group_empty_tool_new(context):
group = build_default_empty_geometry_node_group(data_("Tool"))
group.links.new(group.nodes[data_("Group Input")].outputs[0], group.nodes[data_("Group Output")].inputs[0])
group.asset_mark()
group.is_tool = True
ob_type = context.object.type if context.object else 'MESH'
if ob_type == 'CURVES':
group.is_type_curve = True
elif ob_type == 'POINTCLOUD':
group.is_type_point_cloud = True
else:
group.is_type_mesh = True
mode = context.object.mode if context.object else 'EDIT'
if mode in {'SCULPT', 'SCULPT_CURVES'}:
group.is_mode_sculpt = True
else:
group.is_mode_edit = True
return group
def geometry_modifier_poll(context):
ob = context.object
@ -276,9 +299,7 @@ class NewGeometryNodeGroupTool(Operator):
return space and space.type == 'NODE_EDITOR' and space.geometry_nodes_type == 'TOOL'
def execute(self, context):
group = geometry_node_group_empty_new()
group.asset_mark()
group.is_tool = True
group = geometry_node_group_empty_tool_new(context)
context.space_data.node_tree = group
return {'FINISHED'}

View File

@ -66,7 +66,7 @@ class DATA_PT_display(ArmatureButtonsPanel, Panel):
col = layout.column(heading="Show")
col.prop(arm, "show_names", text="Names")
col.prop(arm, "show_bone_custom_shapes", text="Shapes")
col.prop(arm, "show_group_colors", text="Group Colors")
col.prop(arm, "show_bone_colors", text="Bone Colors")
if ob:
col.prop(ob, "show_in_front", text="In Front")
@ -96,16 +96,10 @@ class DATA_UL_bone_collections(UIList):
class DATA_PT_bone_collections(ArmatureButtonsPanel, Panel):
bl_label = "Bone Collections"
@classmethod
def poll(cls, context):
ob = context.object
return (ob and ob.type == 'ARMATURE' and ob.pose)
def draw(self, context):
layout = self.layout
ob = context.object
arm = ob.data
arm = context.armature
active_bcoll = arm.collections.active
row = layout.row()
@ -243,6 +237,17 @@ class DATA_PT_custom_props_arm(ArmatureButtonsPanel, PropertyPanel, Panel):
_property_type = bpy.types.Armature
class DATA_PT_custom_props_bcoll(ArmatureButtonsPanel, PropertyPanel, Panel):
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'}
_context_path = "armature.collections.active"
_property_type = bpy.types.BoneCollection
bl_parent_id = "DATA_PT_bone_collections"
@classmethod
def poll(cls, context):
return context.armature and context.armature.collections.active
classes = (
DATA_PT_context_arm,
DATA_PT_skeleton,
@ -253,6 +258,7 @@ classes = (
DATA_PT_display,
DATA_PT_iksolver_itasc,
DATA_PT_custom_props_arm,
DATA_PT_custom_props_bcoll,
)
if __name__ == "__main__": # only for live edit.

View File

@ -232,7 +232,6 @@ class BONE_PT_relations(BoneButtonsPanel, Panel):
if ob and pchan:
col.prop(bone, "use_relative_parent")
col.prop_search(pchan, "bone_group", ob.pose, "bone_groups", text="Bone Group")
sub = col.column()
sub.active = (bone.parent is not None)

View File

@ -36,7 +36,7 @@ class OBJECT_MT_modifier_add(Menu):
ob_type = context.object.type
geometry_nodes_supported = ob_type in {'MESH', 'CURVE', 'CURVES', 'FONT', 'SURFACE', 'VOLUME', 'POINTCLOUD'}
if geometry_nodes_supported:
layout.operator("object.modifier_add", text="Empty Modifier").type = 'NODES'
layout.operator("object.modifier_add", icon='GEOMETRY_NODES', text="Geometry Nodes").type = 'NODES'
layout.separator()
if ob_type in {'MESH', 'CURVE', 'FONT', 'SURFACE', 'LATTICE'}:
layout.menu("OBJECT_MT_modifier_add_edit")
@ -227,6 +227,7 @@ class AddModifierMenu(Operator):
@classmethod
def poll(cls, context):
# NOTE: This operator only exists to add a poll to the add modifier shortcut in the property editor.
space = context.space_data
return space and space.type == 'PROPERTIES' and space.context == "MODIFIER"

View File

@ -481,6 +481,7 @@ class RENDER_PT_eevee_next_volumetric_lighting(RenderButtonsPanel, Panel):
layout.active = props.use_volumetric_lights
layout.prop(props, "volumetric_light_clamp", text="Light Clamping")
class RENDER_PT_eevee_next_volumetric_shadows(RenderButtonsPanel, Panel):
bl_label = "Volumetric Shadows"
bl_parent_id = "RENDER_PT_eevee_next_volumetric"

View File

@ -283,8 +283,8 @@ class GRAPH_MT_channel(Menu):
layout.operator("anim.channels_fcurves_enable")
layout.separator()
layout.operator("graph.bake")
layout.operator("graph.unbake")
layout.operator("graph.keys_to_samples")
layout.operator("graph.samples_to_keys")
layout.operator("graph.sound_bake")
layout.separator()
@ -325,6 +325,7 @@ class GRAPH_MT_key_blending(Menu):
layout.operator("graph.blend_to_ease", text="Blend to Ease")
layout.operator("graph.match_slope", text="Match Slope")
layout.operator("graph.shear", text="Shear Keys")
layout.operator("graph.scale_average", text="Scale Average")
class GRAPH_MT_key_smoothing(Menu):

View File

@ -929,7 +929,6 @@ class NODE_PT_node_tree_interface(Panel):
active_item.draw(context, layout)
if active_item.item_type == 'PANEL':
layout.prop(active_item, "name")
layout.prop(active_item, "description")
layout.prop(active_item, "default_closed", text="Closed by Default")

View File

@ -344,7 +344,7 @@ class OUTLINER_MT_asset(Menu):
def draw(self, _context):
layout = self.layout
layout.operator("asset.mark")
layout.operator("asset.mark", icon="ASSET_MANAGER")
layout.operator("asset.clear", text="Clear Asset").set_fake_user = False
layout.operator("asset.clear", text="Clear Asset (Set Fake User)").set_fake_user = True

View File

@ -966,15 +966,9 @@ class SEQUENCER_MT_strip(Menu):
if has_sequencer:
if strip:
strip_type = strip.type
if strip_type != 'SOUND':
layout.separator()
layout.operator_menu_enum("sequencer.strip_video_modifier_add", "type", text="Add Modifier")
layout.operator("sequencer.strip_modifier_copy", text="Copy Modifiers to Selection")
else:
layout.separator()
layout.operator_menu_enum("sequencer.strip_sound_modifier_add", "type", text="Add Modifier")
layout.operator("sequencer.strip_modifier_copy", text="Copy Modifiers to Selection")
layout.separator()
layout.operator_menu_enum("sequencer.strip_modifier_add", "type", text="Add Modifier")
layout.operator("sequencer.strip_modifier_copy", text="Copy Modifiers to Selection")
if strip_type in {
'CROSS', 'ADD', 'SUBTRACT', 'ALPHA_OVER', 'ALPHA_UNDER',
@ -1112,18 +1106,16 @@ class SEQUENCER_MT_context_menu(Menu):
strip_type = strip.type
selected_sequences_count = selected_sequences_len(context)
layout.separator()
layout.operator_menu_enum("sequencer.strip_modifier_add", "type", text="Add Modifier")
layout.operator("sequencer.strip_modifier_copy", text="Copy Modifiers to Selection")
if strip_type != 'SOUND':
layout.separator()
layout.operator_menu_enum("sequencer.strip_video_modifier_add", "type", text="Add Modifier")
layout.operator("sequencer.strip_modifier_copy", text="Copy Modifiers to Selection")
if selected_sequences_count >= 2:
layout.separator()
col = layout.column()
col.menu("SEQUENCER_MT_add_transitions", text="Add Transition")
else:
layout.separator()
layout.operator_menu_enum("sequencer.strip_sound_modifier_add", "type", text="Add Modifier")
layout.operator("sequencer.strip_modifier_copy", text="Copy Modifiers to Selection")
if selected_sequences_count >= 2:
layout.separator()
layout.operator("sequencer.crossfade_sounds", text="Crossfade Sounds")

View File

@ -726,6 +726,7 @@ class TOPBAR_MT_file_context_menu(Menu):
layout.operator_context = 'INVOKE_AREA'
layout.menu("TOPBAR_MT_file_new", text="New", text_ctxt=i18n_contexts.id_windowmanager, icon='FILE_NEW')
layout.operator("wm.open_mainfile", text="Open...", icon='FILE_FOLDER')
layout.menu("TOPBAR_MT_file_open_recent")
layout.separator()

View File

@ -2601,7 +2601,7 @@ class VIEW3D_MT_object(Menu):
layout.separator()
layout.menu("VIEW3D_MT_object_asset")
layout.menu("VIEW3D_MT_object_asset", icon="ASSET_MANAGER")
layout.menu("VIEW3D_MT_object_parent")
layout.menu("VIEW3D_MT_object_collection")
layout.menu("VIEW3D_MT_object_relations")

View File

@ -867,7 +867,7 @@ class VIEW3D_PT_tools_weight_gradient(Panel, View3DPaintPanel):
@classmethod
def poll(cls, context):
# since we dont give context above, check mode here (to not show in other modes like sculpt)
# since we don't give context above, check mode here (to not show in other modes like sculpt).
if context.mode != 'PAINT_WEIGHT':
return False
settings = context.tool_settings.weight_paint

View File

@ -124,6 +124,7 @@ bool ANIM_armature_bonecoll_assign(struct BoneCollection *bcoll, struct Bone *bo
bool ANIM_armature_bonecoll_assign_editbone(struct BoneCollection *bcoll, struct EditBone *ebone);
bool ANIM_armature_bonecoll_assign_and_move(struct BoneCollection *bcoll, struct Bone *bone);
bool ANIM_armature_bonecoll_unassign(struct BoneCollection *bcoll, struct Bone *bone);
void ANIM_armature_bonecoll_unassign_all(struct Bone *bone);
bool ANIM_armature_bonecoll_unassign_editbone(struct BoneCollection *bcoll,
struct EditBone *ebone);

View File

@ -265,11 +265,7 @@ bool ANIM_armature_bonecoll_assign_editbone(BoneCollection *bcoll, EditBone *ebo
bool ANIM_armature_bonecoll_assign_and_move(BoneCollection *bcoll, Bone *bone)
{
/* Remove the bone from all its current collections. */
LISTBASE_FOREACH_MUTABLE (BoneCollectionReference *, ref, &bone->runtime.collections) {
ANIM_armature_bonecoll_unassign(ref->bcoll, bone);
}
/* Assign the new collection. */
ANIM_armature_bonecoll_unassign_all(bone);
return ANIM_armature_bonecoll_assign(bcoll, bone);
}
@ -299,6 +295,13 @@ bool ANIM_armature_bonecoll_unassign(BoneCollection *bcoll, Bone *bone)
return was_found;
}
void ANIM_armature_bonecoll_unassign_all(Bone *bone)
{
LISTBASE_FOREACH_MUTABLE (BoneCollectionReference *, ref, &bone->runtime.collections) {
ANIM_armature_bonecoll_unassign(ref->bcoll, bone);
}
}
bool ANIM_armature_bonecoll_unassign_editbone(BoneCollection *bcoll, EditBone *ebone)
{
bool was_found = false;

View File

@ -49,10 +49,10 @@ bool BKE_blender_version_is_alpha(void);
* Fill in given string buffer with user-readable formatted file version and subversion (if
* provided).
*
* \param str_buff a char buffer where the formatted string is written, minimal recommended size is
* 8, or 16 if subversion is provided.
* \param str_buff: a char buffer where the formatted string is written,
* minimal recommended size is 8, or 16 if subversion is provided.
*
* \param file_subversion the file subversion, if given value < 0, it is ignored, and only the
* \param file_subversion: the file subversion, if given value < 0, it is ignored, and only the
* `file_version` is used.
*/
void BKE_blender_version_blendfile_string_from_values(char *str_buff,

View File

@ -179,7 +179,7 @@ void BKE_constraints_copy_ex(struct ListBase *dst,
/**
* Run the given callback on all ID-blocks in list of constraints.
*
* \param flag the `IDWALK_` flags controlling the behavior of the foreach_id code, see
* \param flag: the `IDWALK_` flags controlling the behavior of the foreach_id code, see
* `BKE_lib_query.h`
*/
void BKE_constraints_id_loop(struct ListBase *list,

View File

@ -259,6 +259,15 @@ inline int2 face_find_adjecent_verts(const IndexRange face,
corner_verts[face_corner_next(face, corner)]};
}
/**
* Return the number of triangles needed to tessellate a face with \a face_size corners.
*/
inline int face_triangles_num(const int face_size)
{
BLI_assert(face_size > 2);
return face_size - 2;
}
/**
* Return the index of the edge's vertex that is not the \a vert.
* If neither edge vertex is equal to \a v, returns -1.

View File

@ -275,7 +275,6 @@ bool BKE_pbvh_bmesh_node_raycast_detail(PBVHNode *node,
* projecting the far clipping plane into the local object space. This works out to
* dividing view3d->clip_end by the object scale, which for small object and large
* clip_end's can easily lead to floating-point overflows.
*
*/
void BKE_pbvh_clip_ray_ortho(
PBVH *pbvh, bool original, float ray_start[3], float ray_end[3], float ray_normal[3]);

View File

@ -2879,7 +2879,7 @@ static void nlastrip_evaluate_meta(const int evaluation_mode,
/* Assert currently supported modes. If new mode added, then assertion marks potentially missed
* area.
*
* NOTE: In the future if support is ever added to metastrips to support nested tracks, then
* NOTE: In the future if support is ever added to meta-strips to support nested tracks, then
* STRIP_EVAL_BLEND and STRIP_EVAL_BLEND_GET_INVERTED_LOWER_SNAPSHOT cases are no longer
* equivalent. The output of nlastrips_ctime_get_strip() may return a list of strips. The only
* case difference should be the evaluation order.

View File

@ -485,8 +485,10 @@ static bool rule_follow_leader(BoidRule *rule,
BoidRuleFollowLeader *flbr = (BoidRuleFollowLeader *)rule;
float vec[3] = {0.0f, 0.0f, 0.0f}, loc[3] = {0.0f, 0.0f, 0.0f};
float mul, len;
int n = (flbr->queue_size <= 1) ? bbd->sim->psys->totpart : flbr->queue_size;
int i, p = pa - bbd->sim->psys->particles;
const int n = (flbr->queue_size <= 1) ? bbd->sim->psys->totpart : flbr->queue_size;
BLI_assert(ARRAY_HAS_ITEM(pa, bbd->sim->psys->particles, bbd->sim->psys->totpart));
const int p = int(pa - bbd->sim->psys->particles);
int i;
bool ret = false;
if (flbr->ob) {

View File

@ -1104,7 +1104,7 @@ static BitVector<> looptri_no_hidden_map_get(const blender::OffsetIndices<int> f
int looptri_no_hidden_len = 0;
int looptri_index = 0;
for (const int64_t i : faces.index_range()) {
const int triangles_num = ME_FACE_TRI_TOT(faces[i].size());
const int triangles_num = blender::bke::mesh::face_triangles_num(faces[i].size());
if (hide_poly[i]) {
looptri_index += triangles_num;
}

View File

@ -4286,10 +4286,11 @@ void BKE_nurbList_handles_set(ListBase *editnurb,
bezt = nu->bezt;
a = nu->pntsu;
while (a--) {
if (bezt->f1 & SELECT) {
const short flag = BKE_nurb_bezt_handle_test_calc_flag(bezt, SELECT, handle_mode);
if (flag & (1 << 0)) {
bezt->h1 = h_new;
}
if (bezt->f3 & SELECT) {
if (flag & (1 << 2)) {
bezt->h2 = h_new;
}

View File

@ -833,33 +833,34 @@ void BKE_defvert_add_index_notest(MDeformVert *dvert, const int defgroup, const
void BKE_defvert_remove_group(MDeformVert *dvert, MDeformWeight *dw)
{
if (dvert && dw) {
int i = dw - dvert->dw;
if (UNLIKELY(!dvert || !dw)) {
return;
}
/* Ensure `dw` is part of `dvert` (security check). */
if (UNLIKELY(uintptr_t(dw - dvert->dw) >= uintptr_t(dvert->totweight))) {
/* Assert as an invalid `dw` (while supported) isn't likely to do what the caller expected. */
BLI_assert_unreachable();
return;
}
/* Security check! */
if (i < 0 || i >= dvert->totweight) {
return;
const int i = dw - dvert->dw;
dvert->totweight--;
/* If there are still other deform weights attached to this vert then remove
* this deform weight, and reshuffle the others. */
if (dvert->totweight) {
BLI_assert(dvert->dw != nullptr);
if (i != dvert->totweight) {
dvert->dw[i] = dvert->dw[dvert->totweight];
}
dvert->totweight--;
/* If there are still other deform weights attached to this vert then remove
* this deform weight, and reshuffle the others.
*/
if (dvert->totweight) {
BLI_assert(dvert->dw != nullptr);
if (i != dvert->totweight) {
dvert->dw[i] = dvert->dw[dvert->totweight];
}
dvert->dw = static_cast<MDeformWeight *>(
MEM_reallocN(dvert->dw, sizeof(MDeformWeight) * dvert->totweight));
}
else {
/* If there are no other deform weights left then just remove this one. */
MEM_freeN(dvert->dw);
dvert->dw = nullptr;
}
dvert->dw = static_cast<MDeformWeight *>(
MEM_reallocN(dvert->dw, sizeof(MDeformWeight) * dvert->totweight));
}
else {
/* If there are no other deform weights left then just remove this one. */
MEM_freeN(dvert->dw);
dvert->dw = nullptr;
}
}
@ -1067,25 +1068,25 @@ void BKE_defvert_extract_vgroup_to_edgeweights(const MDeformVert *dvert,
const bool invert_vgroup,
float *r_weights)
{
if (dvert && defgroup != -1) {
int i = edges_num;
float *tmp_weights = static_cast<float *>(
MEM_mallocN(sizeof(*tmp_weights) * size_t(verts_num), __func__));
BKE_defvert_extract_vgroup_to_vertweights(
dvert, defgroup, verts_num, invert_vgroup, tmp_weights);
while (i--) {
const blender::int2 &edge = edges[i];
r_weights[i] = (tmp_weights[edge[0]] + tmp_weights[edge[1]]) * 0.5f;
}
MEM_freeN(tmp_weights);
}
else {
if (UNLIKELY(!dvert || defgroup == -1)) {
copy_vn_fl(r_weights, edges_num, 0.0f);
return;
}
int i = edges_num;
float *tmp_weights = static_cast<float *>(
MEM_mallocN(sizeof(*tmp_weights) * size_t(verts_num), __func__));
BKE_defvert_extract_vgroup_to_vertweights(
dvert, defgroup, verts_num, invert_vgroup, tmp_weights);
while (i--) {
const blender::int2 &edge = edges[i];
r_weights[i] = (tmp_weights[edge[0]] + tmp_weights[edge[1]]) * 0.5f;
}
MEM_freeN(tmp_weights);
}
void BKE_defvert_extract_vgroup_to_loopweights(const MDeformVert *dvert,
@ -1096,23 +1097,23 @@ void BKE_defvert_extract_vgroup_to_loopweights(const MDeformVert *dvert,
const bool invert_vgroup,
float *r_weights)
{
if (dvert && defgroup != -1) {
int i = loops_num;
float *tmp_weights = static_cast<float *>(
MEM_mallocN(sizeof(*tmp_weights) * size_t(verts_num), __func__));
BKE_defvert_extract_vgroup_to_vertweights(
dvert, defgroup, verts_num, invert_vgroup, tmp_weights);
while (i--) {
r_weights[i] = tmp_weights[corner_verts[i]];
}
MEM_freeN(tmp_weights);
}
else {
if (UNLIKELY(!dvert || defgroup == -1)) {
copy_vn_fl(r_weights, loops_num, 0.0f);
return;
}
int i = loops_num;
float *tmp_weights = static_cast<float *>(
MEM_mallocN(sizeof(*tmp_weights) * size_t(verts_num), __func__));
BKE_defvert_extract_vgroup_to_vertweights(
dvert, defgroup, verts_num, invert_vgroup, tmp_weights);
while (i--) {
r_weights[i] = tmp_weights[corner_verts[i]];
}
MEM_freeN(tmp_weights);
}
void BKE_defvert_extract_vgroup_to_faceweights(const MDeformVert *dvert,
@ -1124,31 +1125,31 @@ void BKE_defvert_extract_vgroup_to_faceweights(const MDeformVert *dvert,
const bool invert_vgroup,
float *r_weights)
{
if (dvert && defgroup != -1) {
int i = faces.size();
float *tmp_weights = static_cast<float *>(
MEM_mallocN(sizeof(*tmp_weights) * size_t(verts_num), __func__));
BKE_defvert_extract_vgroup_to_vertweights(
dvert, defgroup, verts_num, invert_vgroup, tmp_weights);
while (i--) {
const blender::IndexRange face = faces[i];
const int *corner_vert = &corner_verts[face.start()];
int j = face.size();
float w = 0.0f;
for (; j--; corner_vert++) {
w += tmp_weights[*corner_vert];
}
r_weights[i] = w / float(face.size());
}
MEM_freeN(tmp_weights);
}
else {
if (UNLIKELY(!dvert || defgroup == -1)) {
copy_vn_fl(r_weights, faces.size(), 0.0f);
return;
}
int i = faces.size();
float *tmp_weights = static_cast<float *>(
MEM_mallocN(sizeof(*tmp_weights) * size_t(verts_num), __func__));
BKE_defvert_extract_vgroup_to_vertweights(
dvert, defgroup, verts_num, invert_vgroup, tmp_weights);
while (i--) {
const blender::IndexRange face = faces[i];
const int *corner_vert = &corner_verts[face.start()];
int j = face.size();
float w = 0.0f;
for (; j--; corner_vert++) {
w += tmp_weights[*corner_vert];
}
r_weights[i] = w / float(face.size());
}
MEM_freeN(tmp_weights);
}
/** \} */

View File

@ -286,7 +286,7 @@ void BKE_mesh_origindex_map_create_looptri(MeshElemMap **r_map,
index_step = indices;
for (const int64_t i : faces.index_range()) {
map[i].indices = index_step;
index_step += ME_FACE_TRI_TOT(faces[i].size());
index_step += blender::bke::mesh::face_triangles_num(int(faces[i].size()));
}
/* Assign face-tessellation users. */
@ -328,12 +328,18 @@ static Array<int> reverse_indices_in_groups(const Span<int> group_indices,
}
BLI_assert(*std::max_element(group_indices.begin(), group_indices.end()) < offsets.size());
BLI_assert(*std::min_element(group_indices.begin(), group_indices.end()) >= 0);
Array<int> counts(offsets.size(), -1);
/* `counts` keeps track of how many elements have been added to each group, and is incremented
* atomically by many threads in parallel. `calloc` can be measurably faster than a parallel fill
* of zero. Alternatively the offsets could be copied and incremented directly, but the cost of
* the copy is slightly higher than the cost of `calloc`. */
int *counts = MEM_cnew_array<int>(size_t(offsets.size()), __func__);
BLI_SCOPED_DEFER([&]() { MEM_freeN(counts); })
Array<int> results(group_indices.size());
threading::parallel_for(group_indices.index_range(), 1024, [&](const IndexRange range) {
for (const int64_t i : range) {
const int group_index = group_indices[i];
const int index_in_group = atomic_add_and_fetch_int32(&counts[group_index], 1);
const int index_in_group = atomic_fetch_and_add_int32(&counts[group_index], 1);
results[offsets[group_index][index_in_group]] = int(i);
}
});

View File

@ -306,7 +306,7 @@ void looptris_calc_face_indices(const OffsetIndices<int> faces, MutableSpan<int>
for (const int64_t i : range) {
const IndexRange face = faces[i];
const int start = poly_to_tri_count(int(i), int(face.start()));
const int num = ME_FACE_TRI_TOT(int(face.size()));
const int num = face_triangles_num(int(face.size()));
looptri_faces.slice(start, num).fill(int(i));
}
});

View File

@ -369,9 +369,43 @@ static void socket_data_foreach_id(LibraryForeachIDData *data, bNodeTreeInterfac
namespace item_types {
using UidGeneratorFn = blender::FunctionRef<int()>;
static void item_copy(bNodeTreeInterfaceItem &dst,
const bNodeTreeInterfaceItem &src,
const int flag)
int flag,
UidGeneratorFn generate_uid);
/**
* Copy the source items and give each a new unique identifier.
* \param generate_uid: Optional generator function for new item UIDs, copies existing identifiers
* if null.
*/
static void panel_init(bNodeTreeInterfacePanel &panel,
const Span<const bNodeTreeInterfaceItem *> items_src,
const int flag,
UidGeneratorFn generate_uid)
{
panel.items_num = items_src.size();
panel.items_array = MEM_cnew_array<bNodeTreeInterfaceItem *>(panel.items_num, __func__);
/* Copy buffers. */
for (const int i : items_src.index_range()) {
const bNodeTreeInterfaceItem *item_src = items_src[i];
panel.items_array[i] = static_cast<bNodeTreeInterfaceItem *>(MEM_dupallocN(item_src));
item_types::item_copy(*panel.items_array[i], *item_src, flag, generate_uid);
}
}
/**
* Copy data from a source item.
* \param generate_uid: Optional generator function for new item UIDs, copies existing identifiers
* if null.
*/
static void item_copy(bNodeTreeInterfaceItem &dst,
const bNodeTreeInterfaceItem &src,
const int flag,
UidGeneratorFn generate_uid)
{
switch (dst.item_type) {
case NODE_INTERFACE_SOCKET: {
@ -385,7 +419,8 @@ static void item_copy(bNodeTreeInterfaceItem &dst,
dst_socket.description = BLI_strdup_null(src_socket.description);
dst_socket.socket_type = BLI_strdup(src_socket.socket_type);
dst_socket.default_attribute_name = BLI_strdup_null(src_socket.default_attribute_name);
dst_socket.identifier = BLI_strdup(src_socket.identifier);
dst_socket.identifier = generate_uid ? BLI_sprintfN("Socket_%d", generate_uid()) :
BLI_strdup(src_socket.identifier);
if (src_socket.properties) {
dst_socket.properties = IDP_CopyProperty_ex(src_socket.properties, flag);
}
@ -402,24 +437,9 @@ static void item_copy(bNodeTreeInterfaceItem &dst,
dst_panel.name = BLI_strdup(src_panel.name);
dst_panel.description = BLI_strdup_null(src_panel.description);
dst_panel.copy_from(src_panel.items(), flag);
break;
}
}
}
dst_panel.identifier = generate_uid ? generate_uid() : src_panel.identifier;
static void item_set_unique_identifier(const int uid, bNodeTreeInterfaceItem &item)
{
switch (item.item_type) {
case NODE_INTERFACE_SOCKET: {
bNodeTreeInterfaceSocket &socket = reinterpret_cast<bNodeTreeInterfaceSocket &>(item);
MEM_SAFE_FREE(socket.identifier);
socket.identifier = BLI_sprintfN("Socket_%d", uid);
break;
}
case NODE_INTERFACE_PANEL: {
bNodeTreeInterfacePanel &panel = reinterpret_cast<bNodeTreeInterfacePanel &>(item);
panel.identifier = uid;
panel_init(dst_panel, src_panel.items(), flag, generate_uid);
break;
}
}
@ -999,20 +1019,6 @@ static bNodeTreeInterfacePanel *make_panel(const int uid,
return new_panel;
}
void bNodeTreeInterfacePanel::copy_from(
const blender::Span<const bNodeTreeInterfaceItem *> items_src, int flag)
{
items_num = items_src.size();
items_array = MEM_cnew_array<bNodeTreeInterfaceItem *>(items_num, __func__);
/* Copy buffers. */
for (const int i : items_src.index_range()) {
const bNodeTreeInterfaceItem *item_src = items_src[i];
items_array[i] = static_cast<bNodeTreeInterfaceItem *>(MEM_dupallocN(item_src));
item_types::item_copy(*items_array[i], *item_src, flag);
}
}
void bNodeTreeInterface::init_data()
{
/* Root panel is allowed to contain child panels. */
@ -1021,7 +1027,7 @@ void bNodeTreeInterface::init_data()
void bNodeTreeInterface::copy_data(const bNodeTreeInterface &src, int flag)
{
this->root_panel.copy_from(src.root_panel.items(), flag);
item_types::panel_init(this->root_panel, src.root_panel.items(), flag, nullptr);
this->active_index = src.active_index;
}
@ -1188,8 +1194,7 @@ bNodeTreeInterfaceItem *bNodeTreeInterface::add_item_copy(const bNodeTreeInterfa
}
bNodeTreeInterfaceItem *citem = static_cast<bNodeTreeInterfaceItem *>(MEM_dupallocN(&item));
item_types::item_copy(*citem, item, 0);
item_types::item_set_unique_identifier(next_uid++, *citem);
item_types::item_copy(*citem, item, 0, [&]() { return this->next_uid++; });
parent->add_item(*citem);
return citem;
@ -1213,8 +1218,7 @@ bNodeTreeInterfaceItem *bNodeTreeInterface::insert_item_copy(const bNodeTreeInte
}
bNodeTreeInterfaceItem *citem = static_cast<bNodeTreeInterfaceItem *>(MEM_dupallocN(&item));
item_types::item_copy(*citem, item, 0);
item_types::item_set_unique_identifier(next_uid++, *citem);
item_types::item_copy(*citem, item, 0, [&]() { return this->next_uid++; });
parent->insert_item(*citem, position);
return citem;

View File

@ -61,6 +61,10 @@
# include "BPY_extern.h"
#endif
/* -------------------------------------------------------------------- */
/** \name ID Type Implementation
* \{ */
static void screen_free_data(ID *id)
{
bScreen *screen = (bScreen *)id;
@ -189,7 +193,11 @@ IDTypeInfo IDType_ID_SCR = {
/*lib_override_apply_post*/ nullptr,
};
/* ************ Space-type/region-type handling ************** */
/** \} */
/* -------------------------------------------------------------------- */
/** \name Space-type/region-type handling
* \{ */
/** Keep global; this has to be accessible outside of window-manager. */
static ListBase spacetypes = {nullptr, nullptr};
@ -277,7 +285,11 @@ bool BKE_spacetype_exists(int spaceid)
return BKE_spacetype_from_id(spaceid) != nullptr;
}
/* ***************** Space handling ********************** */
/** \} */
/* -------------------------------------------------------------------- */
/** \name Space handling
* \{ */
void BKE_spacedata_freelist(ListBase *lb)
{
@ -570,7 +582,11 @@ void BKE_screen_free_data(bScreen *screen)
screen_free_data(&screen->id);
}
/* ***************** Screen edges & verts ***************** */
/** \} */
/* -------------------------------------------------------------------- */
/** \name Screen edges & verts
* \{ */
ScrEdge *BKE_screen_find_edge(const bScreen *screen, ScrVert *v1, ScrVert *v2)
{
@ -725,7 +741,11 @@ void BKE_screen_remove_unused_scrverts(bScreen *screen)
}
}
/* ***************** Utilities ********************** */
/** \} */
/* -------------------------------------------------------------------- */
/** \name Utilities
* \{ */
ARegion *BKE_region_find_in_listbase_by_type(const ListBase *regionbase, const int region_type)
{
@ -945,6 +965,12 @@ void BKE_screen_header_alignment_reset(bScreen *screen)
screen->do_refresh = true;
}
/** \} */
/* -------------------------------------------------------------------- */
/** \name Blend File IO (Screen & Related Data)
* \{ */
void BKE_screen_view3d_shading_blend_write(BlendWriter *writer, View3DShading *shading)
{
if (shading->prop) {

View File

@ -21,7 +21,6 @@ extern "C" {
* \return The number of indices in r_points.
*
* \note Performance is `O(n.log(n))`, same as `qsort`.
*
*/
int BLI_convexhull_2d(const float (*points)[2], int n, int r_points[/* n */]);

View File

@ -161,7 +161,6 @@ using IndexMaskSegment = OffsetSpan<int64_t, int16_t>;
*
* Extraction:
* An #IndexMask can be converted into various other forms using the `to_*` methods.
*
*/
class IndexMask : private IndexMaskData {
public:

View File

@ -133,6 +133,8 @@ MINLINE void add_v4_v4v4(float r[4], const float a[4], const float b[4]);
MINLINE void add_v3fl_v3fl_v3i(float r[3], const float a[3], const int b[3]);
MINLINE void add_v3_uchar_clamped(uchar r[3], int i);
MINLINE void sub_v2_v2(float r[2], const float a[2]);
MINLINE void sub_v2_v2_db(double r[2], const double a[2]);
MINLINE void sub_v2_v2v2(float r[2], const float a[2], const float b[2]);

View File

@ -89,9 +89,9 @@ template<typename T> class OffsetIndices {
return OffsetIndices(offsets_.slice(range.start(), range.one_after_last()));
}
const T *data() const
Span<T> data() const
{
return offsets_.data();
return offsets_;
}
};

View File

@ -458,6 +458,13 @@ MINLINE void add_v4_v4v4(float r[4], const float a[4], const float b[4])
r[3] = a[3] + b[3];
}
MINLINE void add_v3_uchar_clamped(uchar r[3], int i)
{
r[0] = (uchar)clamp_i(r[0] + i, 0, 255);
r[1] = (uchar)clamp_i(r[1] + i, 0, 255);
r[2] = (uchar)clamp_i(r[2] + i, 0, 255);
}
MINLINE void sub_v2_v2(float r[2], const float a[2])
{
r[0] -= a[0];

View File

@ -203,7 +203,8 @@ void BLO_blendfiledata_free(BlendFileData *bfd);
*
* Called at the end of #setup_add_data from BKE's `blendfile.cc`.
*
* \param new_bmain the newly read Main data-base. */
* \param new_bmain: the newly read Main data-base.
*/
void BLO_read_do_version_after_setup(struct Main *new_bmain, struct BlendFileReadReport *reports);
/** \} */

View File

@ -3317,7 +3317,7 @@ static void lib_link_all(FileData *fd, Main *bmain)
/* Some data that should be persistent, like the 3DCursor or the tool settings, are
* stored in IDs affected by undo, like Scene. So this requires some specific handling. */
/* NOTE: even though the ID may have been detected as unchanged, the 'undo_preserve' may have
* to actually change some of its ID pointers, it's e.g. the case with Scene's toolsettings
* to actually change some of its ID pointers, it's e.g. the case with Scene's tool-settings
* Brush/Palette pointers. This is the case where both new and old ID may be the same. */
if (id_type->blend_read_undo_preserve != nullptr) {
BLI_assert(fd->flags & FD_FLAGS_IS_MEMFILE);

View File

@ -205,10 +205,9 @@ bool BLO_memfile_write_file(MemFile *memfile, const char *filepath)
int file, oflags;
/* NOTE: This is currently used for auto-save and `quit.blend`,
* where _not_ following symlinks is OK,
* where _not_ following symbolic-links is OK,
* however if this is ever executed explicitly by the user,
* we may want to allow writing to symlinks.
*/
* we may want to allow writing to symbolic-links. */
oflags = O_BINARY | O_WRONLY | O_CREAT | O_TRUNC;
#ifdef O_NOFOLLOW

View File

@ -1060,7 +1060,7 @@ static bNodeSocket *version_make_socket_stub(const char *idname,
/* Note: technically socket values can store ref-counted ID pointers, but at this stage the
* refcount can be ignored. It gets recomputed after lib-linking for all ID pointers. Socket
* values don't have allocated data, so a simple dupalloc works here. */
* values don't have allocated data, so a simple duplication works here. */
socket->default_value = default_value ? MEM_dupallocN(default_value) : nullptr;
socket->prop = prop ? IDP_CopyProperty(prop) : nullptr;

View File

@ -626,7 +626,7 @@ void do_versions_after_linking_290(FileData * /*fd*/, Main *bmain)
}
if (!MAIN_VERSION_FILE_ATLEAST(bmain, 292, 8)) {
/* Systematically rebuild posebones to ensure consistent ordering matching the one of bones in
/* Systematically rebuild pose-bones to ensure consistent ordering matching the one of bones in
* Armature obdata. */
LISTBASE_FOREACH (Object *, ob, &bmain->objects) {
if (ob->type == OB_ARMATURE) {

View File

@ -73,7 +73,7 @@ static void version_composite_nodetree_null_id(bNodeTree *ntree, Scene *scene)
}
}
/* Move bonegroup color to the individual bones. */
/* Move bone-group color to the individual bones. */
static void version_bonegroup_migrate_color(Main *bmain)
{
using PoseSet = blender::Set<bPose *>;
@ -91,14 +91,14 @@ static void version_bonegroup_migrate_color(Main *bmain)
/* There is no guarantee that the current state of poses is in sync with the Armature data.
*
* NOTE: No need to handle user refcounting in readfile code. */
* NOTE: No need to handle user reference-counting in readfile code. */
BKE_pose_ensure(bmain, ob, arm, false);
PoseSet &pose_set = armature_poses.lookup_or_add_default(arm);
pose_set.add(ob->pose);
}
/* Move colors from the pose's bonegroup to either the armature bones or the
/* Move colors from the pose's bone-group to either the armature bones or the
* pose bones, depending on how many poses use the Armature. */
for (const PoseSet &pose_set : armature_poses.values()) {
/* If the Armature is shared, the bone group colors might be different, and thus they have to

View File

@ -50,6 +50,9 @@ BMUVOffsets BM_uv_map_get_offsets_from_layer(const BMesh *bm, const int layer)
BMUVOffsets BM_uv_map_get_offsets(const BMesh *bm)
{
const int layer = CustomData_get_active_layer(&bm->ldata, CD_PROP_FLOAT2);
if (layer == -1) {
return {-1, -1, -1, -1};
}
return BM_uv_map_get_offsets_from_layer(bm, layer);
}

View File

@ -129,7 +129,8 @@ void Evaluator::map_node_operation_inputs_to_their_results(DNode node,
* origin is the input socket itself or the input is connected to an unlinked input of a group
* input node and the origin is the input of the group input node. So map the input to the
* result of a newly created Input Single Value Operation. */
auto *input_operation = new InputSingleValueOperation(context_, DInputSocket(dorigin));
InputSingleValueOperation *input_operation = new InputSingleValueOperation(
context_, DInputSocket(dorigin));
operation->map_input_to_result(input->identifier, &input_operation->get_result());
operations_stream_.append(std::unique_ptr<InputSingleValueOperation>(input_operation));

View File

@ -58,7 +58,6 @@ int compute_number_of_diagonals(ivec2 size)
* all share the same maximum value, that is, the longest length:
*
* Length => min(Longest Length, index + 1, Number Of Diagonals - index)
*
*/
int compute_diagonal_length(ivec2 size, int diagonal_index)
{
@ -94,7 +93,6 @@ int compute_diagonal_length(ivec2 size, int diagonal_index)
* while other indices are zero. Which can be described using the compact equation:
*
* Y => max(0, (height - 1) - index)
*
*/
ivec2 compute_diagonal_start(ivec2 size, int index)
{
@ -158,7 +156,6 @@ int compute_anti_diagonal_length(ivec2 size, int diagonal_index)
* from zero to (height - 1). Which can be described using the compact equation:
*
* Y => max(0, index - (width - 1))
*
*/
ivec2 compute_anti_diagonal_start(ivec2 size, int index)
{

View File

@ -42,8 +42,6 @@ void AmbientOcclusion::init()
data_.quality = inst_.scene->eevee.gtao_quality;
/* Size is multiplied by 2 because it is applied in NDC [-1..1] range. */
data_.pixel_size = float2(2.0f) / float2(inst_.film.render_extent_get());
data_.push_update();
}
void AmbientOcclusion::sync()
@ -56,9 +54,9 @@ void AmbientOcclusion::sync()
render_pass_ps_.shader_set(inst_.shaders.static_shader_get(AMBIENT_OCCLUSION_PASS));
render_pass_ps_.bind_texture(RBUFS_UTILITY_TEX_SLOT, &inst_.pipelines.utility_tx);
inst_.bind_uniform_data(&render_pass_ps_);
inst_.sampling.bind_resources(&render_pass_ps_);
inst_.hiz_buffer.bind_resources(&render_pass_ps_);
bind_resources(&render_pass_ps_);
render_pass_ps_.bind_image("in_normal_img", &inst_.render_buffers.rp_color_tx);
render_pass_ps_.push_constant("in_normal_img_layer_index", &inst_.render_buffers.data.normal_id);

View File

@ -10,7 +10,6 @@
* Based on Practical Realtime Strategies for Accurate Indirect Occlusion
* http://blog.selfshadow.com/publications/s2016-shading-course/activision/s2016_pbs_activision_occlusion.pdf
* http://blog.selfshadow.com/publications/s2016-shading-course/activision/s2016_pbs_activision_occlusion.pptx
*
*/
#pragma once
@ -31,11 +30,11 @@ class AmbientOcclusion {
bool render_pass_enabled_;
AODataBuf data_;
AOData &data_;
PassSimple render_pass_ps_ = {"AO Render Pass"};
public:
AmbientOcclusion(Instance &inst) : inst_(inst){};
AmbientOcclusion(Instance &inst, AOData &data) : inst_(inst), data_(data){};
~AmbientOcclusion(){};
void init();
@ -44,11 +43,6 @@ class AmbientOcclusion {
void render(View &view);
void render_pass(View &view);
template<typename T> void bind_resources(draw::detail::PassBase<T> *pass)
{
pass->bind_ubo(AO_BUF_SLOT, &data_);
}
};
/** \} */

View File

@ -180,7 +180,6 @@ void Camera::sync()
}
data_.initialized = true;
data_.push_update();
update_bounds();
}

View File

@ -93,7 +93,7 @@ class Camera {
private:
Instance &inst_;
CameraDataBuf data_;
CameraData &data_;
struct {
float3 center;
@ -104,7 +104,7 @@ class Camera {
bool overscan_changed_;
public:
Camera(Instance &inst) : inst_(inst){};
Camera(Instance &inst, CameraData &data) : inst_(inst), data_(data){};
~Camera(){};
void init();
@ -118,10 +118,6 @@ class Camera {
BLI_assert(data_.initialized);
return data_;
}
GPUUniformBuf *ubo_get() const
{
return data_;
}
bool is_panoramic() const
{
return eevee::is_panoramic(data_.type);

View File

@ -154,21 +154,14 @@
/* Uniform Buffers. */
/* Slot 0 is GPU_NODE_TREE_UBO_SLOT. */
#define CAMERA_BUF_SLOT 1
#define RBUFS_BUF_SLOT 2
#define UNIFORM_BUF_SLOT 1
/* Only during surface shading (forward and deferred eval). */
#define HIZ_BUF_SLOT 3
#define IRRADIANCE_GRID_BUF_SLOT 4
#define AO_BUF_SLOT 5
#define VOLUMES_INFO_BUF_SLOT 6
/* SLOT 6 is used by render shaders (Film, DoF and Motion Blur). Need to check if it should be
* assigned a different slot. */
/* TODO(fclem): This is above the limit of slot 6 for engines. Keep it lower by merging others. */
#define REFLECTION_PROBE_BUF_SLOT 7
#define IRRADIANCE_GRID_BUF_SLOT 2
#define REFLECTION_PROBE_BUF_SLOT 3
/* Only during pre-pass. */
#define VELOCITY_CAMERA_PREV_BUF 3
#define VELOCITY_CAMERA_CURR_BUF 4
#define VELOCITY_CAMERA_NEXT_BUF 5
#define VELOCITY_CAMERA_PREV_BUF 2
#define VELOCITY_CAMERA_CURR_BUF 3
#define VELOCITY_CAMERA_NEXT_BUF 4
/* Storage Buffers. */
#define LIGHT_CULL_BUF_SLOT 0

View File

@ -434,7 +434,7 @@ void Film::sync()
accumulate_ps_.init();
accumulate_ps_.state_set(DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_ALWAYS);
accumulate_ps_.shader_set(inst_.shaders.static_shader_get(shader));
accumulate_ps_.bind_ubo("film_buf", &data_);
inst_.bind_uniform_data(&accumulate_ps_);
accumulate_ps_.bind_ubo("camera_prev", &(*velocity.camera_steps[STEP_PREVIOUS]));
accumulate_ps_.bind_ubo("camera_curr", &(*velocity.camera_steps[STEP_CURRENT]));
accumulate_ps_.bind_ubo("camera_next", &(*velocity.camera_steps[step_next]));
@ -455,7 +455,6 @@ void Film::sync()
accumulate_ps_.bind_image("color_accum_img", &color_accum_tx_);
accumulate_ps_.bind_image("value_accum_img", &value_accum_tx_);
accumulate_ps_.bind_image("cryptomatte_img", &cryptomatte_tx_);
accumulate_ps_.bind_ubo(RBUFS_BUF_SLOT, &inst_.render_buffers.data);
/* Sync with rendering passes. */
accumulate_ps_.barrier(GPU_BARRIER_TEXTURE_FETCH | GPU_BARRIER_SHADER_IMAGE_ACCESS);
if (use_compute) {
@ -646,7 +645,7 @@ void Film::accumulate(const DRWView *view, GPUTexture *combined_final_tx)
combined_final_tx_ = combined_final_tx;
data_.display_only = false;
data_.push_update();
inst_.push_uniform_data();
draw::View drw_view("MainView", view);
@ -675,7 +674,7 @@ void Film::display()
combined_final_tx_ = inst_.render_buffers.combined_tx;
data_.display_only = true;
data_.push_update();
inst_.push_uniform_data();
draw::View drw_view("MainView", DRW_view_default_get());

View File

@ -75,13 +75,13 @@ class Film {
PassSimple accumulate_ps_ = {"Film.Accumulate"};
PassSimple cryptomatte_post_ps_ = {"Film.Cryptomatte.Post"};
FilmDataBuf data_;
FilmData &data_;
int2 display_extent;
eViewLayerEEVEEPassType enabled_passes_ = eViewLayerEEVEEPassType(0);
public:
Film(Instance &inst) : inst_(inst){};
Film(Instance &inst, FilmData &data) : inst_(inst), data_(data){};
~Film(){};
void init(const int2 &full_extent, const rcti *output_rect);

View File

@ -31,7 +31,6 @@ void HiZBuffer::sync()
GPU_texture_mipmap_mode(hiz_tx_, true, false);
data_.uv_scale = float2(render_extent) / float2(hiz_extent);
data_.push_update();
{
hiz_update_ps_.init();

View File

@ -42,10 +42,10 @@ class HiZBuffer {
/** Dirty flag to check if the update is necessary. */
bool is_dirty_ = true;
HiZDataBuf data_;
HiZData &data_;
public:
HiZBuffer(Instance &inst) : inst_(inst)
HiZBuffer(Instance &inst, HiZData &data) : inst_(inst), data_(data)
{
atomic_tile_counter_.clear_to_zero();
};
@ -72,13 +72,11 @@ class HiZBuffer {
void bind_resources(DRWShadingGroup *grp)
{
DRW_shgroup_uniform_texture_ref(grp, "hiz_tx", &hiz_tx_);
DRW_shgroup_uniform_block_ref(grp, "hiz_buf", &data_);
}
template<typename T> void bind_resources(draw::detail::PassBase<T> *pass)
{
pass->bind_texture(HIZ_TEX_SLOT, &hiz_tx_);
pass->bind_ubo(HIZ_BUF_SLOT, &data_);
}
};

View File

@ -280,6 +280,8 @@ void Instance::end_sync()
light_probes.end_sync();
reflection_probes.end_sync();
volume.end_sync();
global_ubo_.push_update();
}
void Instance::render_sync()

View File

@ -51,6 +51,8 @@ class Instance {
friend VelocityModule;
friend MotionBlurModule;
UniformDataBuf global_ubo_;
public:
ShaderModule &shaders;
SyncModule sync;
@ -115,29 +117,29 @@ class Instance {
: shaders(*ShaderModule::module_get()),
sync(*this),
materials(*this),
subsurface(*this),
subsurface(*this, global_ubo_.subsurface),
pipelines(*this),
shadows(*this),
lights(*this),
ambient_occlusion(*this),
raytracing(*this),
ambient_occlusion(*this, global_ubo_.ao),
raytracing(*this, global_ubo_.raytrace),
reflection_probes(*this),
velocity(*this),
motion_blur(*this),
depth_of_field(*this),
cryptomatte(*this),
hiz_buffer(*this),
hiz_buffer(*this, global_ubo_.hiz),
sampling(*this),
camera(*this),
film(*this),
render_buffers(*this),
camera(*this, global_ubo_.camera),
film(*this, global_ubo_.film),
render_buffers(*this, global_ubo_.render_pass),
main_view(*this),
capture_view(*this),
world(*this),
lookdev(*this),
light_probes(*this),
irradiance_cache(*this),
volume(*this){};
volume(*this, global_ubo_.volumes){};
~Instance(){};
/* Render & Viewport. */
@ -216,6 +218,16 @@ class Instance {
((v3d->shading.flag & V3D_SHADING_SCENE_WORLD_RENDER) == 0)));
}
void push_uniform_data()
{
global_ubo_.push_update();
}
template<typename T> void bind_uniform_data(draw::detail::PassBase<T> *pass)
{
pass->bind_ubo(UNIFORM_BUF_SLOT, &global_ubo_);
}
private:
static void object_sync_render(void *instance_,
Object *ob,

View File

@ -417,6 +417,7 @@ void LightModule::debug_pass_sync()
debug_draw_ps_.init();
debug_draw_ps_.state_set(DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_CUSTOM);
debug_draw_ps_.shader_set(inst_.shaders.static_shader_get(LIGHT_CULLING_DEBUG));
inst_.bind_uniform_data(&debug_draw_ps_);
inst_.hiz_buffer.bind_resources(&debug_draw_ps_);
debug_draw_ps_.bind_ssbo("light_buf", &culling_light_buf_);
debug_draw_ps_.bind_ssbo("light_cull_buf", &culling_data_buf_);

View File

@ -125,7 +125,9 @@ void MotionBlurModule::sync()
{
/* Disable motion blur in viewport when changing camera projection type.
* Avoids really high velocities. */
if (inst_.velocity.camera_changed_projection() || inst_.camera.overscan_changed()) {
if (inst_.velocity.camera_changed_projection() ||
(inst_.is_viewport() && inst_.camera.overscan_changed()))
{
motion_blur_fx_enabled_ = false;
}

View File

@ -43,8 +43,7 @@ void BackgroundPipeline::sync(GPUMaterial *gpumat, const float background_opacit
/* Required by validation layers. */
inst_.cryptomatte.bind_resources(&world_ps_);
world_ps_.bind_ubo(CAMERA_BUF_SLOT, inst_.camera.ubo_get());
world_ps_.bind_ubo(RBUFS_BUF_SLOT, &inst_.render_buffers.data);
inst_.bind_uniform_data(&world_ps_);
world_ps_.draw(DRW_cache_fullscreen_quad_get(), handle);
/* To allow opaque pass rendering over it. */
@ -82,8 +81,7 @@ void WorldPipeline::sync(GPUMaterial *gpumat)
pass.push_constant("world_opacity_fade", 1.0f);
pass.bind_texture(RBUFS_UTILITY_TEX_SLOT, inst_.pipelines.utility_tx);
pass.bind_ubo(CAMERA_BUF_SLOT, inst_.camera.ubo_get());
pass.bind_ubo(RBUFS_BUF_SLOT, &inst_.render_buffers.data);
inst_.bind_uniform_data(&pass);
pass.bind_image("rp_normal_img", dummy_renderpass_tx_);
pass.bind_image("rp_light_img", dummy_renderpass_tx_);
pass.bind_image("rp_diffuse_color_img", dummy_renderpass_tx_);
@ -118,6 +116,7 @@ void WorldVolumePipeline::sync(GPUMaterial *gpumat)
{
world_ps_.init();
world_ps_.state_set(DRW_STATE_WRITE_COLOR);
inst_.bind_uniform_data(&world_ps_);
inst_.volume.bind_properties_buffers(world_ps_);
inst_.sampling.bind_resources(&world_ps_);
@ -152,10 +151,10 @@ void ShadowPipeline::sync()
surface_ps_.state_set(DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS);
surface_ps_.bind_texture(RBUFS_UTILITY_TEX_SLOT, inst_.pipelines.utility_tx);
surface_ps_.bind_image(SHADOW_ATLAS_IMG_SLOT, inst_.shadows.atlas_tx_);
surface_ps_.bind_ubo(CAMERA_BUF_SLOT, inst_.camera.ubo_get());
surface_ps_.bind_ssbo(SHADOW_RENDER_MAP_BUF_SLOT, &inst_.shadows.render_map_buf_);
surface_ps_.bind_ssbo(SHADOW_VIEWPORT_INDEX_BUF_SLOT, &inst_.shadows.viewport_index_buf_);
surface_ps_.bind_ssbo(SHADOW_PAGE_INFO_SLOT, &inst_.shadows.pages_infos_data_);
inst_.bind_uniform_data(&surface_ps_);
inst_.sampling.bind_resources(&surface_ps_);
}
@ -192,9 +191,8 @@ void ForwardPipeline::sync()
/* Textures. */
prepass_ps_.bind_texture(RBUFS_UTILITY_TEX_SLOT, inst_.pipelines.utility_tx);
/* Uniform Buffer. */
prepass_ps_.bind_ubo(CAMERA_BUF_SLOT, inst_.camera.ubo_get());
inst_.bind_uniform_data(&prepass_ps_);
inst_.velocity.bind_resources(&prepass_ps_);
inst_.sampling.bind_resources(&prepass_ps_);
}
@ -224,16 +222,11 @@ void ForwardPipeline::sync()
/* Textures. */
opaque_ps_.bind_texture(RBUFS_UTILITY_TEX_SLOT, inst_.pipelines.utility_tx);
/* Uniform Buffer. */
opaque_ps_.bind_ubo(CAMERA_BUF_SLOT, inst_.camera.ubo_get());
opaque_ps_.bind_ubo(RBUFS_BUF_SLOT, &inst_.render_buffers.data);
inst_.bind_uniform_data(&opaque_ps_);
inst_.lights.bind_resources(&opaque_ps_);
inst_.shadows.bind_resources(&opaque_ps_);
inst_.sampling.bind_resources(&opaque_ps_);
inst_.hiz_buffer.bind_resources(&opaque_ps_);
inst_.ambient_occlusion.bind_resources(&opaque_ps_);
inst_.cryptomatte.bind_resources(&opaque_ps_);
}
opaque_single_sided_ps_ = &opaque_ps_.sub("SingleSided");
@ -253,15 +246,13 @@ void ForwardPipeline::sync()
/* Textures. */
sub.bind_texture(RBUFS_UTILITY_TEX_SLOT, inst_.pipelines.utility_tx);
/* Uniform Buffer. */
sub.bind_ubo(CAMERA_BUF_SLOT, inst_.camera.ubo_get());
inst_.bind_uniform_data(&sub);
inst_.lights.bind_resources(&sub);
inst_.shadows.bind_resources(&sub);
inst_.volume.bind_resources(sub);
inst_.sampling.bind_resources(&sub);
inst_.hiz_buffer.bind_resources(&sub);
inst_.ambient_occlusion.bind_resources(&sub);
}
}
@ -368,9 +359,8 @@ void DeferredLayer::begin_sync()
/* Textures. */
prepass_ps_.bind_texture(RBUFS_UTILITY_TEX_SLOT, inst_.pipelines.utility_tx);
/* Uniform Buffer. */
prepass_ps_.bind_ubo(CAMERA_BUF_SLOT, inst_.camera.ubo_get());
inst_.bind_uniform_data(&prepass_ps_);
inst_.velocity.bind_resources(&prepass_ps_);
inst_.sampling.bind_resources(&prepass_ps_);
}
@ -410,13 +400,10 @@ void DeferredLayer::begin_sync()
/* Storage Buffer. */
/* Textures. */
gbuffer_ps_.bind_texture(RBUFS_UTILITY_TEX_SLOT, inst_.pipelines.utility_tx);
/* Uniform Buffer. */
gbuffer_ps_.bind_ubo(CAMERA_BUF_SLOT, inst_.camera.ubo_get());
gbuffer_ps_.bind_ubo(RBUFS_BUF_SLOT, &inst_.render_buffers.data);
inst_.bind_uniform_data(&gbuffer_ps_);
inst_.sampling.bind_resources(&gbuffer_ps_);
inst_.hiz_buffer.bind_resources(&gbuffer_ps_);
inst_.ambient_occlusion.bind_resources(&gbuffer_ps_);
inst_.cryptomatte.bind_resources(&gbuffer_ps_);
}
@ -455,13 +442,12 @@ void DeferredLayer::end_sync()
eval_light_ps_.bind_image(RBUFS_COLOR_SLOT, &inst_.render_buffers.rp_color_tx);
eval_light_ps_.bind_image(RBUFS_VALUE_SLOT, &inst_.render_buffers.rp_value_tx);
eval_light_ps_.bind_texture(RBUFS_UTILITY_TEX_SLOT, inst_.pipelines.utility_tx);
eval_light_ps_.bind_ubo(RBUFS_BUF_SLOT, &inst_.render_buffers.data);
inst_.bind_uniform_data(&eval_light_ps_);
inst_.lights.bind_resources(&eval_light_ps_);
inst_.shadows.bind_resources(&eval_light_ps_);
inst_.sampling.bind_resources(&eval_light_ps_);
inst_.hiz_buffer.bind_resources(&eval_light_ps_);
inst_.ambient_occlusion.bind_resources(&eval_light_ps_);
inst_.reflection_probes.bind_resources(&eval_light_ps_);
inst_.irradiance_cache.bind_resources(&eval_light_ps_);
@ -617,6 +603,7 @@ void VolumePipeline::sync()
{
volume_ps_.init();
volume_ps_.bind_texture(RBUFS_UTILITY_TEX_SLOT, inst_.pipelines.utility_tx);
inst_.bind_uniform_data(&volume_ps_);
inst_.volume.bind_properties_buffers(volume_ps_);
inst_.sampling.bind_resources(&volume_ps_);
}
@ -646,9 +633,8 @@ void DeferredProbeLayer::begin_sync()
/* Textures. */
prepass_ps_.bind_texture(RBUFS_UTILITY_TEX_SLOT, inst_.pipelines.utility_tx);
/* Uniform Buffer. */
prepass_ps_.bind_ubo(CAMERA_BUF_SLOT, inst_.camera.ubo_get());
inst_.bind_uniform_data(&prepass_ps_);
inst_.velocity.bind_resources(&prepass_ps_);
inst_.sampling.bind_resources(&prepass_ps_);
}
@ -680,13 +666,10 @@ void DeferredProbeLayer::begin_sync()
/* Storage Buffer. */
/* Textures. */
gbuffer_ps_.bind_texture(RBUFS_UTILITY_TEX_SLOT, inst_.pipelines.utility_tx);
/* Uniform Buffer. */
gbuffer_ps_.bind_ubo(CAMERA_BUF_SLOT, inst_.camera.ubo_get());
gbuffer_ps_.bind_ubo(RBUFS_BUF_SLOT, &inst_.render_buffers.data);
inst_.bind_uniform_data(&gbuffer_ps_);
inst_.sampling.bind_resources(&gbuffer_ps_);
inst_.hiz_buffer.bind_resources(&gbuffer_ps_);
inst_.ambient_occlusion.bind_resources(&gbuffer_ps_);
inst_.cryptomatte.bind_resources(&gbuffer_ps_);
}
@ -728,13 +711,12 @@ void DeferredProbeLayer::end_sync()
eval_light_ps_.bind_image(RBUFS_COLOR_SLOT, &inst_.render_buffers.rp_color_tx);
eval_light_ps_.bind_image(RBUFS_VALUE_SLOT, &inst_.render_buffers.rp_value_tx);
eval_light_ps_.bind_texture(RBUFS_UTILITY_TEX_SLOT, inst_.pipelines.utility_tx);
eval_light_ps_.bind_ubo(RBUFS_BUF_SLOT, &inst_.render_buffers.data);
inst_.bind_uniform_data(&eval_light_ps_);
inst_.lights.bind_resources(&eval_light_ps_);
inst_.shadows.bind_resources(&eval_light_ps_);
inst_.sampling.bind_resources(&eval_light_ps_);
inst_.hiz_buffer.bind_resources(&eval_light_ps_);
inst_.ambient_occlusion.bind_resources(&eval_light_ps_);
inst_.reflection_probes.bind_resources(&eval_light_ps_);
inst_.irradiance_cache.bind_resources(&eval_light_ps_);
@ -845,8 +827,9 @@ void CapturePipeline::sync()
surface_ps_.bind_ssbo(CAPTURE_BUF_SLOT, &inst_.irradiance_cache.bake.capture_info_buf_);
surface_ps_.bind_texture(RBUFS_UTILITY_TEX_SLOT, inst_.pipelines.utility_tx);
/* TODO(fclem): Remove. There should be no view dependent behavior during capture. */
surface_ps_.bind_ubo(CAMERA_BUF_SLOT, inst_.camera.ubo_get());
/* TODO(fclem): Remove. Binded to get the camera data,
* but there should be no view dependent behavior during capture. */
inst_.bind_uniform_data(&surface_ps_);
}
PassMain::Sub *CapturePipeline::surface_material_add(GPUMaterial *gpumat)

View File

@ -48,7 +48,7 @@ void RayTraceModule::sync()
pass.bind_image("tile_mask_img", &tile_mask_tx_);
pass.bind_ssbo("ray_dispatch_buf", &ray_dispatch_buf_);
pass.bind_ssbo("denoise_dispatch_buf", &denoise_dispatch_buf_);
pass.bind_ubo("raytrace_buf", &data_);
inst_.bind_uniform_data(&pass);
pass.dispatch(&tile_classify_dispatch_size_);
pass.barrier(GPU_BARRIER_SHADER_IMAGE_ACCESS | GPU_BARRIER_SHADER_STORAGE);
}
@ -61,7 +61,7 @@ void RayTraceModule::sync()
pass.bind_ssbo("denoise_dispatch_buf", &denoise_dispatch_buf_);
pass.bind_ssbo("ray_tiles_buf", &ray_tiles_buf_);
pass.bind_ssbo("denoise_tiles_buf", &denoise_tiles_buf_);
pass.bind_ubo("raytrace_buf", &data_);
inst_.bind_uniform_data(&pass);
pass.dispatch(&tile_compact_dispatch_size_);
pass.barrier(GPU_BARRIER_SHADER_STORAGE);
}
@ -91,7 +91,7 @@ void RayTraceModule::sync()
pass.bind_image("ray_data_img", &ray_data_tx_);
pass.bind_image("ray_time_img", &ray_time_tx_);
pass.bind_image("ray_radiance_img", &ray_radiance_tx_);
pass.bind_ubo("raytrace_buf", &data_);
inst_.bind_uniform_data(&pass);
inst_.hiz_buffer.bind_resources(&pass);
inst_.sampling.bind_resources(&pass);
inst_.reflection_probes.bind_resources(&pass);
@ -115,7 +115,7 @@ void RayTraceModule::sync()
pass.bind_image("out_variance_img", &hit_variance_tx_);
pass.bind_image("out_hit_depth_img", &hit_depth_tx_);
pass.bind_image("tile_mask_img", &tile_mask_tx_);
pass.bind_ubo("raytrace_buf", &data_);
inst_.bind_uniform_data(&pass);
inst_.sampling.bind_resources(&pass);
inst_.hiz_buffer.bind_resources(&pass);
pass.dispatch(denoise_dispatch_buf_);
@ -125,7 +125,7 @@ void RayTraceModule::sync()
PassSimple &pass = denoise_temporal_ps_;
pass.init();
pass.shader_set(inst_.shaders.static_shader_get(RAY_DENOISE_TEMPORAL));
pass.bind_ubo("raytrace_buf", &data_);
inst_.bind_uniform_data(&pass);
pass.bind_texture("radiance_history_tx", &radiance_history_tx_);
pass.bind_texture("variance_history_tx", &variance_history_tx_);
pass.bind_texture("tilemask_history_tx", &tilemask_history_tx_);
@ -151,7 +151,7 @@ void RayTraceModule::sync()
pass.bind_image("in_variance_img", &denoise_variance_tx_);
pass.bind_image("tile_mask_img", &tile_mask_tx_);
pass.bind_ssbo("tiles_coord_buf", &denoise_tiles_buf_);
pass.bind_ubo("raytrace_buf", &data_);
inst_.bind_uniform_data(&pass);
inst_.sampling.bind_resources(&pass);
inst_.hiz_buffer.bind_resources(&pass);
pass.dispatch(denoise_dispatch_buf_);
@ -248,7 +248,7 @@ RayTraceResult RayTraceModule::trace(RayTraceBuffer &rt_buffer,
data_.full_resolution = extent;
data_.full_resolution_inv = 1.0f / float2(extent);
data_.skip_denoise = !use_spatial_denoise;
data_.push_update();
inst_.push_uniform_data();
tile_mask_tx_.acquire(tile_mask_extent, RAYTRACE_TILEMASK_FORMAT);
denoise_tiles_buf_.resize(ceil_to_multiple_u(denoise_tile_count, 512));

View File

@ -159,10 +159,10 @@ class RayTraceModule {
RaytraceEEVEE reflection_options_;
RaytraceEEVEE refraction_options_;
RayTraceDataBuf data_;
RayTraceData &data_;
public:
RayTraceModule(Instance &inst) : inst_(inst){};
RayTraceModule(Instance &inst, RayTraceData &data) : inst_(inst), data_(data){};
void init();

View File

@ -51,7 +51,6 @@ void RenderBuffers::sync()
data.ambient_occlusion_id = pass_index_get(EEVEE_RENDER_PASS_AO);
data.aovs = inst_.film.aovs_info;
data.push_update();
}
void RenderBuffers::acquire(int2 extent)

View File

@ -22,7 +22,7 @@ class Instance;
class RenderBuffers {
public:
UniformBuffer<RenderBuffersInfoData> data;
RenderBuffersInfoData &data;
Texture depth_tx;
TextureFromPool combined_tx;
@ -38,7 +38,7 @@ class RenderBuffers {
Instance &inst_;
public:
RenderBuffers(Instance &inst) : inst_(inst){};
RenderBuffers(Instance &inst, RenderBuffersInfoData &data) : data(data), inst_(inst){};
/** WARNING: RenderBuffers and Film use different storage types for AO and Shadow. */
static ePassStorageType pass_storage_type(eViewLayerEEVEEPassType pass_type)

View File

@ -405,11 +405,14 @@ struct VelocityObjectIndex {
BLI_STATIC_ASSERT_ALIGN(VelocityObjectIndex, 16)
struct VelocityGeometryIndex {
/** Offset inside #VelocityGeometryBuf for each timestep. Indexed using eVelocityStep. */
/** Offset inside #VelocityGeometryBuf for each time-step. Indexed using eVelocityStep. */
packed_int3 ofs;
/** If true, compute deformation motion blur. */
bool1 do_deform;
/** Length of data inside #VelocityGeometryBuf for each timestep. Indexed using eVelocityStep. */
/**
* Length of data inside #VelocityGeometryBuf for each time-step.
* Indexed using eVelocityStep.
*/
packed_int3 len;
int _pad0;
@ -861,9 +864,9 @@ struct ShadowPagesInfoData {
int page_alloc_count;
/** Index of the next cache page in the cached page buffer. */
uint page_cached_next;
/** Index of the first page in the buffer since the last defrag. */
/** Index of the first page in the buffer since the last defragment. */
uint page_cached_start;
/** Index of the last page in the buffer since the last defrag. */
/** Index of the last page in the buffer since the last defragment. */
uint page_cached_end;
int _pad0;
@ -1161,6 +1164,9 @@ struct RayTraceData {
bool1 skip_denoise;
/** Closure being ray-traced. */
eClosureBits closure_active;
int _pad0;
int _pad1;
int _pad2;
};
BLI_STATIC_ASSERT_ALIGN(RayTraceData, 16)
@ -1246,6 +1252,25 @@ BLI_STATIC_ASSERT_ALIGN(ReflectionProbeData, 16)
/** \} */
/* -------------------------------------------------------------------- */
/** \name Uniform Data
* \{ */
/* Combines data from several modules to avoid wasting binding slots. */
struct UniformData {
AOData ao;
CameraData camera;
FilmData film;
HiZData hiz;
RayTraceData raytrace;
RenderBuffersInfoData render_pass;
SubsurfaceData subsurface;
VolumesInfoData volumes;
};
BLI_STATIC_ASSERT_ALIGN(UniformData, 16)
/** \} */
/* -------------------------------------------------------------------- */
/** \name Utility Texture
* \{ */
@ -1310,8 +1335,7 @@ using DepthOfFieldDataBuf = draw::UniformBuffer<DepthOfFieldData>;
using DepthOfFieldScatterListBuf = draw::StorageArrayBuffer<ScatterRect, 16, true>;
using DrawIndirectBuf = draw::StorageBuffer<DrawCommand, true>;
using DispatchIndirectBuf = draw::StorageBuffer<DispatchCommand>;
using FilmDataBuf = draw::UniformBuffer<FilmData>;
using HiZDataBuf = draw::UniformBuffer<HiZData>;
using UniformDataBuf = draw::UniformBuffer<UniformData>;
using IrradianceGridDataBuf = draw::UniformArrayBuffer<IrradianceGridData, IRRADIANCE_GRID_MAX>;
using IrradianceBrickBuf = draw::StorageVectorBuffer<IrradianceBrickPacked, 16>;
using LightCullingDataBuf = draw::StorageBuffer<LightCullingData>;
@ -1323,7 +1347,6 @@ using LightDataBuf = draw::StorageArrayBuffer<LightData, LIGHT_CHUNK>;
using MotionBlurDataBuf = draw::UniformBuffer<MotionBlurData>;
using MotionBlurTileIndirectionBuf = draw::StorageBuffer<MotionBlurTileIndirection, true>;
using RayTraceTileBuf = draw::StorageArrayBuffer<uint, 1024, true>;
using RayTraceDataBuf = draw::UniformBuffer<RayTraceData>;
using ReflectionProbeDataBuf =
draw::UniformArrayBuffer<ReflectionProbeData, REFLECTION_PROBES_MAX>;
using SamplingDataBuf = draw::StorageBuffer<SamplingData>;
@ -1334,7 +1357,6 @@ using ShadowPageCacheBuf = draw::StorageArrayBuffer<uint2, SHADOW_MAX_PAGE, true
using ShadowTileMapDataBuf = draw::StorageVectorBuffer<ShadowTileMapData, SHADOW_MAX_TILEMAP>;
using ShadowTileMapClipBuf = draw::StorageArrayBuffer<ShadowTileMapClip, SHADOW_MAX_TILEMAP, true>;
using ShadowTileDataBuf = draw::StorageArrayBuffer<ShadowTileDataPacked, SHADOW_MAX_TILE, true>;
using SubsurfaceDataBuf = draw::UniformBuffer<SubsurfaceData>;
using SurfelBuf = draw::StorageArrayBuffer<Surfel, 64>;
using SurfelRadianceBuf = draw::StorageArrayBuffer<SurfelRadiance, 64>;
using CaptureInfoBuf = draw::StorageBuffer<CaptureInfoData>;
@ -1342,9 +1364,7 @@ using SurfelListInfoBuf = draw::StorageBuffer<SurfelListInfoData>;
using VelocityGeometryBuf = draw::StorageArrayBuffer<float4, 16, true>;
using VelocityIndexBuf = draw::StorageArrayBuffer<VelocityIndex, 16>;
using VelocityObjectBuf = draw::StorageArrayBuffer<float4x4, 16>;
using VolumesInfoDataBuf = draw::UniformBuffer<VolumesInfoData>;
using CryptomatteObjectBuf = draw::StorageArrayBuffer<float2, 16>;
using AODataBuf = draw::UniformBuffer<AOData>;
} // namespace blender::eevee
#endif

View File

@ -780,6 +780,7 @@ void ShadowModule::begin_sync()
sub.push_constant("pixel_world_radius", &pixel_world_radius_);
sub.push_constant("fb_resolution", &usage_tag_fb_resolution_);
sub.push_constant("fb_lod", &usage_tag_fb_lod_);
inst_.bind_uniform_data(&sub);
inst_.hiz_buffer.bind_resources(&sub);
inst_.lights.bind_resources(&sub);
@ -981,6 +982,7 @@ void ShadowModule::end_sync()
sub.bind_ssbo("tilemaps_buf", &tilemap_pool.tilemaps_data);
sub.bind_ssbo("tiles_buf", &tilemap_pool.tiles_data);
sub.push_constant("tilemap_projection_ratio", &tilemap_projection_ratio_);
inst_.bind_uniform_data(&sub);
inst_.hiz_buffer.bind_resources(&sub);
inst_.sampling.bind_resources(&sub);
inst_.lights.bind_resources(&sub);
@ -1121,6 +1123,7 @@ void ShadowModule::debug_end_sync()
debug_draw_ps_.push_constant("debug_tilemap_index", light.tilemap_index);
debug_draw_ps_.bind_ssbo("tilemaps_buf", &tilemap_pool.tilemaps_data);
debug_draw_ps_.bind_ssbo("tiles_buf", &tilemap_pool.tiles_data);
inst_.bind_uniform_data(&debug_draw_ps_);
inst_.hiz_buffer.bind_resources(&debug_draw_ps_);
inst_.lights.bind_resources(&debug_draw_ps_);
inst_.shadows.bind_resources(&debug_draw_ps_);

View File

@ -4,7 +4,6 @@
/** \file
* \ingroup eevee
*
*/
#include "BLI_vector.hh"
@ -18,7 +17,6 @@ namespace blender::eevee {
/* -------------------------------------------------------------------- */
/** \name Subsurface
*
* \{ */
void SubsurfaceModule::end_sync()
@ -33,19 +31,16 @@ void SubsurfaceModule::end_sync()
precompute_samples_location();
data_.push_update();
subsurface_ps_.init();
subsurface_ps_.state_set(DRW_STATE_WRITE_COLOR | DRW_STATE_STENCIL_EQUAL |
DRW_STATE_BLEND_ADD_FULL);
subsurface_ps_.state_stencil(0x00u, 0xFFu, CLOSURE_SSS);
subsurface_ps_.shader_set(inst_.shaders.static_shader_get(SUBSURFACE_EVAL));
inst_.subsurface.bind_resources(&subsurface_ps_);
inst_.bind_uniform_data(&subsurface_ps_);
inst_.hiz_buffer.bind_resources(&subsurface_ps_);
subsurface_ps_.bind_texture("radiance_tx", &diffuse_light_tx_);
subsurface_ps_.bind_texture("gbuffer_closure_tx", &inst_.gbuffer.closure_tx);
subsurface_ps_.bind_texture("gbuffer_color_tx", &inst_.gbuffer.color_tx);
subsurface_ps_.bind_ubo(RBUFS_BUF_SLOT, &inst_.render_buffers.data);
subsurface_ps_.bind_image(RBUFS_COLOR_SLOT, &inst_.render_buffers.rp_color_tx);
/** NOTE: Not used in the shader, but we bind it to avoid debug warnings. */
subsurface_ps_.bind_image(RBUFS_VALUE_SLOT, &inst_.render_buffers.rp_value_tx);

View File

@ -34,14 +34,14 @@ struct SubsurfaceModule {
private:
Instance &inst_;
/** Contains samples locations. */
SubsurfaceDataBuf data_;
SubsurfaceData &data_;
/** Scene diffuse irradiance. Pointer binded at sync time, set at render time. */
GPUTexture *diffuse_light_tx_;
/** Subsurface eval pass. Runs after the deferred pass. */
PassSimple subsurface_ps_ = {"Subsurface"};
public:
SubsurfaceModule(Instance &inst) : inst_(inst)
SubsurfaceModule(Instance &inst, SubsurfaceData &data) : inst_(inst), data_(data)
{
/* Force first update. */
data_.sample_len = -1;
@ -56,11 +56,6 @@ struct SubsurfaceModule {
void render(View &view, Framebuffer &fb, Texture &diffuse_light_tx);
template<typename T> void bind_resources(draw::detail::PassBase<T> *pass)
{
pass->bind_ubo("sss_buf", data_);
}
private:
void precompute_samples_location();

View File

@ -8,7 +8,6 @@
* Volumetric effects rendering using Frostbite's Physically-based & Unified Volumetric Rendering
* approach.
* https://www.ea.com/frostbite/news/physically-based-unified-volumetric-rendering-in-frostbite
*
*/
#include "DNA_volume_types.h"
@ -23,7 +22,7 @@
namespace blender::eevee {
bool VolumeModule::GridAABB::init(Object *ob, const Camera &camera, const VolumesInfoDataBuf &data)
bool VolumeModule::GridAABB::init(Object *ob, const Camera &camera, const VolumesInfoData &data)
{
/* Returns the unified volume grid cell index of a world space coordinate. */
auto to_global_grid_coords = [&](float3 wP) -> int3 {
@ -150,8 +149,6 @@ void VolumeModule::begin_sync()
data_.depth_distribution = 1.0f / (integration_end - integration_start);
}
data_.push_update();
enabled_ = inst_.world.has_volume();
}
@ -273,7 +270,7 @@ void VolumeModule::end_sync()
integration_ps_.init();
integration_ps_.shader_set(inst_.shaders.static_shader_get(VOLUME_INTEGRATION));
integration_ps_.bind_ubo(VOLUMES_INFO_BUF_SLOT, data_);
inst_.bind_uniform_data(&integration_ps_);
integration_ps_.bind_texture("in_scattering_tx", &scatter_tx_);
integration_ps_.bind_texture("in_extinction_tx", &extinction_tx_);
integration_ps_.bind_image("out_scattering_img", &integrated_scatter_tx_);
@ -286,9 +283,9 @@ void VolumeModule::end_sync()
resolve_ps_.init();
resolve_ps_.state_set(DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_CUSTOM);
resolve_ps_.shader_set(inst_.shaders.static_shader_get(VOLUME_RESOLVE));
inst_.bind_uniform_data(&resolve_ps_);
bind_resources(resolve_ps_);
resolve_ps_.bind_texture("depth_tx", &inst_.render_buffers.depth_tx);
resolve_ps_.bind_ubo(RBUFS_BUF_SLOT, &inst_.render_buffers.data);
resolve_ps_.bind_image(RBUFS_COLOR_SLOT, &inst_.render_buffers.rp_color_tx);
/* Sync with the integration pass. */
resolve_ps_.barrier(GPU_BARRIER_TEXTURE_FETCH);

View File

@ -47,7 +47,7 @@ class VolumeModule {
bool enabled_;
VolumesInfoDataBuf data_;
VolumesInfoData &data_;
/* Material Parameters */
Texture prop_scattering_tx_;
@ -82,7 +82,7 @@ class VolumeModule {
int3 min, max;
/* Returns true if visible. */
bool init(Object *ob, const Camera &camera, const VolumesInfoDataBuf &data);
bool init(Object *ob, const Camera &camera, const VolumesInfoData &data);
bool overlaps(const GridAABB &aabb);
};
@ -92,7 +92,7 @@ class VolumeModule {
Map<GPUShader *, Vector<GridAABB>> subpass_aabbs_;
public:
VolumeModule(Instance &inst) : inst_(inst)
VolumeModule(Instance &inst, VolumesInfoData &data) : inst_(inst), data_(data)
{
dummy_scatter_tx_.ensure_3d(GPU_RGBA8, int3(1), GPU_TEXTURE_USAGE_SHADER_READ, float4(0.0f));
dummy_transmit_tx_.ensure_3d(GPU_RGBA8, int3(1), GPU_TEXTURE_USAGE_SHADER_READ, float4(1.0f));
@ -103,7 +103,6 @@ class VolumeModule {
/* Bind resources needed by external passes to perform their own resolve. */
template<typename PassType> void bind_resources(PassType &ps)
{
ps.bind_ubo(VOLUMES_INFO_BUF_SLOT, data_);
ps.bind_texture(VOLUME_SCATTERING_TEX_SLOT, &transparent_pass_scatter_tx_);
ps.bind_texture(VOLUME_TRANSMITTANCE_TEX_SLOT, &transparent_pass_transmit_tx_);
}
@ -111,7 +110,6 @@ class VolumeModule {
/* Bind the common resources needed by all volumetric passes. */
template<typename PassType> void bind_properties_buffers(PassType &ps)
{
ps.bind_ubo(VOLUMES_INFO_BUF_SLOT, &data_);
ps.bind_image(VOLUME_PROP_SCATTERING_IMG_SLOT, &prop_scattering_tx_);
ps.bind_image(VOLUME_PROP_EXTINCTION_IMG_SLOT, &prop_extinction_tx_);
ps.bind_image(VOLUME_PROP_EMISSION_IMG_SLOT, &prop_emission_tx_);

View File

@ -102,10 +102,10 @@ float ambient_ambient_occlusion_search_horizon(vec3 vI,
/* Gives us good precision at center and ensure we cross at least one pixel per iteration. */
time = 1.0 + iter + sqr((iter + noise) / sample_count) * ssray.max_time;
float stride = time - prev_time;
float lod = (log2(stride) - noise) / (1.0 + ao_buf.quality);
float lod = (log2(stride) - noise) / (1.0 + uniform_buf.ao.quality);
vec2 uv = ssray.origin.xy + ssray.direction.xy * time;
float depth = textureLod(depth_tx, uv * hiz_buf.uv_scale, floor(lod)).r;
float depth = textureLod(depth_tx, uv * uniform_buf.hiz.uv_scale, floor(lod)).r;
if (depth == 1.0 && inverted == 0.0) {
/* Skip background. Avoids making shadow on the geometry near the far plane. */
@ -163,13 +163,13 @@ OcclusionData ambient_occlusion_search(vec3 vP,
ScreenSpaceRay ssray;
ssray = raytrace_screenspace_ray_create(ray, ao_buf.pixel_size);
ssray = raytrace_screenspace_ray_create(ray, uniform_buf.ao.pixel_size);
data.horizons[0 + i * 2] = ambient_ambient_occlusion_search_horizon(
vI, vP, noise.y, ssray, depth_tx, inverted, radius, dir_sample_count);
ray.direction = -ray.direction;
ssray = raytrace_screenspace_ray_create(ray, ao_buf.pixel_size);
ssray = raytrace_screenspace_ray_create(ray, uniform_buf.ao.pixel_size);
data.horizons[1 + i * 2] = -ambient_ambient_occlusion_search_horizon(
vI, vP, noise.y, ssray, depth_tx, inverted, radius, dir_sample_count);

View File

@ -81,7 +81,8 @@ void main()
vec3 Ng = transform_direction(ViewMatrixInverse, vNg);
vec3 N = imageLoad(in_normal_img, ivec3(texel, in_normal_img_layer_index)).xyz;
OcclusionData data = ambient_occlusion_search(vP, hiz_tx, texel, ao_buf.distance, 0.0, 8.0);
OcclusionData data = ambient_occlusion_search(
vP, hiz_tx, texel, uniform_buf.ao.distance, 0.0, 8.0);
float visibility;
float visibility_error_out;

View File

@ -45,7 +45,7 @@ void cryptomatte_store_film_sample(FilmSample dst,
if (crypto_sample.y == 0.0) {
return;
}
for (int i = 0; i < film_buf.cryptomatte_samples_len / 2; i++) {
for (int i = 0; i < uniform_buf.film.cryptomatte_samples_len / 2; i++) {
ivec3 img_co = ivec3(dst.texel, cryptomatte_layer_id + i);
vec4 sample_pair = imageLoad(cryptomatte_img, img_co);
if (cryptomatte_can_merge_sample(sample_pair.xy, crypto_sample)) {
@ -60,7 +60,7 @@ void cryptomatte_store_film_sample(FilmSample dst,
else if (cryptomatte_can_merge_sample(sample_pair.zw, crypto_sample)) {
sample_pair.zw = cryptomatte_merge_sample(sample_pair.zw, crypto_sample);
}
else if (i == film_buf.cryptomatte_samples_len / 2 - 1) {
else if (i == uniform_buf.film.cryptomatte_samples_len / 2 - 1) {
/* TODO(jbakker): New hash detected, but there is no space left to store it. Currently we
* will ignore this sample, but ideally we could replace a sample with a lowest weight. */
continue;

View File

@ -91,15 +91,19 @@ void main()
diffuse_data.color = is_refraction ? vec3(0.0) : gbuffer_color_unpack(color_1_packed);
/* Light passes. */
if (rp_buf.diffuse_light_id >= 0) {
imageStore(rp_color_img, ivec3(texel, rp_buf.diffuse_light_id), vec4(diffuse_light, 1.0));
if (uniform_buf.render_pass.diffuse_light_id >= 0) {
imageStore(rp_color_img,
ivec3(texel, uniform_buf.render_pass.diffuse_light_id),
vec4(diffuse_light, 1.0));
}
if (rp_buf.specular_light_id >= 0) {
if (uniform_buf.render_pass.specular_light_id >= 0) {
vec3 specular_light = reflection_light + refraction_light;
imageStore(rp_color_img, ivec3(texel, rp_buf.specular_light_id), vec4(specular_light, 1.0));
imageStore(rp_color_img,
ivec3(texel, uniform_buf.render_pass.specular_light_id),
vec4(specular_light, 1.0));
}
if (rp_buf.shadow_id >= 0) {
imageStore(rp_value_img, ivec3(texel, rp_buf.shadow_id), vec4(shadow));
if (uniform_buf.render_pass.shadow_id >= 0) {
imageStore(rp_value_img, ivec3(texel, uniform_buf.render_pass.shadow_id), vec4(shadow));
}
if (!is_last_eval_pass) {

View File

@ -249,9 +249,9 @@ DofSample dof_sample_history(vec2 input_texel)
/* Slide 92. */
vec2 weight_12 = weights[1] + weights[2];
vec2 uv_12 = (center_texel + weights[2] / weight_12) * film_buf.extent_inv;
vec2 uv_0 = (center_texel - 1.0) * film_buf.extent_inv;
vec2 uv_3 = (center_texel + 2.0) * film_buf.extent_inv;
vec2 uv_12 = (center_texel + weights[2] / weight_12) * uniform_buf.film.extent_inv;
vec2 uv_0 = (center_texel - 1.0) * uniform_buf.film.extent_inv;
vec2 uv_3 = (center_texel + 2.0) * uniform_buf.film.extent_inv;
vec4 color;
vec4 weight_cross = weight_12.xyyx * vec4(weights[0].yx, weights[3].xy);

View File

@ -7,25 +7,26 @@
void main()
{
ivec2 texel_film = ivec2(gl_FragCoord.xy) - film_buf.offset;
ivec2 texel_film = ivec2(gl_FragCoord.xy) - uniform_buf.film.offset;
float out_depth;
if (film_buf.display_only) {
if (uniform_buf.film.display_only) {
out_depth = imageLoad(depth_img, texel_film).r;
if (film_buf.display_id == -1) {
if (uniform_buf.film.display_id == -1) {
out_color = texelFetch(in_combined_tx, texel_film, 0);
}
else if (film_buf.display_storage_type == PASS_STORAGE_VALUE) {
out_color.rgb = imageLoad(value_accum_img, ivec3(texel_film, film_buf.display_id)).rrr;
else if (uniform_buf.film.display_storage_type == PASS_STORAGE_VALUE) {
out_color.rgb =
imageLoad(value_accum_img, ivec3(texel_film, uniform_buf.film.display_id)).rrr;
out_color.a = 1.0;
}
else if (film_buf.display_storage_type == PASS_STORAGE_COLOR) {
out_color = imageLoad(color_accum_img, ivec3(texel_film, film_buf.display_id));
else if (uniform_buf.film.display_storage_type == PASS_STORAGE_COLOR) {
out_color = imageLoad(color_accum_img, ivec3(texel_film, uniform_buf.film.display_id));
}
else /* PASS_STORAGE_CRYPTOMATTE */ {
out_color = cryptomatte_false_color(
imageLoad(cryptomatte_img, ivec3(texel_film, film_buf.display_id)).r);
imageLoad(cryptomatte_img, ivec3(texel_film, uniform_buf.film.display_id)).r);
}
}
else {

View File

@ -39,7 +39,7 @@ float film_luma_weight(float luma)
{
/* Slide 20 of "High Quality Temporal Supersampling" by Brian Karis at Siggraph 2014. */
/* To preserve more details in dark areas, we use a bigger bias. */
return 1.0 / (4.0 + luma * film_buf.exposure_scale);
return 1.0 / (4.0 + luma * uniform_buf.film.exposure_scale);
}
/* -------------------------------------------------------------------- */
@ -55,21 +55,22 @@ FilmSample film_sample_get(int sample_n, ivec2 texel_film)
#else
# ifdef SCALED_RENDERING
texel_film /= film_buf.scaling_factor;
texel_film /= uniform_buf.film.scaling_factor;
# endif
FilmSample film_sample = film_buf.samples[sample_n];
film_sample.texel += texel_film + film_buf.render_offset;
FilmSample film_sample = uniform_buf.film.samples[sample_n];
film_sample.texel += texel_film + uniform_buf.film.render_offset;
/* Use extend on borders. */
film_sample.texel = clamp(film_sample.texel, ivec2(0, 0), film_buf.render_extent - 1);
film_sample.texel = clamp(film_sample.texel, ivec2(0, 0), uniform_buf.film.render_extent - 1);
/* TODO(fclem): Panoramic projection will need to compute the sample weight in the shader
* instead of precomputing it on CPU. */
# ifdef SCALED_RENDERING
/* We need to compute the real distance and weight since a sample
* can be used by many final pixel. */
vec2 offset = film_buf.subpixel_offset - vec2(texel_film % film_buf.scaling_factor);
film_sample.weight = film_filter_weight(film_buf.filter_size, len_squared(offset));
vec2 offset = uniform_buf.film.subpixel_offset -
vec2(texel_film % uniform_buf.film.scaling_factor);
film_sample.weight = film_filter_weight(uniform_buf.film.filter_size, len_squared(offset));
# endif
#endif /* PANORAMIC */
@ -85,12 +86,12 @@ float film_weight_accumulation(ivec2 texel_film)
{
#if 0 /* TODO(fclem): Reference implementation, also needed for panoramic cameras. */
float weight = 0.0;
for (int i = 0; i < film_buf.samples_len; i++) {
for (int i = 0; i < uniform_buf.film.samples_len; i++) {
weight += film_sample_get(i, texel_film).weight;
}
return weight;
#endif
return film_buf.samples_weight_total;
return uniform_buf.film.samples_weight_total;
}
void film_sample_accum(
@ -113,7 +114,7 @@ void film_sample_accum(
void film_sample_accum_mist(FilmSample samp, inout float accum)
{
if (film_buf.mist_id == -1) {
if (uniform_buf.film.mist_id == -1) {
return;
}
float depth = texelFetch(depth_tx, samp.texel, 0).x;
@ -122,15 +123,15 @@ void film_sample_accum_mist(FilmSample samp, inout float accum)
bool is_persp = ProjectionMatrix[3][3] == 0.0;
float mist = (is_persp) ? length(vP) : abs(vP.z);
/* Remap to 0..1 range. */
mist = saturate(mist * film_buf.mist_scale + film_buf.mist_bias);
mist = saturate(mist * uniform_buf.film.mist_scale + uniform_buf.film.mist_bias);
/* Falloff. */
mist = pow(mist, film_buf.mist_exponent);
mist = pow(mist, uniform_buf.film.mist_exponent);
accum += mist * samp.weight;
}
void film_sample_accum_combined(FilmSample samp, inout vec4 accum, inout float weight_accum)
{
if (film_buf.combined_id == -1) {
if (uniform_buf.film.combined_id == -1) {
return;
}
vec4 color = film_texelfetch_as_YCoCg_opacity(combined_tx, samp.texel);
@ -179,7 +180,7 @@ void film_cryptomatte_layer_accum_and_store(
}
/* x = hash, y = accumulated weight. Only keep track of 4 highest weighted samples. */
vec2 crypto_samples[4] = vec2[4](vec2(0.0), vec2(0.0), vec2(0.0), vec2(0.0));
for (int i = 0; i < film_buf.samples_len; i++) {
for (int i = 0; i < uniform_buf.film.samples_len; i++) {
FilmSample src = film_sample_get(i, texel_film);
film_sample_cryptomatte_accum(src, layer_component, cryptomatte_tx, crypto_samples);
}
@ -200,7 +201,7 @@ float film_distance_load(ivec2 texel)
/* Repeat texture coordinates as the weight can be optimized to a small portion of the film. */
texel = texel % imageSize(in_weight_img).xy;
if (!film_buf.use_history || film_buf.use_reprojection) {
if (!uniform_buf.film.use_history || uniform_buf.film.use_reprojection) {
return 1.0e16;
}
return imageLoad(in_weight_img, ivec3(texel, FILM_WEIGHT_LAYER_DISTANCE)).x;
@ -211,7 +212,7 @@ float film_weight_load(ivec2 texel)
/* Repeat texture coordinates as the weight can be optimized to a small portion of the film. */
texel = texel % imageSize(in_weight_img).xy;
if (!film_buf.use_history || film_buf.use_reprojection) {
if (!uniform_buf.film.use_history || uniform_buf.film.use_reprojection) {
return 0.0;
}
return imageLoad(in_weight_img, ivec3(texel, FILM_WEIGHT_LAYER_ACCUMULATION)).x;
@ -239,7 +240,7 @@ vec2 film_pixel_history_motion_vector(ivec2 texel_sample)
vec4 vector = velocity_resolve(vector_tx, nearest_texel, min_depth);
/* Transform to pixel space. */
vector.xy *= vec2(film_buf.extent);
vector.xy *= vec2(uniform_buf.film.extent);
return vector.xy;
}
@ -297,9 +298,9 @@ vec4 film_sample_catmull_rom(sampler2D color_tx, vec2 input_texel)
/* Slide 92. */
vec2 weight_12 = weights[1] + weights[2];
vec2 uv_12 = (center_texel + weights[2] / weight_12) * film_buf.extent_inv;
vec2 uv_0 = (center_texel - 1.0) * film_buf.extent_inv;
vec2 uv_3 = (center_texel + 2.0) * film_buf.extent_inv;
vec2 uv_12 = (center_texel + weights[2] / weight_12) * uniform_buf.film.extent_inv;
vec2 uv_0 = (center_texel - 1.0) * uniform_buf.film.extent_inv;
vec2 uv_3 = (center_texel + 2.0) * uniform_buf.film.extent_inv;
vec4 color;
vec4 weight_cross = weight_12.xyyx * vec4(weights[0].yx, weights[3].xy);
@ -430,11 +431,12 @@ float film_history_blend_factor(float velocity,
/* Linearly blend when history gets below to 25% of the bbox size. */
blend *= saturate(distance_to_luma_clip * 4.0 + 0.1);
/* Discard out of view history. */
if (any(lessThan(texel, vec2(0))) || any(greaterThanEqual(texel, vec2(film_buf.extent)))) {
if (any(lessThan(texel, vec2(0))) || any(greaterThanEqual(texel, vec2(uniform_buf.film.extent))))
{
blend = 1.0;
}
/* Discard history if invalid. */
if (film_buf.use_history == false) {
if (uniform_buf.film.use_history == false) {
blend = 1.0;
}
return blend;
@ -444,7 +446,7 @@ float film_history_blend_factor(float velocity,
void film_store_combined(
FilmSample dst, ivec2 src_texel, vec4 color, float color_weight, inout vec4 display)
{
if (film_buf.combined_id == -1) {
if (uniform_buf.film.combined_id == -1) {
return;
}
@ -454,7 +456,7 @@ void film_store_combined(
/* Undo the weighting to get final spatially-filtered color. */
color_src = color / color_weight;
if (film_buf.use_reprojection) {
if (uniform_buf.film.use_reprojection) {
/* Interactive accumulation. Do reprojection and Temporal Anti-Aliasing. */
/* Reproject by finding where this pixel was in the previous frame. */
@ -507,7 +509,7 @@ void film_store_combined(
color = vec4(0.0, 0.0, 0.0, 1.0);
}
if (film_buf.display_id == -1) {
if (uniform_buf.film.display_id == -1) {
display = color;
}
imageStore(out_combined_img, dst.texel, color);
@ -528,7 +530,7 @@ void film_store_color(FilmSample dst, int pass_id, vec4 color, inout vec4 displa
color = vec4(0.0, 0.0, 0.0, 1.0);
}
if (film_buf.display_id == pass_id) {
if (uniform_buf.film.display_id == pass_id) {
display = color;
}
imageStore(color_accum_img, ivec3(dst.texel, pass_id), color);
@ -549,7 +551,7 @@ void film_store_value(FilmSample dst, int pass_id, float value, inout vec4 displ
value = 0.0;
}
if (film_buf.display_id == pass_id) {
if (uniform_buf.film.display_id == pass_id) {
display = vec4(value, value, value, 1.0);
}
imageStore(value_accum_img, ivec3(dst.texel, pass_id), vec4(value));
@ -562,7 +564,7 @@ void film_store_data(ivec2 texel_film, int pass_id, vec4 data_sample, inout vec4
return;
}
if (film_buf.display_id == pass_id) {
if (uniform_buf.film.display_id == pass_id) {
display = data_sample;
}
imageStore(color_accum_img, ivec3(texel_film, pass_id), data_sample);
@ -570,7 +572,7 @@ void film_store_data(ivec2 texel_film, int pass_id, vec4 data_sample, inout vec4
void film_store_depth(ivec2 texel_film, float value, out float out_depth)
{
if (film_buf.depth_id == -1) {
if (uniform_buf.film.depth_id == -1) {
return;
}
@ -624,13 +626,13 @@ void film_process_data(ivec2 texel_film, out vec4 out_color, out float out_depth
/* NOTE: We split the accumulations into separate loops to avoid using too much registers and
* maximize occupancy. */
if (film_buf.combined_id != -1) {
if (uniform_buf.film.combined_id != -1) {
/* NOTE: Do weight accumulation again since we use custom weights. */
float weight_accum = 0.0;
vec4 combined_accum = vec4(0.0);
FilmSample src;
for (int i = film_buf.samples_len - 1; i >= 0; i--) {
for (int i = uniform_buf.film.samples_len - 1; i >= 0; i--) {
src = film_sample_get(i, texel_film);
film_sample_accum_combined(src, combined_accum, weight_accum);
}
@ -638,62 +640,70 @@ void film_process_data(ivec2 texel_film, out vec4 out_color, out float out_depth
film_store_combined(dst, src.texel, combined_accum, weight_accum, out_color);
}
if (film_buf.has_data) {
if (uniform_buf.film.has_data) {
float film_distance = film_distance_load(texel_film);
/* Get sample closest to target texel. It is always sample 0. */
FilmSample film_sample = film_sample_get(0, texel_film);
if (film_buf.use_reprojection || film_sample.weight < film_distance) {
vec4 normal = texelFetch(rp_color_tx, ivec3(film_sample.texel, rp_buf.normal_id), 0);
if (uniform_buf.film.use_reprojection || film_sample.weight < film_distance) {
vec4 normal = texelFetch(
rp_color_tx, ivec3(film_sample.texel, uniform_buf.render_pass.normal_id), 0);
float depth = texelFetch(depth_tx, film_sample.texel, 0).x;
vec4 vector = velocity_resolve(vector_tx, film_sample.texel, depth);
/* Transform to pixel space. */
vector *= vec4(vec2(film_buf.render_extent), -vec2(film_buf.render_extent));
vector *= vec4(vec2(uniform_buf.film.render_extent), -vec2(uniform_buf.film.render_extent));
film_store_depth(texel_film, depth, out_depth);
film_store_data(texel_film, film_buf.normal_id, normal, out_color);
film_store_data(texel_film, film_buf.vector_id, vector, out_color);
film_store_data(texel_film, uniform_buf.film.normal_id, normal, out_color);
film_store_data(texel_film, uniform_buf.film.vector_id, vector, out_color);
film_store_distance(texel_film, film_sample.weight);
}
else {
out_depth = imageLoad(depth_img, texel_film).r;
if (film_buf.display_id != -1 && film_buf.display_id == film_buf.normal_id) {
out_color = imageLoad(color_accum_img, ivec3(texel_film, film_buf.display_id));
if (uniform_buf.film.display_id != -1 &&
uniform_buf.film.display_id == uniform_buf.film.normal_id) {
out_color = imageLoad(color_accum_img, ivec3(texel_film, uniform_buf.film.display_id));
}
}
}
if (film_buf.any_render_pass_1) {
if (uniform_buf.film.any_render_pass_1) {
vec4 diffuse_light_accum = vec4(0.0);
vec4 specular_light_accum = vec4(0.0);
vec4 volume_light_accum = vec4(0.0);
vec4 emission_accum = vec4(0.0);
for (int i = 0; i < film_buf.samples_len; i++) {
for (int i = 0; i < uniform_buf.film.samples_len; i++) {
FilmSample src = film_sample_get(i, texel_film);
film_sample_accum(src,
film_buf.diffuse_light_id,
rp_buf.diffuse_light_id,
uniform_buf.film.diffuse_light_id,
uniform_buf.render_pass.diffuse_light_id,
rp_color_tx,
diffuse_light_accum);
film_sample_accum(src,
film_buf.specular_light_id,
rp_buf.specular_light_id,
uniform_buf.film.specular_light_id,
uniform_buf.render_pass.specular_light_id,
rp_color_tx,
specular_light_accum);
film_sample_accum(
src, film_buf.volume_light_id, rp_buf.volume_light_id, rp_color_tx, volume_light_accum);
film_sample_accum(
src, film_buf.emission_id, rp_buf.emission_id, rp_color_tx, emission_accum);
film_sample_accum(src,
uniform_buf.film.volume_light_id,
uniform_buf.render_pass.volume_light_id,
rp_color_tx,
volume_light_accum);
film_sample_accum(src,
uniform_buf.film.emission_id,
uniform_buf.render_pass.emission_id,
rp_color_tx,
emission_accum);
}
film_store_color(dst, film_buf.diffuse_light_id, diffuse_light_accum, out_color);
film_store_color(dst, film_buf.specular_light_id, specular_light_accum, out_color);
film_store_color(dst, film_buf.volume_light_id, volume_light_accum, out_color);
film_store_color(dst, film_buf.emission_id, emission_accum, out_color);
film_store_color(dst, uniform_buf.film.diffuse_light_id, diffuse_light_accum, out_color);
film_store_color(dst, uniform_buf.film.specular_light_id, specular_light_accum, out_color);
film_store_color(dst, uniform_buf.film.volume_light_id, volume_light_accum, out_color);
film_store_color(dst, uniform_buf.film.emission_id, emission_accum, out_color);
}
if (film_buf.any_render_pass_2) {
if (uniform_buf.film.any_render_pass_2) {
vec4 diffuse_color_accum = vec4(0.0);
vec4 specular_color_accum = vec4(0.0);
vec4 environment_accum = vec4(0.0);
@ -701,64 +711,75 @@ void film_process_data(ivec2 texel_film, out vec4 out_color, out float out_depth
float shadow_accum = 0.0;
float ao_accum = 0.0;
for (int i = 0; i < film_buf.samples_len; i++) {
for (int i = 0; i < uniform_buf.film.samples_len; i++) {
FilmSample src = film_sample_get(i, texel_film);
film_sample_accum(src,
film_buf.diffuse_color_id,
rp_buf.diffuse_color_id,
uniform_buf.film.diffuse_color_id,
uniform_buf.render_pass.diffuse_color_id,
rp_color_tx,
diffuse_color_accum);
film_sample_accum(src,
film_buf.specular_color_id,
rp_buf.specular_color_id,
uniform_buf.film.specular_color_id,
uniform_buf.render_pass.specular_color_id,
rp_color_tx,
specular_color_accum);
film_sample_accum(
src, film_buf.environment_id, rp_buf.environment_id, rp_color_tx, environment_accum);
film_sample_accum(src, film_buf.shadow_id, rp_buf.shadow_id, rp_value_tx, shadow_accum);
film_sample_accum(
src, film_buf.ambient_occlusion_id, rp_buf.ambient_occlusion_id, rp_value_tx, ao_accum);
film_sample_accum(src,
uniform_buf.film.environment_id,
uniform_buf.render_pass.environment_id,
rp_color_tx,
environment_accum);
film_sample_accum(src,
uniform_buf.film.shadow_id,
uniform_buf.render_pass.shadow_id,
rp_value_tx,
shadow_accum);
film_sample_accum(src,
uniform_buf.film.ambient_occlusion_id,
uniform_buf.render_pass.ambient_occlusion_id,
rp_value_tx,
ao_accum);
film_sample_accum_mist(src, mist_accum);
}
film_store_color(dst, film_buf.diffuse_color_id, diffuse_color_accum, out_color);
film_store_color(dst, film_buf.specular_color_id, specular_color_accum, out_color);
film_store_color(dst, film_buf.environment_id, environment_accum, out_color);
film_store_color(dst, film_buf.shadow_id, vec4(vec3(shadow_accum), 1.0), out_color);
film_store_color(dst, film_buf.ambient_occlusion_id, vec4(vec3(ao_accum), 1.0), out_color);
film_store_value(dst, film_buf.mist_id, mist_accum, out_color);
film_store_color(dst, uniform_buf.film.diffuse_color_id, diffuse_color_accum, out_color);
film_store_color(dst, uniform_buf.film.specular_color_id, specular_color_accum, out_color);
film_store_color(dst, uniform_buf.film.environment_id, environment_accum, out_color);
film_store_color(dst, uniform_buf.film.shadow_id, vec4(vec3(shadow_accum), 1.0), out_color);
film_store_color(
dst, uniform_buf.film.ambient_occlusion_id, vec4(vec3(ao_accum), 1.0), out_color);
film_store_value(dst, uniform_buf.film.mist_id, mist_accum, out_color);
}
for (int aov = 0; aov < film_buf.aov_color_len; aov++) {
for (int aov = 0; aov < uniform_buf.film.aov_color_len; aov++) {
vec4 aov_accum = vec4(0.0);
for (int i = 0; i < film_buf.samples_len; i++) {
for (int i = 0; i < uniform_buf.film.samples_len; i++) {
FilmSample src = film_sample_get(i, texel_film);
film_sample_accum(src, 0, rp_buf.color_len + aov, rp_color_tx, aov_accum);
film_sample_accum(src, 0, uniform_buf.render_pass.color_len + aov, rp_color_tx, aov_accum);
}
film_store_color(dst, film_buf.aov_color_id + aov, aov_accum, out_color);
film_store_color(dst, uniform_buf.film.aov_color_id + aov, aov_accum, out_color);
}
for (int aov = 0; aov < film_buf.aov_value_len; aov++) {
for (int aov = 0; aov < uniform_buf.film.aov_value_len; aov++) {
float aov_accum = 0.0;
for (int i = 0; i < film_buf.samples_len; i++) {
for (int i = 0; i < uniform_buf.film.samples_len; i++) {
FilmSample src = film_sample_get(i, texel_film);
film_sample_accum(src, 0, rp_buf.value_len + aov, rp_value_tx, aov_accum);
film_sample_accum(src, 0, uniform_buf.render_pass.value_len + aov, rp_value_tx, aov_accum);
}
film_store_value(dst, film_buf.aov_value_id + aov, aov_accum, out_color);
film_store_value(dst, uniform_buf.film.aov_value_id + aov, aov_accum, out_color);
}
if (film_buf.cryptomatte_samples_len != 0) {
if (uniform_buf.film.cryptomatte_samples_len != 0) {
/* Cryptomatte passes cannot be cleared by a weighted store like other passes. */
if (!film_buf.use_history || film_buf.use_reprojection) {
if (!uniform_buf.film.use_history || uniform_buf.film.use_reprojection) {
cryptomatte_clear_samples(dst);
}
film_cryptomatte_layer_accum_and_store(
dst, texel_film, film_buf.cryptomatte_object_id, 0, out_color);
dst, texel_film, uniform_buf.film.cryptomatte_object_id, 0, out_color);
film_cryptomatte_layer_accum_and_store(
dst, texel_film, film_buf.cryptomatte_asset_id, 1, out_color);
dst, texel_film, uniform_buf.film.cryptomatte_asset_id, 1, out_color);
film_cryptomatte_layer_accum_and_store(
dst, texel_film, film_buf.cryptomatte_material_id, 2, out_color);
dst, texel_film, uniform_buf.film.cryptomatte_material_id, 2, out_color);
}
}

View File

@ -378,11 +378,11 @@ void output_renderpass_value(int id, float value)
void clear_aovs()
{
#if defined(MAT_RENDER_PASS_SUPPORT) && defined(GPU_FRAGMENT_SHADER)
for (int i = 0; i < AOV_MAX && i < rp_buf.aovs.color_len; i++) {
output_renderpass_color(rp_buf.color_len + i, vec4(0));
for (int i = 0; i < AOV_MAX && i < uniform_buf.render_pass.aovs.color_len; i++) {
output_renderpass_color(uniform_buf.render_pass.color_len + i, vec4(0));
}
for (int i = 0; i < AOV_MAX && i < rp_buf.aovs.value_len; i++) {
output_renderpass_value(rp_buf.value_len + i, 0.0);
for (int i = 0; i < AOV_MAX && i < uniform_buf.render_pass.aovs.value_len; i++) {
output_renderpass_value(uniform_buf.render_pass.value_len + i, 0.0);
}
#endif
}
@ -390,15 +390,19 @@ void clear_aovs()
void output_aov(vec4 color, float value, uint hash)
{
#if defined(MAT_RENDER_PASS_SUPPORT) && defined(GPU_FRAGMENT_SHADER)
for (int i = 0; i < AOV_MAX && i < rp_buf.aovs.color_len; i++) {
if (rp_buf.aovs.hash_color[i].x == hash) {
imageStore(rp_color_img, ivec3(ivec2(gl_FragCoord.xy), rp_buf.color_len + i), color);
for (int i = 0; i < AOV_MAX && i < uniform_buf.render_pass.aovs.color_len; i++) {
if (uniform_buf.render_pass.aovs.hash_color[i].x == hash) {
imageStore(rp_color_img,
ivec3(ivec2(gl_FragCoord.xy), uniform_buf.render_pass.color_len + i),
color);
return;
}
}
for (int i = 0; i < AOV_MAX && i < rp_buf.aovs.value_len; i++) {
if (rp_buf.aovs.hash_value[i].x == hash) {
imageStore(rp_value_img, ivec3(ivec2(gl_FragCoord.xy), rp_buf.value_len + i), vec4(value));
for (int i = 0; i < AOV_MAX && i < uniform_buf.render_pass.aovs.value_len; i++) {
if (uniform_buf.render_pass.aovs.hash_value[i].x == hash) {
imageStore(rp_value_img,
ivec3(ivec2(gl_FragCoord.xy), uniform_buf.render_pass.value_len + i),
vec4(value));
return;
}
}
@ -497,7 +501,7 @@ vec3 coordinate_screen(vec3 P)
else {
/* TODO(fclem): Actual camera transform. */
window.xy = project_point(ProjectionMatrix, transform_point(ViewMatrix, P)).xy * 0.5 + 0.5;
window.xy = window.xy * camera_buf.uv_scale + camera_buf.uv_bias;
window.xy = window.xy * uniform_buf.camera.uv_scale + uniform_buf.camera.uv_bias;
}
return window;
}

View File

@ -102,7 +102,7 @@ void main()
const uint tile_size = RAYTRACE_GROUP_SIZE;
uvec2 tile_coord = unpackUvec2x16(tiles_coord_buf[gl_WorkGroupID.x]);
ivec2 texel_fullres = ivec2(gl_LocalInvocationID.xy + tile_coord * tile_size);
vec2 center_uv = vec2(texel_fullres) * raytrace_buf.full_resolution_inv;
vec2 center_uv = vec2(texel_fullres) * uniform_buf.raytrace.full_resolution_inv;
float center_depth = texelFetch(hiz_tx, texel_fullres, 0).r;
vec3 center_P = get_world_space_from_depth(center_uv, center_depth);
@ -160,7 +160,7 @@ void main()
}
float sample_depth = texelFetch(hiz_tx, sample_texel, 0).r;
vec2 sample_uv = vec2(sample_texel) * raytrace_buf.full_resolution_inv;
vec2 sample_uv = vec2(sample_texel) * uniform_buf.raytrace.full_resolution_inv;
vec3 sample_P = get_world_space_from_depth(sample_uv, sample_depth);
/* Background case. */

View File

@ -107,9 +107,9 @@ void main()
uvec2 tile_coord = unpackUvec2x16(tiles_coord_buf[gl_WorkGroupID.x]);
ivec2 texel_fullres = ivec2(gl_LocalInvocationID.xy + tile_coord * tile_size);
ivec2 texel = (texel_fullres) / raytrace_buf.resolution_scale;
ivec2 texel = (texel_fullres) / uniform_buf.raytrace.resolution_scale;
if (raytrace_buf.skip_denoise) {
if (uniform_buf.raytrace.skip_denoise) {
imageStore(out_radiance_img, texel_fullres, imageLoad(ray_radiance_img, texel));
return;
}
@ -152,7 +152,7 @@ void main()
return;
}
vec2 uv = (vec2(texel_fullres) + 0.5) * raytrace_buf.full_resolution_inv;
vec2 uv = (vec2(texel_fullres) + 0.5) * uniform_buf.raytrace.full_resolution_inv;
vec3 V = transform_direction(ViewMatrixInverse, get_view_vector_from_screen_uv(uv));
ClosureT closure;
@ -166,7 +166,7 @@ void main()
/* NOTE: filter_size should never be greater than twice RAYTRACE_GROUP_SIZE. Otherwise, the
* reconstruction can becomes ill defined since we don't know if further tiles are valid. */
filter_size = 12.0 * sqrt(filter_size_factor);
if (raytrace_buf.resolution_scale > 1) {
if (uniform_buf.raytrace.resolution_scale > 1) {
/* Filter at least 1 trace pixel to fight the undersampling. */
filter_size = max(filter_size, 3.0);
sample_count = max(sample_count, 5u);
@ -189,7 +189,8 @@ void main()
ivec2 sample_texel = texel + offset;
/* Reject samples outside of valid neighbor tiles. */
ivec2 sample_tile = ivec2(sample_texel * raytrace_buf.resolution_scale) / int(tile_size);
ivec2 sample_tile = ivec2(sample_texel * uniform_buf.raytrace.resolution_scale) /
int(tile_size);
ivec2 sample_tile_relative = sample_tile - ivec2(tile_coord);
if (neighbor_tile_mask_bit_get(invalid_neighbor_tile_mask, sample_tile_relative)) {
continue;

View File

@ -111,7 +111,7 @@ vec4 radiance_history_fetch(ivec2 texel, float bilinear_weight)
vec4 radiance_history_sample(vec3 P, LocalStatistics local)
{
vec2 uv = project_point(raytrace_buf.history_persmat, P).xy * 0.5 + 0.5;
vec2 uv = project_point(uniform_buf.raytrace.history_persmat, P).xy * 0.5 + 0.5;
/* FIXME(fclem): Find why we need this half pixel offset. */
vec2 texel_co = uv * vec2(textureSize(radiance_history_tx, 0).xy) - 0.5;
@ -139,7 +139,7 @@ vec4 radiance_history_sample(vec3 P, LocalStatistics local)
vec2 variance_history_sample(vec3 P)
{
vec2 uv = project_point(raytrace_buf.history_persmat, P).xy * 0.5 + 0.5;
vec2 uv = project_point(uniform_buf.raytrace.history_persmat, P).xy * 0.5 + 0.5;
if (!in_range_exclusive(uv, vec2(0.0), vec2(1.0))) {
/* Out of history view. Return sample without weight. */
@ -164,7 +164,7 @@ void main()
const uint tile_size = RAYTRACE_GROUP_SIZE;
uvec2 tile_coord = unpackUvec2x16(tiles_coord_buf[gl_WorkGroupID.x]);
ivec2 texel_fullres = ivec2(gl_LocalInvocationID.xy + tile_coord * tile_size);
vec2 uv = (vec2(texel_fullres) + 0.5) * raytrace_buf.full_resolution_inv;
vec2 uv = (vec2(texel_fullres) + 0.5) * uniform_buf.raytrace.full_resolution_inv;
float in_variance = imageLoad(in_variance_img, texel_fullres).r;
vec3 in_radiance = imageLoad(in_radiance_img, texel_fullres).rgb;

View File

@ -19,7 +19,8 @@ void main()
uvec2 tile_coord = unpackUvec2x16(tiles_coord_buf[gl_WorkGroupID.x]);
ivec2 texel = ivec2(gl_LocalInvocationID.xy + tile_coord * tile_size);
ivec2 texel_fullres = texel * raytrace_buf.resolution_scale + raytrace_buf.resolution_bias;
ivec2 texel_fullres = texel * uniform_buf.raytrace.resolution_scale +
uniform_buf.raytrace.resolution_bias;
bool valid_texel = in_texture_range(texel_fullres, stencil_tx);
uint closure_bits = (!valid_texel) ? 0u : texelFetch(stencil_tx, texel_fullres, 0).r;

View File

@ -44,8 +44,8 @@ void main()
eClosureBits closure_bits = eClosureBits(texelFetch(stencil_tx, texel, 0).r);
if (flag_test(closure_bits, raytrace_buf.closure_active)) {
int gbuffer_layer = raytrace_buf.closure_active == CLOSURE_REFRACTION ? 1 : 0;
if (flag_test(closure_bits, uniform_buf.raytrace.closure_active)) {
int gbuffer_layer = uniform_buf.raytrace.closure_active == CLOSURE_REFRACTION ? 1 : 0;
vec4 gbuffer_packed = texelFetch(gbuffer_closure_tx, ivec3(texel, gbuffer_layer), 0);
float roughness = gbuffer_packed.z;

Some files were not shown because too many files have changed in this diff Show More