UI: Asset Shelf (Experimental Feature) #104831

Closed
Julian Eisel wants to merge 399 commits from asset-shelf into main

When changing the target branch, be careful to rebase the branch in your fork to match. See documentation.
275 changed files with 2175 additions and 1744 deletions
Showing only changes of commit 47c9c31138 - Show all commits

View File

@ -1,45 +0,0 @@
name: Bug Report
about: File a bug report
labels:
- bug
ref: master
body:
- type: markdown
attributes:
value: |
### First time bug reporting?
Read [these tips](https://wiki.blender.org/wiki/Process/Bug_Reports) and watch this **[How to Report a Bug](https://www.youtube.com/watch?v=JTD0OJq_rF4)** video to make a complete, valid bug report. Remember to write your bug report in **English**.
### What not to report here
For feature requests, feedback, questions or issues building Blender, see [communication channels](https://wiki.blender.org/wiki/Communication/Contact#User_Feedback_and_Requests).
### Please verify
* Always test with the latest official release from [blender.org](https://www.blender.org/) and daily build from [builder.blender.org](https://builder.blender.org/).
* Please use `Help > Report a Bug` in Blender to automatically fill system information and exact Blender version.
* Test [previous Blender versions](https://download.blender.org/release/) to find the latest version that was working as expected.
* Find steps to redo the bug consistently without any non-official add-ons, and include a **small and simple .blend file** to demonstrate the bug.
* If there are multiple bugs, make multiple bug reports.
* Sometimes, driver or software upgrades cause problems. On Windows, try a clean install of the graphics drivers.
### Help the developers
Bug fixing is important, the developers will handle a report swiftly. For that reason, we need your help to carefully provide instructions that others can follow quickly. You do your half of the work, then we do our half!
If a report is tagged with Needs Information from User and it has no reply after a week, we will assume the issue is gone and close the report.
- type: textarea
attributes:
label: "Description"
value: |
**System Information**
Operating system:
Graphics card:
**Blender Version**
Broken: (example: 2.80, edbf15d3c044, master, 2018-11-28, as found on the splash screen)
Worked: (newest version of Blender that worked as expected)
**Short description of error**
**Exact steps for others to reproduce the error**
Based on the default startup or an attached .blend file (as simple as possible).

View File

@ -0,0 +1,41 @@
name: Bug Report
about: File a bug report
labels:
- bug
body:
- type: markdown
attributes:
value: |
### Instructions
First time reporting? See [tips](https://wiki.blender.org/wiki/Process/Bug_Reports) and [walkthrough video](https://www.youtube.com/watch?v=JTD0OJq_rF4).
* Use **Help > Report a Bug** in Blender to fill system information and exact Blender version.
* Test [daily builds](https://builder.blender.org/) to verify if the issue is already fixed.
* Test [previous versions](https://download.blender.org/release/) to find an older working version.
* For feature requests, feedback, questions or build issues, see [communication channels](https://wiki.blender.org/wiki/Communication/Contact#User_Feedback_and_Requests).
* If there are multiple bugs, make multiple bug reports.
- type: textarea
id: body
attributes:
label: "Description"
value: |
**System Information**
Operating system:
Graphics card:
**Blender Version**
Broken: (example: 2.80, edbf15d3c044, master, 2018-11-28, as found on the splash screen)
Worked: (newest version of Blender that worked as expected)
**Short description of error**
**Exact steps for others to reproduce the error**
Based on the default startup or an attached .blend file (as simple as possible).
- type: markdown
attributes:
value: |
### Help the developers
Bug fixing is important, the developers will handle reports swiftly. For that reason, carefully provide exact steps and a **small and simple .blend file** to reproduce the problem. You do your half of the work, then we do our half!

View File

@ -0,0 +1 @@
blank_issues_enabled: false

View File

@ -0,0 +1,9 @@
name: Design
about: Create a design task (for developers only)
labels:
- design
body:
- type: textarea
id: body
attributes:
label: "Description"

View File

@ -0,0 +1,9 @@
name: To Do
about: Create a to do task (for developers only)
labels:
- todo
body:
- type: textarea
id: body
attributes:
label: "Description"

View File

@ -1,4 +0,0 @@
---
name: Pull Request
about: Submit a pull request
---

View File

@ -0,0 +1,20 @@
name: Pull Request
about: Contribute code to Blender
body:
- type: markdown
attributes:
value: |
### Instructions
Guides to [contributing code](https://wiki.blender.org/index.php/Dev:Doc/Process/Contributing_Code) and effective [code review](https://wiki.blender.org/index.php/Dev:Doc/Tools/Code_Review).
By submitting code here, you agree that the code is (compatible with) GNU GPL v2 or later.
- type: textarea
id: body
attributes:
label: "Description"
value: |
Description of the problem that is addressed in the patch.
Description of the proposed solution and its implementation.

View File

@ -102,10 +102,9 @@ ccl_device_inline float shift_cos_in(float cos_in, const float frequency_multipl
return val;
}
ccl_device_inline bool bsdf_is_transmission(ccl_private const ShaderClosure *sc,
const float3 omega_in)
ccl_device_inline bool bsdf_is_transmission(ccl_private const ShaderClosure *sc, const float3 wo)
{
return dot(sc->N, omega_in) < 0.0f;
return dot(sc->N, wo) < 0.0f;
}
ccl_device_inline int bsdf_sample(KernelGlobals kg,
@ -114,7 +113,7 @@ ccl_device_inline int bsdf_sample(KernelGlobals kg,
float randu,
float randv,
ccl_private Spectrum *eval,
ccl_private float3 *omega_in,
ccl_private float3 *wo,
ccl_private float *pdf,
ccl_private float2 *sampled_roughness,
ccl_private float *eta)
@ -126,43 +125,43 @@ ccl_device_inline int bsdf_sample(KernelGlobals kg,
switch (sc->type) {
case CLOSURE_BSDF_DIFFUSE_ID:
label = bsdf_diffuse_sample(sc, Ng, sd->I, randu, randv, eval, omega_in, pdf);
label = bsdf_diffuse_sample(sc, Ng, sd->wi, randu, randv, eval, wo, pdf);
*sampled_roughness = one_float2();
*eta = 1.0f;
break;
#if defined(__SVM__) || defined(__OSL__)
case CLOSURE_BSDF_OREN_NAYAR_ID:
label = bsdf_oren_nayar_sample(sc, Ng, sd->I, randu, randv, eval, omega_in, pdf);
label = bsdf_oren_nayar_sample(sc, Ng, sd->wi, randu, randv, eval, wo, pdf);
*sampled_roughness = one_float2();
*eta = 1.0f;
break;
# ifdef __OSL__
case CLOSURE_BSDF_PHONG_RAMP_ID:
label = bsdf_phong_ramp_sample(
sc, Ng, sd->I, randu, randv, eval, omega_in, pdf, sampled_roughness);
sc, Ng, sd->wi, randu, randv, eval, wo, pdf, sampled_roughness);
*eta = 1.0f;
break;
case CLOSURE_BSDF_DIFFUSE_RAMP_ID:
label = bsdf_diffuse_ramp_sample(sc, Ng, sd->I, randu, randv, eval, omega_in, pdf);
label = bsdf_diffuse_ramp_sample(sc, Ng, sd->wi, randu, randv, eval, wo, pdf);
*sampled_roughness = one_float2();
*eta = 1.0f;
break;
# endif
case CLOSURE_BSDF_TRANSLUCENT_ID:
label = bsdf_translucent_sample(sc, Ng, sd->I, randu, randv, eval, omega_in, pdf);
label = bsdf_translucent_sample(sc, Ng, sd->wi, randu, randv, eval, wo, pdf);
*sampled_roughness = one_float2();
*eta = 1.0f;
break;
case CLOSURE_BSDF_REFLECTION_ID:
label = bsdf_reflection_sample(sc, Ng, sd->I, randu, randv, eval, omega_in, pdf, eta);
label = bsdf_reflection_sample(sc, Ng, sd->wi, randu, randv, eval, wo, pdf, eta);
*sampled_roughness = zero_float2();
break;
case CLOSURE_BSDF_REFRACTION_ID:
label = bsdf_refraction_sample(sc, Ng, sd->I, randu, randv, eval, omega_in, pdf, eta);
label = bsdf_refraction_sample(sc, Ng, sd->wi, randu, randv, eval, wo, pdf, eta);
*sampled_roughness = zero_float2();
break;
case CLOSURE_BSDF_TRANSPARENT_ID:
label = bsdf_transparent_sample(sc, Ng, sd->I, randu, randv, eval, omega_in, pdf);
label = bsdf_transparent_sample(sc, Ng, sd->wi, randu, randv, eval, wo, pdf);
*sampled_roughness = zero_float2();
*eta = 1.0f;
break;
@ -171,85 +170,65 @@ ccl_device_inline int bsdf_sample(KernelGlobals kg,
case CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID:
case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID:
label = bsdf_microfacet_ggx_sample(
kg, sc, Ng, sd->I, randu, randv, eval, omega_in, pdf, sampled_roughness, eta);
kg, sc, Ng, sd->wi, randu, randv, eval, wo, pdf, sampled_roughness, eta);
break;
case CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID:
case CLOSURE_BSDF_MICROFACET_MULTI_GGX_FRESNEL_ID:
label = bsdf_microfacet_multi_ggx_sample(kg,
sc,
Ng,
sd->I,
randu,
randv,
eval,
omega_in,
pdf,
&sd->lcg_state,
sampled_roughness,
eta);
label = bsdf_microfacet_multi_ggx_sample(
kg, sc, Ng, sd->wi, randu, randv, eval, wo, pdf, &sd->lcg_state, sampled_roughness, eta);
break;
case CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID:
case CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_FRESNEL_ID:
label = bsdf_microfacet_multi_ggx_glass_sample(kg,
sc,
Ng,
sd->I,
randu,
randv,
eval,
omega_in,
pdf,
&sd->lcg_state,
sampled_roughness,
eta);
label = bsdf_microfacet_multi_ggx_glass_sample(
kg, sc, Ng, sd->wi, randu, randv, eval, wo, pdf, &sd->lcg_state, sampled_roughness, eta);
break;
case CLOSURE_BSDF_MICROFACET_BECKMANN_ID:
case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID:
label = bsdf_microfacet_beckmann_sample(
kg, sc, Ng, sd->I, randu, randv, eval, omega_in, pdf, sampled_roughness, eta);
kg, sc, Ng, sd->wi, randu, randv, eval, wo, pdf, sampled_roughness, eta);
break;
case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID:
label = bsdf_ashikhmin_shirley_sample(
sc, Ng, sd->I, randu, randv, eval, omega_in, pdf, sampled_roughness);
sc, Ng, sd->wi, randu, randv, eval, wo, pdf, sampled_roughness);
*eta = 1.0f;
break;
case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID:
label = bsdf_ashikhmin_velvet_sample(sc, Ng, sd->I, randu, randv, eval, omega_in, pdf);
label = bsdf_ashikhmin_velvet_sample(sc, Ng, sd->wi, randu, randv, eval, wo, pdf);
*sampled_roughness = one_float2();
*eta = 1.0f;
break;
case CLOSURE_BSDF_DIFFUSE_TOON_ID:
label = bsdf_diffuse_toon_sample(sc, Ng, sd->I, randu, randv, eval, omega_in, pdf);
label = bsdf_diffuse_toon_sample(sc, Ng, sd->wi, randu, randv, eval, wo, pdf);
*sampled_roughness = one_float2();
*eta = 1.0f;
break;
case CLOSURE_BSDF_GLOSSY_TOON_ID:
label = bsdf_glossy_toon_sample(sc, Ng, sd->I, randu, randv, eval, omega_in, pdf);
label = bsdf_glossy_toon_sample(sc, Ng, sd->wi, randu, randv, eval, wo, pdf);
// double check if this is valid
*sampled_roughness = one_float2();
*eta = 1.0f;
break;
case CLOSURE_BSDF_HAIR_REFLECTION_ID:
label = bsdf_hair_reflection_sample(
sc, Ng, sd->I, randu, randv, eval, omega_in, pdf, sampled_roughness);
sc, Ng, sd->wi, randu, randv, eval, wo, pdf, sampled_roughness);
*eta = 1.0f;
break;
case CLOSURE_BSDF_HAIR_TRANSMISSION_ID:
label = bsdf_hair_transmission_sample(
sc, Ng, sd->I, randu, randv, eval, omega_in, pdf, sampled_roughness);
sc, Ng, sd->wi, randu, randv, eval, wo, pdf, sampled_roughness);
*eta = 1.0f;
break;
case CLOSURE_BSDF_HAIR_PRINCIPLED_ID:
label = bsdf_principled_hair_sample(
kg, sc, sd, randu, randv, eval, omega_in, pdf, sampled_roughness, eta);
kg, sc, sd, randu, randv, eval, wo, pdf, sampled_roughness, eta);
break;
case CLOSURE_BSDF_PRINCIPLED_DIFFUSE_ID:
label = bsdf_principled_diffuse_sample(sc, Ng, sd->I, randu, randv, eval, omega_in, pdf);
label = bsdf_principled_diffuse_sample(sc, Ng, sd->wi, randu, randv, eval, wo, pdf);
*sampled_roughness = one_float2();
*eta = 1.0f;
break;
case CLOSURE_BSDF_PRINCIPLED_SHEEN_ID:
label = bsdf_principled_sheen_sample(sc, Ng, sd->I, randu, randv, eval, omega_in, pdf);
label = bsdf_principled_sheen_sample(sc, Ng, sd->wi, randu, randv, eval, wo, pdf);
*sampled_roughness = one_float2();
*eta = 1.0f;
break;
@ -274,12 +253,12 @@ ccl_device_inline int bsdf_sample(KernelGlobals kg,
const float frequency_multiplier =
kernel_data_fetch(objects, sd->object).shadow_terminator_shading_offset;
if (frequency_multiplier > 1.0f) {
const float cosNI = dot(*omega_in, sc->N);
*eval *= shift_cos_in(cosNI, frequency_multiplier);
const float cosNO = dot(*wo, sc->N);
*eval *= shift_cos_in(cosNO, frequency_multiplier);
}
if (label & LABEL_DIFFUSE) {
if (!isequal(sc->N, sd->N)) {
*eval *= bump_shadowing_term(sd->N, sc->N, *omega_in);
*eval *= bump_shadowing_term(sd->N, sc->N, *wo);
}
}
}
@ -426,7 +405,7 @@ ccl_device_inline void bsdf_roughness_eta(const KernelGlobals kg,
ccl_device_inline int bsdf_label(const KernelGlobals kg,
ccl_private const ShaderClosure *sc,
const float3 omega_in)
const float3 wo)
{
/* For curves use the smooth normal, particularly for ribbons the geometric
* normal gives too much darkening otherwise. */
@ -482,8 +461,8 @@ ccl_device_inline int bsdf_label(const KernelGlobals kg,
}
case CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID:
case CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_FRESNEL_ID:
label = (bsdf_is_transmission(sc, omega_in)) ? LABEL_TRANSMIT | LABEL_GLOSSY :
LABEL_REFLECT | LABEL_GLOSSY;
label = (bsdf_is_transmission(sc, wo)) ? LABEL_TRANSMIT | LABEL_GLOSSY :
LABEL_REFLECT | LABEL_GLOSSY;
break;
case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID:
label = LABEL_REFLECT | LABEL_GLOSSY;
@ -504,7 +483,7 @@ ccl_device_inline int bsdf_label(const KernelGlobals kg,
label = LABEL_TRANSMIT | LABEL_GLOSSY;
break;
case CLOSURE_BSDF_HAIR_PRINCIPLED_ID:
if (bsdf_is_transmission(sc, omega_in))
if (bsdf_is_transmission(sc, wo))
label = LABEL_TRANSMIT | LABEL_GLOSSY;
else
label = LABEL_REFLECT | LABEL_GLOSSY;
@ -543,83 +522,83 @@ ccl_device_inline
bsdf_eval(KernelGlobals kg,
ccl_private ShaderData *sd,
ccl_private const ShaderClosure *sc,
const float3 omega_in,
const float3 wo,
ccl_private float *pdf)
{
Spectrum eval = zero_spectrum();
switch (sc->type) {
case CLOSURE_BSDF_DIFFUSE_ID:
eval = bsdf_diffuse_eval(sc, sd->I, omega_in, pdf);
eval = bsdf_diffuse_eval(sc, sd->wi, wo, pdf);
break;
#if defined(__SVM__) || defined(__OSL__)
case CLOSURE_BSDF_OREN_NAYAR_ID:
eval = bsdf_oren_nayar_eval(sc, sd->I, omega_in, pdf);
eval = bsdf_oren_nayar_eval(sc, sd->wi, wo, pdf);
break;
# ifdef __OSL__
case CLOSURE_BSDF_PHONG_RAMP_ID:
eval = bsdf_phong_ramp_eval(sc, sd->I, omega_in, pdf);
eval = bsdf_phong_ramp_eval(sc, sd->wi, wo, pdf);
break;
case CLOSURE_BSDF_DIFFUSE_RAMP_ID:
eval = bsdf_diffuse_ramp_eval(sc, sd->I, omega_in, pdf);
eval = bsdf_diffuse_ramp_eval(sc, sd->wi, wo, pdf);
break;
# endif
case CLOSURE_BSDF_TRANSLUCENT_ID:
eval = bsdf_translucent_eval(sc, sd->I, omega_in, pdf);
eval = bsdf_translucent_eval(sc, sd->wi, wo, pdf);
break;
case CLOSURE_BSDF_REFLECTION_ID:
eval = bsdf_reflection_eval(sc, sd->I, omega_in, pdf);
eval = bsdf_reflection_eval(sc, sd->wi, wo, pdf);
break;
case CLOSURE_BSDF_REFRACTION_ID:
eval = bsdf_refraction_eval(sc, sd->I, omega_in, pdf);
eval = bsdf_refraction_eval(sc, sd->wi, wo, pdf);
break;
case CLOSURE_BSDF_TRANSPARENT_ID:
eval = bsdf_transparent_eval(sc, sd->I, omega_in, pdf);
eval = bsdf_transparent_eval(sc, sd->wi, wo, pdf);
break;
case CLOSURE_BSDF_MICROFACET_GGX_ID:
case CLOSURE_BSDF_MICROFACET_GGX_FRESNEL_ID:
case CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID:
case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID:
eval = bsdf_microfacet_ggx_eval(sc, sd->N, sd->I, omega_in, pdf);
eval = bsdf_microfacet_ggx_eval(sc, sd->N, sd->wi, wo, pdf);
break;
case CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID:
case CLOSURE_BSDF_MICROFACET_MULTI_GGX_FRESNEL_ID:
eval = bsdf_microfacet_multi_ggx_eval(sc, sd->N, sd->I, omega_in, pdf, &sd->lcg_state);
eval = bsdf_microfacet_multi_ggx_eval(sc, sd->N, sd->wi, wo, pdf, &sd->lcg_state);
break;
case CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID:
case CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_FRESNEL_ID:
eval = bsdf_microfacet_multi_ggx_glass_eval(sc, sd->I, omega_in, pdf, &sd->lcg_state);
eval = bsdf_microfacet_multi_ggx_glass_eval(sc, sd->wi, wo, pdf, &sd->lcg_state);
break;
case CLOSURE_BSDF_MICROFACET_BECKMANN_ID:
case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID:
eval = bsdf_microfacet_beckmann_eval(sc, sd->N, sd->I, omega_in, pdf);
eval = bsdf_microfacet_beckmann_eval(sc, sd->N, sd->wi, wo, pdf);
break;
case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID:
eval = bsdf_ashikhmin_shirley_eval(sc, sd->N, sd->I, omega_in, pdf);
eval = bsdf_ashikhmin_shirley_eval(sc, sd->N, sd->wi, wo, pdf);
break;
case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID:
eval = bsdf_ashikhmin_velvet_eval(sc, sd->I, omega_in, pdf);
eval = bsdf_ashikhmin_velvet_eval(sc, sd->wi, wo, pdf);
break;
case CLOSURE_BSDF_DIFFUSE_TOON_ID:
eval = bsdf_diffuse_toon_eval(sc, sd->I, omega_in, pdf);
eval = bsdf_diffuse_toon_eval(sc, sd->wi, wo, pdf);
break;
case CLOSURE_BSDF_GLOSSY_TOON_ID:
eval = bsdf_glossy_toon_eval(sc, sd->I, omega_in, pdf);
eval = bsdf_glossy_toon_eval(sc, sd->wi, wo, pdf);
break;
case CLOSURE_BSDF_HAIR_PRINCIPLED_ID:
eval = bsdf_principled_hair_eval(kg, sd, sc, omega_in, pdf);
eval = bsdf_principled_hair_eval(kg, sd, sc, wo, pdf);
break;
case CLOSURE_BSDF_HAIR_REFLECTION_ID:
eval = bsdf_hair_reflection_eval(sc, sd->I, omega_in, pdf);
eval = bsdf_hair_reflection_eval(sc, sd->wi, wo, pdf);
break;
case CLOSURE_BSDF_HAIR_TRANSMISSION_ID:
eval = bsdf_hair_transmission_eval(sc, sd->I, omega_in, pdf);
eval = bsdf_hair_transmission_eval(sc, sd->wi, wo, pdf);
break;
case CLOSURE_BSDF_PRINCIPLED_DIFFUSE_ID:
eval = bsdf_principled_diffuse_eval(sc, sd->I, omega_in, pdf);
eval = bsdf_principled_diffuse_eval(sc, sd->wi, wo, pdf);
break;
case CLOSURE_BSDF_PRINCIPLED_SHEEN_ID:
eval = bsdf_principled_sheen_eval(sc, sd->I, omega_in, pdf);
eval = bsdf_principled_sheen_eval(sc, sd->wi, wo, pdf);
break;
#endif
default:
@ -628,7 +607,7 @@ ccl_device_inline
if (CLOSURE_IS_BSDF_DIFFUSE(sc->type)) {
if (!isequal(sc->N, sd->N)) {
eval *= bump_shadowing_term(sd->N, sc->N, omega_in);
eval *= bump_shadowing_term(sd->N, sc->N, wo);
}
}
@ -636,9 +615,9 @@ ccl_device_inline
const float frequency_multiplier =
kernel_data_fetch(objects, sd->object).shadow_terminator_shading_offset;
if (frequency_multiplier > 1.0f) {
const float cosNI = dot(omega_in, sc->N);
if (cosNI >= 0.0f) {
eval *= shift_cos_in(cosNI, frequency_multiplier);
const float cosNO = dot(wo, sc->N);
if (cosNO >= 0.0f) {
eval *= shift_cos_in(cosNO, frequency_multiplier);
}
}

View File

@ -41,20 +41,20 @@ ccl_device_inline float bsdf_ashikhmin_shirley_roughness_to_exponent(float rough
ccl_device_forceinline Spectrum bsdf_ashikhmin_shirley_eval(ccl_private const ShaderClosure *sc,
const float3 Ng,
const float3 I,
const float3 omega_in,
const float3 wi,
const float3 wo,
ccl_private float *pdf)
{
ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc;
const float cosNgI = dot(Ng, omega_in);
const float cosNgO = dot(Ng, wo);
float3 N = bsdf->N;
float NdotI = dot(N, I); /* in Cycles/OSL convention I is omega_out */
float NdotO = dot(N, omega_in); /* and consequently we use for O omaga_in ;) */
float NdotI = dot(N, wi);
float NdotO = dot(N, wo);
float out = 0.0f;
if ((cosNgI < 0.0f) || fmaxf(bsdf->alpha_x, bsdf->alpha_y) <= 1e-4f ||
if ((cosNgO < 0.0f) || fmaxf(bsdf->alpha_x, bsdf->alpha_y) <= 1e-4f ||
!(NdotI > 0.0f && NdotO > 0.0f)) {
*pdf = 0.0f;
return zero_spectrum();
@ -62,15 +62,15 @@ ccl_device_forceinline Spectrum bsdf_ashikhmin_shirley_eval(ccl_private const Sh
NdotI = fmaxf(NdotI, 1e-6f);
NdotO = fmaxf(NdotO, 1e-6f);
float3 H = normalize(omega_in + I);
float HdotI = fmaxf(fabsf(dot(H, I)), 1e-6f);
float3 H = normalize(wi + wo);
float HdotI = fmaxf(fabsf(dot(H, wi)), 1e-6f);
float HdotN = fmaxf(dot(H, N), 1e-6f);
/* pump from original paper
* (first derivative disc., but cancels the HdotI in the pdf nicely) */
float pump = 1.0f / fmaxf(1e-6f, (HdotI * fmaxf(NdotO, NdotI)));
float pump = 1.0f / fmaxf(1e-6f, (HdotI * fmaxf(NdotI, NdotO)));
/* pump from d-brdf paper */
/*float pump = 1.0f / fmaxf(1e-4f, ((NdotO + NdotI) * (NdotO*NdotI))); */
/*float pump = 1.0f / fmaxf(1e-4f, ((NdotI + NdotO) * (NdotI * NdotO))); */
float n_x = bsdf_ashikhmin_shirley_roughness_to_exponent(bsdf->alpha_x);
float n_y = bsdf_ashikhmin_shirley_roughness_to_exponent(bsdf->alpha_y);
@ -124,11 +124,11 @@ ccl_device_inline void bsdf_ashikhmin_shirley_sample_first_quadrant(float n_x,
ccl_device int bsdf_ashikhmin_shirley_sample(ccl_private const ShaderClosure *sc,
float3 Ng,
float3 I,
float3 wi,
float randu,
float randv,
ccl_private Spectrum *eval,
ccl_private float3 *omega_in,
ccl_private float3 *wo,
ccl_private float *pdf,
ccl_private float2 *sampled_roughness)
{
@ -137,7 +137,7 @@ ccl_device int bsdf_ashikhmin_shirley_sample(ccl_private const ShaderClosure *sc
float3 N = bsdf->N;
int label = LABEL_REFLECT | LABEL_GLOSSY;
float NdotI = dot(N, I);
float NdotI = dot(N, wi);
if (!(NdotI > 0.0f)) {
*pdf = 0.0f;
*eval = zero_spectrum();
@ -198,12 +198,12 @@ ccl_device int bsdf_ashikhmin_shirley_sample(ccl_private const ShaderClosure *sc
/* half vector to world space */
float3 H = h.x * X + h.y * Y + h.z * N;
float HdotI = dot(H, I);
float HdotI = dot(H, wi);
if (HdotI < 0.0f)
H = -H;
/* reflect I on H to get omega_in */
*omega_in = -I + (2.0f * HdotI) * H;
/* reflect wi on H to get wo */
*wo = -wi + (2.0f * HdotI) * H;
if (fmaxf(bsdf->alpha_x, bsdf->alpha_y) <= 1e-4f) {
/* Some high number for MIS. */
@ -213,7 +213,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, I, *omega_in, pdf);
*eval = bsdf_ashikhmin_shirley_eval(sc, N, wi, *wo, pdf);
}
return label;

View File

@ -32,35 +32,35 @@ ccl_device int bsdf_ashikhmin_velvet_setup(ccl_private VelvetBsdf *bsdf)
}
ccl_device Spectrum bsdf_ashikhmin_velvet_eval(ccl_private const ShaderClosure *sc,
const float3 I,
const float3 omega_in,
const float3 wi,
const float3 wo,
ccl_private float *pdf)
{
ccl_private const VelvetBsdf *bsdf = (ccl_private const VelvetBsdf *)sc;
float m_invsigma2 = bsdf->invsigma2;
float3 N = bsdf->N;
float cosNO = dot(N, I);
float cosNI = dot(N, omega_in);
if (!(cosNO > 0 && cosNI > 0)) {
float cosNI = dot(N, wi);
float cosNO = dot(N, wo);
if (!(cosNI > 0 && cosNO > 0)) {
*pdf = 0.0f;
return zero_spectrum();
}
float3 H = normalize(omega_in + I);
float3 H = normalize(wi + wo);
float cosNH = dot(N, H);
float cosHO = fabsf(dot(I, H));
float cosHI = fabsf(dot(wi, H));
if (!(fabsf(cosNH) < 1.0f - 1e-5f && cosHO > 1e-5f)) {
if (!(fabsf(cosNH) < 1.0f - 1e-5f && cosHI > 1e-5f)) {
*pdf = 0.0f;
return zero_spectrum();
}
float cosNHdivHO = cosNH / cosHO;
cosNHdivHO = fmaxf(cosNHdivHO, 1e-5f);
float cosNHdivHI = cosNH / cosHI;
cosNHdivHI = fmaxf(cosNHdivHI, 1e-5f);
float fac1 = 2 * fabsf(cosNHdivHO * cosNO);
float fac2 = 2 * fabsf(cosNHdivHO * cosNI);
float fac1 = 2 * fabsf(cosNHdivHI * cosNI);
float fac2 = 2 * fabsf(cosNHdivHI * cosNO);
float sinNH2 = 1 - cosNH * cosNH;
float sinNH4 = sinNH2 * sinNH2;
@ -69,7 +69,7 @@ ccl_device Spectrum bsdf_ashikhmin_velvet_eval(ccl_private const ShaderClosure *
float D = expf(-cotangent2 * m_invsigma2) * m_invsigma2 * M_1_PI_F / sinNH4;
float G = fminf(1.0f, fminf(fac1, fac2)); // TODO: derive G from D analytically
float out = 0.25f * (D * G) / cosNO;
float out = 0.25f * (D * G) / cosNI;
*pdf = 0.5f * M_1_PI_F;
return make_spectrum(out);
@ -77,11 +77,11 @@ ccl_device Spectrum bsdf_ashikhmin_velvet_eval(ccl_private const ShaderClosure *
ccl_device int bsdf_ashikhmin_velvet_sample(ccl_private const ShaderClosure *sc,
float3 Ng,
float3 I,
float3 wi,
float randu,
float randv,
ccl_private Spectrum *eval,
ccl_private float3 *omega_in,
ccl_private float3 *wo,
ccl_private float *pdf)
{
ccl_private const VelvetBsdf *bsdf = (ccl_private const VelvetBsdf *)sc;
@ -90,32 +90,32 @@ ccl_device int bsdf_ashikhmin_velvet_sample(ccl_private const ShaderClosure *sc,
// we are viewing the surface from above - send a ray out with uniform
// distribution over the hemisphere
sample_uniform_hemisphere(N, randu, randv, omega_in, pdf);
sample_uniform_hemisphere(N, randu, randv, wo, pdf);
if (!(dot(Ng, *omega_in) > 0)) {
if (!(dot(Ng, *wo) > 0)) {
*pdf = 0.0f;
*eval = zero_spectrum();
return LABEL_NONE;
}
float3 H = normalize(*omega_in + I);
float3 H = normalize(wi + *wo);
float cosNI = dot(N, *omega_in);
float cosNO = dot(N, I);
float cosNI = dot(N, wi);
float cosNO = dot(N, *wo);
float cosHI = fabsf(dot(wi, H));
float cosNH = dot(N, H);
float cosHO = fabsf(dot(I, H));
if (!(fabsf(cosNO) > 1e-5f && fabsf(cosNH) < 1.0f - 1e-5f && cosHO > 1e-5f)) {
if (!(fabsf(cosNI) > 1e-5f && fabsf(cosNH) < 1.0f - 1e-5f && cosHI > 1e-5f)) {
*pdf = 0.0f;
*eval = zero_spectrum();
return LABEL_NONE;
}
float cosNHdivHO = cosNH / cosHO;
cosNHdivHO = fmaxf(cosNHdivHO, 1e-5f);
float cosNHdivHI = cosNH / cosHI;
cosNHdivHI = fmaxf(cosNHdivHI, 1e-5f);
float fac1 = 2 * fabsf(cosNHdivHO * cosNO);
float fac2 = 2 * fabsf(cosNHdivHO * cosNI);
float fac1 = 2 * fabsf(cosNHdivHI * cosNI);
float fac2 = 2 * fabsf(cosNHdivHI * cosNO);
float sinNH2 = 1 - cosNH * cosNH;
float sinNH4 = sinNH2 * sinNH2;
@ -124,7 +124,7 @@ ccl_device int bsdf_ashikhmin_velvet_sample(ccl_private const ShaderClosure *sc,
float D = expf(-cotangent2 * m_invsigma2) * m_invsigma2 * M_1_PI_F / sinNH4;
float G = fminf(1.0f, fminf(fac1, fac2)); // TODO: derive G from D analytically
float power = 0.25f * (D * G) / cosNO;
float power = 0.25f * (D * G) / cosNI;
*eval = make_spectrum(power);

View File

@ -27,34 +27,34 @@ ccl_device int bsdf_diffuse_setup(ccl_private DiffuseBsdf *bsdf)
}
ccl_device Spectrum bsdf_diffuse_eval(ccl_private const ShaderClosure *sc,
const float3 I,
const float3 omega_in,
const float3 wi,
const float3 wo,
ccl_private float *pdf)
{
ccl_private const DiffuseBsdf *bsdf = (ccl_private const DiffuseBsdf *)sc;
float3 N = bsdf->N;
float cos_pi = fmaxf(dot(N, omega_in), 0.0f) * M_1_PI_F;
*pdf = cos_pi;
return make_spectrum(cos_pi);
float cosNO = fmaxf(dot(N, wo), 0.0f) * M_1_PI_F;
*pdf = cosNO;
return make_spectrum(cosNO);
}
ccl_device int bsdf_diffuse_sample(ccl_private const ShaderClosure *sc,
float3 Ng,
float3 I,
float3 wi,
float randu,
float randv,
ccl_private Spectrum *eval,
ccl_private float3 *omega_in,
ccl_private float3 *wo,
ccl_private float *pdf)
{
ccl_private const DiffuseBsdf *bsdf = (ccl_private const DiffuseBsdf *)sc;
float3 N = bsdf->N;
// distribution over the hemisphere
sample_cos_hemisphere(N, randu, randv, omega_in, pdf);
sample_cos_hemisphere(N, randu, randv, wo, pdf);
if (dot(Ng, *omega_in) > 0.0f) {
if (dot(Ng, *wo) > 0.0f) {
*eval = make_spectrum(*pdf);
}
else {
@ -73,25 +73,25 @@ ccl_device int bsdf_translucent_setup(ccl_private DiffuseBsdf *bsdf)
}
ccl_device Spectrum bsdf_translucent_eval(ccl_private const ShaderClosure *sc,
const float3 I,
const float3 omega_in,
const float3 wi,
const float3 wo,
ccl_private float *pdf)
{
ccl_private const DiffuseBsdf *bsdf = (ccl_private const DiffuseBsdf *)sc;
float3 N = bsdf->N;
float cos_pi = fmaxf(-dot(N, omega_in), 0.0f) * M_1_PI_F;
*pdf = cos_pi;
return make_spectrum(cos_pi);
float cosNO = fmaxf(-dot(N, wo), 0.0f) * M_1_PI_F;
*pdf = cosNO;
return make_spectrum(cosNO);
}
ccl_device int bsdf_translucent_sample(ccl_private const ShaderClosure *sc,
float3 Ng,
float3 I,
float3 wi,
float randu,
float randv,
ccl_private Spectrum *eval,
ccl_private float3 *omega_in,
ccl_private float3 *wo,
ccl_private float *pdf)
{
ccl_private const DiffuseBsdf *bsdf = (ccl_private const DiffuseBsdf *)sc;
@ -99,8 +99,8 @@ ccl_device int bsdf_translucent_sample(ccl_private const ShaderClosure *sc,
// we are viewing the surface from the right side - send a ray out with cosine
// distribution over the hemisphere
sample_cos_hemisphere(-N, randu, randv, omega_in, pdf);
if (dot(Ng, *omega_in) < 0) {
sample_cos_hemisphere(-N, randu, randv, wo, pdf);
if (dot(Ng, *wo) < 0) {
*eval = make_spectrum(*pdf);
}
else {

View File

@ -48,17 +48,17 @@ ccl_device void bsdf_diffuse_ramp_blur(ccl_private ShaderClosure *sc, float roug
}
ccl_device Spectrum bsdf_diffuse_ramp_eval(ccl_private const ShaderClosure *sc,
const float3 I,
const float3 omega_in,
const float3 wi,
const float3 wo,
ccl_private float *pdf)
{
const DiffuseRampBsdf *bsdf = (const DiffuseRampBsdf *)sc;
float3 N = bsdf->N;
float cos_pi = fmaxf(dot(N, omega_in), 0.0f);
if (cos_pi >= 0.0f) {
*pdf = cos_pi * M_1_PI_F;
return rgb_to_spectrum(bsdf_diffuse_ramp_get_color(bsdf->colors, cos_pi) * M_1_PI_F);
float cosNO = fmaxf(dot(N, wo), 0.0f);
if (cosNO >= 0.0f) {
*pdf = cosNO * M_1_PI_F;
return rgb_to_spectrum(bsdf_diffuse_ramp_get_color(bsdf->colors, cosNO) * M_1_PI_F);
}
else {
*pdf = 0.0f;
@ -68,20 +68,20 @@ ccl_device Spectrum bsdf_diffuse_ramp_eval(ccl_private const ShaderClosure *sc,
ccl_device int bsdf_diffuse_ramp_sample(ccl_private const ShaderClosure *sc,
float3 Ng,
float3 I,
float3 wi,
float randu,
float randv,
ccl_private Spectrum *eval,
ccl_private float3 *omega_in,
ccl_private float3 *wo,
ccl_private float *pdf)
{
const DiffuseRampBsdf *bsdf = (const DiffuseRampBsdf *)sc;
float3 N = bsdf->N;
// distribution over the hemisphere
sample_cos_hemisphere(N, randu, randv, omega_in, pdf);
sample_cos_hemisphere(N, randu, randv, wo, pdf);
if (dot(Ng, *omega_in) > 0.0f) {
if (dot(Ng, *wo) > 0.0f) {
*eval = rgb_to_spectrum(bsdf_diffuse_ramp_get_color(bsdf->colors, *pdf * M_PI_F) * M_1_PI_F);
}
else {

View File

@ -38,12 +38,12 @@ ccl_device int bsdf_hair_transmission_setup(ccl_private HairBsdf *bsdf)
}
ccl_device Spectrum bsdf_hair_reflection_eval(ccl_private const ShaderClosure *sc,
const float3 I,
const float3 omega_in,
const float3 wi,
const float3 wo,
ccl_private float *pdf)
{
ccl_private const HairBsdf *bsdf = (ccl_private const HairBsdf *)sc;
if (dot(bsdf->N, omega_in) < 0.0f) {
if (dot(bsdf->N, wo) < 0.0f) {
*pdf = 0.0f;
return zero_spectrum();
}
@ -53,16 +53,16 @@ ccl_device Spectrum bsdf_hair_reflection_eval(ccl_private const ShaderClosure *s
float roughness1 = bsdf->roughness1;
float roughness2 = bsdf->roughness2;
float Iz = dot(Tg, I);
float3 locy = normalize(I - Tg * Iz);
float Iz = dot(Tg, wi);
float3 locy = normalize(wi - Tg * Iz);
float theta_r = M_PI_2_F - fast_acosf(Iz);
float omega_in_z = dot(Tg, omega_in);
float3 omega_in_y = normalize(omega_in - Tg * omega_in_z);
float wo_z = dot(Tg, wo);
float3 wo_y = normalize(wo - Tg * wo_z);
float theta_i = M_PI_2_F - fast_acosf(omega_in_z);
float cosphi_i = dot(omega_in_y, locy);
float theta_i = M_PI_2_F - fast_acosf(wo_z);
float cosphi_i = dot(wo_y, locy);
if (M_PI_2_F - fabsf(theta_i) < 0.001f || cosphi_i < 0.0f) {
*pdf = 0.0f;
@ -90,12 +90,12 @@ ccl_device Spectrum bsdf_hair_reflection_eval(ccl_private const ShaderClosure *s
}
ccl_device Spectrum bsdf_hair_transmission_eval(ccl_private const ShaderClosure *sc,
const float3 I,
const float3 omega_in,
const float3 wi,
const float3 wo,
ccl_private float *pdf)
{
ccl_private const HairBsdf *bsdf = (ccl_private const HairBsdf *)sc;
if (dot(bsdf->N, omega_in) >= 0.0f) {
if (dot(bsdf->N, wo) >= 0.0f) {
*pdf = 0.0f;
return zero_spectrum();
}
@ -104,16 +104,16 @@ ccl_device Spectrum bsdf_hair_transmission_eval(ccl_private const ShaderClosure
float3 Tg = bsdf->T;
float roughness1 = bsdf->roughness1;
float roughness2 = bsdf->roughness2;
float Iz = dot(Tg, I);
float3 locy = normalize(I - Tg * Iz);
float Iz = dot(Tg, wi);
float3 locy = normalize(wi - Tg * Iz);
float theta_r = M_PI_2_F - fast_acosf(Iz);
float omega_in_z = dot(Tg, omega_in);
float3 omega_in_y = normalize(omega_in - Tg * omega_in_z);
float wo_z = dot(Tg, wo);
float3 wo_y = normalize(wo - Tg * wo_z);
float theta_i = M_PI_2_F - fast_acosf(omega_in_z);
float phi_i = fast_acosf(dot(omega_in_y, locy));
float theta_i = M_PI_2_F - fast_acosf(wo_z);
float phi_i = fast_acosf(dot(wo_y, locy));
if (M_PI_2_F - fabsf(theta_i) < 0.001f) {
*pdf = 0.0f;
@ -142,11 +142,11 @@ ccl_device Spectrum bsdf_hair_transmission_eval(ccl_private const ShaderClosure
ccl_device int bsdf_hair_reflection_sample(ccl_private const ShaderClosure *sc,
float3 Ng,
float3 I,
float3 wi,
float randu,
float randv,
ccl_private Spectrum *eval,
ccl_private float3 *omega_in,
ccl_private float3 *wo,
ccl_private float *pdf,
ccl_private float2 *sampled_roughness)
{
@ -156,8 +156,8 @@ ccl_device int bsdf_hair_reflection_sample(ccl_private const ShaderClosure *sc,
float roughness1 = bsdf->roughness1;
float roughness2 = bsdf->roughness2;
*sampled_roughness = make_float2(roughness1, roughness2);
float Iz = dot(Tg, I);
float3 locy = normalize(I - Tg * Iz);
float Iz = dot(Tg, wi);
float3 locy = normalize(wi - Tg * Iz);
float3 locx = cross(locy, Tg);
float theta_r = M_PI_2_F - fast_acosf(Iz);
@ -182,7 +182,7 @@ ccl_device int bsdf_hair_reflection_sample(ccl_private const ShaderClosure *sc,
float sinphi, cosphi;
fast_sincosf(phi, &sinphi, &cosphi);
*omega_in = (cosphi * costheta_i) * locy - (sinphi * costheta_i) * locx + (sintheta_i)*Tg;
*wo = (cosphi * costheta_i) * locy - (sinphi * costheta_i) * locx + (sintheta_i)*Tg;
*pdf = fabsf(phi_pdf * theta_pdf);
if (M_PI_2_F - fabsf(theta_i) < 0.001f)
@ -195,11 +195,11 @@ ccl_device int bsdf_hair_reflection_sample(ccl_private const ShaderClosure *sc,
ccl_device int bsdf_hair_transmission_sample(ccl_private const ShaderClosure *sc,
float3 Ng,
float3 I,
float3 wi,
float randu,
float randv,
ccl_private Spectrum *eval,
ccl_private float3 *omega_in,
ccl_private float3 *wo,
ccl_private float *pdf,
ccl_private float2 *sampled_roughness)
{
@ -209,8 +209,8 @@ ccl_device int bsdf_hair_transmission_sample(ccl_private const ShaderClosure *sc
float roughness1 = bsdf->roughness1;
float roughness2 = bsdf->roughness2;
*sampled_roughness = make_float2(roughness1, roughness2);
float Iz = dot(Tg, I);
float3 locy = normalize(I - Tg * Iz);
float Iz = dot(Tg, wi);
float3 locy = normalize(wi - Tg * Iz);
float3 locx = cross(locy, Tg);
float theta_r = M_PI_2_F - fast_acosf(Iz);
@ -235,7 +235,7 @@ ccl_device int bsdf_hair_transmission_sample(ccl_private const ShaderClosure *sc
float sinphi, cosphi;
fast_sincosf(phi, &sinphi, &cosphi);
*omega_in = (cosphi * costheta_i) * locy - (sinphi * costheta_i) * locx + (sintheta_i)*Tg;
*wo = (cosphi * costheta_i) * locy - (sinphi * costheta_i) * locx + (sintheta_i)*Tg;
*pdf = fabsf(phi_pdf * theta_pdf);
if (M_PI_2_F - fabsf(theta_i) < 0.001f) {
@ -247,7 +247,7 @@ ccl_device int bsdf_hair_transmission_sample(ccl_private const ShaderClosure *sc
/* TODO(sergey): Should always be negative, but seems some precision issue
* is involved here.
*/
kernel_assert(dot(locy, *omega_in) < 1e-4f);
kernel_assert(dot(locy, *wo) < 1e-4f);
return LABEL_TRANSMIT | LABEL_GLOSSY;
}

View File

@ -179,7 +179,7 @@ ccl_device int bsdf_principled_hair_setup(ccl_private ShaderData *sd,
/* Compute local frame, aligned to curve tangent and ray direction. */
float3 X = safe_normalize(sd->dPdu);
float3 Y = safe_normalize(cross(X, sd->I));
float3 Y = safe_normalize(cross(X, sd->wi));
float3 Z = safe_normalize(cross(X, Y));
/* h -1..0..1 means the rays goes from grazing the hair, to hitting it at
@ -259,7 +259,7 @@ ccl_device_inline void hair_alpha_angles(float sin_theta_i,
ccl_device Spectrum bsdf_principled_hair_eval(KernelGlobals kg,
ccl_private const ShaderData *sd,
ccl_private const ShaderClosure *sc,
const float3 omega_in,
const float3 wo,
ccl_private float *pdf)
{
kernel_assert(isfinite_safe(sd->P) && isfinite_safe(sd->ray_length));
@ -271,12 +271,13 @@ ccl_device Spectrum bsdf_principled_hair_eval(KernelGlobals kg,
kernel_assert(fabsf(dot(X, Y)) < 1e-3f);
const float3 Z = safe_normalize(cross(X, Y));
const float3 wo = make_float3(dot(sd->I, X), dot(sd->I, Y), dot(sd->I, Z));
const float3 wi = make_float3(dot(omega_in, X), dot(omega_in, Y), dot(omega_in, Z));
/* local_I is the illumination direction. */
const float3 local_O = make_float3(dot(sd->wi, X), dot(sd->wi, Y), dot(sd->wi, Z));
const float3 local_I = make_float3(dot(wo, X), dot(wo, Y), dot(wo, Z));
const float sin_theta_o = wo.x;
const float sin_theta_o = local_O.x;
const float cos_theta_o = cos_from_sin(sin_theta_o);
const float phi_o = atan2f(wo.z, wo.y);
const float phi_o = atan2f(local_O.z, local_O.y);
const float sin_theta_t = sin_theta_o / bsdf->eta;
const float cos_theta_t = cos_from_sin(sin_theta_t);
@ -295,9 +296,9 @@ ccl_device Spectrum bsdf_principled_hair_eval(KernelGlobals kg,
hair_attenuation(
kg, fresnel_dielectric_cos(cos_theta_o * cos_gamma_o, bsdf->eta), T, Ap, Ap_energy);
const float sin_theta_i = wi.x;
const float sin_theta_i = local_I.x;
const float cos_theta_i = cos_from_sin(sin_theta_i);
const float phi_i = atan2f(wi.z, wi.y);
const float phi_i = atan2f(local_I.z, local_I.y);
const float phi = phi_i - phi_o;
@ -343,7 +344,7 @@ ccl_device int bsdf_principled_hair_sample(KernelGlobals kg,
float randu,
float randv,
ccl_private Spectrum *eval,
ccl_private float3 *omega_in,
ccl_private float3 *wo,
ccl_private float *pdf,
ccl_private float2 *sampled_roughness,
ccl_private float *eta)
@ -359,16 +360,16 @@ ccl_device int bsdf_principled_hair_sample(KernelGlobals kg,
kernel_assert(fabsf(dot(X, Y)) < 1e-3f);
const float3 Z = safe_normalize(cross(X, Y));
const float3 wo = make_float3(dot(sd->I, X), dot(sd->I, Y), dot(sd->I, Z));
const float3 local_O = make_float3(dot(sd->wi, X), dot(sd->wi, Y), dot(sd->wi, Z));
float2 u[2];
u[0] = make_float2(randu, randv);
u[1].x = lcg_step_float(&sd->lcg_state);
u[1].y = lcg_step_float(&sd->lcg_state);
const float sin_theta_o = wo.x;
const float sin_theta_o = local_O.x;
const float cos_theta_o = cos_from_sin(sin_theta_o);
const float phi_o = atan2f(wo.z, wo.y);
const float phi_o = atan2f(local_O.z, local_O.y);
const float sin_theta_t = sin_theta_o / bsdf->eta;
const float cos_theta_t = cos_from_sin(sin_theta_t);
@ -458,7 +459,7 @@ ccl_device int bsdf_principled_hair_sample(KernelGlobals kg,
*eval = F;
*pdf = F_energy;
*omega_in = X * sin_theta_i + Y * cos_theta_i * cosf(phi_i) + Z * cos_theta_i * sinf(phi_i);
*wo = X * sin_theta_i + Y * cos_theta_i * cosf(phi_i) + Z * cos_theta_i * sinf(phi_i);
return LABEL_GLOSSY | ((p == 0) ? LABEL_REFLECT : LABEL_TRANSMIT);
}

View File

@ -175,7 +175,7 @@ ccl_device_inline void microfacet_ggx_sample_slopes(const float cos_theta_i,
}
ccl_device_forceinline float3 microfacet_sample_stretched(KernelGlobals kg,
const float3 omega_i,
const float3 wi,
const float alpha_x,
const float alpha_y,
const float randu,
@ -183,26 +183,26 @@ ccl_device_forceinline float3 microfacet_sample_stretched(KernelGlobals kg,
bool beckmann,
ccl_private float *G1i)
{
/* 1. stretch omega_i */
float3 omega_i_ = make_float3(alpha_x * omega_i.x, alpha_y * omega_i.y, omega_i.z);
omega_i_ = normalize(omega_i_);
/* 1. stretch wi */
float3 wi_ = make_float3(alpha_x * wi.x, alpha_y * wi.y, wi.z);
wi_ = normalize(wi_);
/* get polar coordinates of omega_i_ */
/* get polar coordinates of wi_ */
float costheta_ = 1.0f;
float sintheta_ = 0.0f;
float cosphi_ = 1.0f;
float sinphi_ = 0.0f;
if (omega_i_.z < 0.99999f) {
costheta_ = omega_i_.z;
if (wi_.z < 0.99999f) {
costheta_ = wi_.z;
sintheta_ = safe_sqrtf(1.0f - costheta_ * costheta_);
float invlen = 1.0f / sintheta_;
cosphi_ = omega_i_.x * invlen;
sinphi_ = omega_i_.y * invlen;
cosphi_ = wi_.x * invlen;
sinphi_ = wi_.y * invlen;
}
/* 2. sample P22_{omega_i}(x_slope, y_slope, 1, 1) */
/* 2. sample P22_{wi}(x_slope, y_slope, 1, 1) */
float slope_x, slope_y;
if (beckmann) {
@ -265,7 +265,7 @@ ccl_device_forceinline void bsdf_microfacet_fresnel_color(ccl_private const Shad
float F0 = fresnel_dielectric_cos(1.0f, bsdf->ior);
bsdf->extra->fresnel_color = interpolate_fresnel_color(
sd->I, bsdf->N, bsdf->ior, F0, bsdf->extra->cspec0);
sd->wi, bsdf->N, bsdf->ior, F0, bsdf->extra->cspec0);
if (bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID) {
bsdf->extra->fresnel_color *= 0.25f * bsdf->extra->clearcoat;
@ -359,13 +359,13 @@ ccl_device void bsdf_microfacet_ggx_blur(ccl_private ShaderClosure *sc, float ro
ccl_device Spectrum bsdf_microfacet_ggx_eval_reflect(ccl_private const MicrofacetBsdf *bsdf,
const float3 N,
const float3 I,
const float3 omega_in,
const float3 wi,
const float3 wo,
ccl_private float *pdf,
const float alpha_x,
const float alpha_y,
const float cosNO,
const float cosNI)
const float cosNI,
const float cosNO)
{
if (!(cosNI > 0 && cosNO > 0)) {
*pdf = 0.0f;
@ -373,9 +373,9 @@ ccl_device Spectrum bsdf_microfacet_ggx_eval_reflect(ccl_private const Microface
}
/* get half vector */
float3 m = normalize(omega_in + I);
float3 m = normalize(wi + wo);
float alpha2 = alpha_x * alpha_y;
float D, G1o, G1i;
float D, G1i, G1o;
if (alpha_x == alpha_y) {
/* isotropic
@ -399,8 +399,8 @@ ccl_device Spectrum bsdf_microfacet_ggx_eval_reflect(ccl_private const Microface
}
/* eq. 34: now calculate G1(i,m) and G1(o,m) */
G1o = 2 / (1 + safe_sqrtf(1 + alpha2 * (1 - cosNO * cosNO) / (cosNO * cosNO)));
G1i = 2 / (1 + safe_sqrtf(1 + alpha2 * (1 - cosNI * cosNI) / (cosNI * cosNI)));
G1o = 2 / (1 + safe_sqrtf(1 + alpha2 * (1 - cosNO * cosNO) / (cosNO * cosNO)));
}
else {
/* anisotropic */
@ -420,33 +420,33 @@ ccl_device Spectrum bsdf_microfacet_ggx_eval_reflect(ccl_private const Microface
D = 1 / ((slope_len * slope_len) * M_PI_F * alpha2 * cosThetaM4);
/* G1(i,m) and G1(o,m) */
float tanThetaO2 = (1 - cosNO * cosNO) / (cosNO * cosNO);
float cosPhiO = dot(I, X);
float sinPhiO = dot(I, Y);
float alphaO2 = (cosPhiO * cosPhiO) * (alpha_x * alpha_x) +
(sinPhiO * sinPhiO) * (alpha_y * alpha_y);
alphaO2 /= cosPhiO * cosPhiO + sinPhiO * sinPhiO;
G1o = 2 / (1 + safe_sqrtf(1 + alphaO2 * tanThetaO2));
float tanThetaI2 = (1 - cosNI * cosNI) / (cosNI * cosNI);
float cosPhiI = dot(omega_in, X);
float sinPhiI = dot(omega_in, Y);
float cosPhiI = dot(wi, X);
float sinPhiI = dot(wi, Y);
float alphaI2 = (cosPhiI * cosPhiI) * (alpha_x * alpha_x) +
(sinPhiI * sinPhiI) * (alpha_y * alpha_y);
alphaI2 /= cosPhiI * cosPhiI + sinPhiI * sinPhiI;
G1i = 2 / (1 + safe_sqrtf(1 + alphaI2 * tanThetaI2));
float tanThetaO2 = (1 - cosNO * cosNO) / (cosNO * cosNO);
float cosPhiO = dot(wo, X);
float sinPhiO = dot(wo, Y);
float alphaO2 = (cosPhiO * cosPhiO) * (alpha_x * alpha_x) +
(sinPhiO * sinPhiO) * (alpha_y * alpha_y);
alphaO2 /= cosPhiO * cosPhiO + sinPhiO * sinPhiO;
G1o = 2 / (1 + safe_sqrtf(1 + alphaO2 * tanThetaO2));
}
float G = G1o * G1i;
float G = G1i * G1o;
/* eq. 20 */
float common = D * 0.25f / cosNO;
float common = D * 0.25f / cosNI;
Spectrum F = reflection_color(bsdf, omega_in, m);
Spectrum F = reflection_color(bsdf, wo, m);
if (bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID) {
F *= 0.25f * bsdf->extra->clearcoat;
}
@ -454,38 +454,38 @@ ccl_device Spectrum bsdf_microfacet_ggx_eval_reflect(ccl_private const Microface
Spectrum out = F * G * common;
/* eq. 2 in distribution of visible normals sampling
* `pm = Dw = G1o * dot(m, I) * D / dot(N, I);` */
* `pm = Dw = G1i * dot(m, I) * D / dot(N, I);` */
/* eq. 38 - but see also:
* eq. 17 in http://www.graphics.cornell.edu/~bjw/wardnotes.pdf
* `pdf = pm * 0.25 / dot(m, I);` */
*pdf = G1o * common;
*pdf = G1i * common;
return out;
}
ccl_device Spectrum bsdf_microfacet_ggx_eval_transmit(ccl_private const MicrofacetBsdf *bsdf,
const float3 N,
const float3 I,
const float3 omega_in,
const float3 wi,
const float3 wo,
ccl_private float *pdf,
const float alpha_x,
const float alpha_y,
const float cosNO,
const float cosNI)
const float cosNI,
const float cosNO)
{
if (cosNO <= 0 || cosNI >= 0) {
if (cosNI <= 0 || cosNO >= 0) {
*pdf = 0.0f;
return zero_spectrum(); /* vectors on same side -- not possible */
}
/* compute half-vector of the refraction (eq. 16) */
float m_eta = bsdf->ior;
float3 ht = -(m_eta * omega_in + I);
float3 ht = -(m_eta * wo + wi);
float3 Ht = normalize(ht);
float cosHO = dot(Ht, I);
float cosHI = dot(Ht, omega_in);
float cosHI = dot(Ht, wi);
float cosHO = dot(Ht, wo);
float D, G1o, G1i;
float D, G1i, G1o;
/* eq. 33: first we calculate D(m) with m=Ht: */
float alpha2 = alpha_x * alpha_y;
@ -496,61 +496,61 @@ ccl_device Spectrum bsdf_microfacet_ggx_eval_transmit(ccl_private const Microfac
D = alpha2 / (M_PI_F * cosThetaM4 * (alpha2 + tanThetaM2) * (alpha2 + tanThetaM2));
/* eq. 34: now calculate G1(i,m) and G1(o,m) */
G1o = 2 / (1 + safe_sqrtf(1 + alpha2 * (1 - cosNO * cosNO) / (cosNO * cosNO)));
G1i = 2 / (1 + safe_sqrtf(1 + alpha2 * (1 - cosNI * cosNI) / (cosNI * cosNI)));
G1o = 2 / (1 + safe_sqrtf(1 + alpha2 * (1 - cosNO * cosNO) / (cosNO * cosNO)));
float G = G1o * G1i;
float G = G1i * G1o;
/* probability */
float Ht2 = dot(ht, ht);
/* eq. 2 in distribution of visible normals sampling
* pm = Dw = G1o * dot(m, I) * D / dot(N, I); */
* pm = Dw = G1i * dot(m, I) * D / dot(N, I); */
/* out = fabsf(cosHI * cosHO) * (m_eta * m_eta) * G * D / (cosNO * Ht2)
* pdf = pm * (m_eta * m_eta) * fabsf(cosHI) / Ht2 */
float common = D * (m_eta * m_eta) / (cosNO * Ht2);
/* out = fabsf(cosHI * cosHO) * (m_eta * m_eta) * G * D / (cosNI * Ht2)
* pdf = pm * (m_eta * m_eta) * fabsf(cosHO) / Ht2 */
float common = D * (m_eta * m_eta) / (cosNI * Ht2);
float out = G * fabsf(cosHI * cosHO) * common;
*pdf = G1o * fabsf(cosHO * cosHI) * common;
*pdf = G1i * fabsf(cosHI * cosHO) * common;
return make_spectrum(out);
}
ccl_device Spectrum bsdf_microfacet_ggx_eval(ccl_private const ShaderClosure *sc,
const float3 Ng,
const float3 I,
const float3 omega_in,
const float3 wi,
const float3 wo,
ccl_private float *pdf)
{
ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc;
const bool m_refractive = bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID;
const float alpha_x = bsdf->alpha_x;
const float alpha_y = bsdf->alpha_y;
const float cosNgI = dot(Ng, omega_in);
const float cosNgO = dot(Ng, wo);
if (((cosNgI < 0.0f) != m_refractive) || alpha_x * alpha_y <= 1e-7f) {
if (((cosNgO < 0.0f) != m_refractive) || alpha_x * alpha_y <= 1e-7f) {
*pdf = 0.0f;
return zero_spectrum();
}
const float3 N = bsdf->N;
const float cosNO = dot(N, I);
const float cosNI = dot(N, omega_in);
const float cosNI = dot(N, wi);
const float cosNO = dot(N, wo);
return (cosNgI < 0.0f) ? bsdf_microfacet_ggx_eval_transmit(
bsdf, N, I, omega_in, pdf, alpha_x, alpha_y, cosNO, cosNI) :
return (cosNgO < 0.0f) ? bsdf_microfacet_ggx_eval_transmit(
bsdf, N, wi, wo, pdf, alpha_x, alpha_y, cosNI, cosNO) :
bsdf_microfacet_ggx_eval_reflect(
bsdf, N, I, omega_in, pdf, alpha_x, alpha_y, cosNO, cosNI);
bsdf, N, wi, wo, pdf, alpha_x, alpha_y, cosNI, cosNO);
}
ccl_device int bsdf_microfacet_ggx_sample(KernelGlobals kg,
ccl_private const ShaderClosure *sc,
float3 Ng,
float3 I,
float3 wi,
float randu,
float randv,
ccl_private Spectrum *eval,
ccl_private float3 *omega_in,
ccl_private float3 *wo,
ccl_private float *pdf,
ccl_private float2 *sampled_roughness,
ccl_private float *eta)
@ -566,8 +566,8 @@ ccl_device int bsdf_microfacet_ggx_sample(KernelGlobals kg,
float3 N = bsdf->N;
int label;
float cosNO = dot(N, I);
if (cosNO > 0) {
float cosNI = dot(N, wi);
if (cosNI > 0) {
float3 X, Y, Z = N;
if (alpha_x == alpha_y)
@ -577,26 +577,26 @@ ccl_device int bsdf_microfacet_ggx_sample(KernelGlobals kg,
/* importance sampling with distribution of visible normals. vectors are
* transformed to local space before and after */
float3 local_I = make_float3(dot(X, I), dot(Y, I), cosNO);
float3 local_I = make_float3(dot(X, wi), dot(Y, wi), cosNI);
float3 local_m;
float G1o;
float G1i;
local_m = microfacet_sample_stretched(
kg, local_I, alpha_x, alpha_y, randu, randv, false, &G1o);
kg, local_I, alpha_x, alpha_y, randu, randv, false, &G1i);
float3 m = X * local_m.x + Y * local_m.y + Z * local_m.z;
float cosThetaM = local_m.z;
/* reflection or refraction? */
if (!m_refractive) {
float cosMO = dot(m, I);
float cosMI = dot(m, wi);
label = LABEL_REFLECT | LABEL_GLOSSY;
if (cosMO > 0) {
if (cosMI > 0) {
/* eq. 39 - compute actual reflected direction */
*omega_in = 2 * cosMO * m - I;
*wo = 2 * cosMI * m - wi;
if (dot(Ng, *omega_in) > 0) {
if (dot(Ng, *wo) > 0) {
if (alpha_x * alpha_y <= 1e-7f) {
/* some high number for MIS */
*pdf = 1e6f;
@ -607,7 +607,7 @@ ccl_device int bsdf_microfacet_ggx_sample(KernelGlobals kg,
/* if fresnel is used, calculate the color with reflection_color(...) */
if (use_fresnel) {
*eval *= reflection_color(bsdf, *omega_in, m);
*eval *= reflection_color(bsdf, *wo, m);
}
label = LABEL_REFLECT | LABEL_SINGULAR;
@ -616,7 +616,7 @@ ccl_device int bsdf_microfacet_ggx_sample(KernelGlobals kg,
/* microfacet normal is visible to this ray */
/* eq. 33 */
float alpha2 = alpha_x * alpha_y;
float D, G1i;
float D, G1o;
if (alpha_x == alpha_y) {
/* isotropic */
@ -624,8 +624,8 @@ ccl_device int bsdf_microfacet_ggx_sample(KernelGlobals kg,
float cosThetaM4 = cosThetaM2 * cosThetaM2;
float tanThetaM2 = 1 / (cosThetaM2)-1;
/* eval BRDF*cosNI */
float cosNI = dot(N, *omega_in);
/* eval BRDF*cosNO */
float cosNO = dot(N, *wo);
if (bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID) {
/* use GTR1 for clearcoat */
@ -634,16 +634,16 @@ ccl_device int bsdf_microfacet_ggx_sample(KernelGlobals kg,
/* the alpha value for clearcoat is a fixed 0.25 => alpha2 = 0.25 * 0.25 */
alpha2 = 0.0625f;
/* recalculate G1o */
G1o = 2 / (1 + safe_sqrtf(1 + alpha2 * (1 - cosNO * cosNO) / (cosNO * cosNO)));
/* recalculate G1i */
G1i = 2 / (1 + safe_sqrtf(1 + alpha2 * (1 - cosNI * cosNI) / (cosNI * cosNI)));
}
else {
/* use GTR2 otherwise */
D = alpha2 / (M_PI_F * cosThetaM4 * (alpha2 + tanThetaM2) * (alpha2 + tanThetaM2));
}
/* eq. 34: now calculate G1(i,m) */
G1i = 2 / (1 + safe_sqrtf(1 + alpha2 * (1 - cosNI * cosNI) / (cosNI * cosNI)));
/* eq. 34: now calculate G1(o,m) */
G1o = 2 / (1 + safe_sqrtf(1 + alpha2 * (1 - cosNO * cosNO) / (cosNO * cosNO)));
}
else {
/* anisotropic distribution */
@ -658,27 +658,27 @@ ccl_device int bsdf_microfacet_ggx_sample(KernelGlobals kg,
D = 1 / ((slope_len * slope_len) * M_PI_F * alpha2 * cosThetaM4);
/* calculate G1(i,m) */
float cosNI = dot(N, *omega_in);
/* calculate G1(o,m) */
float cosNO = dot(N, *wo);
float tanThetaI2 = (1 - cosNI * cosNI) / (cosNI * cosNI);
float cosPhiI = dot(*omega_in, X);
float sinPhiI = dot(*omega_in, Y);
float tanThetaO2 = (1 - cosNO * cosNO) / (cosNO * cosNO);
float cosPhiO = dot(*wo, X);
float sinPhiO = dot(*wo, Y);
float alphaI2 = (cosPhiI * cosPhiI) * (alpha_x * alpha_x) +
(sinPhiI * sinPhiI) * (alpha_y * alpha_y);
alphaI2 /= cosPhiI * cosPhiI + sinPhiI * sinPhiI;
float alphaO2 = (cosPhiO * cosPhiO) * (alpha_x * alpha_x) +
(sinPhiO * sinPhiO) * (alpha_y * alpha_y);
alphaO2 /= cosPhiO * cosPhiO + sinPhiO * sinPhiO;
G1i = 2 / (1 + safe_sqrtf(1 + alphaI2 * tanThetaI2));
G1o = 2 / (1 + safe_sqrtf(1 + alphaO2 * tanThetaO2));
}
/* see eval function for derivation */
float common = (G1o * D) * 0.25f / cosNO;
float common = (G1i * D) * 0.25f / cosNI;
*pdf = common;
Spectrum F = reflection_color(bsdf, *omega_in, m);
Spectrum F = reflection_color(bsdf, *wo, m);
*eval = G1i * common * F;
*eval = G1o * common * F;
}
if (bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID) {
@ -694,16 +694,14 @@ ccl_device int bsdf_microfacet_ggx_sample(KernelGlobals kg,
else {
label = LABEL_TRANSMIT | LABEL_GLOSSY;
/* CAUTION: the i and o variables are inverted relative to the paper
* eq. 39 - compute actual refractive direction */
float3 R, T;
float m_eta = bsdf->ior, fresnel;
bool inside;
fresnel = fresnel_dielectric(m_eta, m, I, &R, &T, &inside);
fresnel = fresnel_dielectric(m_eta, m, wi, &R, &T, &inside);
if (!inside && fresnel != 1.0f) {
*omega_in = T;
*wo = T;
if (alpha_x * alpha_y <= 1e-7f || fabsf(m_eta - 1.0f) < 1e-4f) {
/* some high number for MIS */
@ -719,22 +717,22 @@ ccl_device int bsdf_microfacet_ggx_sample(KernelGlobals kg,
float tanThetaM2 = 1 / (cosThetaM2)-1;
float D = alpha2 / (M_PI_F * cosThetaM4 * (alpha2 + tanThetaM2) * (alpha2 + tanThetaM2));
/* eval BRDF*cosNI */
float cosNI = dot(N, *omega_in);
/* eval BRDF*cosNO */
float cosNO = dot(N, *wo);
/* eq. 34: now calculate G1(i,m) */
float G1i = 2 / (1 + safe_sqrtf(1 + alpha2 * (1 - cosNI * cosNI) / (cosNI * cosNI)));
/* eq. 34: now calculate G1(o,m) */
float G1o = 2 / (1 + safe_sqrtf(1 + alpha2 * (1 - cosNO * cosNO) / (cosNO * cosNO)));
/* eq. 21 */
float cosHI = dot(m, *omega_in);
float cosHO = dot(m, I);
float Ht2 = m_eta * cosHI + cosHO;
float cosHO = dot(m, *wo);
float cosHI = dot(m, wi);
float Ht2 = m_eta * cosHO + cosHI;
Ht2 *= Ht2;
/* see eval function for derivation */
float common = (G1o * D) * (m_eta * m_eta) / (cosNO * Ht2);
float out = G1i * fabsf(cosHI * cosHO) * common;
*pdf = cosHO * fabsf(cosHI) * common;
float common = (G1i * D) * (m_eta * m_eta) / (cosNO * Ht2);
float out = G1o * fabsf(cosHI * cosHO) * common;
*pdf = cosHI * fabsf(cosHO) * common;
*eval = make_spectrum(out);
}
@ -823,24 +821,24 @@ ccl_device_inline float bsdf_beckmann_aniso_G1(
ccl_device Spectrum bsdf_microfacet_beckmann_eval_reflect(ccl_private const MicrofacetBsdf *bsdf,
const float3 N,
const float3 I,
const float3 omega_in,
const float3 wi,
const float3 wo,
ccl_private float *pdf,
const float alpha_x,
const float alpha_y,
const float cosNO,
const float cosNI)
const float cosNI,
const float cosNO)
{
if (!(cosNO > 0 && cosNI > 0)) {
if (!(cosNI > 0 && cosNO > 0)) {
*pdf = 0.0f;
return zero_spectrum();
}
/* get half vector */
float3 m = normalize(omega_in + I);
float3 m = normalize(wi + wo);
float alpha2 = alpha_x * alpha_y;
float D, G1o, G1i;
float D, G1i, G1o;
if (alpha_x == alpha_y) {
/* isotropic
@ -853,8 +851,8 @@ ccl_device Spectrum bsdf_microfacet_beckmann_eval_reflect(ccl_private const Micr
D = expf(-tanThetaM2 / alpha2) / (M_PI_F * alpha2 * cosThetaM4);
/* eq. 26, 27: now calculate G1(i,m) and G1(o,m) */
G1o = bsdf_beckmann_G1(alpha_x, cosNO);
G1i = bsdf_beckmann_G1(alpha_x, cosNI);
G1o = bsdf_beckmann_G1(alpha_x, cosNO);
}
else {
/* anisotropic */
@ -873,48 +871,48 @@ ccl_device Spectrum bsdf_microfacet_beckmann_eval_reflect(ccl_private const Micr
D = expf(-slope_x * slope_x - slope_y * slope_y) / (M_PI_F * alpha2 * cosThetaM4);
/* G1(i,m) and G1(o,m) */
G1o = bsdf_beckmann_aniso_G1(alpha_x, alpha_y, cosNO, dot(I, X), dot(I, Y));
G1i = bsdf_beckmann_aniso_G1(alpha_x, alpha_y, cosNI, dot(omega_in, X), dot(omega_in, Y));
G1i = bsdf_beckmann_aniso_G1(alpha_x, alpha_y, cosNI, dot(wi, X), dot(wi, Y));
G1o = bsdf_beckmann_aniso_G1(alpha_x, alpha_y, cosNO, dot(wo, X), dot(wo, Y));
}
float G = G1o * G1i;
float G = G1i * G1o;
/* eq. 20 */
float common = D * 0.25f / cosNO;
float common = D * 0.25f / cosNI;
float out = G * common;
/* eq. 2 in distribution of visible normals sampling
* pm = Dw = G1o * dot(m, I) * D / dot(N, I); */
* pm = Dw = G1i * dot(m, I) * D / dot(N, I); */
/* eq. 38 - but see also:
* eq. 17 in http://www.graphics.cornell.edu/~bjw/wardnotes.pdf
* pdf = pm * 0.25 / dot(m, I); */
*pdf = G1o * common;
*pdf = G1i * common;
return make_spectrum(out);
}
ccl_device Spectrum bsdf_microfacet_beckmann_eval_transmit(ccl_private const MicrofacetBsdf *bsdf,
const float3 N,
const float3 I,
const float3 omega_in,
const float3 wi,
const float3 wo,
ccl_private float *pdf,
const float alpha_x,
const float alpha_y,
const float cosNO,
const float cosNI)
const float cosNI,
const float cosNO)
{
if (cosNO <= 0 || cosNI >= 0) {
if (cosNI <= 0 || cosNO >= 0) {
*pdf = 0.0f;
return zero_spectrum();
}
const float m_eta = bsdf->ior;
/* compute half-vector of the refraction (eq. 16) */
float3 ht = -(m_eta * omega_in + I);
float3 ht = -(m_eta * wo + wi);
float3 Ht = normalize(ht);
float cosHO = dot(Ht, I);
float cosHI = dot(Ht, omega_in);
float cosHI = dot(Ht, wi);
float cosHO = dot(Ht, wo);
/* eq. 25: first we calculate D(m) with m=Ht: */
float alpha2 = alpha_x * alpha_y;
@ -925,60 +923,60 @@ ccl_device Spectrum bsdf_microfacet_beckmann_eval_transmit(ccl_private const Mic
float D = expf(-tanThetaM2 / alpha2) / (M_PI_F * alpha2 * cosThetaM4);
/* eq. 26, 27: now calculate G1(i,m) and G1(o,m) */
float G1o = bsdf_beckmann_G1(alpha_x, cosNO);
float G1i = bsdf_beckmann_G1(alpha_x, cosNI);
float G = G1o * G1i;
float G1o = bsdf_beckmann_G1(alpha_x, cosNO);
float G = G1i * G1o;
/* probability */
float Ht2 = dot(ht, ht);
/* eq. 2 in distribution of visible normals sampling
* pm = Dw = G1o * dot(m, I) * D / dot(N, I); */
* pm = Dw = G1i * dot(m, I) * D / dot(N, I); */
/* out = fabsf(cosHI * cosHO) * (m_eta * m_eta) * G * D / (cosNO * Ht2)
* pdf = pm * (m_eta * m_eta) * fabsf(cosHI) / Ht2 */
float common = D * (m_eta * m_eta) / (cosNO * Ht2);
/* out = fabsf(cosHI * cosHO) * (m_eta * m_eta) * G * D / (cosNI * Ht2)
* pdf = pm * (m_eta * m_eta) * fabsf(cosHO) / Ht2 */
float common = D * (m_eta * m_eta) / (cosNI * Ht2);
float out = G * fabsf(cosHI * cosHO) * common;
*pdf = G1o * fabsf(cosHO * cosHI) * common;
*pdf = G1i * fabsf(cosHI * cosHO) * common;
return make_spectrum(out);
}
ccl_device Spectrum bsdf_microfacet_beckmann_eval(ccl_private const ShaderClosure *sc,
const float3 Ng,
const float3 I,
const float3 omega_in,
const float3 wi,
const float3 wo,
ccl_private float *pdf)
{
ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc;
const bool m_refractive = bsdf->type == CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID;
const float alpha_x = bsdf->alpha_x;
const float alpha_y = bsdf->alpha_y;
const float cosNgI = dot(Ng, omega_in);
const float cosNgO = dot(Ng, wo);
if (((cosNgI < 0.0f) != m_refractive) || alpha_x * alpha_y <= 1e-7f) {
if (((cosNgO < 0.0f) != m_refractive) || alpha_x * alpha_y <= 1e-7f) {
*pdf = 0.0f;
return zero_spectrum();
}
const float3 N = bsdf->N;
const float cosNO = dot(N, I);
const float cosNI = dot(N, omega_in);
const float cosNI = dot(N, wi);
const float cosNO = dot(N, wo);
return (cosNI < 0.0f) ? bsdf_microfacet_beckmann_eval_transmit(
bsdf, N, I, omega_in, pdf, alpha_x, alpha_y, cosNO, cosNI) :
return (cosNO < 0.0f) ? bsdf_microfacet_beckmann_eval_transmit(
bsdf, N, wi, wo, pdf, alpha_x, alpha_y, cosNI, cosNO) :
bsdf_microfacet_beckmann_eval_reflect(
bsdf, N, I, omega_in, pdf, alpha_x, alpha_y, cosNO, cosNI);
bsdf, N, wi, wo, pdf, alpha_x, alpha_y, cosNI, cosNO);
}
ccl_device int bsdf_microfacet_beckmann_sample(KernelGlobals kg,
ccl_private const ShaderClosure *sc,
float3 Ng,
float3 I,
float3 wi,
float randu,
float randv,
ccl_private Spectrum *eval,
ccl_private float3 *omega_in,
ccl_private float3 *wo,
ccl_private float *pdf,
ccl_private float2 *sampled_roughness,
ccl_private float *eta)
@ -993,8 +991,8 @@ ccl_device int bsdf_microfacet_beckmann_sample(KernelGlobals kg,
*sampled_roughness = make_float2(alpha_x, alpha_y);
*eta = m_refractive ? 1.0f / bsdf->ior : bsdf->ior;
float cosNO = dot(N, I);
if (cosNO > 0) {
float cosNI = dot(N, wi);
if (cosNI > 0) {
float3 X, Y, Z = N;
if (alpha_x == alpha_y)
@ -1004,11 +1002,11 @@ ccl_device int bsdf_microfacet_beckmann_sample(KernelGlobals kg,
/* importance sampling with distribution of visible normals. vectors are
* transformed to local space before and after */
float3 local_I = make_float3(dot(X, I), dot(Y, I), cosNO);
float3 local_I = make_float3(dot(X, wi), dot(Y, wi), cosNI);
float3 local_m;
float G1o;
float G1i;
local_m = microfacet_sample_stretched(kg, local_I, alpha_x, alpha_x, randu, randv, true, &G1o);
local_m = microfacet_sample_stretched(kg, local_I, alpha_x, alpha_x, randu, randv, true, &G1i);
float3 m = X * local_m.x + Y * local_m.y + Z * local_m.z;
float cosThetaM = local_m.z;
@ -1016,13 +1014,13 @@ ccl_device int bsdf_microfacet_beckmann_sample(KernelGlobals kg,
/* reflection or refraction? */
if (!m_refractive) {
label = LABEL_REFLECT | LABEL_GLOSSY;
float cosMO = dot(m, I);
float cosMI = dot(m, wi);
if (cosMO > 0) {
if (cosMI > 0) {
/* eq. 39 - compute actual reflected direction */
*omega_in = 2 * cosMO * m - I;
*wo = 2 * cosMI * m - wi;
if (dot(Ng, *omega_in) > 0) {
if (dot(Ng, *wo) > 0) {
if (alpha_x * alpha_y <= 1e-7f) {
/* some high number for MIS */
*pdf = 1e6f;
@ -1033,7 +1031,7 @@ ccl_device int bsdf_microfacet_beckmann_sample(KernelGlobals kg,
/* microfacet normal is visible to this ray
* eq. 25 */
float alpha2 = alpha_x * alpha_y;
float D, G1i;
float D, G1o;
if (alpha_x == alpha_y) {
/* Isotropic distribution. */
@ -1042,11 +1040,11 @@ ccl_device int bsdf_microfacet_beckmann_sample(KernelGlobals kg,
float tanThetaM2 = 1 / (cosThetaM2)-1;
D = expf(-tanThetaM2 / alpha2) / (M_PI_F * alpha2 * cosThetaM4);
/* eval BRDF*cosNI */
float cosNI = dot(N, *omega_in);
/* eval BRDF*cosNO */
float cosNO = dot(N, *wo);
/* eq. 26, 27: now calculate G1(i,m) */
G1i = bsdf_beckmann_G1(alpha_x, cosNI);
/* eq. 26, 27: now calculate G1(o,m) */
G1o = bsdf_beckmann_G1(alpha_x, cosNO);
}
else {
/* anisotropic distribution */
@ -1060,17 +1058,17 @@ ccl_device int bsdf_microfacet_beckmann_sample(KernelGlobals kg,
D = expf(-slope_x * slope_x - slope_y * slope_y) / (M_PI_F * alpha2 * cosThetaM4);
/* G1(i,m) */
G1i = bsdf_beckmann_aniso_G1(
alpha_x, alpha_y, dot(*omega_in, N), dot(*omega_in, X), dot(*omega_in, Y));
/* G1(o,m) */
G1o = bsdf_beckmann_aniso_G1(
alpha_x, alpha_y, dot(*wo, N), dot(*wo, X), dot(*wo, Y));
}
float G = G1o * G1i;
float G = G1i * G1o;
/* see eval function for derivation */
float common = D * 0.25f / cosNO;
float common = D * 0.25f / cosNI;
float out = G * common;
*pdf = G1o * common;
*pdf = G1i * common;
*eval = make_spectrum(out);
}
@ -1084,16 +1082,14 @@ ccl_device int bsdf_microfacet_beckmann_sample(KernelGlobals kg,
else {
label = LABEL_TRANSMIT | LABEL_GLOSSY;
/* CAUTION: the i and o variables are inverted relative to the paper
* eq. 39 - compute actual refractive direction */
float3 R, T;
float m_eta = bsdf->ior, fresnel;
bool inside;
fresnel = fresnel_dielectric(m_eta, m, I, &R, &T, &inside);
fresnel = fresnel_dielectric(m_eta, m, wi, &R, &T, &inside);
if (!inside && fresnel != 1.0f) {
*omega_in = T;
*wo = T;
if (alpha_x * alpha_y <= 1e-7f || fabsf(m_eta - 1.0f) < 1e-4f) {
/* some high number for MIS */
@ -1109,23 +1105,23 @@ ccl_device int bsdf_microfacet_beckmann_sample(KernelGlobals kg,
float tanThetaM2 = 1 / (cosThetaM2)-1;
float D = expf(-tanThetaM2 / alpha2) / (M_PI_F * alpha2 * cosThetaM4);
/* eval BRDF*cosNI */
float cosNI = dot(N, *omega_in);
/* eval BRDF*cosNO */
float cosNO = dot(N, *wo);
/* eq. 26, 27: now calculate G1(i,m) */
float G1i = bsdf_beckmann_G1(alpha_x, cosNI);
float G = G1o * G1i;
/* eq. 26, 27: now calculate G1(o,m) */
float G1o = bsdf_beckmann_G1(alpha_x, cosNO);
float G = G1i * G1o;
/* eq. 21 */
float cosHI = dot(m, *omega_in);
float cosHO = dot(m, I);
float Ht2 = m_eta * cosHI + cosHO;
float cosHI = dot(m, wi);
float cosHO = dot(m, *wo);
float Ht2 = m_eta * cosHO + cosHI;
Ht2 *= Ht2;
/* see eval function for derivation */
float common = D * (m_eta * m_eta) / (cosNO * Ht2);
float out = G * fabsf(cosHI * cosHO) * common;
*pdf = G1o * cosHO * fabsf(cosHI) * common;
float common = D * (m_eta * m_eta) / (cosNI * Ht2);
float out = G * fabsf(cosHO * cosHI) * common;
*pdf = G1i * cosHI * fabsf(cosHO) * common;
*eval = make_spectrum(out);
}

View File

@ -417,15 +417,15 @@ ccl_device int bsdf_microfacet_multi_ggx_refraction_setup(ccl_private Microfacet
ccl_device Spectrum bsdf_microfacet_multi_ggx_eval(ccl_private const ShaderClosure *sc,
const float3 Ng,
const float3 I,
const float3 omega_in,
const float3 wi,
const float3 wo,
ccl_private float *pdf,
ccl_private uint *lcg_state)
{
ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc;
const float cosNgI = dot(Ng, omega_in);
const float cosNgO = dot(Ng, wo);
if ((cosNgI < 0.0f) || bsdf->alpha_x * bsdf->alpha_y < 1e-7f) {
if ((cosNgO < 0.0f) || bsdf->alpha_x * bsdf->alpha_y < 1e-7f) {
*pdf = 0.0f;
return zero_spectrum();
}
@ -434,7 +434,7 @@ ccl_device Spectrum bsdf_microfacet_multi_ggx_eval(ccl_private const ShaderClosu
Z = bsdf->N;
/* Ensure that the both directions are on the outside w.r.t. the shading normal. */
if (dot(Z, I) <= 0.0f || dot(Z, omega_in) <= 0.0f) {
if (dot(Z, wi) <= 0.0f || dot(Z, wo) <= 0.0f) {
*pdf = 0.0f;
return zero_spectrum();
}
@ -447,21 +447,21 @@ ccl_device Spectrum bsdf_microfacet_multi_ggx_eval(ccl_private const ShaderClosu
else
make_orthonormals(Z, &X, &Y);
float3 localI = make_float3(dot(I, X), dot(I, Y), dot(I, Z));
float3 localO = make_float3(dot(omega_in, X), dot(omega_in, Y), dot(omega_in, Z));
float3 local_I = make_float3(dot(wi, X), dot(wi, Y), dot(wi, Z));
float3 local_O = make_float3(dot(wo, X), dot(wo, Y), dot(wo, Z));
if (is_aniso)
*pdf = mf_ggx_aniso_pdf(localI, localO, make_float2(bsdf->alpha_x, bsdf->alpha_y));
*pdf = mf_ggx_aniso_pdf(local_I, local_O, make_float2(bsdf->alpha_x, bsdf->alpha_y));
else
*pdf = mf_ggx_pdf(localI, localO, bsdf->alpha_x);
*pdf = mf_ggx_pdf(local_I, local_O, bsdf->alpha_x);
if (*pdf <= 0.f) {
*pdf = 0.f;
return make_float3(0.f, 0.f, 0.f);
}
return mf_eval_glossy(localI,
localO,
return mf_eval_glossy(local_I,
local_O,
true,
bsdf->extra->color,
bsdf->alpha_x,
@ -475,11 +475,11 @@ ccl_device Spectrum bsdf_microfacet_multi_ggx_eval(ccl_private const ShaderClosu
ccl_device int bsdf_microfacet_multi_ggx_sample(KernelGlobals kg,
ccl_private const ShaderClosure *sc,
float3 Ng,
float3 I,
float3 wi,
float randu,
float randv,
ccl_private Spectrum *eval,
ccl_private float3 *omega_in,
ccl_private float3 *wo,
ccl_private float *pdf,
ccl_private uint *lcg_state,
ccl_private float2 *sampled_roughness,
@ -491,7 +491,7 @@ ccl_device int bsdf_microfacet_multi_ggx_sample(KernelGlobals kg,
Z = bsdf->N;
/* Ensure that the view direction is on the outside w.r.t. the shading normal. */
if (dot(Z, I) <= 0.0f) {
if (dot(Z, wi) <= 0.0f) {
*pdf = 0.0f;
return LABEL_NONE;
}
@ -499,8 +499,8 @@ ccl_device int bsdf_microfacet_multi_ggx_sample(KernelGlobals kg,
/* Special case: Extremely low roughness.
* Don't bother with microfacets, just do specular reflection. */
if (bsdf->alpha_x * bsdf->alpha_y < 1e-7f) {
*omega_in = 2 * dot(Z, I) * Z - I;
if (dot(Ng, *omega_in) <= 0.0f) {
*wo = 2 * dot(Z, wi) * Z - wi;
if (dot(Ng, *wo) <= 0.0f) {
*pdf = 0.0f;
return LABEL_NONE;
}
@ -520,11 +520,11 @@ ccl_device int bsdf_microfacet_multi_ggx_sample(KernelGlobals kg,
else
make_orthonormals(Z, &X, &Y);
float3 localI = make_float3(dot(I, X), dot(I, Y), dot(I, Z));
float3 localO;
float3 local_I = make_float3(dot(wi, X), dot(wi, Y), dot(wi, Z));
float3 local_O;
*eval = mf_sample_glossy(localI,
&localO,
*eval = mf_sample_glossy(local_I,
&local_O,
bsdf->extra->color,
bsdf->alpha_x,
bsdf->alpha_y,
@ -532,18 +532,18 @@ ccl_device int bsdf_microfacet_multi_ggx_sample(KernelGlobals kg,
bsdf->ior,
use_fresnel,
bsdf->extra->cspec0);
*omega_in = X * localO.x + Y * localO.y + Z * localO.z;
*wo = X * local_O.x + Y * local_O.y + Z * local_O.z;
/* Ensure that the light direction is on the outside w.r.t. the geometry normal. */
if (dot(Ng, *omega_in) <= 0.0f) {
if (dot(Ng, *wo) <= 0.0f) {
*pdf = 0.0f;
return LABEL_NONE;
}
if (is_aniso)
*pdf = mf_ggx_aniso_pdf(localI, localO, make_float2(bsdf->alpha_x, bsdf->alpha_y));
*pdf = mf_ggx_aniso_pdf(local_I, local_O, make_float2(bsdf->alpha_x, bsdf->alpha_y));
else
*pdf = mf_ggx_pdf(localI, localO, bsdf->alpha_x);
*pdf = mf_ggx_pdf(local_I, local_O, bsdf->alpha_x);
*pdf = fmaxf(0.f, *pdf);
*eval *= *pdf;
@ -581,8 +581,8 @@ ccl_device int bsdf_microfacet_multi_ggx_glass_fresnel_setup(ccl_private Microfa
}
ccl_device Spectrum bsdf_microfacet_multi_ggx_glass_eval(ccl_private const ShaderClosure *sc,
const float3 I,
const float3 omega_in,
const float3 wi,
const float3 wo,
ccl_private float *pdf,
ccl_private uint *lcg_state)
{
@ -597,17 +597,17 @@ ccl_device Spectrum bsdf_microfacet_multi_ggx_glass_eval(ccl_private const Shade
Z = bsdf->N;
make_orthonormals(Z, &X, &Y);
float3 localI = make_float3(dot(I, X), dot(I, Y), dot(I, Z));
float3 localO = make_float3(dot(omega_in, X), dot(omega_in, Y), dot(omega_in, Z));
float3 local_I = make_float3(dot(wi, X), dot(wi, Y), dot(wi, Z));
float3 local_O = make_float3(dot(wo, X), dot(wo, Y), dot(wo, Z));
const bool is_transmission = localO.z < 0.0f;
const bool is_transmission = local_O.z < 0.0f;
const bool use_fresnel = !is_transmission &&
(bsdf->type == CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_FRESNEL_ID);
*pdf = mf_glass_pdf(localI, localO, bsdf->alpha_x, bsdf->ior);
*pdf = mf_glass_pdf(local_I, local_O, bsdf->alpha_x, bsdf->ior);
kernel_assert(*pdf >= 0.f);
return mf_eval_glass(localI,
localO,
return mf_eval_glass(local_I,
local_O,
!is_transmission,
bsdf->extra->color,
bsdf->alpha_x,
@ -621,11 +621,11 @@ ccl_device Spectrum bsdf_microfacet_multi_ggx_glass_eval(ccl_private const Shade
ccl_device int bsdf_microfacet_multi_ggx_glass_sample(KernelGlobals kg,
ccl_private const ShaderClosure *sc,
float3 Ng,
float3 I,
float3 wi,
float randu,
float randv,
ccl_private Spectrum *eval,
ccl_private float3 *omega_in,
ccl_private float3 *wo,
ccl_private float *pdf,
ccl_private uint *lcg_state,
ccl_private float2 *sampled_roughness,
@ -642,16 +642,16 @@ ccl_device int bsdf_microfacet_multi_ggx_glass_sample(KernelGlobals kg,
if (bsdf->alpha_x * bsdf->alpha_y < 1e-7f) {
float3 R, T;
bool inside;
float fresnel = fresnel_dielectric(bsdf->ior, Z, I, &R, &T, &inside);
float fresnel = fresnel_dielectric(bsdf->ior, Z, wi, &R, &T, &inside);
*pdf = 1e6f;
*eval = make_spectrum(1e6f);
if (randu < fresnel) {
*omega_in = R;
*wo = R;
return LABEL_REFLECT | LABEL_SINGULAR;
}
else {
*omega_in = T;
*wo = T;
return LABEL_TRANSMIT | LABEL_SINGULAR;
}
}
@ -660,11 +660,11 @@ ccl_device int bsdf_microfacet_multi_ggx_glass_sample(KernelGlobals kg,
make_orthonormals(Z, &X, &Y);
float3 localI = make_float3(dot(I, X), dot(I, Y), dot(I, Z));
float3 localO;
float3 local_I = make_float3(dot(wi, X), dot(wi, Y), dot(wi, Z));
float3 local_O;
*eval = mf_sample_glass(localI,
&localO,
*eval = mf_sample_glass(local_I,
&local_O,
bsdf->extra->color,
bsdf->alpha_x,
bsdf->alpha_y,
@ -672,12 +672,12 @@ ccl_device int bsdf_microfacet_multi_ggx_glass_sample(KernelGlobals kg,
bsdf->ior,
use_fresnel,
bsdf->extra->cspec0);
*pdf = mf_glass_pdf(localI, localO, bsdf->alpha_x, bsdf->ior);
*pdf = mf_glass_pdf(local_I, local_O, bsdf->alpha_x, bsdf->ior);
kernel_assert(*pdf >= 0.f);
*eval *= *pdf;
*omega_in = X * localO.x + Y * localO.y + Z * localO.z;
if (localO.z * localI.z > 0.0f) {
*wo = X * local_O.x + Y * local_O.y + Z * local_O.z;
if (local_O.z * local_I.z > 0.0f) {
return LABEL_REFLECT | LABEL_GLOSSY;
}
else {

View File

@ -48,14 +48,14 @@ ccl_device int bsdf_oren_nayar_setup(ccl_private OrenNayarBsdf *bsdf)
}
ccl_device Spectrum bsdf_oren_nayar_eval(ccl_private const ShaderClosure *sc,
const float3 I,
const float3 omega_in,
const float3 wi,
const float3 wo,
ccl_private float *pdf)
{
ccl_private const OrenNayarBsdf *bsdf = (ccl_private const OrenNayarBsdf *)sc;
if (dot(bsdf->N, omega_in) > 0.0f) {
if (dot(bsdf->N, wo) > 0.0f) {
*pdf = 0.5f * M_1_PI_F;
return bsdf_oren_nayar_get_intensity(sc, bsdf->N, I, omega_in);
return bsdf_oren_nayar_get_intensity(sc, bsdf->N, wi, wo);
}
else {
*pdf = 0.0f;
@ -65,18 +65,18 @@ ccl_device Spectrum bsdf_oren_nayar_eval(ccl_private const ShaderClosure *sc,
ccl_device int bsdf_oren_nayar_sample(ccl_private const ShaderClosure *sc,
float3 Ng,
float3 I,
float3 wi,
float randu,
float randv,
ccl_private Spectrum *eval,
ccl_private float3 *omega_in,
ccl_private float3 *wo,
ccl_private float *pdf)
{
ccl_private const OrenNayarBsdf *bsdf = (ccl_private const OrenNayarBsdf *)sc;
sample_uniform_hemisphere(bsdf->N, randu, randv, omega_in, pdf);
sample_uniform_hemisphere(bsdf->N, randu, randv, wo, pdf);
if (dot(Ng, *omega_in) > 0.0f) {
*eval = bsdf_oren_nayar_get_intensity(sc, bsdf->N, I, *omega_in);
if (dot(Ng, *wo) > 0.0f) {
*eval = bsdf_oren_nayar_get_intensity(sc, bsdf->N, wi, *wo);
}
else {
*pdf = 0.0f;

View File

@ -45,23 +45,23 @@ ccl_device int bsdf_phong_ramp_setup(ccl_private PhongRampBsdf *bsdf)
}
ccl_device Spectrum bsdf_phong_ramp_eval(ccl_private const ShaderClosure *sc,
const float3 I,
const float3 omega_in,
const float3 wi,
const float3 wo,
ccl_private float *pdf)
{
ccl_private const PhongRampBsdf *bsdf = (ccl_private const PhongRampBsdf *)sc;
float m_exponent = bsdf->exponent;
float cosNI = dot(bsdf->N, omega_in);
float cosNO = dot(bsdf->N, I);
float cosNI = dot(bsdf->N, wi);
float cosNO = dot(bsdf->N, wo);
if (cosNI > 0 && cosNO > 0) {
// reflect the view vector
float3 R = (2 * cosNO) * bsdf->N - I;
float cosRI = dot(R, omega_in);
if (cosRI > 0) {
float cosp = powf(cosRI, m_exponent);
float3 R = (2 * cosNI) * bsdf->N - wi;
float cosRO = dot(R, wo);
if (cosRO > 0) {
float cosp = powf(cosRO, m_exponent);
float common = 0.5f * M_1_PI_F * cosp;
float out = cosNI * (m_exponent + 2) * common;
float out = cosNO * (m_exponent + 2) * common;
*pdf = (m_exponent + 1) * common;
return rgb_to_spectrum(bsdf_phong_ramp_get_color(bsdf->colors, cosp) * out);
}
@ -77,39 +77,39 @@ ccl_device_inline float phong_ramp_exponent_to_roughness(float exponent)
ccl_device int bsdf_phong_ramp_sample(ccl_private const ShaderClosure *sc,
float3 Ng,
float3 I,
float3 wi,
float randu,
float randv,
ccl_private Spectrum *eval,
ccl_private float3 *omega_in,
ccl_private float3 *wo,
ccl_private float *pdf,
ccl_private float2 *sampled_roughness)
{
ccl_private const PhongRampBsdf *bsdf = (ccl_private const PhongRampBsdf *)sc;
float cosNO = dot(bsdf->N, I);
float cosNI = dot(bsdf->N, wi);
float m_exponent = bsdf->exponent;
const float m_roughness = phong_ramp_exponent_to_roughness(m_exponent);
*sampled_roughness = make_float2(m_roughness, m_roughness);
if (cosNO > 0) {
if (cosNI > 0) {
// reflect the view vector
float3 R = (2 * cosNO) * bsdf->N - I;
float3 R = (2 * cosNI) * bsdf->N - wi;
float3 T, B;
make_orthonormals(R, &T, &B);
float phi = M_2PI_F * randu;
float cosTheta = powf(randv, 1 / (m_exponent + 1));
float sinTheta2 = 1 - cosTheta * cosTheta;
float sinTheta = sinTheta2 > 0 ? sqrtf(sinTheta2) : 0;
*omega_in = (cosf(phi) * sinTheta) * T + (sinf(phi) * sinTheta) * B + (cosTheta)*R;
if (dot(Ng, *omega_in) > 0.0f) {
*wo = (cosf(phi) * sinTheta) * T + (sinf(phi) * sinTheta) * B + (cosTheta)*R;
if (dot(Ng, *wo) > 0.0f) {
// common terms for pdf and eval
float cosNI = dot(bsdf->N, *omega_in);
float cosNO = dot(bsdf->N, *wo);
// make sure the direction we chose is still in the right hemisphere
if (cosNI > 0) {
if (cosNO > 0) {
float cosp = powf(cosTheta, m_exponent);
float common = 0.5f * M_1_PI_F * cosp;
*pdf = (m_exponent + 1) * common;
float out = cosNI * (m_exponent + 2) * common;
float out = cosNO * (m_exponent + 2) * common;
*eval = rgb_to_spectrum(bsdf_phong_ramp_get_color(bsdf->colors, cosp) * out);
}
}

View File

@ -110,17 +110,17 @@ ccl_device int bsdf_principled_diffuse_setup(ccl_private PrincipledDiffuseBsdf *
}
ccl_device Spectrum bsdf_principled_diffuse_eval(ccl_private const ShaderClosure *sc,
const float3 I,
const float3 omega_in,
const float3 wi,
const float3 wo,
ccl_private float *pdf)
{
ccl_private const PrincipledDiffuseBsdf *bsdf = (ccl_private const PrincipledDiffuseBsdf *)sc;
const float3 N = bsdf->N;
if (dot(N, omega_in) > 0.0f) {
const float3 V = I; // outgoing
const float3 L = omega_in; // incoming
*pdf = fmaxf(dot(N, omega_in), 0.0f) * M_1_PI_F;
if (dot(N, wo) > 0.0f) {
const float3 V = wi;
const float3 L = wo;
*pdf = fmaxf(dot(N, wo), 0.0f) * M_1_PI_F;
return bsdf_principled_diffuse_compute_brdf(bsdf, N, V, L, pdf);
}
else {
@ -131,21 +131,21 @@ ccl_device Spectrum bsdf_principled_diffuse_eval(ccl_private const ShaderClosure
ccl_device int bsdf_principled_diffuse_sample(ccl_private const ShaderClosure *sc,
float3 Ng,
float3 I,
float3 wi,
float randu,
float randv,
ccl_private Spectrum *eval,
ccl_private float3 *omega_in,
ccl_private float3 *wo,
ccl_private float *pdf)
{
ccl_private const PrincipledDiffuseBsdf *bsdf = (ccl_private const PrincipledDiffuseBsdf *)sc;
float3 N = bsdf->N;
sample_cos_hemisphere(N, randu, randv, omega_in, pdf);
sample_cos_hemisphere(N, randu, randv, wo, pdf);
if (dot(Ng, *omega_in) > 0) {
*eval = bsdf_principled_diffuse_compute_brdf(bsdf, N, I, *omega_in, pdf);
if (dot(Ng, *wo) > 0) {
*eval = bsdf_principled_diffuse_compute_brdf(bsdf, N, wi, *wo, pdf);
}
else {
*pdf = 0.0f;

View File

@ -54,25 +54,25 @@ ccl_device int bsdf_principled_sheen_setup(ccl_private const ShaderData *sd,
ccl_private PrincipledSheenBsdf *bsdf)
{
bsdf->type = CLOSURE_BSDF_PRINCIPLED_SHEEN_ID;
bsdf->avg_value = calculate_avg_principled_sheen_brdf(bsdf->N, sd->I);
bsdf->avg_value = calculate_avg_principled_sheen_brdf(bsdf->N, sd->wi);
bsdf->sample_weight *= bsdf->avg_value;
return SD_BSDF | SD_BSDF_HAS_EVAL;
}
ccl_device Spectrum bsdf_principled_sheen_eval(ccl_private const ShaderClosure *sc,
const float3 I,
const float3 omega_in,
const float3 wi,
const float3 wo,
ccl_private float *pdf)
{
ccl_private const PrincipledSheenBsdf *bsdf = (ccl_private const PrincipledSheenBsdf *)sc;
const float3 N = bsdf->N;
if (dot(N, omega_in) > 0.0f) {
const float3 V = I; // outgoing
const float3 L = omega_in; // incoming
if (dot(N, wo) > 0.0f) {
const float3 V = wi;
const float3 L = wo;
const float3 H = normalize(L + V);
*pdf = fmaxf(dot(N, omega_in), 0.0f) * M_1_PI_F;
*pdf = fmaxf(dot(N, wo), 0.0f) * M_1_PI_F;
return calculate_principled_sheen_brdf(N, V, L, H, pdf);
}
else {
@ -83,23 +83,23 @@ ccl_device Spectrum bsdf_principled_sheen_eval(ccl_private const ShaderClosure *
ccl_device int bsdf_principled_sheen_sample(ccl_private const ShaderClosure *sc,
float3 Ng,
float3 I,
float3 wi,
float randu,
float randv,
ccl_private Spectrum *eval,
ccl_private float3 *omega_in,
ccl_private float3 *wo,
ccl_private float *pdf)
{
ccl_private const PrincipledSheenBsdf *bsdf = (ccl_private const PrincipledSheenBsdf *)sc;
float3 N = bsdf->N;
sample_cos_hemisphere(N, randu, randv, omega_in, pdf);
sample_cos_hemisphere(N, randu, randv, wo, pdf);
if (dot(Ng, *omega_in) > 0) {
float3 H = normalize(I + *omega_in);
if (dot(Ng, *wo) > 0) {
float3 H = normalize(wi + *wo);
*eval = calculate_principled_sheen_brdf(N, I, *omega_in, H, pdf);
*eval = calculate_principled_sheen_brdf(N, wi, *wo, H, pdf);
}
else {
*eval = zero_spectrum();

View File

@ -19,8 +19,8 @@ ccl_device int bsdf_reflection_setup(ccl_private MicrofacetBsdf *bsdf)
}
ccl_device Spectrum bsdf_reflection_eval(ccl_private const ShaderClosure *sc,
const float3 I,
const float3 omega_in,
const float3 wi,
const float3 wo,
ccl_private float *pdf)
{
*pdf = 0.0f;
@ -29,11 +29,11 @@ ccl_device Spectrum bsdf_reflection_eval(ccl_private const ShaderClosure *sc,
ccl_device int bsdf_reflection_sample(ccl_private const ShaderClosure *sc,
float3 Ng,
float3 I,
float3 wi,
float randu,
float randv,
ccl_private Spectrum *eval,
ccl_private float3 *omega_in,
ccl_private float3 *wo,
ccl_private float *pdf,
ccl_private float *eta)
{
@ -42,10 +42,10 @@ ccl_device int bsdf_reflection_sample(ccl_private const ShaderClosure *sc,
*eta = bsdf->ior;
// only one direction is possible
float cosNO = dot(N, I);
if (cosNO > 0) {
*omega_in = (2 * cosNO) * N - I;
if (dot(Ng, *omega_in) > 0) {
float cosNI = dot(N, wi);
if (cosNI > 0) {
*wo = (2 * cosNI) * N - wi;
if (dot(Ng, *wo) > 0) {
/* Some high number for MIS. */
*pdf = 1e6f;
*eval = make_spectrum(1e6f);

View File

@ -19,8 +19,8 @@ ccl_device int bsdf_refraction_setup(ccl_private MicrofacetBsdf *bsdf)
}
ccl_device Spectrum bsdf_refraction_eval(ccl_private const ShaderClosure *sc,
const float3 I,
const float3 omega_in,
const float3 wi,
const float3 wo,
ccl_private float *pdf)
{
*pdf = 0.0f;
@ -29,11 +29,11 @@ ccl_device Spectrum bsdf_refraction_eval(ccl_private const ShaderClosure *sc,
ccl_device int bsdf_refraction_sample(ccl_private const ShaderClosure *sc,
float3 Ng,
float3 I,
float3 wi,
float randu,
float randv,
ccl_private Spectrum *eval,
ccl_private float3 *omega_in,
ccl_private float3 *wo,
ccl_private float *pdf,
ccl_private float *eta)
{
@ -46,13 +46,13 @@ ccl_device int bsdf_refraction_sample(ccl_private const ShaderClosure *sc,
float3 R, T;
bool inside;
float fresnel;
fresnel = fresnel_dielectric(m_eta, N, I, &R, &T, &inside);
fresnel = fresnel_dielectric(m_eta, N, wi, &R, &T, &inside);
if (!inside && fresnel != 1.0f) {
/* Some high number for MIS. */
*pdf = 1e6f;
*eval = make_spectrum(1e6f);
*omega_in = T;
*wo = T;
}
else {
*pdf = 0.0f;

View File

@ -50,17 +50,17 @@ ccl_device float bsdf_toon_get_sample_angle(float max_angle, float smooth)
}
ccl_device Spectrum bsdf_diffuse_toon_eval(ccl_private const ShaderClosure *sc,
const float3 I,
const float3 omega_in,
const float3 wi,
const float3 wo,
ccl_private float *pdf)
{
ccl_private const ToonBsdf *bsdf = (ccl_private const ToonBsdf *)sc;
float cosNI = dot(bsdf->N, omega_in);
float cosNO = dot(bsdf->N, wo);
if (cosNI >= 0.0f) {
if (cosNO >= 0.0f) {
float max_angle = bsdf->size * M_PI_2_F;
float smooth = bsdf->smooth * M_PI_2_F;
float angle = safe_acosf(fmaxf(cosNI, 0.0f));
float angle = safe_acosf(fmaxf(cosNO, 0.0f));
float eval = bsdf_toon_get_intensity(max_angle, smooth, angle);
@ -78,11 +78,11 @@ ccl_device Spectrum bsdf_diffuse_toon_eval(ccl_private const ShaderClosure *sc,
ccl_device int bsdf_diffuse_toon_sample(ccl_private const ShaderClosure *sc,
float3 Ng,
float3 I,
float3 wi,
float randu,
float randv,
ccl_private Spectrum *eval,
ccl_private float3 *omega_in,
ccl_private float3 *wo,
ccl_private float *pdf)
{
ccl_private const ToonBsdf *bsdf = (ccl_private const ToonBsdf *)sc;
@ -92,9 +92,9 @@ ccl_device int bsdf_diffuse_toon_sample(ccl_private const ShaderClosure *sc,
float angle = sample_angle * randu;
if (sample_angle > 0.0f) {
sample_uniform_cone(bsdf->N, sample_angle, randu, randv, omega_in, pdf);
sample_uniform_cone(bsdf->N, sample_angle, randu, randv, wo, pdf);
if (dot(Ng, *omega_in) > 0.0f) {
if (dot(Ng, *wo) > 0.0f) {
*eval = make_spectrum(*pdf * bsdf_toon_get_intensity(max_angle, smooth, angle));
}
else {
@ -122,22 +122,22 @@ ccl_device int bsdf_glossy_toon_setup(ccl_private ToonBsdf *bsdf)
}
ccl_device Spectrum bsdf_glossy_toon_eval(ccl_private const ShaderClosure *sc,
const float3 I,
const float3 omega_in,
const float3 wi,
const float3 wo,
ccl_private float *pdf)
{
ccl_private const ToonBsdf *bsdf = (ccl_private const ToonBsdf *)sc;
float max_angle = bsdf->size * M_PI_2_F;
float smooth = bsdf->smooth * M_PI_2_F;
float cosNI = dot(bsdf->N, omega_in);
float cosNO = dot(bsdf->N, I);
float cosNI = dot(bsdf->N, wi);
float cosNO = dot(bsdf->N, wo);
if (cosNI > 0 && cosNO > 0) {
/* reflect the view vector */
float3 R = (2 * cosNO) * bsdf->N - I;
float cosRI = dot(R, omega_in);
float3 R = (2 * cosNI) * bsdf->N - wi;
float cosRO = dot(R, wo);
float angle = safe_acosf(fmaxf(cosRI, 0.0f));
float angle = safe_acosf(fmaxf(cosRO, 0.0f));
float eval = bsdf_toon_get_intensity(max_angle, smooth, angle);
float sample_angle = bsdf_toon_get_sample_angle(max_angle, smooth);
@ -151,32 +151,32 @@ ccl_device Spectrum bsdf_glossy_toon_eval(ccl_private const ShaderClosure *sc,
ccl_device int bsdf_glossy_toon_sample(ccl_private const ShaderClosure *sc,
float3 Ng,
float3 I,
float3 wi,
float randu,
float randv,
ccl_private Spectrum *eval,
ccl_private float3 *omega_in,
ccl_private float3 *wo,
ccl_private float *pdf)
{
ccl_private const ToonBsdf *bsdf = (ccl_private const ToonBsdf *)sc;
float max_angle = bsdf->size * M_PI_2_F;
float smooth = bsdf->smooth * M_PI_2_F;
float cosNO = dot(bsdf->N, I);
float cosNI = dot(bsdf->N, wi);
if (cosNO > 0) {
if (cosNI > 0) {
/* reflect the view vector */
float3 R = (2 * cosNO) * bsdf->N - I;
float3 R = (2 * cosNI) * bsdf->N - wi;
float sample_angle = bsdf_toon_get_sample_angle(max_angle, smooth);
float angle = sample_angle * randu;
sample_uniform_cone(R, sample_angle, randu, randv, omega_in, pdf);
sample_uniform_cone(R, sample_angle, randu, randv, wo, pdf);
if (dot(Ng, *omega_in) > 0.0f) {
float cosNI = dot(bsdf->N, *omega_in);
if (dot(Ng, *wo) > 0.0f) {
float cosNO = dot(bsdf->N, *wo);
/* make sure the direction we chose is still in the right hemisphere */
if (cosNI > 0) {
if (cosNO > 0) {
*eval = make_spectrum(*pdf * bsdf_toon_get_intensity(max_angle, smooth, angle));
}
else {

View File

@ -60,8 +60,8 @@ ccl_device void bsdf_transparent_setup(ccl_private ShaderData *sd,
}
ccl_device Spectrum bsdf_transparent_eval(ccl_private const ShaderClosure *sc,
const float3 I,
const float3 omega_in,
const float3 wi,
const float3 wo,
ccl_private float *pdf)
{
*pdf = 0.0f;
@ -70,15 +70,15 @@ ccl_device Spectrum bsdf_transparent_eval(ccl_private const ShaderClosure *sc,
ccl_device int bsdf_transparent_sample(ccl_private const ShaderClosure *sc,
float3 Ng,
float3 I,
float3 wi,
float randu,
float randv,
ccl_private Spectrum *eval,
ccl_private float3 *omega_in,
ccl_private float3 *wo,
ccl_private float *pdf)
{
// only one direction is possible
*omega_in = -I;
*wo = -wi;
*pdf = 1;
*eval = one_spectrum();
return LABEL_TRANSMIT | LABEL_TRANSPARENT;

View File

@ -293,7 +293,7 @@ ccl_device int bssrdf_setup(ccl_private ShaderData *sd,
/* Ad-hoc weight adjustment to avoid retro-reflection taking away half the
* samples from BSSRDF. */
bsdf->sample_weight *= bsdf_principled_diffuse_retro_reflection_sample_weight(bsdf, sd->I);
bsdf->sample_weight *= bsdf_principled_diffuse_retro_reflection_sample_weight(bsdf, sd->wi);
}
}

View File

@ -36,27 +36,24 @@ ccl_device void emission_setup(ccl_private ShaderData *sd, const Spectrum weight
}
}
/* return the probability distribution function in the direction I,
/* return the probability distribution function in the direction wi,
* given the parameters and the light's surface normal. This MUST match
* the PDF computed by sample(). */
ccl_device float emissive_pdf(const float3 Ng, const float3 I)
ccl_device float emissive_pdf(const float3 Ng, const float3 wi)
{
float cosNO = fabsf(dot(Ng, I));
return (cosNO > 0.0f) ? 1.0f : 0.0f;
float cosNI = fabsf(dot(Ng, wi));
return (cosNI > 0.0f) ? 1.0f : 0.0f;
}
ccl_device void emissive_sample(const float3 Ng,
float randu,
float randv,
ccl_private float3 *omega_out,
ccl_private float *pdf)
ccl_device void emissive_sample(
const float3 Ng, float randu, float randv, ccl_private float3 *wi, ccl_private float *pdf)
{
/* todo: not implemented and used yet */
}
ccl_device Spectrum emissive_simple_eval(const float3 Ng, const float3 I)
ccl_device Spectrum emissive_simple_eval(const float3 Ng, const float3 wi)
{
float res = emissive_pdf(Ng, I);
float res = emissive_pdf(Ng, wi);
return make_spectrum(res);
}

View File

@ -49,18 +49,18 @@ ccl_device int volume_henyey_greenstein_setup(ccl_private HenyeyGreensteinVolume
}
ccl_device Spectrum volume_henyey_greenstein_eval_phase(ccl_private const ShaderVolumeClosure *svc,
const float3 I,
float3 omega_in,
const float3 wi,
float3 wo,
ccl_private float *pdf)
{
float g = svc->g;
/* note that I points towards the viewer */
/* note that wi points towards the viewer */
if (fabsf(g) < 1e-3f) {
*pdf = M_1_PI_F * 0.25f;
}
else {
float cos_theta = dot(-I, omega_in);
float cos_theta = dot(-wi, wo);
*pdf = single_peaked_henyey_greenstein(cos_theta, g);
}
@ -100,17 +100,17 @@ henyey_greenstrein_sample(float3 D, float g, float randu, float randv, ccl_priva
}
ccl_device int volume_henyey_greenstein_sample(ccl_private const ShaderVolumeClosure *svc,
float3 I,
float3 wi,
float randu,
float randv,
ccl_private Spectrum *eval,
ccl_private float3 *omega_in,
ccl_private float3 *wo,
ccl_private float *pdf)
{
float g = svc->g;
/* note that I points towards the viewer and so is used negated */
*omega_in = henyey_greenstrein_sample(-I, g, randu, randv, pdf);
/* note that wi points towards the viewer and so is used negated */
*wo = henyey_greenstrein_sample(-wi, g, randu, randv, pdf);
*eval = make_spectrum(*pdf); /* perfect importance sampling */
return LABEL_VOLUME_SCATTER;
@ -120,10 +120,10 @@ ccl_device int volume_henyey_greenstein_sample(ccl_private const ShaderVolumeClo
ccl_device Spectrum volume_phase_eval(ccl_private const ShaderData *sd,
ccl_private const ShaderVolumeClosure *svc,
float3 omega_in,
float3 wo,
ccl_private float *pdf)
{
return volume_henyey_greenstein_eval_phase(svc, sd->I, omega_in, pdf);
return volume_henyey_greenstein_eval_phase(svc, sd->wi, wo, pdf);
}
ccl_device int volume_phase_sample(ccl_private const ShaderData *sd,
@ -131,10 +131,10 @@ ccl_device int volume_phase_sample(ccl_private const ShaderData *sd,
float randu,
float randv,
ccl_private Spectrum *eval,
ccl_private float3 *omega_in,
ccl_private float3 *wo,
ccl_private float *pdf)
{
return volume_henyey_greenstein_sample(svc, sd->I, randu, randv, eval, omega_in, pdf);
return volume_henyey_greenstein_sample(svc, sd->wi, randu, randv, eval, wo, pdf);
}
/* Volume sampling utilities. */

View File

@ -252,7 +252,7 @@ ccl_device float3 curve_tangent_normal(KernelGlobals kg, ccl_private const Shade
if (sd->type & PRIMITIVE_CURVE) {
tgN = -(-sd->I - sd->dPdu * (dot(sd->dPdu, -sd->I) / len_squared(sd->dPdu)));
tgN = -(-sd->wi - sd->dPdu * (dot(sd->dPdu, -sd->wi) / len_squared(sd->dPdu)));
tgN = normalize(tgN);
/* need to find suitable scaled gd for corrected normal */

View File

@ -738,7 +738,7 @@ ccl_device_inline void curve_shader_setup(KernelGlobals kg,
/* NOTE: It is possible that P will be the same as P_inside (precision issues, or very small
* radius). In this case use the view direction to approximate the normal. */
const float3 P_inside = float4_to_float3(catmull_rom_basis_eval(P_curve, sd->u));
const float3 N = (!isequal(P, P_inside)) ? normalize(P - P_inside) : -sd->I;
const float3 N = (!isequal(P, P_inside)) ? normalize(P - P_inside) : -sd->wi;
sd->N = N;
sd->v = 0.0f;
@ -757,7 +757,7 @@ ccl_device_inline void curve_shader_setup(KernelGlobals kg,
}
sd->P = P;
sd->Ng = (sd->type & PRIMITIVE_CURVE_RIBBON) ? sd->I : sd->N;
sd->Ng = (sd->type & PRIMITIVE_CURVE_RIBBON) ? sd->wi : sd->N;
sd->dPdv = cross(sd->dPdu, sd->Ng);
sd->shader = kernel_data_fetch(curves, sd->prim).shader_id;
}

View File

@ -55,7 +55,7 @@ ccl_device_inline void shader_setup_from_ray(KernelGlobals kg,
#endif
/* Read ray data into shader globals. */
sd->I = -ray->D;
sd->wi = -ray->D;
#ifdef __HAIR__
if (sd->type & PRIMITIVE_CURVE) {
@ -111,7 +111,7 @@ ccl_device_inline void shader_setup_from_ray(KernelGlobals kg,
sd->flag = kernel_data_fetch(shaders, (sd->shader & SHADER_MASK)).flags;
/* backfacing test */
bool backfacing = (dot(sd->Ng, sd->I) < 0.0f);
bool backfacing = (dot(sd->Ng, sd->wi) < 0.0f);
if (backfacing) {
sd->flag |= SD_BACKFACING;
@ -152,7 +152,7 @@ ccl_device_inline void shader_setup_from_sample(KernelGlobals kg,
sd->P = P;
sd->N = Ng;
sd->Ng = Ng;
sd->I = I;
sd->wi = I;
sd->shader = shader;
if (prim != PRIM_NONE)
sd->type = PRIMITIVE_TRIANGLE;
@ -185,7 +185,7 @@ ccl_device_inline void shader_setup_from_sample(KernelGlobals kg,
object_position_transform_auto(kg, sd, &sd->P);
object_normal_transform_auto(kg, sd, &sd->Ng);
sd->N = sd->Ng;
object_dir_transform_auto(kg, sd, &sd->I);
object_dir_transform_auto(kg, sd, &sd->wi);
}
if (sd->type == PRIMITIVE_TRIANGLE) {
@ -227,7 +227,7 @@ ccl_device_inline void shader_setup_from_sample(KernelGlobals kg,
/* backfacing test */
if (sd->prim != PRIM_NONE) {
bool backfacing = (dot(sd->Ng, sd->I) < 0.0f);
bool backfacing = (dot(sd->Ng, sd->wi) < 0.0f);
if (backfacing) {
sd->flag |= SD_BACKFACING;
@ -341,7 +341,7 @@ ccl_device void shader_setup_from_curve(KernelGlobals kg,
}
/* No view direction, normals or bitangent. */
sd->I = zero_float3();
sd->wi = zero_float3();
sd->N = zero_float3();
sd->Ng = zero_float3();
#ifdef __DPDU__
@ -372,7 +372,7 @@ ccl_device_inline void shader_setup_from_background(KernelGlobals kg,
sd->P = ray_D;
sd->N = -ray_D;
sd->Ng = -ray_D;
sd->I = -ray_D;
sd->wi = -ray_D;
sd->shader = kernel_data.background.surface_shader;
sd->flag = kernel_data_fetch(shaders, (sd->shader & SHADER_MASK)).flags;
sd->object_flag = 0;
@ -412,7 +412,7 @@ ccl_device_inline void shader_setup_from_volume(KernelGlobals kg,
sd->P = ray->P + ray->D * ray->tmin;
sd->N = -ray->D;
sd->Ng = -ray->D;
sd->I = -ray->D;
sd->wi = -ray->D;
sd->shader = SHADER_NONE;
sd->flag = 0;
sd->object_flag = 0;

View File

@ -44,7 +44,7 @@ ccl_device_forceinline void guiding_record_surface_segment(KernelGlobals kg,
state->guiding.path_segment = kg->opgl_path_segment_storage->NextSegment();
openpgl::cpp::SetPosition(state->guiding.path_segment, guiding_point3f(sd->P));
openpgl::cpp::SetDirectionOut(state->guiding.path_segment, guiding_vec3f(sd->I));
openpgl::cpp::SetDirectionOut(state->guiding.path_segment, guiding_vec3f(sd->wi));
openpgl::cpp::SetVolumeScatter(state->guiding.path_segment, false);
openpgl::cpp::SetScatteredContribution(state->guiding.path_segment, zero);
openpgl::cpp::SetDirectContribution(state->guiding.path_segment, zero);
@ -60,7 +60,7 @@ ccl_device_forceinline void guiding_record_surface_bounce(KernelGlobals kg,
const Spectrum weight,
const float pdf,
const float3 N,
const float3 omega_in,
const float3 wo,
const float2 roughness,
const float eta)
{
@ -78,7 +78,7 @@ ccl_device_forceinline void guiding_record_surface_bounce(KernelGlobals kg,
openpgl::cpp::SetTransmittanceWeight(state->guiding.path_segment, guiding_vec3f(one_float3()));
openpgl::cpp::SetVolumeScatter(state->guiding.path_segment, false);
openpgl::cpp::SetNormal(state->guiding.path_segment, guiding_vec3f(normal));
openpgl::cpp::SetDirectionIn(state->guiding.path_segment, guiding_vec3f(omega_in));
openpgl::cpp::SetDirectionIn(state->guiding.path_segment, guiding_vec3f(wo));
openpgl::cpp::SetPDFDirectionIn(state->guiding.path_segment, pdf);
openpgl::cpp::SetScatteringWeight(state->guiding.path_segment, guiding_vec3f(weight_rgb));
openpgl::cpp::SetIsDelta(state->guiding.path_segment, is_delta);
@ -113,7 +113,7 @@ ccl_device_forceinline void guiding_record_surface_emission(KernelGlobals kg,
ccl_device_forceinline void guiding_record_bssrdf_segment(KernelGlobals kg,
IntegratorState state,
const float3 P,
const float3 I)
const float3 wi)
{
#if defined(__PATH_GUIDING__) && PATH_GUIDING_LEVEL >= 1
if (!kernel_data.integrator.train_guiding) {
@ -124,7 +124,7 @@ ccl_device_forceinline void guiding_record_bssrdf_segment(KernelGlobals kg,
state->guiding.path_segment = kg->opgl_path_segment_storage->NextSegment();
openpgl::cpp::SetPosition(state->guiding.path_segment, guiding_point3f(P));
openpgl::cpp::SetDirectionOut(state->guiding.path_segment, guiding_vec3f(I));
openpgl::cpp::SetDirectionOut(state->guiding.path_segment, guiding_vec3f(wi));
openpgl::cpp::SetVolumeScatter(state->guiding.path_segment, true);
openpgl::cpp::SetScatteredContribution(state->guiding.path_segment, zero);
openpgl::cpp::SetDirectContribution(state->guiding.path_segment, zero);
@ -166,7 +166,7 @@ ccl_device_forceinline void guiding_record_bssrdf_bounce(KernelGlobals kg,
IntegratorState state,
const float pdf,
const float3 N,
const float3 omega_in,
const float3 wo,
const Spectrum weight,
const Spectrum albedo)
{
@ -181,7 +181,7 @@ ccl_device_forceinline void guiding_record_bssrdf_bounce(KernelGlobals kg,
openpgl::cpp::SetVolumeScatter(state->guiding.path_segment, false);
openpgl::cpp::SetNormal(state->guiding.path_segment, guiding_vec3f(normal));
openpgl::cpp::SetDirectionIn(state->guiding.path_segment, guiding_vec3f(omega_in));
openpgl::cpp::SetDirectionIn(state->guiding.path_segment, guiding_vec3f(wo));
openpgl::cpp::SetPDFDirectionIn(state->guiding.path_segment, pdf);
openpgl::cpp::SetTransmittanceWeight(state->guiding.path_segment, guiding_vec3f(weight_rgb));
#endif
@ -222,7 +222,7 @@ ccl_device_forceinline void guiding_record_volume_bounce(KernelGlobals kg,
ccl_private const ShaderData *sd,
const Spectrum weight,
const float pdf,
const float3 omega_in,
const float3 wo,
const float roughness)
{
#if defined(__PATH_GUIDING__) && PATH_GUIDING_LEVEL >= 4
@ -237,7 +237,7 @@ ccl_device_forceinline void guiding_record_volume_bounce(KernelGlobals kg,
openpgl::cpp::SetVolumeScatter(state->guiding.path_segment, true);
openpgl::cpp::SetTransmittanceWeight(state->guiding.path_segment, guiding_vec3f(one_float3()));
openpgl::cpp::SetNormal(state->guiding.path_segment, guiding_vec3f(normal));
openpgl::cpp::SetDirectionIn(state->guiding.path_segment, guiding_vec3f(omega_in));
openpgl::cpp::SetDirectionIn(state->guiding.path_segment, guiding_vec3f(wo));
openpgl::cpp::SetPDFDirectionIn(state->guiding.path_segment, pdf);
openpgl::cpp::SetScatteringWeight(state->guiding.path_segment, guiding_vec3f(weight_rgb));
openpgl::cpp::SetIsDelta(state->guiding.path_segment, false);
@ -467,13 +467,13 @@ ccl_device_forceinline bool guiding_bsdf_init(KernelGlobals kg,
ccl_device_forceinline float guiding_bsdf_sample(KernelGlobals kg,
IntegratorState state,
const float2 rand_bsdf,
ccl_private float3 *omega_in)
ccl_private float3 *wo)
{
#if defined(__PATH_GUIDING__) && PATH_GUIDING_LEVEL >= 4
pgl_vec3f wo;
pgl_vec3f pgl_wo;
const pgl_point2f rand = openpgl::cpp::Point2(rand_bsdf.x, rand_bsdf.y);
const float pdf = kg->opgl_surface_sampling_distribution->SamplePDF(rand, wo);
*omega_in = make_float3(wo.x, wo.y, wo.z);
const float pdf = kg->opgl_surface_sampling_distribution->SamplePDF(rand, pgl_wo);
*wo = make_float3(pgl_wo.x, pgl_wo.y, pgl_wo.z);
return pdf;
#else
return 0.0f;
@ -482,10 +482,10 @@ ccl_device_forceinline float guiding_bsdf_sample(KernelGlobals kg,
ccl_device_forceinline float guiding_bsdf_pdf(KernelGlobals kg,
IntegratorState state,
const float3 omega_in)
const float3 wo)
{
#if defined(__PATH_GUIDING__) && PATH_GUIDING_LEVEL >= 4
return kg->opgl_surface_sampling_distribution->PDF(guiding_vec3f(omega_in));
return kg->opgl_surface_sampling_distribution->PDF(guiding_vec3f(wo));
#else
return 0.0f;
#endif
@ -520,13 +520,13 @@ ccl_device_forceinline bool guiding_phase_init(KernelGlobals kg,
ccl_device_forceinline float guiding_phase_sample(KernelGlobals kg,
IntegratorState state,
const float2 rand_phase,
ccl_private float3 *omega_in)
ccl_private float3 *wo)
{
#if defined(__PATH_GUIDING__) && PATH_GUIDING_LEVEL >= 4
pgl_vec3f wo;
pgl_vec3f pgl_wo;
const pgl_point2f rand = openpgl::cpp::Point2(rand_phase.x, rand_phase.y);
const float pdf = kg->opgl_volume_sampling_distribution->SamplePDF(rand, wo);
*omega_in = make_float3(wo.x, wo.y, wo.z);
const float pdf = kg->opgl_volume_sampling_distribution->SamplePDF(rand, pgl_wo);
*wo = make_float3(pgl_wo.x, pgl_wo.y, pgl_wo.z);
return pdf;
#else
return 0.0f;
@ -535,10 +535,10 @@ ccl_device_forceinline float guiding_phase_sample(KernelGlobals kg,
ccl_device_forceinline float guiding_phase_pdf(KernelGlobals kg,
IntegratorState state,
const float3 omega_in)
const float3 wo)
{
#if defined(__PATH_GUIDING__) && PATH_GUIDING_LEVEL >= 4
return kg->opgl_volume_sampling_distribution->PDF(guiding_vec3f(omega_in));
return kg->opgl_volume_sampling_distribution->PDF(guiding_vec3f(wo));
#else
return 0.0f;
#endif

View File

@ -607,11 +607,11 @@ ccl_device_forceinline Spectrum mnee_eval_bsdf_contribution(ccl_private ShaderCl
{
ccl_private MicrofacetBsdf *bsdf = (ccl_private MicrofacetBsdf *)closure;
float cosNO = dot(bsdf->N, wi);
float cosNI = dot(bsdf->N, wo);
float cosNI = dot(bsdf->N, wi);
float cosNO = dot(bsdf->N, wo);
float3 Ht = normalize(-(bsdf->ior * wo + wi));
float cosHO = dot(Ht, wi);
float cosHI = dot(Ht, wi);
float alpha2 = bsdf->alpha_x * bsdf->alpha_y;
float cosThetaM = dot(bsdf->N, Ht);
@ -619,12 +619,12 @@ ccl_device_forceinline Spectrum mnee_eval_bsdf_contribution(ccl_private ShaderCl
float G;
if (bsdf->type == CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID) {
/* Eq. 26, 27: now calculate G1(i,m) and G1(o,m). */
G = bsdf_beckmann_G1(bsdf->alpha_x, cosNO) * bsdf_beckmann_G1(bsdf->alpha_x, cosNI);
G = bsdf_beckmann_G1(bsdf->alpha_x, cosNI) * bsdf_beckmann_G1(bsdf->alpha_x, cosNO);
}
else { /* bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID assumed */
/* Eq. 34: now calculate G1(i,m) and G1(o,m). */
G = (2.f / (1.f + safe_sqrtf(1.f + alpha2 * (1.f - cosNO * cosNO) / (cosNO * cosNO)))) *
(2.f / (1.f + safe_sqrtf(1.f + alpha2 * (1.f - cosNI * cosNI) / (cosNI * cosNI))));
G = (2.f / (1.f + safe_sqrtf(1.f + alpha2 * (1.f - cosNI * cosNI) / (cosNI * cosNI)))) *
(2.f / (1.f + safe_sqrtf(1.f + alpha2 * (1.f - cosNO * cosNO) / (cosNO * cosNO))));
}
/*
@ -635,7 +635,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)|
*/
return bsdf->weight * G * fabsf(cosHO / (cosNO * sqr(cosThetaM)));
return bsdf->weight * G * fabsf(cosHI / (cosNI * sqr(cosThetaM)));
}
/* Compute transfer matrix determinant |T1| = |dx1/dxn| (and |dh/dx| in the process) */

View File

@ -364,7 +364,7 @@ ccl_device_forceinline int integrate_surface_bsdf_bssrdf_bounce(
/* BSDF closure, sample direction. */
float bsdf_pdf = 0.0f, unguided_bsdf_pdf = 0.0f;
BsdfEval bsdf_eval ccl_optional_struct_init;
float3 bsdf_omega_in ccl_optional_struct_init;
float3 bsdf_wo ccl_optional_struct_init;
int label;
float2 bsdf_sampled_roughness = make_float2(1.0f, 1.0f);
@ -378,7 +378,7 @@ ccl_device_forceinline int integrate_surface_bsdf_bssrdf_bounce(
sc,
rand_bsdf,
&bsdf_eval,
&bsdf_omega_in,
&bsdf_wo,
&bsdf_pdf,
&unguided_bsdf_pdf,
&bsdf_sampled_roughness,
@ -398,7 +398,7 @@ ccl_device_forceinline int integrate_surface_bsdf_bssrdf_bounce(
sc,
rand_bsdf,
&bsdf_eval,
&bsdf_omega_in,
&bsdf_wo,
&bsdf_pdf,
&bsdf_sampled_roughness,
&bsdf_eta);
@ -416,7 +416,7 @@ ccl_device_forceinline int integrate_surface_bsdf_bssrdf_bounce(
}
else {
/* Setup ray with changed origin and direction. */
const float3 D = normalize(bsdf_omega_in);
const float3 D = normalize(bsdf_wo);
INTEGRATOR_STATE_WRITE(state, ray, P) = integrate_surface_ray_offset(kg, sd, sd->P, D);
INTEGRATOR_STATE_WRITE(state, ray, D) = D;
INTEGRATOR_STATE_WRITE(state, ray, tmin) = 0.0f;
@ -455,7 +455,7 @@ ccl_device_forceinline int integrate_surface_bsdf_bssrdf_bounce(
bsdf_weight,
bsdf_pdf,
sd->N,
normalize(bsdf_omega_in),
normalize(bsdf_wo),
bsdf_sampled_roughness,
bsdf_eta);

View File

@ -912,7 +912,7 @@ ccl_device_forceinline bool integrate_volume_phase_scatter(
/* Phase closure, sample direction. */
float phase_pdf = 0.0f, unguided_phase_pdf = 0.0f;
BsdfEval phase_eval ccl_optional_struct_init;
float3 phase_omega_in ccl_optional_struct_init;
float3 phase_wo ccl_optional_struct_init;
float sampled_roughness = 1.0f;
int label;
@ -924,7 +924,7 @@ ccl_device_forceinline bool integrate_volume_phase_scatter(
svc,
rand_phase,
&phase_eval,
&phase_omega_in,
&phase_wo,
&phase_pdf,
&unguided_phase_pdf,
&sampled_roughness);
@ -938,15 +938,8 @@ ccl_device_forceinline bool integrate_volume_phase_scatter(
else
# endif
{
label = volume_shader_phase_sample(kg,
sd,
phases,
svc,
rand_phase,
&phase_eval,
&phase_omega_in,
&phase_pdf,
&sampled_roughness);
label = volume_shader_phase_sample(
kg, sd, phases, svc, rand_phase, &phase_eval, &phase_wo, &phase_pdf, &sampled_roughness);
if (phase_pdf == 0.0f || bsdf_eval_is_zero(&phase_eval)) {
return false;
@ -957,7 +950,7 @@ ccl_device_forceinline bool integrate_volume_phase_scatter(
/* Setup ray. */
INTEGRATOR_STATE_WRITE(state, ray, P) = sd->P;
INTEGRATOR_STATE_WRITE(state, ray, D) = normalize(phase_omega_in);
INTEGRATOR_STATE_WRITE(state, ray, D) = normalize(phase_wo);
INTEGRATOR_STATE_WRITE(state, ray, tmin) = 0.0f;
INTEGRATOR_STATE_WRITE(state, ray, tmax) = FLT_MAX;
# ifdef __RAY_DIFFERENTIALS__
@ -971,7 +964,7 @@ ccl_device_forceinline bool integrate_volume_phase_scatter(
/* Add phase function sampling data to the path segment. */
guiding_record_volume_bounce(
kg, state, sd, phase_weight, phase_pdf, normalize(phase_omega_in), sampled_roughness);
kg, state, sd, phase_weight, phase_pdf, normalize(phase_wo), sampled_roughness);
/* Update throughput. */
const Spectrum throughput = INTEGRATOR_STATE(state, path, throughput);
@ -1076,7 +1069,7 @@ ccl_device VolumeIntegrateEvent volume_integrate(KernelGlobals kg,
float3 transmittance_weight = spectrum_to_rgb(
safe_divide_color(result.indirect_throughput, initial_throughput));
guiding_record_volume_transmission(kg, state, transmittance_weight);
guiding_record_volume_segment(kg, state, direct_P, sd.I);
guiding_record_volume_segment(kg, state, direct_P, sd.wi);
guiding_generated_new_segment = true;
unlit_throughput = result.indirect_throughput / continuation_probability;
rand_phase_guiding = path_state_rng_1D(kg, &rng_state, PRNG_VOLUME_PHASE_GUIDING_DISTANCE);
@ -1139,7 +1132,7 @@ ccl_device VolumeIntegrateEvent volume_integrate(KernelGlobals kg,
# if defined(__PATH_GUIDING__)
# if PATH_GUIDING_LEVEL >= 1
if (!guiding_generated_new_segment) {
guiding_record_volume_segment(kg, state, sd.P, sd.I);
guiding_record_volume_segment(kg, state, sd.P, sd.wi);
}
# endif
# if PATH_GUIDING_LEVEL >= 4

View File

@ -174,14 +174,14 @@ ccl_device_inline void surface_shader_prepare_closures(KernelGlobals kg,
#if 0
ccl_device_inline void surface_shader_validate_bsdf_sample(const KernelGlobals kg,
const ShaderClosure *sc,
const float3 omega_in,
const float3 wo,
const int org_label,
const float2 org_roughness,
const float org_eta)
{
/* Validate the the bsdf_label and bsdf_roughness_eta functions
* by estimating the values after a bsdf sample. */
const int comp_label = bsdf_label(kg, sc, omega_in);
const int comp_label = bsdf_label(kg, sc, wo);
kernel_assert(org_label == comp_label);
float2 comp_roughness;
@ -218,7 +218,7 @@ ccl_device_forceinline bool _surface_shader_exclude(ClosureType type, uint light
ccl_device_inline float _surface_shader_bsdf_eval_mis(KernelGlobals kg,
ccl_private ShaderData *sd,
const float3 omega_in,
const float3 wo,
ccl_private const ShaderClosure *skip_sc,
ccl_private BsdfEval *result_eval,
float sum_pdf,
@ -237,7 +237,7 @@ ccl_device_inline float _surface_shader_bsdf_eval_mis(KernelGlobals kg,
if (CLOSURE_IS_BSDF_OR_BSSRDF(sc->type)) {
if (CLOSURE_IS_BSDF(sc->type) && !_surface_shader_exclude(sc->type, light_shader_flags)) {
float bsdf_pdf = 0.0f;
Spectrum eval = bsdf_eval(kg, sd, sc, omega_in, &bsdf_pdf);
Spectrum eval = bsdf_eval(kg, sd, sc, wo, &bsdf_pdf);
if (bsdf_pdf != 0.0f) {
bsdf_eval_accum(result_eval, sc->type, eval * sc->weight);
@ -254,7 +254,7 @@ ccl_device_inline float _surface_shader_bsdf_eval_mis(KernelGlobals kg,
ccl_device_inline float surface_shader_bsdf_eval_pdfs(const KernelGlobals kg,
ccl_private ShaderData *sd,
const float3 omega_in,
const float3 wo,
ccl_private BsdfEval *result_eval,
ccl_private float *pdfs,
const uint light_shader_flags)
@ -270,7 +270,7 @@ ccl_device_inline float surface_shader_bsdf_eval_pdfs(const KernelGlobals kg,
if (CLOSURE_IS_BSDF_OR_BSSRDF(sc->type)) {
if (CLOSURE_IS_BSDF(sc->type) && !_surface_shader_exclude(sc->type, light_shader_flags)) {
float bsdf_pdf = 0.0f;
Spectrum eval = bsdf_eval(kg, sd, sc, omega_in, &bsdf_pdf);
Spectrum eval = bsdf_eval(kg, sd, sc, wo, &bsdf_pdf);
kernel_assert(bsdf_pdf >= 0.0f);
if (bsdf_pdf != 0.0f) {
bsdf_eval_accum(result_eval, sc->type, eval * sc->weight);
@ -310,20 +310,20 @@ ccl_device_inline
surface_shader_bsdf_eval(KernelGlobals kg,
IntegratorState state,
ccl_private ShaderData *sd,
const float3 omega_in,
const float3 wo,
ccl_private BsdfEval *bsdf_eval,
const uint light_shader_flags)
{
bsdf_eval_init(bsdf_eval, CLOSURE_NONE_ID, zero_spectrum());
float pdf = _surface_shader_bsdf_eval_mis(
kg, sd, omega_in, NULL, bsdf_eval, 0.0f, 0.0f, light_shader_flags);
kg, sd, wo, NULL, bsdf_eval, 0.0f, 0.0f, light_shader_flags);
#if defined(__PATH_GUIDING__) && PATH_GUIDING_LEVEL >= 4
if (state->guiding.use_surface_guiding) {
const float guiding_sampling_prob = state->guiding.surface_guiding_sampling_prob;
const float bssrdf_sampling_prob = state->guiding.bssrdf_sampling_prob;
const float guide_pdf = guiding_bsdf_pdf(kg, state, omega_in);
const float guide_pdf = guiding_bsdf_pdf(kg, state, wo);
pdf = (guiding_sampling_prob * guide_pdf * (1.0f - bssrdf_sampling_prob)) +
(1.0f - guiding_sampling_prob) * pdf;
}
@ -407,7 +407,7 @@ ccl_device int surface_shader_bsdf_guided_sample_closure(KernelGlobals kg,
ccl_private const ShaderClosure *sc,
const float2 rand_bsdf,
ccl_private BsdfEval *bsdf_eval,
ccl_private float3 *omega_in,
ccl_private float3 *wo,
ccl_private float *bsdf_pdf,
ccl_private float *unguided_bsdf_pdf,
ccl_private float2 *sampled_rougness,
@ -443,14 +443,14 @@ ccl_device int surface_shader_bsdf_guided_sample_closure(KernelGlobals kg,
if (sample_guiding) {
/* Sample guiding distribution. */
guide_pdf = guiding_bsdf_sample(kg, state, rand_bsdf, omega_in);
guide_pdf = guiding_bsdf_sample(kg, state, rand_bsdf, wo);
*bsdf_pdf = 0.0f;
if (guide_pdf != 0.0f) {
float unguided_bsdf_pdfs[MAX_CLOSURE];
*unguided_bsdf_pdf = surface_shader_bsdf_eval_pdfs(
kg, sd, *omega_in, bsdf_eval, unguided_bsdf_pdfs, 0);
kg, sd, *wo, bsdf_eval, unguided_bsdf_pdfs, 0);
*bsdf_pdf = (guiding_sampling_prob * guide_pdf * (1.0f - bssrdf_sampling_prob)) +
((1.0f - guiding_sampling_prob) * (*unguided_bsdf_pdf));
float sum_pdfs = 0.0f;
@ -471,7 +471,7 @@ ccl_device int surface_shader_bsdf_guided_sample_closure(KernelGlobals kg,
* the sum of all unguided_bsdf_pdfs is just < 1.0f. */
idx = (rand_bsdf_guiding > sum_pdfs) ? sd->num_closure - 1 : idx;
label = bsdf_label(kg, &sd->closure[idx], *omega_in);
label = bsdf_label(kg, &sd->closure[idx], *wo);
}
}
@ -483,19 +483,11 @@ ccl_device int surface_shader_bsdf_guided_sample_closure(KernelGlobals kg,
else {
/* Sample BSDF. */
*bsdf_pdf = 0.0f;
label = bsdf_sample(kg,
sd,
sc,
rand_bsdf.x,
rand_bsdf.y,
&eval,
omega_in,
unguided_bsdf_pdf,
sampled_rougness,
eta);
label = bsdf_sample(
kg, sd, sc, rand_bsdf.x, rand_bsdf.y, &eval, wo, unguided_bsdf_pdf, sampled_rougness, eta);
# if 0
if (*unguided_bsdf_pdf > 0.0f) {
surface_shader_validate_bsdf_sample(kg, sc, *omega_in, label, sampled_roughness, eta);
surface_shader_validate_bsdf_sample(kg, sc, *wo, label, sampled_roughness, eta);
}
# endif
@ -507,13 +499,13 @@ ccl_device int surface_shader_bsdf_guided_sample_closure(KernelGlobals kg,
if (sd->num_closure > 1) {
float sweight = sc->sample_weight;
*unguided_bsdf_pdf = _surface_shader_bsdf_eval_mis(
kg, sd, *omega_in, sc, bsdf_eval, (*unguided_bsdf_pdf) * sweight, sweight, 0);
kg, sd, *wo, sc, bsdf_eval, (*unguided_bsdf_pdf) * sweight, sweight, 0);
kernel_assert(reduce_min(bsdf_eval_sum(bsdf_eval)) >= 0.0f);
}
*bsdf_pdf = *unguided_bsdf_pdf;
if (use_surface_guiding) {
guide_pdf = guiding_bsdf_pdf(kg, state, *omega_in);
guide_pdf = guiding_bsdf_pdf(kg, state, *wo);
*bsdf_pdf *= 1.0f - guiding_sampling_prob;
*bsdf_pdf += guiding_sampling_prob * guide_pdf * (1.0f - bssrdf_sampling_prob);
}
@ -533,7 +525,7 @@ ccl_device int surface_shader_bsdf_sample_closure(KernelGlobals kg,
ccl_private const ShaderClosure *sc,
const float2 rand_bsdf,
ccl_private BsdfEval *bsdf_eval,
ccl_private float3 *omega_in,
ccl_private float3 *wo,
ccl_private float *pdf,
ccl_private float2 *sampled_roughness,
ccl_private float *eta)
@ -546,15 +538,14 @@ ccl_device int surface_shader_bsdf_sample_closure(KernelGlobals kg,
*pdf = 0.0f;
label = bsdf_sample(
kg, sd, sc, rand_bsdf.x, rand_bsdf.y, &eval, omega_in, pdf, sampled_roughness, eta);
kg, sd, sc, rand_bsdf.x, rand_bsdf.y, &eval, wo, pdf, sampled_roughness, eta);
if (*pdf != 0.0f) {
bsdf_eval_init(bsdf_eval, sc->type, eval * sc->weight);
if (sd->num_closure > 1) {
float sweight = sc->sample_weight;
*pdf = _surface_shader_bsdf_eval_mis(
kg, sd, *omega_in, sc, bsdf_eval, *pdf * sweight, sweight, 0);
*pdf = _surface_shader_bsdf_eval_mis(kg, sd, *wo, sc, bsdf_eval, *pdf * sweight, sweight, 0);
}
}
else {
@ -758,7 +749,7 @@ ccl_device Spectrum surface_shader_background(ccl_private const ShaderData *sd)
ccl_device Spectrum surface_shader_emission(ccl_private const ShaderData *sd)
{
if (sd->flag & SD_EMISSION) {
return emissive_simple_eval(sd->Ng, sd->I) * sd->closure_emission_background;
return emissive_simple_eval(sd->Ng, sd->wi) * sd->closure_emission_background;
}
else {
return zero_spectrum();

View File

@ -202,7 +202,7 @@ ccl_device_inline ccl_private const ShaderVolumeClosure *volume_shader_phase_pic
ccl_device_inline float _volume_shader_phase_eval_mis(ccl_private const ShaderData *sd,
ccl_private const ShaderVolumePhases *phases,
const float3 omega_in,
const float3 wo,
int skip_phase,
ccl_private BsdfEval *result_eval,
float sum_pdf,
@ -214,7 +214,7 @@ ccl_device_inline float _volume_shader_phase_eval_mis(ccl_private const ShaderDa
ccl_private const ShaderVolumeClosure *svc = &phases->closure[i];
float phase_pdf = 0.0f;
Spectrum eval = volume_phase_eval(sd, svc, omega_in, &phase_pdf);
Spectrum eval = volume_phase_eval(sd, svc, wo, &phase_pdf);
if (phase_pdf != 0.0f) {
bsdf_eval_accum(result_eval, CLOSURE_VOLUME_HENYEY_GREENSTEIN_ID, eval);
@ -230,11 +230,11 @@ ccl_device_inline float _volume_shader_phase_eval_mis(ccl_private const ShaderDa
ccl_device float volume_shader_phase_eval(KernelGlobals kg,
ccl_private const ShaderData *sd,
ccl_private const ShaderVolumeClosure *svc,
const float3 omega_in,
const float3 wo,
ccl_private BsdfEval *phase_eval)
{
float phase_pdf = 0.0f;
Spectrum eval = volume_phase_eval(sd, svc, omega_in, &phase_pdf);
Spectrum eval = volume_phase_eval(sd, svc, wo, &phase_pdf);
if (phase_pdf != 0.0f) {
bsdf_eval_accum(phase_eval, CLOSURE_VOLUME_HENYEY_GREENSTEIN_ID, eval);
@ -247,17 +247,17 @@ ccl_device float volume_shader_phase_eval(KernelGlobals kg,
IntegratorState state,
ccl_private const ShaderData *sd,
ccl_private const ShaderVolumePhases *phases,
const float3 omega_in,
const float3 wo,
ccl_private BsdfEval *phase_eval)
{
bsdf_eval_init(phase_eval, CLOSURE_VOLUME_HENYEY_GREENSTEIN_ID, zero_spectrum());
float pdf = _volume_shader_phase_eval_mis(sd, phases, omega_in, -1, phase_eval, 0.0f, 0.0f);
float pdf = _volume_shader_phase_eval_mis(sd, phases, wo, -1, phase_eval, 0.0f, 0.0f);
# if defined(__PATH_GUIDING__) && PATH_GUIDING_LEVEL >= 4
if (state->guiding.use_volume_guiding) {
const float guiding_sampling_prob = state->guiding.volume_guiding_sampling_prob;
const float guide_pdf = guiding_phase_pdf(kg, state, omega_in);
const float guide_pdf = guiding_phase_pdf(kg, state, wo);
pdf = (guiding_sampling_prob * guide_pdf) + (1.0f - guiding_sampling_prob) * pdf;
}
# endif
@ -272,7 +272,7 @@ ccl_device int volume_shader_phase_guided_sample(KernelGlobals kg,
ccl_private const ShaderVolumeClosure *svc,
const float2 rand_phase,
ccl_private BsdfEval *phase_eval,
ccl_private float3 *omega_in,
ccl_private float3 *wo,
ccl_private float *phase_pdf,
ccl_private float *unguided_phase_pdf,
ccl_private float *sampled_roughness)
@ -304,11 +304,11 @@ ccl_device int volume_shader_phase_guided_sample(KernelGlobals kg,
if (sample_guiding) {
/* Sample guiding distribution. */
guide_pdf = guiding_phase_sample(kg, state, rand_phase, omega_in);
guide_pdf = guiding_phase_sample(kg, state, rand_phase, wo);
*phase_pdf = 0.0f;
if (guide_pdf != 0.0f) {
*unguided_phase_pdf = volume_shader_phase_eval(kg, sd, svc, *omega_in, phase_eval);
*unguided_phase_pdf = volume_shader_phase_eval(kg, sd, svc, *wo, phase_eval);
*phase_pdf = (guiding_sampling_prob * guide_pdf) +
((1.0f - guiding_sampling_prob) * (*unguided_phase_pdf));
label = LABEL_VOLUME_SCATTER;
@ -318,14 +318,14 @@ ccl_device int volume_shader_phase_guided_sample(KernelGlobals kg,
/* Sample phase. */
*phase_pdf = 0.0f;
label = volume_phase_sample(
sd, svc, rand_phase.x, rand_phase.y, &eval, omega_in, unguided_phase_pdf);
sd, svc, rand_phase.x, rand_phase.y, &eval, wo, unguided_phase_pdf);
if (*unguided_phase_pdf != 0.0f) {
bsdf_eval_init(phase_eval, CLOSURE_VOLUME_HENYEY_GREENSTEIN_ID, eval);
*phase_pdf = *unguided_phase_pdf;
if (use_volume_guiding) {
guide_pdf = guiding_phase_pdf(kg, state, *omega_in);
guide_pdf = guiding_phase_pdf(kg, state, *wo);
*phase_pdf *= 1.0f - guiding_sampling_prob;
*phase_pdf += guiding_sampling_prob * guide_pdf;
}
@ -349,7 +349,7 @@ ccl_device int volume_shader_phase_sample(KernelGlobals kg,
ccl_private const ShaderVolumeClosure *svc,
float2 rand_phase,
ccl_private BsdfEval *phase_eval,
ccl_private float3 *omega_in,
ccl_private float3 *wo,
ccl_private float *pdf,
ccl_private float *sampled_roughness)
{
@ -357,7 +357,7 @@ ccl_device int volume_shader_phase_sample(KernelGlobals kg,
Spectrum eval = zero_spectrum();
*pdf = 0.0f;
int label = volume_phase_sample(sd, svc, rand_phase.x, rand_phase.y, &eval, omega_in, pdf);
int label = volume_phase_sample(sd, svc, rand_phase.x, rand_phase.y, &eval, wo, pdf);
if (*pdf != 0.0f) {
bsdf_eval_init(phase_eval, CLOSURE_VOLUME_HENYEY_GREENSTEIN_ID, eval);

View File

@ -63,7 +63,7 @@ ccl_device_forceinline float triangle_light_pdf(KernelGlobals kg,
const float3 e2 = V[2] - V[1];
const float longest_edge_squared = max(len_squared(e0), max(len_squared(e1), len_squared(e2)));
const float3 N = cross(e0, e1);
const float distance_to_plane = fabsf(dot(N, sd->I * t)) / dot(N, N);
const float distance_to_plane = fabsf(dot(N, sd->wi * t)) / dot(N, N);
const float area = 0.5f * len(N);
float pdf;
@ -71,7 +71,7 @@ ccl_device_forceinline float triangle_light_pdf(KernelGlobals kg,
if (longest_edge_squared > distance_to_plane * distance_to_plane) {
/* sd contains the point on the light source
* calculate Px, the point that we're shading */
const float3 Px = sd->P + sd->I * t;
const float3 Px = sd->P + sd->wi * t;
const float3 v0_p = V[0] - Px;
const float3 v1_p = V[1] - Px;
const float3 v2_p = V[2] - Px;
@ -99,7 +99,7 @@ ccl_device_forceinline float triangle_light_pdf(KernelGlobals kg,
return 0.0f;
}
pdf = triangle_light_pdf_area_sampling(sd->Ng, sd->I, t) / area;
pdf = triangle_light_pdf_area_sampling(sd->Ng, sd->wi, t) / area;
}
/* Belongs in distribution.h but can reuse computations here. */

View File

@ -80,7 +80,7 @@ ccl_device void osl_closure_diffuse_setup(KernelGlobals kg,
return;
}
bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N);
bsdf->N = ensure_valid_reflection(sd->Ng, sd->wi, closure->N);
sd->flag |= bsdf_diffuse_setup(bsdf);
}
@ -101,7 +101,7 @@ ccl_device void osl_closure_oren_nayar_setup(KernelGlobals kg,
return;
}
bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N);
bsdf->N = ensure_valid_reflection(sd->Ng, sd->wi, closure->N);
bsdf->roughness = closure->roughness;
sd->flag |= bsdf_oren_nayar_setup(bsdf);
@ -123,7 +123,7 @@ ccl_device void osl_closure_translucent_setup(KernelGlobals kg,
return;
}
bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N);
bsdf->N = ensure_valid_reflection(sd->Ng, sd->wi, closure->N);
sd->flag |= bsdf_translucent_setup(bsdf);
}
@ -144,7 +144,7 @@ ccl_device void osl_closure_reflection_setup(KernelGlobals kg,
return;
}
bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N);
bsdf->N = ensure_valid_reflection(sd->Ng, sd->wi, closure->N);
sd->flag |= bsdf_reflection_setup(bsdf);
}
@ -165,7 +165,7 @@ ccl_device void osl_closure_refraction_setup(KernelGlobals kg,
return;
}
bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N);
bsdf->N = ensure_valid_reflection(sd->Ng, sd->wi, closure->N);
bsdf->ior = closure->ior;
sd->flag |= bsdf_refraction_setup(bsdf);
@ -199,7 +199,7 @@ ccl_device void osl_closure_microfacet_setup(KernelGlobals kg,
return;
}
bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N);
bsdf->N = ensure_valid_reflection(sd->Ng, sd->wi, closure->N);
bsdf->alpha_x = closure->alpha_x;
bsdf->alpha_y = closure->alpha_y;
bsdf->ior = closure->ior;
@ -257,7 +257,7 @@ ccl_device void osl_closure_microfacet_ggx_setup(
return;
}
bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N);
bsdf->N = ensure_valid_reflection(sd->Ng, sd->wi, closure->N);
bsdf->alpha_x = closure->alpha_x;
sd->flag |= bsdf_microfacet_ggx_isotropic_setup(bsdf);
@ -280,7 +280,7 @@ ccl_device void osl_closure_microfacet_ggx_aniso_setup(
return;
}
bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N);
bsdf->N = ensure_valid_reflection(sd->Ng, sd->wi, closure->N);
bsdf->alpha_x = closure->alpha_x;
bsdf->alpha_y = closure->alpha_y;
bsdf->T = closure->T;
@ -305,7 +305,7 @@ ccl_device void osl_closure_microfacet_ggx_refraction_setup(
return;
}
bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N);
bsdf->N = ensure_valid_reflection(sd->Ng, sd->wi, closure->N);
bsdf->alpha_x = closure->alpha_x;
bsdf->ior = closure->ior;
@ -337,7 +337,7 @@ ccl_device void osl_closure_microfacet_ggx_fresnel_setup(
return;
}
bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N);
bsdf->N = ensure_valid_reflection(sd->Ng, sd->wi, closure->N);
bsdf->alpha_x = closure->alpha_x;
bsdf->alpha_y = bsdf->alpha_x;
bsdf->ior = closure->ior;
@ -375,7 +375,7 @@ ccl_device void osl_closure_microfacet_ggx_aniso_fresnel_setup(
return;
}
bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N);
bsdf->N = ensure_valid_reflection(sd->Ng, sd->wi, closure->N);
bsdf->alpha_x = closure->alpha_x;
bsdf->alpha_y = closure->alpha_y;
bsdf->ior = closure->ior;
@ -418,7 +418,7 @@ ccl_device void osl_closure_microfacet_multi_ggx_setup(
return;
}
bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N);
bsdf->N = ensure_valid_reflection(sd->Ng, sd->wi, closure->N);
bsdf->alpha_x = closure->alpha_x;
bsdf->alpha_y = bsdf->alpha_x;
bsdf->ior = 1.0f;
@ -459,7 +459,7 @@ ccl_device void osl_closure_microfacet_multi_ggx_glass_setup(
return;
}
bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N);
bsdf->N = ensure_valid_reflection(sd->Ng, sd->wi, closure->N);
bsdf->alpha_x = closure->alpha_x;
bsdf->alpha_y = bsdf->alpha_x;
bsdf->ior = closure->ior;
@ -500,7 +500,7 @@ ccl_device void osl_closure_microfacet_multi_ggx_aniso_setup(
return;
}
bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N);
bsdf->N = ensure_valid_reflection(sd->Ng, sd->wi, closure->N);
bsdf->alpha_x = closure->alpha_x;
bsdf->alpha_y = closure->alpha_y;
bsdf->ior = 1.0f;
@ -543,7 +543,7 @@ ccl_device void osl_closure_microfacet_multi_ggx_fresnel_setup(
return;
}
bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N);
bsdf->N = ensure_valid_reflection(sd->Ng, sd->wi, closure->N);
bsdf->alpha_x = closure->alpha_x;
bsdf->alpha_y = bsdf->alpha_x;
bsdf->ior = closure->ior;
@ -584,7 +584,7 @@ ccl_device void osl_closure_microfacet_multi_ggx_glass_fresnel_setup(
return;
}
bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N);
bsdf->N = ensure_valid_reflection(sd->Ng, sd->wi, closure->N);
bsdf->alpha_x = closure->alpha_x;
bsdf->alpha_y = bsdf->alpha_x;
bsdf->ior = closure->ior;
@ -625,7 +625,7 @@ ccl_device void osl_closure_microfacet_multi_ggx_aniso_fresnel_setup(
return;
}
bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N);
bsdf->N = ensure_valid_reflection(sd->Ng, sd->wi, closure->N);
bsdf->alpha_x = closure->alpha_x;
bsdf->alpha_y = closure->alpha_y;
bsdf->ior = closure->ior;
@ -659,7 +659,7 @@ ccl_device void osl_closure_microfacet_beckmann_setup(
return;
}
bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N);
bsdf->N = ensure_valid_reflection(sd->Ng, sd->wi, closure->N);
bsdf->alpha_x = closure->alpha_x;
sd->flag |= bsdf_microfacet_beckmann_isotropic_setup(bsdf);
@ -682,7 +682,7 @@ ccl_device void osl_closure_microfacet_beckmann_aniso_setup(
return;
}
bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N);
bsdf->N = ensure_valid_reflection(sd->Ng, sd->wi, closure->N);
bsdf->alpha_x = closure->alpha_x;
bsdf->alpha_y = closure->alpha_y;
bsdf->T = closure->T;
@ -707,7 +707,7 @@ ccl_device void osl_closure_microfacet_beckmann_refraction_setup(
return;
}
bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N);
bsdf->N = ensure_valid_reflection(sd->Ng, sd->wi, closure->N);
bsdf->alpha_x = closure->alpha_x;
bsdf->ior = closure->ior;
@ -733,7 +733,7 @@ ccl_device void osl_closure_ashikhmin_velvet_setup(
return;
}
bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N);
bsdf->N = ensure_valid_reflection(sd->Ng, sd->wi, closure->N);
bsdf->sigma = closure->sigma;
sd->flag |= bsdf_ashikhmin_velvet_setup(bsdf);
@ -756,7 +756,7 @@ ccl_device void osl_closure_ashikhmin_shirley_setup(
return;
}
bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N);
bsdf->N = ensure_valid_reflection(sd->Ng, sd->wi, closure->N);
bsdf->alpha_x = closure->alpha_x;
bsdf->alpha_y = closure->alpha_y;
bsdf->T = closure->T;
@ -780,7 +780,7 @@ ccl_device void osl_closure_diffuse_toon_setup(KernelGlobals kg,
return;
}
bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N);
bsdf->N = ensure_valid_reflection(sd->Ng, sd->wi, closure->N);
bsdf->size = closure->size;
bsdf->smooth = closure->smooth;
@ -803,7 +803,7 @@ ccl_device void osl_closure_glossy_toon_setup(KernelGlobals kg,
return;
}
bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N);
bsdf->N = ensure_valid_reflection(sd->Ng, sd->wi, closure->N);
bsdf->size = closure->size;
bsdf->smooth = closure->smooth;
@ -829,7 +829,7 @@ ccl_device void osl_closure_principled_diffuse_setup(
return;
}
bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N);
bsdf->N = ensure_valid_reflection(sd->Ng, sd->wi, closure->N);
bsdf->roughness = closure->roughness;
sd->flag |= bsdf_principled_diffuse_setup(bsdf);
@ -852,7 +852,7 @@ ccl_device void osl_closure_principled_sheen_setup(
return;
}
bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N);
bsdf->N = ensure_valid_reflection(sd->Ng, sd->wi, closure->N);
bsdf->avg_value = 0.0f;
sd->flag |= bsdf_principled_sheen_setup(sd, bsdf);
@ -876,7 +876,7 @@ ccl_device void osl_closure_principled_clearcoat_setup(
return;
}
bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N);
bsdf->N = ensure_valid_reflection(sd->Ng, sd->wi, closure->N);
bsdf->alpha_x = closure->clearcoat_roughness;
bsdf->alpha_y = closure->clearcoat_roughness;
bsdf->ior = 1.5f;
@ -948,7 +948,7 @@ ccl_device void osl_closure_diffuse_ramp_setup(KernelGlobals kg,
return;
}
bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N);
bsdf->N = ensure_valid_reflection(sd->Ng, sd->wi, closure->N);
bsdf->colors = (float3 *)closure_alloc_extra(sd, sizeof(float3) * 8);
if (!bsdf->colors) {
@ -973,7 +973,7 @@ ccl_device void osl_closure_phong_ramp_setup(KernelGlobals kg,
return;
}
bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N);
bsdf->N = ensure_valid_reflection(sd->Ng, sd->wi, closure->N);
bsdf->exponent = closure->exponent;
bsdf->colors = (float3 *)closure_alloc_extra(sd, sizeof(float3) * 8);
@ -1024,7 +1024,7 @@ ccl_device void osl_closure_bssrdf_setup(KernelGlobals kg,
/* create one closure per color channel */
bssrdf->albedo = closure->albedo;
bssrdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N);
bssrdf->N = ensure_valid_reflection(sd->Ng, sd->wi, closure->N);
bssrdf->roughness = closure->roughness;
bssrdf->anisotropy = clamp(closure->anisotropy, 0.0f, 0.9f);
@ -1049,7 +1049,7 @@ ccl_device void osl_closure_hair_reflection_setup(KernelGlobals kg,
return;
}
bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N);
bsdf->N = ensure_valid_reflection(sd->Ng, sd->wi, closure->N);
bsdf->T = closure->T;
bsdf->roughness1 = closure->roughness1;
bsdf->roughness2 = closure->roughness2;
@ -1075,7 +1075,7 @@ ccl_device void osl_closure_hair_transmission_setup(
return;
}
bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N);
bsdf->N = ensure_valid_reflection(sd->Ng, sd->wi, closure->N);
bsdf->T = closure->T;
bsdf->roughness1 = closure->roughness1;
bsdf->roughness2 = closure->roughness2;
@ -1107,7 +1107,7 @@ ccl_device void osl_closure_principled_hair_setup(KernelGlobals kg,
return;
}
bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N);
bsdf->N = ensure_valid_reflection(sd->Ng, sd->wi, closure->N);
bsdf->sigma = closure->sigma;
bsdf->v = closure->v;
bsdf->s = closure->s;

View File

@ -25,13 +25,13 @@ ccl_device_inline void shaderdata_to_shaderglobals(KernelGlobals kg,
ccl_private ShaderGlobals *globals)
{
const differential3 dP = differential_from_compact(sd->Ng, sd->dP);
const differential3 dI = differential_from_compact(sd->I, sd->dI);
const differential3 dI = differential_from_compact(sd->wi, sd->dI);
/* copy from shader data to shader globals */
globals->P = sd->P;
globals->dPdx = dP.dx;
globals->dPdy = dP.dy;
globals->I = sd->I;
globals->I = sd->wi;
globals->dIdx = dI.dx;
globals->dIdy = dI.dy;
globals->N = sd->N;

View File

@ -1720,8 +1720,8 @@ bool OSLRenderServices::getmessage(OSL::ShaderGlobals *sg,
return set_attribute_float3(f, type, derivatives, val);
}
else if (name == u_I) {
const differential3 dI = differential_from_compact(sd->I, sd->dI);
float3 f[3] = {sd->I, dI.dx, dI.dy};
const differential3 dI = differential_from_compact(sd->wi, sd->dI);
float3 f[3] = {sd->wi, dI.dx, dI.dy};
return set_attribute_float3(f, type, derivatives, val);
}
else if (name == u_u) {

View File

@ -111,8 +111,8 @@ shader node_principled_bsdf(string distribution = "Multiscatter GGX",
float eta = backfacing() ? 1.0 / f : f;
if (distribution == "GGX" || Roughness <= 5e-2) {
float cosNO = dot(Normal, I);
float Fr = fresnel_dielectric_cos(cosNO, eta);
float cosNI = dot(Normal, I);
float Fr = fresnel_dielectric_cos(cosNI, eta);
float refl_roughness = Roughness;
if (Roughness <= 1e-2)

View File

@ -33,19 +33,19 @@ ccl_device void make_orthonormals_tangent(const float3 N,
/* sample direction with cosine weighted distributed in hemisphere */
ccl_device_inline void sample_cos_hemisphere(
const float3 N, float randu, float randv, ccl_private float3 *omega_in, ccl_private float *pdf)
const float3 N, float randu, float randv, ccl_private float3 *wo, ccl_private float *pdf)
{
to_unit_disk(&randu, &randv);
float costheta = sqrtf(max(1.0f - randu * randu - randv * randv, 0.0f));
float3 T, B;
make_orthonormals(N, &T, &B);
*omega_in = randu * T + randv * B + costheta * N;
*wo = randu * T + randv * B + costheta * N;
*pdf = costheta * M_1_PI_F;
}
/* sample direction uniformly distributed in hemisphere */
ccl_device_inline void sample_uniform_hemisphere(
const float3 N, float randu, float randv, ccl_private float3 *omega_in, ccl_private float *pdf)
const float3 N, float randu, float randv, ccl_private float3 *wo, ccl_private float *pdf)
{
float z = randu;
float r = sqrtf(max(0.0f, 1.0f - z * z));
@ -55,7 +55,7 @@ ccl_device_inline void sample_uniform_hemisphere(
float3 T, B;
make_orthonormals(N, &T, &B);
*omega_in = x * T + y * B + z * N;
*wo = x * T + y * B + z * N;
*pdf = 0.5f * M_1_PI_F;
}
@ -64,7 +64,7 @@ ccl_device_inline void sample_uniform_cone(const float3 N,
float angle,
float randu,
float randv,
ccl_private float3 *omega_in,
ccl_private float3 *wo,
ccl_private float *pdf)
{
float zMin = cosf(angle);
@ -76,7 +76,7 @@ ccl_device_inline void sample_uniform_cone(const float3 N,
float3 T, B;
make_orthonormals(N, &T, &B);
*omega_in = x * T + y * B + z * N;
*wo = x * T + y * B + z * N;
*pdf = M_1_2PI_F / (1.0f - zMin);
}

View File

@ -102,7 +102,7 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg,
float3 N = stack_valid(data_node.x) ? stack_load_float3(stack, data_node.x) : sd->N;
if (!(sd->type & PRIMITIVE_CURVE)) {
N = ensure_valid_reflection(sd->Ng, sd->I, N);
N = ensure_valid_reflection(sd->Ng, sd->wi, N);
}
float param1 = (stack_valid(param1_offset)) ? stack_load_float(stack, param1_offset) :
@ -162,8 +162,8 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg,
float ior = (sd->flag & SD_BACKFACING) ? 1.0f / eta : eta;
// calculate fresnel for refraction
float cosNO = dot(N, sd->I);
float fresnel = fresnel_dielectric_cos(cosNO, ior);
float cosNI = dot(N, sd->wi);
float fresnel = fresnel_dielectric_cos(cosNI, ior);
// calculate weights of the diffuse and specular part
float diffuse_weight = (1.0f - saturatef(metallic)) * (1.0f - saturatef(transmission));
@ -185,7 +185,7 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg,
stack_load_float3(stack, data_cn_ssr.x) :
sd->N;
if (!(sd->type & PRIMITIVE_CURVE)) {
clearcoat_normal = ensure_valid_reflection(sd->Ng, sd->I, clearcoat_normal);
clearcoat_normal = ensure_valid_reflection(sd->Ng, sd->wi, clearcoat_normal);
}
float3 subsurface_radius = stack_valid(data_cn_ssr.y) ?
stack_load_float3(stack, data_cn_ssr.y) :
@ -652,8 +652,8 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg,
eta = (sd->flag & SD_BACKFACING) ? 1.0f / eta : eta;
/* fresnel */
float cosNO = dot(N, sd->I);
float fresnel = fresnel_dielectric_cos(cosNO, eta);
float cosNI = dot(N, sd->wi);
float fresnel = fresnel_dielectric_cos(cosNI, eta);
float roughness = sqr(param1);
/* reflection */

View File

@ -71,7 +71,7 @@ ccl_device_noinline void svm_node_set_bump(KernelGlobals kg,
object_normal_transform(kg, sd, &normal_out);
}
normal_out = ensure_valid_reflection(sd->Ng, sd->I, normal_out);
normal_out = ensure_valid_reflection(sd->Ng, sd->wi, normal_out);
stack_store_float3(stack, node.w, normal_out);
}
else

View File

@ -22,7 +22,7 @@ ccl_device_noinline void svm_node_fresnel(ccl_private ShaderData *sd,
eta = fmaxf(eta, 1e-5f);
eta = (sd->flag & SD_BACKFACING) ? 1.0f / eta : eta;
float f = fresnel_dielectric_cos(dot(sd->I, normal_in), eta);
float f = fresnel_dielectric_cos(dot(sd->wi, normal_in), eta);
stack_store_float(stack, out_offset, f);
}
@ -50,10 +50,10 @@ ccl_device_noinline void svm_node_layer_weight(ccl_private ShaderData *sd,
float eta = fmaxf(1.0f - blend, 1e-5f);
eta = (sd->flag & SD_BACKFACING) ? eta : 1.0f / eta;
f = fresnel_dielectric_cos(dot(sd->I, normal_in), eta);
f = fresnel_dielectric_cos(dot(sd->wi, normal_in), eta);
}
else {
f = fabsf(dot(sd->I, normal_in));
f = fabsf(dot(sd->wi, normal_in));
if (blend != 0.5f) {
blend = clamp(blend, 0.0f, 1.0f - 1e-5f);

View File

@ -28,7 +28,7 @@ ccl_device_noinline void svm_node_geometry(KernelGlobals kg,
break;
#endif
case NODE_GEOM_I:
data = sd->I;
data = sd->wi;
break;
case NODE_GEOM_Ng:
data = sd->Ng;

View File

@ -64,9 +64,9 @@ ccl_device_noinline int svm_node_tex_coord(KernelGlobals kg,
}
case NODE_TEXCO_REFLECTION: {
if (sd->object != OBJECT_NONE)
data = 2.0f * dot(sd->N, sd->I) * sd->N - sd->I;
data = 2.0f * dot(sd->N, sd->wi) * sd->N - sd->wi;
else
data = sd->I;
data = sd->wi;
break;
}
case NODE_TEXCO_DUPLI_GENERATED: {
@ -146,9 +146,9 @@ ccl_device_noinline int svm_node_tex_coord_bump_dx(KernelGlobals kg,
}
case NODE_TEXCO_REFLECTION: {
if (sd->object != OBJECT_NONE)
data = 2.0f * dot(sd->N, sd->I) * sd->N - sd->I;
data = 2.0f * dot(sd->N, sd->wi) * sd->N - sd->wi;
else
data = sd->I;
data = sd->wi;
break;
}
case NODE_TEXCO_DUPLI_GENERATED: {
@ -231,9 +231,9 @@ ccl_device_noinline int svm_node_tex_coord_bump_dy(KernelGlobals kg,
}
case NODE_TEXCO_REFLECTION: {
if (sd->object != OBJECT_NONE)
data = 2.0f * dot(sd->N, sd->I) * sd->N - sd->I;
data = 2.0f * dot(sd->N, sd->wi) * sd->N - sd->wi;
else
data = sd->I;
data = sd->wi;
break;
}
case NODE_TEXCO_DUPLI_GENERATED: {

View File

@ -47,8 +47,8 @@ ccl_device_inline float wireframe(KernelGlobals kg,
if (pixel_size) {
// Project the derivatives of P to the viewing plane defined
// by I so we have a measure of how big is a pixel at this point
float pixelwidth_x = len(dP.dx - dot(dP.dx, sd->I) * sd->I);
float pixelwidth_y = len(dP.dy - dot(dP.dy, sd->I) * sd->I);
float pixelwidth_x = len(dP.dx - dot(dP.dx, sd->wi) * sd->wi);
float pixelwidth_y = len(dP.dy - dot(dP.dy, sd->wi) * sd->wi);
// Take the average of both axis' length
pixelwidth = (pixelwidth_x + pixelwidth_y) * 0.5f;
}

View File

@ -888,7 +888,7 @@ typedef struct ccl_align(16) ShaderData
/* true geometric normal */
float3 Ng;
/* view/incoming direction */
float3 I;
float3 wi;
/* shader id */
int shader;
/* booleans describing shader, see ShaderDataFlag */
@ -920,7 +920,7 @@ typedef struct ccl_align(16) ShaderData
#ifdef __RAY_DIFFERENTIALS__
/* Radius of differential of P. */
float dP;
/* Radius of differential of I. */
/* Radius of differential of wi. */
float dI;
/* differential of u, v */
differential du;

View File

@ -6,6 +6,8 @@
#include "util/system.h"
#include "util/windows.h"
#include <system_error>
CCL_NAMESPACE_BEGIN
thread::thread(function<void()> run_cb) : run_cb_(run_cb), joined_(false)

@ -1 +1 @@
Subproject commit 7084c4ecd97d93459d9d23fd90f81589b09be5df
Subproject commit f1425d8a7fc38e8111c2a9e125f0e7877dcd0fdf

View File

@ -41,7 +41,7 @@ def get_download_url(version: Version, file_name: str) -> str:
"""
Get the download url for the given version and file_name
"""
return (f"https://www.blender.org/download/Blender{version.major}"
return (f"https://www.blender.org/download/release/Blender{version.major}"
f".{version.minor}/{file_name}")

@ -1 +1 @@
Subproject commit a9d4443c244f89399ec4bcc427e05a07950528cc
Subproject commit bf49eeaa14c445d3c53068203fdf91bff568fe64

@ -1 +1 @@
Subproject commit bdcfdd47ec3451822b21d1cff2ea2db751093c9a
Subproject commit 0f72f6c85c3743a9072273acb6a8a34b1cf1064b

View File

@ -1588,8 +1588,7 @@ class WM_OT_properties_edit(Operator):
self.default_string = rna_data["default"]
elif self.property_type in {'BOOL', 'BOOL_ARRAY'}:
self.default_int = self._convert_new_value_array(rna_data["default"], bool, 32)
if self.property_type in {'FLOAT_ARRAY', 'INT_ARRAY', 'BOOL_ARRAY'}:
elif self.property_type in {'FLOAT_ARRAY', 'INT_ARRAY', 'BOOL_ARRAY'}:
self.array_length = len(item[name])
# The dictionary does not contain the description if it was empty.
@ -1604,33 +1603,26 @@ class WM_OT_properties_edit(Operator):
def _get_converted_value(self, item, name_old, prop_type_new):
if prop_type_new == 'INT':
return self._convert_new_value_single(item[name_old], int)
if prop_type_new == 'FLOAT':
elif prop_type_new == 'FLOAT':
return self._convert_new_value_single(item[name_old], float)
if prop_type_new == 'BOOL':
elif prop_type_new == 'BOOL':
return self._convert_new_value_single(item[name_old], bool)
if prop_type_new == 'INT_ARRAY':
elif prop_type_new == 'INT_ARRAY':
prop_type_old = self.get_property_type(item, name_old)
if prop_type_old in {'INT', 'FLOAT', 'INT_ARRAY', 'FLOAT_ARRAY', 'BOOL_ARRAY'}:
return self._convert_new_value_array(item[name_old], int, self.array_length)
if prop_type_new == 'FLOAT_ARRAY':
elif prop_type_new == 'FLOAT_ARRAY':
prop_type_old = self.get_property_type(item, name_old)
if prop_type_old in {'INT', 'FLOAT', 'FLOAT_ARRAY', 'INT_ARRAY', 'BOOL_ARRAY'}:
return self._convert_new_value_array(item[name_old], float, self.array_length)
if prop_type_new == 'BOOL_ARRAY':
elif prop_type_new == 'BOOL_ARRAY':
prop_type_old = self.get_property_type(item, name_old)
if prop_type_old in {'INT', 'FLOAT', 'FLOAT_ARRAY', 'INT_ARRAY'}:
if prop_type_old in {'INT', 'FLOAT', 'FLOAT_ARRAY', 'INT_ARRAY', 'BOOL_ARRAY'}:
return self._convert_new_value_array(item[name_old], bool, self.array_length)
else:
return [False] * self.array_length
if prop_type_new == 'STRING':
elif prop_type_new == 'STRING':
return self.convert_custom_property_to_string(item, name_old)
# If all else fails, create an empty string property. That should avoid errors later on anyway.
return ""
@ -1667,7 +1659,7 @@ class WM_OT_properties_edit(Operator):
default=self.default_int[0] if prop_type_new == 'INT' else self.default_int[:self.array_length],
description=self.description,
)
if prop_type_new in {'BOOL', 'BOOL_ARRAY'}:
elif prop_type_new in {'BOOL', 'BOOL_ARRAY'}:
ui_data = item.id_properties_ui(name)
ui_data.update(
default=self.default_bool[0] if prop_type_new == 'BOOL' else self.default_bool[:self.array_length],

View File

@ -565,9 +565,11 @@ class GreasePencilMaterialsPanel:
if is_view3d and ma is not None and ma.grease_pencil is not None:
gpcolor = ma.grease_pencil
if gpcolor.stroke_style == 'SOLID':
row = layout.row()
row.prop(gpcolor, "color", text="Stroke Color")
col = layout.column(align=True)
if gpcolor.show_stroke and gpcolor.stroke_style == 'SOLID':
col.prop(gpcolor, "color", text="Stroke Color")
if gpcolor.show_fill and gpcolor.fill_style == 'SOLID':
col.prop(gpcolor, "fill_color", text="Fill Color")
else:
space = context.space_data

View File

@ -7,7 +7,6 @@
#pragma once
struct IDRemapper;
struct Main;
#ifdef __cplusplus
extern "C" {

View File

@ -28,7 +28,6 @@ extern "C" {
struct ColorManagedDisplay;
struct ResultBLF;
struct rctf;
struct rcti;
int BLF_init(void);

View File

@ -11,7 +11,6 @@ struct FontBLF;
struct GlyphBLF;
struct GlyphCacheBLF;
struct ResultBLF;
struct rctf;
struct rcti;
/* Max number of FontBLFs in memory. Take care that every font has a glyph cache per size/dpi,

View File

@ -33,7 +33,6 @@ struct PointerRNA;
struct PropertyRNA;
struct bAction;
struct bActionGroup;
struct bContext;
/* Container for data required to do FCurve and Driver evaluation. */
typedef struct AnimationEvalContext {

View File

@ -13,11 +13,7 @@ struct BlendHandle;
struct ID;
struct Library;
struct LibraryLink_Params;
struct Main;
struct ReportList;
struct Scene;
struct View3D;
struct ViewLayer;
typedef struct BlendfileLinkAppendContext BlendfileLinkAppendContext;
typedef struct BlendfileLinkAppendContextItem BlendfileLinkAppendContextItem;

View File

@ -19,7 +19,6 @@ extern "C" {
#endif
struct ID;
struct ListBase;
struct Main;
struct ReportList;

View File

@ -18,7 +18,6 @@ extern "C" {
struct Brush;
struct ImBuf;
struct ImagePool;
struct Object;
struct Main;
struct MTex;
struct Scene;

View File

@ -16,7 +16,6 @@ struct CollisionModifierData;
struct Depsgraph;
struct MVertTri;
struct Object;
struct Scene;
////////////////////////////////////////
// used for collisions in collision.c

View File

@ -15,7 +15,6 @@ extern "C" {
struct BoundBox;
struct Curves;
struct CustomDataLayer;
struct Depsgraph;
struct Main;
struct Object;

View File

@ -18,6 +18,7 @@
#include "BLI_generic_virtual_array.hh"
#include "BLI_index_mask.hh"
#include "BLI_math_vector_types.hh"
#include "BLI_offset_indices.hh"
#include "BLI_shared_cache.hh"
#include "BLI_span.hh"
#include "BLI_task.hh"
@ -164,23 +165,17 @@ class CurvesGeometry : public ::CurvesGeometry {
IndexRange points_range() const;
IndexRange curves_range() const;
/**
* Number of control points in the indexed curve.
*/
int points_num_for_curve(const int index) const;
/**
* The index of the first point in every curve. The size of this span is one larger than the
* number of curves. Consider using #points_for_curve rather than using the offsets directly.
* number of curves. Consider using #points_by_curve rather than using the offsets directly.
*/
Span<int> offsets() const;
MutableSpan<int> offsets_for_write();
/**
* Access a range of indices of point data for a specific curve.
* The offsets of every curve into arrays on the points domain.
*/
IndexRange points_for_curve(int index) const;
IndexRange points_for_curves(IndexRange curves) const;
OffsetIndices<int> points_by_curve() const;
/** The type (#CurveType) of each curve, or potentially a single if all are the same type. */
VArray<int8_t> curve_types() const;
@ -852,16 +847,6 @@ inline IndexRange CurvesGeometry::curves_range() const
return IndexRange(this->curves_num());
}
inline int CurvesGeometry::points_num_for_curve(const int index) const
{
BLI_assert(this->curve_num > 0);
BLI_assert(this->curve_num > index);
BLI_assert(this->curve_offsets != nullptr);
const int offset = this->curve_offsets[index];
const int offset_next = this->curve_offsets[index + 1];
return offset_next - offset;
}
inline bool CurvesGeometry::is_single_type(const CurveType type) const
{
return this->curve_type_counts()[type] == this->curves_num();
@ -884,25 +869,9 @@ inline const std::array<int, CURVE_TYPES_NUM> &CurvesGeometry::curve_type_counts
return this->runtime->type_counts;
}
inline IndexRange CurvesGeometry::points_for_curve(const int index) const
inline OffsetIndices<int> CurvesGeometry::points_by_curve() const
{
/* Offsets are not allocated when there are no curves. */
BLI_assert(this->curve_num > 0);
BLI_assert(this->curve_num > index);
BLI_assert(this->curve_offsets != nullptr);
const int offset = this->curve_offsets[index];
const int offset_next = this->curve_offsets[index + 1];
return {offset, offset_next - offset};
}
inline IndexRange CurvesGeometry::points_for_curves(const IndexRange curves) const
{
/* Offsets are not allocated when there are no curves. */
BLI_assert(this->curve_num > 0);
BLI_assert(this->curve_offsets != nullptr);
const int offset = this->curve_offsets[curves.start()];
const int offset_next = this->curve_offsets[curves.one_after_last()];
return {offset, offset_next - offset};
return OffsetIndices<int>({this->curve_offsets, this->curve_num + 1});
}
inline int CurvesGeometry::evaluated_points_num() const
@ -928,7 +897,8 @@ inline IndexRange CurvesGeometry::evaluated_points_for_curves(const IndexRange c
inline Span<int> CurvesGeometry::bezier_evaluated_offsets_for_curve(const int curve_index) const
{
const IndexRange points = this->points_for_curve(curve_index);
const OffsetIndices points_by_curve = this->points_by_curve();
const IndexRange points = points_by_curve[curve_index];
return this->runtime->bezier_evaluated_offsets.as_span().slice(points);
}

View File

@ -532,11 +532,6 @@ void fill_curve_counts(const bke::CurvesGeometry &curves,
Span<IndexRange> curve_ranges,
MutableSpan<int> counts);
/**
* Turn an array of sizes into the offset at each index including all previous sizes.
*/
void accumulate_counts_to_offsets(MutableSpan<int> counts_to_offsets, int start_offset = 0);
IndexMask indices_for_type(const VArray<int8_t> &types,
const std::array<int, CURVE_TYPES_NUM> &type_counts,
const CurveType type,

View File

@ -43,7 +43,6 @@ enum {
struct Depsgraph;
struct ListBase;
struct Mesh;
struct Object;
struct Scene;

View File

@ -8,7 +8,6 @@
* Common field utilities and field definitions for geometry components.
*/
#include "BKE_attribute.h"
#include "BKE_geometry_set.hh"
#include "FN_field.hh"

View File

@ -10,7 +10,6 @@
extern "C" {
#endif
struct Collection;
struct GeometrySet;
struct Object;

View File

@ -10,24 +10,18 @@
#include <iostream>
#include <mutex>
#include "BLI_float4x4.hh"
#include "BLI_function_ref.hh"
#include "BLI_hash.hh"
#include "BLI_map.hh"
#include "BLI_math_vector_types.hh"
#include "BLI_set.hh"
#include "BLI_user_counter.hh"
#include "BLI_vector_set.hh"
#include "BKE_anonymous_attribute_id.hh"
#include "BKE_attribute.hh"
#include "BKE_geometry_set.h"
struct Curves;
struct Collection;
struct Curve;
struct Mesh;
struct Object;
struct PointCloud;
struct Volume;

View File

@ -2,6 +2,8 @@
#pragma once
#include "BLI_float4x4.hh"
#include "BKE_geometry_set.hh"
namespace blender::bke {

View File

@ -16,7 +16,6 @@ struct Brush;
struct CurveMapping;
struct Depsgraph;
struct GHash;
struct GPencilUpdateCache;
struct ListBase;
struct MDeformVert;
struct Main;

View File

@ -14,7 +14,6 @@ extern "C" {
struct Depsgraph;
struct Main;
struct Object;
struct RegionView3D;
struct Scene;
struct bGPDcurve;
struct bGPDframe;

View File

@ -565,7 +565,6 @@ struct PartialUpdateUser *BKE_image_partial_update_create(const struct Image *im
void BKE_image_partial_update_free(struct PartialUpdateUser *user);
/* --- partial updater (image side) --- */
struct PartialUpdateRegister;
void BKE_image_partial_update_register_free(struct Image *image);
/** \brief Mark a region of the image to update. */

View File

@ -23,7 +23,6 @@
#include "DNA_image_types.h"
extern "C" {
struct PartialUpdateRegister;
struct PartialUpdateUser;
}

View File

@ -40,7 +40,6 @@ struct MPoly;
struct Main;
struct MemArena;
struct Mesh;
struct ModifierData;
struct Object;
struct PointCloud;
struct Scene;
@ -247,11 +246,13 @@ struct BoundBox *BKE_mesh_boundbox_get(struct Object *ob);
void BKE_mesh_texspace_calc(struct Mesh *me);
void BKE_mesh_texspace_ensure(struct Mesh *me);
void BKE_mesh_texspace_get(struct Mesh *me, float r_loc[3], float r_size[3]);
void BKE_mesh_texspace_get(struct Mesh *me,
float r_texspace_location[3],
float r_texspace_size[3]);
void BKE_mesh_texspace_get_reference(struct Mesh *me,
char **r_texflag,
float **r_loc,
float **r_size);
char **r_texspace_flag,
float **r_texspace_location,
float **r_texspace_size);
void BKE_mesh_texspace_copy_from_object(struct Mesh *me, struct Object *ob);
/**

View File

@ -8,7 +8,6 @@
struct BMEditMesh;
struct CustomData_MeshMasks;
struct Mesh;
struct Object;
#ifdef __cplusplus
extern "C" {

View File

@ -24,8 +24,6 @@ struct Object;
struct Scene;
struct SubdivCCG;
struct MLoop;
struct MLoopTri;
struct MPoly;
/**

View File

@ -29,27 +29,19 @@ extern "C" {
/* not very important, but the stack solver likes to know a maximum */
#define MAX_SOCKET 512
struct ARegion;
struct BlendDataReader;
struct BlendExpander;
struct BlendLibReader;
struct BlendWriter;
struct ColorManagedDisplaySettings;
struct ColorManagedViewSettings;
struct CryptomatteSession;
struct FreestyleLineStyle;
struct GPUMaterial;
struct GPUNodeStack;
struct ID;
struct ImBuf;
struct ImageFormatData;
struct Light;
struct ListBase;
struct MTex;
struct Main;
struct Material;
struct PointerRNA;
struct RenderData;
struct Scene;
struct SpaceNode;
struct Tex;
@ -1355,8 +1347,6 @@ void BKE_nodetree_remove_layer_n(struct bNodeTree *ntree, struct Scene *scene, i
/** \name Texture Nodes
* \{ */
struct TexResult;
#define TEX_NODE_OUTPUT 401
#define TEX_NODE_CHECKER 402
#define TEX_NODE_TEXTURE 403

View File

@ -20,7 +20,6 @@ struct Base;
struct BoundBox;
struct Curve;
struct Depsgraph;
struct GeometrySet;
struct GpencilModifierData;
struct HookGpencilModifierData;
struct HookModifierData;
@ -33,7 +32,6 @@ struct Object;
struct RegionView3D;
struct RigidBodyWorld;
struct Scene;
struct ShaderFxData;
struct SubsurfModifierData;
struct View3D;
struct ViewLayer;
@ -507,9 +505,9 @@ void BKE_object_handle_update_ex(struct Depsgraph *depsgraph,
void BKE_object_sculpt_data_create(struct Object *ob);
bool BKE_object_obdata_texspace_get(struct Object *ob,
char **r_texflag,
float **r_loc,
float **r_size);
char **r_texspace_flag,
float **r_texspace_location,
float **r_texspace_size);
struct Mesh *BKE_object_get_evaluated_mesh_no_subsurf(const struct Object *object);
/** Get evaluated mesh for given object. */

View File

@ -31,7 +31,6 @@ struct CustomData_MeshMasks;
struct Depsgraph;
struct EdgeHash;
struct KDTree_3d;
struct LatticeDeformData;
struct LinkNode;
struct MCol;
struct MFace;

View File

@ -20,7 +20,6 @@ extern "C" {
#endif
struct BoundBox;
struct CustomDataLayer;
struct Depsgraph;
struct Main;
struct Object;

View File

@ -24,7 +24,6 @@ struct CCGVert;
struct DMFlagMat;
struct DerivedMesh;
struct EdgeHash;
struct MPoly;
struct Mesh;
struct MeshElemMap;
struct Object;

View File

@ -574,7 +574,8 @@ static void loose_data_instantiate_obdata_preprocess(
* (return false). */
static bool loose_data_instantiate_collection_parents_check_recursive(Collection *collection)
{
for (CollectionParent *parent_collection = collection->parents.first; parent_collection != NULL;
for (CollectionParent *parent_collection = collection->runtime.parents.first;
parent_collection != NULL;
parent_collection = parent_collection->next) {
if ((parent_collection->collection->id.tag & LIB_TAG_DOIT) != 0) {
return true;

View File

@ -112,14 +112,13 @@ static void collection_copy_data(Main *bmain, ID *id_dst, const ID *id_src, cons
collection_dst->preview = NULL;
}
collection_dst->flag &= ~COLLECTION_HAS_OBJECT_CACHE;
collection_dst->flag &= ~COLLECTION_HAS_OBJECT_CACHE_INSTANCED;
BLI_listbase_clear(&collection_dst->object_cache);
BLI_listbase_clear(&collection_dst->object_cache_instanced);
collection_dst->flag &= ~(COLLECTION_HAS_OBJECT_CACHE | COLLECTION_HAS_OBJECT_CACHE_INSTANCED);
BLI_listbase_clear(&collection_dst->runtime.object_cache);
BLI_listbase_clear(&collection_dst->runtime.object_cache_instanced);
BLI_listbase_clear(&collection_dst->gobject);
BLI_listbase_clear(&collection_dst->children);
BLI_listbase_clear(&collection_dst->parents);
BLI_listbase_clear(&collection_dst->runtime.parents);
LISTBASE_FOREACH (CollectionChild *, child, &collection_src->children) {
collection_child_add(collection_dst, child->collection, flag, false);
@ -138,7 +137,7 @@ static void collection_free_data(ID *id)
BLI_freelistN(&collection->gobject);
BLI_freelistN(&collection->children);
BLI_freelistN(&collection->parents);
BLI_freelistN(&collection->runtime.parents);
BKE_collection_object_cache_free(collection);
}
@ -148,7 +147,7 @@ static void collection_foreach_id(ID *id, LibraryForeachIDData *data)
Collection *collection = (Collection *)id;
BKE_LIB_FOREACHID_PROCESS_ID(
data, collection->owner_id, IDWALK_CB_LOOPBACK | IDWALK_CB_NEVER_SELF);
data, collection->runtime.owner_id, IDWALK_CB_LOOPBACK | IDWALK_CB_NEVER_SELF);
LISTBASE_FOREACH (CollectionObject *, cob, &collection->gobject) {
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, cob->ob, IDWALK_CB_USER);
@ -157,7 +156,7 @@ static void collection_foreach_id(ID *id, LibraryForeachIDData *data)
BKE_LIB_FOREACHID_PROCESS_IDSUPER(
data, child->collection, IDWALK_CB_NEVER_SELF | IDWALK_CB_USER);
}
LISTBASE_FOREACH (CollectionParent *, parent, &collection->parents) {
LISTBASE_FOREACH (CollectionParent *, parent, &collection->runtime.parents) {
/* XXX This is very weak. The whole idea of keeping pointers to private IDs is very bad
* anyway... */
const int cb_flag = ((parent->collection != NULL &&
@ -178,11 +177,12 @@ static ID **collection_owner_pointer_get(ID *id)
Collection *master_collection = (Collection *)id;
BLI_assert((master_collection->flag & COLLECTION_IS_MASTER) != 0);
BLI_assert(master_collection->owner_id != NULL);
BLI_assert(GS(master_collection->owner_id->name) == ID_SCE);
BLI_assert(((Scene *)master_collection->owner_id)->master_collection == master_collection);
BLI_assert(master_collection->runtime.owner_id != NULL);
BLI_assert(GS(master_collection->runtime.owner_id->name) == ID_SCE);
BLI_assert(((Scene *)master_collection->runtime.owner_id)->master_collection ==
master_collection);
return &master_collection->owner_id;
return &master_collection->runtime.owner_id;
}
void BKE_collection_blend_write_nolib(BlendWriter *writer, Collection *collection)
@ -205,13 +205,9 @@ static void collection_blend_write(BlendWriter *writer, ID *id, const void *id_a
{
Collection *collection = (Collection *)id;
memset(&collection->runtime, 0, sizeof(collection->runtime));
/* Clean up, important in undo case to reduce false detection of changed data-blocks. */
collection->flag &= ~COLLECTION_HAS_OBJECT_CACHE;
collection->flag &= ~COLLECTION_HAS_OBJECT_CACHE_INSTANCED;
collection->tag = 0;
BLI_listbase_clear(&collection->object_cache);
BLI_listbase_clear(&collection->object_cache_instanced);
BLI_listbase_clear(&collection->parents);
collection->flag &= ~COLLECTION_FLAG_ALL_RUNTIME;
/* write LibData */
BLO_write_id_struct(writer, Collection, id_address, &collection->id);
@ -258,7 +254,11 @@ void BKE_collection_blend_read_data(BlendDataReader *reader, Collection *collect
}
collection->id.flag |= LIB_EMBEDDED_DATA;
}
collection->owner_id = owner_id;
memset(&collection->runtime, 0, sizeof(collection->runtime));
collection->flag &= ~COLLECTION_FLAG_ALL_RUNTIME;
collection->runtime.owner_id = owner_id;
BLO_read_list(reader, &collection->gobject);
BLO_read_list(reader, &collection->children);
@ -266,13 +266,6 @@ void BKE_collection_blend_read_data(BlendDataReader *reader, Collection *collect
BLO_read_data_address(reader, &collection->preview);
BKE_previewimg_blend_read(reader, collection->preview);
collection->flag &= ~COLLECTION_HAS_OBJECT_CACHE;
collection->flag &= ~COLLECTION_HAS_OBJECT_CACHE_INSTANCED;
collection->tag = 0;
BLI_listbase_clear(&collection->object_cache);
BLI_listbase_clear(&collection->object_cache_instanced);
BLI_listbase_clear(&collection->parents);
#ifdef USE_COLLECTION_COMPAT_28
/* This runs before the very first doversion. */
BLO_read_data_address(reader, &collection->collection);
@ -543,7 +536,7 @@ bool BKE_collection_delete(Main *bmain, Collection *collection, bool hierarchy)
else {
/* Link child collections into parent collection. */
LISTBASE_FOREACH (CollectionChild *, child, &collection->children) {
LISTBASE_FOREACH (CollectionParent *, cparent, &collection->parents) {
LISTBASE_FOREACH (CollectionParent *, cparent, &collection->runtime.parents) {
Collection *parent = cparent->collection;
collection_child_add(parent, child->collection, 0, true);
}
@ -552,7 +545,7 @@ bool BKE_collection_delete(Main *bmain, Collection *collection, bool hierarchy)
CollectionObject *cob = collection->gobject.first;
while (cob != NULL) {
/* Link child object into parent collections. */
LISTBASE_FOREACH (CollectionParent *, cparent, &collection->parents) {
LISTBASE_FOREACH (CollectionParent *, cparent, &collection->runtime.parents) {
Collection *parent = cparent->collection;
collection_object_add(bmain, parent, cob->ob, 0, true);
}
@ -816,13 +809,13 @@ ListBase BKE_collection_object_cache_get(Collection *collection)
BLI_mutex_lock(&cache_lock);
if (!(collection->flag & COLLECTION_HAS_OBJECT_CACHE)) {
collection_object_cache_fill(&collection->object_cache, collection, 0, false);
collection_object_cache_fill(&collection->runtime.object_cache, collection, 0, false);
collection->flag |= COLLECTION_HAS_OBJECT_CACHE;
}
BLI_mutex_unlock(&cache_lock);
}
return collection->object_cache;
return collection->runtime.object_cache;
}
ListBase BKE_collection_object_cache_instanced_get(Collection *collection)
@ -832,24 +825,24 @@ ListBase BKE_collection_object_cache_instanced_get(Collection *collection)
BLI_mutex_lock(&cache_lock);
if (!(collection->flag & COLLECTION_HAS_OBJECT_CACHE_INSTANCED)) {
collection_object_cache_fill(&collection->object_cache_instanced, collection, 0, true);
collection_object_cache_fill(
&collection->runtime.object_cache_instanced, collection, 0, true);
collection->flag |= COLLECTION_HAS_OBJECT_CACHE_INSTANCED;
}
BLI_mutex_unlock(&cache_lock);
}
return collection->object_cache_instanced;
return collection->runtime.object_cache_instanced;
}
static void collection_object_cache_free(Collection *collection)
{
/* Clear own cache an for all parents, since those are affected by changes as well. */
collection->flag &= ~COLLECTION_HAS_OBJECT_CACHE;
collection->flag &= ~COLLECTION_HAS_OBJECT_CACHE_INSTANCED;
BLI_freelistN(&collection->object_cache);
BLI_freelistN(&collection->object_cache_instanced);
collection->flag &= ~(COLLECTION_HAS_OBJECT_CACHE | COLLECTION_HAS_OBJECT_CACHE_INSTANCED);
BLI_freelistN(&collection->runtime.object_cache);
BLI_freelistN(&collection->runtime.object_cache_instanced);
LISTBASE_FOREACH (CollectionParent *, parent, &collection->parents) {
LISTBASE_FOREACH (CollectionParent *, parent, &collection->runtime.parents) {
collection_object_cache_free(parent->collection);
}
}
@ -884,7 +877,7 @@ Collection *BKE_collection_master_add(Scene *scene)
Collection *master_collection = BKE_libblock_alloc(
NULL, ID_GR, BKE_SCENE_COLLECTION_NAME, LIB_ID_CREATE_NO_MAIN);
master_collection->id.flag |= LIB_EMBEDDED_DATA;
master_collection->owner_id = &scene->id;
master_collection->runtime.owner_id = &scene->id;
master_collection->flag |= COLLECTION_IS_MASTER;
master_collection->color_tag = COLLECTION_COLOR_NONE;
@ -1024,7 +1017,7 @@ static void collection_tag_update_parent_recursive(Main *bmain,
DEG_id_tag_update_ex(bmain, &collection->id, flag);
LISTBASE_FOREACH (CollectionParent *, collection_parent, &collection->parents) {
LISTBASE_FOREACH (CollectionParent *, collection_parent, &collection->runtime.parents) {
if (collection_parent->collection->flag & COLLECTION_IS_MASTER) {
/* We don't care about scene/master collection here. */
continue;
@ -1045,7 +1038,7 @@ static Collection *collection_parent_editable_find_recursive(const ViewLayer *vi
return NULL;
}
LISTBASE_FOREACH (CollectionParent *, collection_parent, &collection->parents) {
LISTBASE_FOREACH (CollectionParent *, collection_parent, &collection->runtime.parents) {
if (!ID_IS_LINKED(collection_parent->collection) &&
!ID_IS_OVERRIDE_LIBRARY(collection_parent->collection)) {
if (view_layer != NULL &&
@ -1071,8 +1064,8 @@ static bool collection_object_add(
{
if (ob->instance_collection) {
/* Cyclic dependency check. */
if (collection_find_child_recursive(ob->instance_collection, collection) ||
ob->instance_collection == collection) {
if ((ob->instance_collection == collection) ||
collection_find_child_recursive(ob->instance_collection, collection)) {
return false;
}
}
@ -1344,9 +1337,9 @@ static void collection_null_children_remove(Collection *collection)
static void collection_missing_parents_remove(Collection *collection)
{
LISTBASE_FOREACH_MUTABLE (CollectionParent *, parent, &collection->parents) {
LISTBASE_FOREACH_MUTABLE (CollectionParent *, parent, &collection->runtime.parents) {
if ((parent->collection == NULL) || !collection_find_child(parent->collection, collection)) {
BLI_freelinkN(&collection->parents, parent);
BLI_freelinkN(&collection->runtime.parents, parent);
}
}
}
@ -1380,11 +1373,11 @@ void BKE_collections_child_remove_nulls(Main *bmain,
}
}
else {
LISTBASE_FOREACH_MUTABLE (CollectionParent *, parent, &child_collection->parents) {
LISTBASE_FOREACH_MUTABLE (CollectionParent *, parent, &child_collection->runtime.parents) {
collection_null_children_remove(parent->collection);
if (!collection_find_child(parent->collection, child_collection)) {
BLI_freelinkN(&child_collection->parents, parent);
BLI_freelinkN(&child_collection->runtime.parents, parent);
}
}
}
@ -1420,7 +1413,7 @@ bool BKE_collection_is_in_scene(Collection *collection)
return true;
}
LISTBASE_FOREACH (CollectionParent *, cparent, &collection->parents) {
LISTBASE_FOREACH (CollectionParent *, cparent, &collection->runtime.parents) {
if (BKE_collection_is_in_scene(cparent->collection)) {
return true;
}
@ -1474,7 +1467,7 @@ bool BKE_collection_cycle_find(Collection *new_ancestor, Collection *collection)
collection = new_ancestor;
}
LISTBASE_FOREACH (CollectionParent *, parent, &new_ancestor->parents) {
LISTBASE_FOREACH (CollectionParent *, parent, &new_ancestor->runtime.parents) {
if (BKE_collection_cycle_find(parent->collection, collection)) {
return true;
}
@ -1514,7 +1507,7 @@ static bool collection_cycle_fix_recursive(Main *bmain,
{
bool cycles_found = false;
LISTBASE_FOREACH_MUTABLE (CollectionParent *, parent, &parent_collection->parents) {
LISTBASE_FOREACH_MUTABLE (CollectionParent *, parent, &parent_collection->runtime.parents) {
if (BKE_collection_cycle_find(parent->collection, collection)) {
BKE_collection_child_remove(bmain, parent->collection, parent_collection);
cycles_found = true;
@ -1560,7 +1553,7 @@ bool BKE_collection_has_collection(const Collection *parent, const Collection *c
static CollectionParent *collection_find_parent(Collection *child, Collection *collection)
{
return BLI_findptr(&child->parents, collection, offsetof(CollectionParent, collection));
return BLI_findptr(&child->runtime.parents, collection, offsetof(CollectionParent, collection));
}
static bool collection_child_add(Collection *parent,
@ -1584,7 +1577,7 @@ static bool collection_child_add(Collection *parent,
if ((flag & LIB_ID_CREATE_NO_MAIN) == 0) {
CollectionParent *cparent = MEM_callocN(sizeof(CollectionParent), "CollectionParent");
cparent->collection = parent;
BLI_addtail(&collection->parents, cparent);
BLI_addtail(&collection->runtime.parents, cparent);
}
if (add_us) {
@ -1604,7 +1597,7 @@ static bool collection_child_remove(Collection *parent, Collection *collection)
}
CollectionParent *cparent = collection_find_parent(collection, parent);
BLI_freelinkN(&collection->parents, cparent);
BLI_freelinkN(&collection->runtime.parents, cparent);
BLI_freelinkN(&parent->children, child);
id_us_min(&collection->id);
@ -1664,19 +1657,19 @@ void BKE_collection_parent_relations_rebuild(Collection *collection)
BLI_assert(collection_find_parent(child->collection, collection) == NULL);
CollectionParent *cparent = MEM_callocN(sizeof(CollectionParent), __func__);
cparent->collection = collection;
BLI_addtail(&child->collection->parents, cparent);
BLI_addtail(&child->collection->runtime.parents, cparent);
}
}
static void collection_parents_rebuild_recursive(Collection *collection)
{
/* A same collection may be child of several others, no need to process it more than once. */
if ((collection->tag & COLLECTION_TAG_RELATION_REBUILD) == 0) {
if ((collection->runtime.tag & COLLECTION_TAG_RELATION_REBUILD) == 0) {
return;
}
BKE_collection_parent_relations_rebuild(collection);
collection->tag &= ~COLLECTION_TAG_RELATION_REBUILD;
collection->runtime.tag &= ~COLLECTION_TAG_RELATION_REBUILD;
LISTBASE_FOREACH (CollectionChild *, child, &collection->children) {
/* See comment above in `BKE_collection_parent_relations_rebuild`. */
@ -1691,9 +1684,9 @@ void BKE_main_collections_parent_relations_rebuild(Main *bmain)
{
/* Only collections not in bmain (master ones in scenes) have no parent... */
LISTBASE_FOREACH (Collection *, collection, &bmain->collections) {
BLI_freelistN(&collection->parents);
BLI_freelistN(&collection->runtime.parents);
collection->tag |= COLLECTION_TAG_RELATION_REBUILD;
collection->runtime.tag |= COLLECTION_TAG_RELATION_REBUILD;
}
/* Scene's master collections will be 'root' parent of most of our collections, so start with
@ -1702,8 +1695,8 @@ void BKE_main_collections_parent_relations_rebuild(Main *bmain)
/* This function can be called from readfile.c, when this pointer is not guaranteed to be NULL.
*/
if (scene->master_collection != NULL) {
BLI_assert(BLI_listbase_is_empty(&scene->master_collection->parents));
scene->master_collection->tag |= COLLECTION_TAG_RELATION_REBUILD;
BLI_assert(BLI_listbase_is_empty(&scene->master_collection->runtime.parents));
scene->master_collection->runtime.tag |= COLLECTION_TAG_RELATION_REBUILD;
collection_parents_rebuild_recursive(scene->master_collection);
}
}
@ -1711,7 +1704,7 @@ void BKE_main_collections_parent_relations_rebuild(Main *bmain)
/* We may have parent chains outside of scene's master_collection context? At least, readfile's
* lib_link_collection_data() seems to assume that, so do the same here. */
LISTBASE_FOREACH (Collection *, collection, &bmain->collections) {
if (collection->tag & COLLECTION_TAG_RELATION_REBUILD) {
if (collection->runtime.tag & COLLECTION_TAG_RELATION_REBUILD) {
/* NOTE: we do not have easy access to 'which collections is root' info in that case, which
* means test for cycles in collection relationships may fail here. I don't think that is an
* issue in practice here, but worth keeping in mind... */

View File

@ -258,7 +258,7 @@ static void curve_blend_read_data(BlendDataReader *reader, ID *id)
switch_endian_knots(nu);
}
}
cu->texflag &= ~CU_AUTOSPACE_EVALUATED;
cu->texspace_flag &= ~CU_TEXSPACE_FLAG_AUTO_EVALUATED;
BLO_read_data_address(reader, &cu->bevel_profile);
if (cu->bevel_profile != nullptr) {
@ -517,7 +517,7 @@ BoundBox *BKE_curve_boundbox_get(Object *ob)
void BKE_curve_texspace_calc(Curve *cu)
{
if (cu->texflag & CU_AUTOSPACE) {
if (cu->texspace_flag & CU_TEXSPACE_FLAG_AUTO) {
float min[3], max[3];
INIT_MINMAX(min, max);
@ -526,35 +526,36 @@ void BKE_curve_texspace_calc(Curve *cu)
max[0] = max[1] = max[2] = 1.0f;
}
float loc[3], size[3];
mid_v3_v3v3(loc, min, max);
float texspace_location[3], texspace_size[3];
mid_v3_v3v3(texspace_location, min, max);
size[0] = (max[0] - min[0]) / 2.0f;
size[1] = (max[1] - min[1]) / 2.0f;
size[2] = (max[2] - min[2]) / 2.0f;
texspace_size[0] = (max[0] - min[0]) / 2.0f;
texspace_size[1] = (max[1] - min[1]) / 2.0f;
texspace_size[2] = (max[2] - min[2]) / 2.0f;
for (int a = 0; a < 3; a++) {
if (size[a] == 0.0f) {
size[a] = 1.0f;
if (texspace_size[a] == 0.0f) {
texspace_size[a] = 1.0f;
}
else if (size[a] > 0.0f && size[a] < 0.00001f) {
size[a] = 0.00001f;
else if (texspace_size[a] > 0.0f && texspace_size[a] < 0.00001f) {
texspace_size[a] = 0.00001f;
}
else if (size[a] < 0.0f && size[a] > -0.00001f) {
size[a] = -0.00001f;
else if (texspace_size[a] < 0.0f && texspace_size[a] > -0.00001f) {
texspace_size[a] = -0.00001f;
}
}
copy_v3_v3(cu->loc, loc);
copy_v3_v3(cu->size, size);
copy_v3_v3(cu->texspace_location, texspace_location);
copy_v3_v3(cu->texspace_size, texspace_size);
cu->texflag |= CU_AUTOSPACE_EVALUATED;
cu->texspace_flag |= CU_TEXSPACE_FLAG_AUTO_EVALUATED;
}
}
void BKE_curve_texspace_ensure(Curve *cu)
{
if ((cu->texflag & CU_AUTOSPACE) && !(cu->texflag & CU_AUTOSPACE_EVALUATED)) {
if ((cu->texspace_flag & CU_TEXSPACE_FLAG_AUTO) &&
(cu->texspace_flag & CU_TEXSPACE_FLAG_AUTO_EVALUATED) == 0) {
BKE_curve_texspace_calc(cu);
}
}
@ -5508,10 +5509,10 @@ void BKE_curve_eval_geometry(Depsgraph *depsgraph, Curve *curve)
BKE_curve_texspace_calc(curve);
if (DEG_is_active(depsgraph)) {
Curve *curve_orig = (Curve *)DEG_get_original_id(&curve->id);
if (curve->texflag & CU_AUTOSPACE_EVALUATED) {
curve_orig->texflag |= CU_AUTOSPACE_EVALUATED;
copy_v3_v3(curve_orig->loc, curve->loc);
copy_v3_v3(curve_orig->size, curve->size);
if (curve->texspace_flag & CU_TEXSPACE_FLAG_AUTO_EVALUATED) {
curve_orig->texspace_flag |= CU_TEXSPACE_FLAG_AUTO_EVALUATED;
copy_v3_v3(curve_orig->texspace_location, curve->texspace_location);
copy_v3_v3(curve_orig->texspace_size, curve->texspace_size);
}
}
}

View File

@ -108,6 +108,7 @@ Curves *curve_legacy_to_curves(const Curve &curve_legacy, const ListBase &nurbs_
return curves_id;
}
const OffsetIndices points_by_curve = curves.points_by_curve();
MutableSpan<float3> positions = curves.positions_for_write();
SpanAttributeWriter<float> radius_attribute =
curves_attributes.lookup_or_add_for_write_only_span<float>("radius", ATTR_DOMAIN_POINT);
@ -119,7 +120,7 @@ Curves *curve_legacy_to_curves(const Curve &curve_legacy, const ListBase &nurbs_
for (const int curve_i : selection.slice(range)) {
const Nurb &src_curve = *src_curves[curve_i];
const Span<BPoint> src_points(src_curve.bp, src_curve.pntsu);
const IndexRange points = curves.points_for_curve(curve_i);
const IndexRange points = points_by_curve[curve_i];
for (const int i : src_points.index_range()) {
const BPoint &bp = src_points[i];
@ -146,7 +147,7 @@ Curves *curve_legacy_to_curves(const Curve &curve_legacy, const ListBase &nurbs_
for (const int curve_i : selection.slice(range)) {
const Nurb &src_curve = *src_curves[curve_i];
const Span<BezTriple> src_points(src_curve.bezt, src_curve.pntsu);
const IndexRange points = curves.points_for_curve(curve_i);
const IndexRange points = points_by_curve[curve_i];
resolutions[curve_i] = src_curve.resolu;
@ -174,7 +175,7 @@ Curves *curve_legacy_to_curves(const Curve &curve_legacy, const ListBase &nurbs_
for (const int curve_i : selection.slice(range)) {
const Nurb &src_curve = *src_curves[curve_i];
const Span src_points(src_curve.bp, src_curve.pntsu);
const IndexRange points = curves.points_for_curve(curve_i);
const IndexRange points = points_by_curve[curve_i];
resolutions[curve_i] = src_curve.resolu;
nurbs_orders[curve_i] = src_curve.orderu;

View File

@ -633,10 +633,11 @@ static void write_sharp_bezier_edges(const CurvesInfo &curves_info,
sharp_edges = mesh_attributes.lookup_or_add_for_write_span<bool>("sharp_edge", ATTR_DOMAIN_EDGE);
const OffsetIndices profile_points_by_curve = profile.points_by_curve();
const VArray<int8_t> types = profile.curve_types();
foreach_curve_combination(curves_info, offsets, [&](const CombinationInfo &info) {
if (types[info.i_profile] == CURVE_TYPE_BEZIER) {
const IndexRange points = profile.points_for_curve(info.i_profile);
const IndexRange points = profile_points_by_curve[info.i_profile];
mark_bezier_vector_edges_sharp(points.size(),
info.main_segment_num,
profile.bezier_evaluated_offsets_for_curve(info.i_profile),

View File

@ -263,7 +263,7 @@ void CurvesGeometry::fill_curve_types(const IndexMask selection, const CurveType
}
if (std::optional<int8_t> single_type = this->curve_types().get_if_single()) {
if (single_type == type) {
/* No need for an array if the types are already a single with the correct type. */
this->fill_curve_types(type);
return;
}
}
@ -457,6 +457,7 @@ static void calculate_evaluated_offsets(const CurvesGeometry &curves,
MutableSpan<int> offsets,
MutableSpan<int> bezier_evaluated_offsets)
{
const OffsetIndices points_by_curve = curves.points_by_curve();
VArray<int8_t> types = curves.curve_types();
VArray<int> resolution = curves.resolution();
VArray<bool> cyclic = curves.cyclic();
@ -468,7 +469,7 @@ static void calculate_evaluated_offsets(const CurvesGeometry &curves,
VArray<int8_t> nurbs_knots_modes = curves.nurbs_knots_modes();
build_offsets(offsets, [&](const int curve_index) -> int {
const IndexRange points = curves.points_for_curve(curve_index);
const IndexRange points = points_by_curve[curve_index];
switch (types[curve_index]) {
case CURVE_TYPE_CATMULL_ROM:
return curves::catmull_rom::calculate_evaluated_num(
@ -533,9 +534,10 @@ IndexMask CurvesGeometry::indices_for_curve_type(const CurveType type,
Array<int> CurvesGeometry::point_to_curve_map() const
{
const OffsetIndices points_by_curve = this->points_by_curve();
Array<int> map(this->points_num());
for (const int i : this->curves_range()) {
map.as_mutable_span().slice(this->points_for_curve(i)).fill(i);
map.as_mutable_span().slice(points_by_curve[i]).fill(i);
}
return map;
}
@ -552,13 +554,14 @@ void CurvesGeometry::ensure_nurbs_basis_cache() const
this->runtime->nurbs_basis_cache.resize(this->curves_num());
MutableSpan<curves::nurbs::BasisCache> basis_caches(this->runtime->nurbs_basis_cache);
const OffsetIndices points_by_curve = this->points_by_curve();
VArray<bool> cyclic = this->cyclic();
VArray<int8_t> orders = this->nurbs_orders();
VArray<int8_t> knots_modes = this->nurbs_knots_modes();
threading::parallel_for(nurbs_mask.index_range(), 64, [&](const IndexRange range) {
for (const int curve_index : nurbs_mask.slice(range)) {
const IndexRange points = this->points_for_curve(curve_index);
const IndexRange points = points_by_curve[curve_index];
const IndexRange evaluated_points = this->evaluated_points_for_curve(curve_index);
const int8_t order = orders[curve_index];
@ -597,6 +600,7 @@ Span<float3> CurvesGeometry::evaluated_positions() const
MutableSpan<float3> evaluated_positions = this->runtime->evaluated_position_cache;
this->runtime->evaluated_positions_span = evaluated_positions;
const OffsetIndices points_by_curve = this->points_by_curve();
VArray<int8_t> types = this->curve_types();
VArray<bool> cyclic = this->cyclic();
VArray<int> resolution = this->resolution();
@ -613,7 +617,7 @@ Span<float3> CurvesGeometry::evaluated_positions() const
threading::parallel_for(this->curves_range(), 128, [&](IndexRange curves_range) {
for (const int curve_index : curves_range) {
const IndexRange points = this->points_for_curve(curve_index);
const IndexRange points = points_by_curve[curve_index];
const IndexRange evaluated_points = this->evaluated_points_for_curve(curve_index);
switch (types[curve_index]) {
@ -677,6 +681,7 @@ Span<float3> CurvesGeometry::evaluated_tangents() const
Vector<int64_t> bezier_indices;
const IndexMask bezier_mask = this->indices_for_curve_type(CURVE_TYPE_BEZIER, bezier_indices);
if (!bezier_mask.is_empty()) {
const OffsetIndices points_by_curve = this->points_by_curve();
const Span<float3> positions = this->positions();
const Span<float3> handles_left = this->handle_positions_left();
const Span<float3> handles_right = this->handle_positions_right();
@ -686,7 +691,7 @@ Span<float3> CurvesGeometry::evaluated_tangents() const
if (cyclic[curve_index]) {
continue;
}
const IndexRange points = this->points_for_curve(curve_index);
const IndexRange points = points_by_curve[curve_index];
const IndexRange evaluated_points = this->evaluated_points_for_curve(curve_index);
const float epsilon = 1e-6f;
@ -716,14 +721,58 @@ static void rotate_directions_around_axes(MutableSpan<float3> directions,
}
}
static void evaluate_generic_data_for_curve(
const int curve_index,
const IndexRange points,
const VArray<int8_t> &types,
const VArray<bool> &cyclic,
const VArray<int> &resolution,
const Span<int> bezier_evaluated_offsets,
const Span<curves::nurbs::BasisCache> nurbs_basis_cache,
const VArray<int8_t> &nurbs_orders,
const Span<float> nurbs_weights,
const GSpan src,
GMutableSpan dst)
{
switch (types[curve_index]) {
case CURVE_TYPE_CATMULL_ROM:
curves::catmull_rom::interpolate_to_evaluated(
src, cyclic[curve_index], resolution[curve_index], dst);
break;
case CURVE_TYPE_POLY:
dst.copy_from(src);
break;
case CURVE_TYPE_BEZIER:
curves::bezier::interpolate_to_evaluated(src, bezier_evaluated_offsets.slice(points), dst);
break;
case CURVE_TYPE_NURBS:
curves::nurbs::interpolate_to_evaluated(nurbs_basis_cache[curve_index],
nurbs_orders[curve_index],
nurbs_weights.slice_safe(points),
src,
dst);
break;
}
}
Span<float3> CurvesGeometry::evaluated_normals() const
{
this->runtime->normal_cache_mutex.ensure([&]() {
const Span<float3> evaluated_tangents = this->evaluated_tangents();
const OffsetIndices points_by_curve = this->points_by_curve();
const VArray<int8_t> types = this->curve_types();
const VArray<bool> cyclic = this->cyclic();
const VArray<int8_t> normal_mode = this->normal_mode();
const VArray<int8_t> types = this->curve_types();
const VArray<int> resolution = this->resolution();
const VArray<int8_t> nurbs_orders = this->nurbs_orders();
const Span<float> nurbs_weights = this->nurbs_weights();
const Span<float3> evaluated_tangents = this->evaluated_tangents();
const VArray<float> tilt = this->tilt();
VArraySpan<float> tilt_span;
const bool use_tilt = !(tilt.is_single() && tilt.get_internal_single() == 0.0f);
if (use_tilt) {
tilt_span = tilt;
}
this->runtime->evaluated_normal_cache.resize(this->evaluated_points_num());
MutableSpan<float3> evaluated_normals = this->runtime->evaluated_normal_cache;
@ -748,19 +797,26 @@ Span<float3> CurvesGeometry::evaluated_normals() const
/* If the "tilt" attribute exists, rotate the normals around the tangents by the
* evaluated angles. We can avoid copying the tilts to evaluate them for poly curves. */
if (!(tilt.is_single() && tilt.get_internal_single() == 0.0f)) {
const IndexRange points = this->points_for_curve(curve_index);
Span<float> curve_tilt = tilt.get_internal_span().slice(points);
if (use_tilt) {
const IndexRange points = points_by_curve[curve_index];
if (types[curve_index] == CURVE_TYPE_POLY) {
rotate_directions_around_axes(evaluated_normals.slice(evaluated_points),
evaluated_tangents.slice(evaluated_points),
curve_tilt);
tilt_span.slice(points));
}
else {
evaluated_tilts.clear();
evaluated_tilts.resize(evaluated_points.size());
this->interpolate_to_evaluated(
curve_index, curve_tilt, evaluated_tilts.as_mutable_span());
evaluated_tilts.reinitialize(evaluated_points.size());
evaluate_generic_data_for_curve(curve_index,
points,
types,
cyclic,
resolution,
this->runtime->bezier_evaluated_offsets.as_span(),
this->runtime->nurbs_basis_cache.as_span(),
nurbs_orders,
nurbs_weights,
tilt_span.slice(points),
evaluated_tilts.as_mutable_span());
rotate_directions_around_axes(evaluated_normals.slice(evaluated_points),
evaluated_tangents.slice(evaluated_points),
evaluated_tilts.as_span());
@ -778,36 +834,28 @@ void CurvesGeometry::interpolate_to_evaluated(const int curve_index,
{
BLI_assert(this->runtime->offsets_cache_mutex.is_cached());
BLI_assert(this->runtime->nurbs_basis_cache_mutex.is_cached());
const IndexRange points = this->points_for_curve(curve_index);
const OffsetIndices points_by_curve = this->points_by_curve();
const IndexRange points = points_by_curve[curve_index];
BLI_assert(src.size() == points.size());
BLI_assert(dst.size() == this->evaluated_points_for_curve(curve_index).size());
switch (this->curve_types()[curve_index]) {
case CURVE_TYPE_CATMULL_ROM:
curves::catmull_rom::interpolate_to_evaluated(
src, this->cyclic()[curve_index], this->resolution()[curve_index], dst);
return;
case CURVE_TYPE_POLY:
dst.type().copy_assign_n(src.data(), dst.data(), src.size());
return;
case CURVE_TYPE_BEZIER:
curves::bezier::interpolate_to_evaluated(
src, this->runtime->bezier_evaluated_offsets.as_span().slice(points), dst);
return;
case CURVE_TYPE_NURBS:
curves::nurbs::interpolate_to_evaluated(this->runtime->nurbs_basis_cache[curve_index],
this->nurbs_orders()[curve_index],
this->nurbs_weights().slice_safe(points),
src,
dst);
return;
}
BLI_assert_unreachable();
evaluate_generic_data_for_curve(curve_index,
points,
this->curve_types(),
this->cyclic(),
this->resolution(),
this->runtime->bezier_evaluated_offsets.as_span(),
this->runtime->nurbs_basis_cache.as_span(),
this->nurbs_orders(),
this->nurbs_weights(),
src,
dst);
}
void CurvesGeometry::interpolate_to_evaluated(const GSpan src, GMutableSpan dst) const
{
BLI_assert(this->runtime->offsets_cache_mutex.is_cached());
BLI_assert(this->runtime->nurbs_basis_cache_mutex.is_cached());
const OffsetIndices points_by_curve = this->points_by_curve();
const VArray<int8_t> types = this->curve_types();
const VArray<int> resolution = this->resolution();
const VArray<bool> cyclic = this->cyclic();
@ -816,32 +864,19 @@ void CurvesGeometry::interpolate_to_evaluated(const GSpan src, GMutableSpan dst)
threading::parallel_for(this->curves_range(), 512, [&](IndexRange curves_range) {
for (const int curve_index : curves_range) {
const IndexRange points = this->points_for_curve(curve_index);
const IndexRange points = points_by_curve[curve_index];
const IndexRange evaluated_points = this->evaluated_points_for_curve(curve_index);
switch (types[curve_index]) {
case CURVE_TYPE_CATMULL_ROM:
curves::catmull_rom::interpolate_to_evaluated(src.slice(points),
cyclic[curve_index],
resolution[curve_index],
dst.slice(evaluated_points));
continue;
case CURVE_TYPE_POLY:
dst.slice(evaluated_points).copy_from(src.slice(points));
continue;
case CURVE_TYPE_BEZIER:
curves::bezier::interpolate_to_evaluated(
src.slice(points),
this->runtime->bezier_evaluated_offsets.as_span().slice(points),
dst.slice(evaluated_points));
continue;
case CURVE_TYPE_NURBS:
curves::nurbs::interpolate_to_evaluated(this->runtime->nurbs_basis_cache[curve_index],
nurbs_orders[curve_index],
nurbs_weights.slice_safe(points),
src.slice(points),
dst.slice(evaluated_points));
continue;
}
evaluate_generic_data_for_curve(curve_index,
points,
types,
cyclic,
resolution,
this->runtime->bezier_evaluated_offsets,
this->runtime->nurbs_basis_cache,
nurbs_orders,
nurbs_weights,
src.slice(points),
dst.slice(evaluated_points));
}
});
}
@ -946,6 +981,7 @@ void CurvesGeometry::calculate_bezier_auto_handles()
if (this->handle_positions_left().is_empty() || this->handle_positions_right().is_empty()) {
return;
}
const OffsetIndices points_by_curve = this->points_by_curve();
const VArray<int8_t> types = this->curve_types();
const VArray<bool> cyclic = this->cyclic();
const VArraySpan<int8_t> types_left{this->handle_types_left()};
@ -957,7 +993,7 @@ void CurvesGeometry::calculate_bezier_auto_handles()
threading::parallel_for(this->curves_range(), 128, [&](IndexRange range) {
for (const int i_curve : range) {
if (types[i_curve] == CURVE_TYPE_BEZIER) {
const IndexRange points = this->points_for_curve(i_curve);
const IndexRange points = points_by_curve[i_curve];
curves::bezier::calculate_auto_handles(cyclic[i_curve],
types_left.slice(points),
types_right.slice(points),
@ -1044,10 +1080,11 @@ static void copy_with_map(const GSpan src, const Span<int> map, GMutableSpan dst
*/
static Array<int> build_point_to_curve_map(const CurvesGeometry &curves)
{
const OffsetIndices points_by_curve = curves.points_by_curve();
Array<int> point_to_curve_map(curves.points_num());
threading::parallel_for(curves.curves_range(), 1024, [&](const IndexRange curves_range) {
for (const int i_curve : curves_range) {
point_to_curve_map.as_mutable_span().slice(curves.points_for_curve(i_curve)).fill(i_curve);
point_to_curve_map.as_mutable_span().slice(points_by_curve[i_curve]).fill(i_curve);
}
});
return point_to_curve_map;
@ -1175,6 +1212,7 @@ static CurvesGeometry copy_with_removed_curves(
const IndexMask curves_to_delete,
const AnonymousAttributePropagationInfo &propagation_info)
{
const OffsetIndices old_points_by_curve = curves.points_by_curve();
const Span<int> old_offsets = curves.offsets();
const Vector<IndexRange> old_curve_ranges = curves_to_delete.extract_ranges_invert(
curves.curves_range(), nullptr);
@ -1187,7 +1225,7 @@ static CurvesGeometry copy_with_removed_curves(
new_curve_ranges.append(IndexRange(new_tot_curves, curve_range.size()));
new_tot_curves += curve_range.size();
const IndexRange old_point_range = curves.points_for_curves(curve_range);
const IndexRange old_point_range = old_points_by_curve[curve_range];
old_point_ranges.append(old_point_range);
new_point_ranges.append(IndexRange(new_tot_points, old_point_range.size()));
new_tot_points += old_point_range.size();
@ -1292,9 +1330,10 @@ static void reverse_curve_point_data(const CurvesGeometry &curves,
const IndexMask curve_selection,
MutableSpan<T> data)
{
const OffsetIndices points_by_curve = curves.points_by_curve();
threading::parallel_for(curve_selection.index_range(), 256, [&](IndexRange range) {
for (const int curve_i : curve_selection.slice(range)) {
data.slice(curves.points_for_curve(curve_i)).reverse();
data.slice(points_by_curve[curve_i]).reverse();
}
});
}
@ -1305,9 +1344,10 @@ static void reverse_swap_curve_point_data(const CurvesGeometry &curves,
MutableSpan<T> data_a,
MutableSpan<T> data_b)
{
const OffsetIndices points_by_curve = curves.points_by_curve();
threading::parallel_for(curve_selection.index_range(), 256, [&](IndexRange range) {
for (const int curve_i : curve_selection.slice(range)) {
const IndexRange points = curves.points_for_curve(curve_i);
const IndexRange points = points_by_curve[curve_i];
MutableSpan<T> a = data_a.slice(points);
MutableSpan<T> b = data_b.slice(points);
for (const int i : IndexRange(points.size() / 2)) {
@ -1413,9 +1453,10 @@ static void adapt_curve_domain_point_to_curve_impl(const CurvesGeometry &curves,
{
attribute_math::DefaultMixer<T> mixer(r_values);
const OffsetIndices points_by_curve = curves.points_by_curve();
threading::parallel_for(curves.curves_range(), 128, [&](const IndexRange range) {
for (const int i_curve : range) {
for (const int i_point : curves.points_for_curve(i_curve)) {
for (const int i_point : points_by_curve[i_curve]) {
mixer.mix_in(i_curve, old_values[i_point]);
}
}
@ -1435,9 +1476,10 @@ void adapt_curve_domain_point_to_curve_impl(const CurvesGeometry &curves,
const VArray<bool> &old_values,
MutableSpan<bool> r_values)
{
const OffsetIndices points_by_curve = curves.points_by_curve();
r_values.fill(true);
for (const int i_curve : IndexRange(curves.curves_num())) {
for (const int i_point : curves.points_for_curve(i_curve)) {
for (const int i_point : points_by_curve[i_curve]) {
if (!old_values[i_point]) {
r_values[i_curve] = false;
break;
@ -1473,8 +1515,9 @@ static void adapt_curve_domain_curve_to_point_impl(const CurvesGeometry &curves,
const VArray<T> &old_values,
MutableSpan<T> r_values)
{
const OffsetIndices points_by_curve = curves.points_by_curve();
for (const int i_curve : IndexRange(curves.curves_num())) {
r_values.slice(curves.points_for_curve(i_curve)).fill(old_values[i_curve]);
r_values.slice(points_by_curve[i_curve]).fill(old_values[i_curve]);
}
}

View File

@ -14,39 +14,30 @@ void fill_curve_counts(const bke::CurvesGeometry &curves,
const Span<IndexRange> curve_ranges,
MutableSpan<int> counts)
{
const OffsetIndices points_by_curve = curves.points_by_curve();
threading::parallel_for(curve_ranges.index_range(), 512, [&](IndexRange ranges_range) {
for (const IndexRange curves_range : curve_ranges.slice(ranges_range)) {
threading::parallel_for(curves_range, 4096, [&](IndexRange range) {
for (const int i : range) {
counts[i] = curves.points_for_curve(i).size();
counts[i] = points_by_curve.size(i);
}
});
}
});
}
void accumulate_counts_to_offsets(MutableSpan<int> counts_to_offsets, const int start_offset)
{
int offset = start_offset;
for (const int i : counts_to_offsets.index_range().drop_back(1)) {
const int count = counts_to_offsets[i];
BLI_assert(count > 0);
counts_to_offsets[i] = offset;
offset += count;
}
counts_to_offsets.last() = offset;
}
void copy_point_data(const CurvesGeometry &src_curves,
const CurvesGeometry &dst_curves,
const Span<IndexRange> curve_ranges,
const GSpan src,
GMutableSpan dst)
{
const OffsetIndices src_points_by_curve = src_curves.points_by_curve();
const OffsetIndices dst_points_by_curve = dst_curves.points_by_curve();
threading::parallel_for(curve_ranges.index_range(), 512, [&](IndexRange range) {
for (const IndexRange range : curve_ranges.slice(range)) {
const IndexRange src_points = src_curves.points_for_curves(range);
const IndexRange dst_points = dst_curves.points_for_curves(range);
const IndexRange src_points = src_points_by_curve[range];
const IndexRange dst_points = dst_points_by_curve[range];
/* The arrays might be large, so a threaded copy might make sense here too. */
dst.slice(dst_points).copy_from(src.slice(src_points));
}
@ -59,10 +50,12 @@ void copy_point_data(const CurvesGeometry &src_curves,
const GSpan src,
GMutableSpan dst)
{
const OffsetIndices src_points_by_curve = src_curves.points_by_curve();
const OffsetIndices dst_points_by_curve = dst_curves.points_by_curve();
threading::parallel_for(src_curve_selection.index_range(), 512, [&](IndexRange range) {
for (const int i : src_curve_selection.slice(range)) {
const IndexRange src_points = src_curves.points_for_curve(i);
const IndexRange dst_points = dst_curves.points_for_curve(i);
const IndexRange src_points = src_points_by_curve[i];
const IndexRange dst_points = dst_points_by_curve[i];
/* The arrays might be large, so a threaded copy might make sense here too. */
dst.slice(dst_points).copy_from(src.slice(src_points));
}
@ -76,10 +69,11 @@ void fill_points(const CurvesGeometry &curves,
{
BLI_assert(*value.type() == dst.type());
const CPPType &type = dst.type();
const OffsetIndices points_by_curve = curves.points_by_curve();
threading::parallel_for(curve_selection.index_range(), 512, [&](IndexRange range) {
for (const int i : curve_selection.slice(range)) {
const IndexRange points = curves.points_for_curve(i);
type.fill_assign_n(value.get(), dst.slice(curves.points_for_curve(i)).data(), points.size());
const IndexRange points = points_by_curve[i];
type.fill_assign_n(value.get(), dst.slice(points).data(), points.size());
}
});
}
@ -91,9 +85,10 @@ void fill_points(const CurvesGeometry &curves,
{
BLI_assert(*value.type() == dst.type());
const CPPType &type = dst.type();
const OffsetIndices points_by_curve = curves.points_by_curve();
threading::parallel_for(curve_ranges.index_range(), 512, [&](IndexRange range) {
for (const IndexRange range : curve_ranges.slice(range)) {
const IndexRange points = curves.points_for_curves(range);
const IndexRange points = points_by_curve[range];
type.fill_assign_n(value.get(), dst.slice(points).data(), points.size());
}
});

View File

@ -143,6 +143,7 @@ namespace blender::bke {
static Array<float3> curve_normal_point_domain(const bke::CurvesGeometry &curves)
{
const OffsetIndices points_by_curve = curves.points_by_curve();
const VArray<int8_t> types = curves.curve_types();
const VArray<int> resolutions = curves.resolution();
const VArray<bool> curves_cyclic = curves.cyclic();
@ -158,7 +159,7 @@ static Array<float3> curve_normal_point_domain(const bke::CurvesGeometry &curves
Vector<float3> nurbs_tangents;
for (const int i_curve : range) {
const IndexRange points = curves.points_for_curve(i_curve);
const IndexRange points = points_by_curve[i_curve];
const IndexRange evaluated_points = curves.evaluated_points_for_curve(i_curve);
MutableSpan<float3> curve_normals = results.as_mutable_span().slice(points);

View File

@ -2218,7 +2218,7 @@ void BKE_keyblock_convert_to_mesh(const KeyBlock *kb,
const int totvert)
{
const int tot = min_ii(kb->totelem, totvert);
memcpy(kb->data, vert_positions, sizeof(float[3]) * tot);
memcpy(vert_positions, kb->data, sizeof(float[3]) * tot);
}
void BKE_keyblock_mesh_calc_normals(const KeyBlock *kb,

View File

@ -626,7 +626,8 @@ static bool layer_collection_hidden(ViewLayer *view_layer, LayerCollection *lc)
}
/* Restriction flags stay set, so we need to check parents */
CollectionParent *parent = static_cast<CollectionParent *>(lc->collection->parents.first);
CollectionParent *parent = static_cast<CollectionParent *>(
lc->collection->runtime.parents.first);
if (parent) {
lc = BKE_layer_collection_first_from_scene_collection(view_layer, parent->collection);
@ -662,7 +663,8 @@ bool BKE_layer_collection_activate(ViewLayer *view_layer, LayerCollection *lc)
LayerCollection *BKE_layer_collection_activate_parent(ViewLayer *view_layer, LayerCollection *lc)
{
CollectionParent *parent = static_cast<CollectionParent *>(lc->collection->parents.first);
CollectionParent *parent = static_cast<CollectionParent *>(
lc->collection->runtime.parents.first);
if (parent) {
lc = BKE_layer_collection_first_from_scene_collection(view_layer, parent->collection);

View File

@ -32,7 +32,6 @@
/* Unused currently. */
// static CLG_LogRef LOG = {.identifier = "bke.library"};
struct BlendWriter;
struct BlendDataReader;
static void library_runtime_reset(Library *lib)

View File

@ -85,9 +85,6 @@ static void metaball_free_data(ID *id)
MEM_SAFE_FREE(metaball->mat);
BLI_freelistN(&metaball->elems);
if (metaball->disp.first) {
BKE_displist_free(&metaball->disp);
}
}
static void metaball_foreach_id(ID *id, LibraryForeachIDData *data)
@ -103,7 +100,6 @@ static void metaball_blend_write(BlendWriter *writer, ID *id, const void *id_add
MetaBall *mb = (MetaBall *)id;
/* Clean up, important in undo case to reduce false detection of changed datablocks. */
BLI_listbase_clear(&mb->disp);
mb->editelems = nullptr;
/* Must always be cleared (meta's don't have their own edit-data). */
mb->needs_flush_to_id = 0;
@ -134,7 +130,6 @@ static void metaball_blend_read_data(BlendDataReader *reader, ID *id)
BLO_read_list(reader, &(mb->elems));
BLI_listbase_clear(&mb->disp);
mb->editelems = nullptr;
/* Must always be cleared (meta's don't have their own edit-data). */
mb->needs_flush_to_id = 0;

View File

@ -360,7 +360,7 @@ static void mesh_blend_read_data(BlendDataReader *reader, ID *id)
BLO_read_data_address(reader, &mesh->active_color_attribute);
BLO_read_data_address(reader, &mesh->default_color_attribute);
mesh->texflag &= ~ME_AUTOSPACE_EVALUATED;
mesh->texspace_flag &= ~ME_TEXSPACE_FLAG_AUTO_EVALUATED;
mesh->edit_mesh = nullptr;
mesh->runtime = new blender::bke::MeshRuntime();
@ -1029,9 +1029,9 @@ void BKE_mesh_copy_parameters(Mesh *me_dst, const Mesh *me_src)
me_dst->face_sets_color_default = me_src->face_sets_color_default;
/* Copy texture space. */
me_dst->texflag = me_src->texflag;
copy_v3_v3(me_dst->loc, me_src->loc);
copy_v3_v3(me_dst->size, me_src->size);
me_dst->texspace_flag = me_src->texspace_flag;
copy_v3_v3(me_dst->texspace_location, me_src->texspace_location);
copy_v3_v3(me_dst->texspace_size, me_src->texspace_size);
me_dst->vertex_group_active_index = me_src->vertex_group_active_index;
me_dst->attributes_active_index = me_src->attributes_active_index;
@ -1228,7 +1228,7 @@ BoundBox *BKE_mesh_boundbox_get(Object *ob)
void BKE_mesh_texspace_calc(Mesh *me)
{
if (me->texflag & ME_AUTOSPACE) {
if (me->texspace_flag & ME_TEXSPACE_FLAG_AUTO) {
float min[3], max[3];
INIT_MINMAX(min, max);
@ -1237,75 +1237,79 @@ void BKE_mesh_texspace_calc(Mesh *me)
max[0] = max[1] = max[2] = 1.0f;
}
float loc[3], size[3];
mid_v3_v3v3(loc, min, max);
float texspace_location[3], texspace_size[3];
mid_v3_v3v3(texspace_location, min, max);
size[0] = (max[0] - min[0]) / 2.0f;
size[1] = (max[1] - min[1]) / 2.0f;
size[2] = (max[2] - min[2]) / 2.0f;
texspace_size[0] = (max[0] - min[0]) / 2.0f;
texspace_size[1] = (max[1] - min[1]) / 2.0f;
texspace_size[2] = (max[2] - min[2]) / 2.0f;
for (int a = 0; a < 3; a++) {
if (size[a] == 0.0f) {
size[a] = 1.0f;
if (texspace_size[a] == 0.0f) {
texspace_size[a] = 1.0f;
}
else if (size[a] > 0.0f && size[a] < 0.00001f) {
size[a] = 0.00001f;
else if (texspace_size[a] > 0.0f && texspace_size[a] < 0.00001f) {
texspace_size[a] = 0.00001f;
}
else if (size[a] < 0.0f && size[a] > -0.00001f) {
size[a] = -0.00001f;
else if (texspace_size[a] < 0.0f && texspace_size[a] > -0.00001f) {
texspace_size[a] = -0.00001f;
}
}
copy_v3_v3(me->loc, loc);
copy_v3_v3(me->size, size);
copy_v3_v3(me->texspace_location, texspace_location);
copy_v3_v3(me->texspace_size, texspace_size);
me->texflag |= ME_AUTOSPACE_EVALUATED;
me->texspace_flag |= ME_TEXSPACE_FLAG_AUTO_EVALUATED;
}
}
void BKE_mesh_texspace_ensure(Mesh *me)
{
if ((me->texflag & ME_AUTOSPACE) && !(me->texflag & ME_AUTOSPACE_EVALUATED)) {
if ((me->texspace_flag & ME_TEXSPACE_FLAG_AUTO) &&
!(me->texspace_flag & ME_TEXSPACE_FLAG_AUTO_EVALUATED)) {
BKE_mesh_texspace_calc(me);
}
}
void BKE_mesh_texspace_get(Mesh *me, float r_loc[3], float r_size[3])
void BKE_mesh_texspace_get(Mesh *me, float r_texspace_location[3], float r_texspace_size[3])
{
BKE_mesh_texspace_ensure(me);
if (r_loc) {
copy_v3_v3(r_loc, me->loc);
if (r_texspace_location) {
copy_v3_v3(r_texspace_location, me->texspace_location);
}
if (r_size) {
copy_v3_v3(r_size, me->size);
if (r_texspace_size) {
copy_v3_v3(r_texspace_size, me->texspace_size);
}
}
void BKE_mesh_texspace_get_reference(Mesh *me, char **r_texflag, float **r_loc, float **r_size)
void BKE_mesh_texspace_get_reference(Mesh *me,
char **r_texspace_flag,
float **r_texspace_location,
float **r_texspace_size)
{
BKE_mesh_texspace_ensure(me);
if (r_texflag != nullptr) {
*r_texflag = &me->texflag;
if (r_texspace_flag != nullptr) {
*r_texspace_flag = &me->texspace_flag;
}
if (r_loc != nullptr) {
*r_loc = me->loc;
if (r_texspace_location != nullptr) {
*r_texspace_location = me->texspace_location;
}
if (r_size != nullptr) {
*r_size = me->size;
if (r_texspace_size != nullptr) {
*r_texspace_size = me->texspace_size;
}
}
void BKE_mesh_texspace_copy_from_object(Mesh *me, Object *ob)
{
float *texloc, *texsize;
char *texflag;
float *texspace_location, *texspace_size;
char *texspace_flag;
if (BKE_object_obdata_texspace_get(ob, &texflag, &texloc, &texsize)) {
me->texflag = *texflag;
copy_v3_v3(me->loc, texloc);
copy_v3_v3(me->size, texsize);
if (BKE_object_obdata_texspace_get(ob, &texspace_flag, &texspace_location, &texspace_size)) {
me->texspace_flag = *texspace_flag;
copy_v3_v3(me->texspace_location, texspace_location);
copy_v3_v3(me->texspace_size, texspace_size);
}
}
@ -1329,22 +1333,22 @@ float (*BKE_mesh_orco_verts_get(Object *ob))[3]
void BKE_mesh_orco_verts_transform(Mesh *me, float (*orco)[3], int totvert, int invert)
{
float loc[3], size[3];
float texspace_location[3], texspace_size[3];
BKE_mesh_texspace_get(me->texcomesh ? me->texcomesh : me, loc, size);
BKE_mesh_texspace_get(me->texcomesh ? me->texcomesh : me, texspace_location, texspace_size);
if (invert) {
for (int a = 0; a < totvert; a++) {
float *co = orco[a];
madd_v3_v3v3v3(co, loc, co, size);
madd_v3_v3v3v3(co, texspace_location, co, texspace_size);
}
}
else {
for (int a = 0; a < totvert; a++) {
float *co = orco[a];
co[0] = (co[0] - loc[0]) / size[0];
co[1] = (co[1] - loc[1]) / size[1];
co[2] = (co[2] - loc[2]) / size[2];
co[0] = (co[0] - texspace_location[0]) / texspace_size[0];
co[1] = (co[1] - texspace_location[1]) / texspace_size[1];
co[2] = (co[2] - texspace_location[2]) / texspace_size[2];
}
}
}
@ -1889,10 +1893,10 @@ void BKE_mesh_eval_geometry(Depsgraph *depsgraph, Mesh *mesh)
}
if (DEG_is_active(depsgraph)) {
Mesh *mesh_orig = (Mesh *)DEG_get_original_id(&mesh->id);
if (mesh->texflag & ME_AUTOSPACE_EVALUATED) {
mesh_orig->texflag |= ME_AUTOSPACE_EVALUATED;
copy_v3_v3(mesh_orig->loc, mesh->loc);
copy_v3_v3(mesh_orig->size, mesh->size);
if (mesh->texspace_flag & ME_TEXSPACE_FLAG_AUTO_EVALUATED) {
mesh_orig->texspace_flag |= ME_TEXSPACE_FLAG_AUTO_EVALUATED;
copy_v3_v3(mesh_orig->texspace_location, mesh->texspace_location);
copy_v3_v3(mesh_orig->texspace_size, mesh->texspace_size);
}
}
}

View File

@ -401,9 +401,9 @@ static Mesh *mesh_nurbs_displist_to_mesh(const Curve *cu, const ListBase *dispba
*/
static void mesh_copy_texture_space_from_curve_type(const Curve *cu, Mesh *me)
{
me->texflag = cu->texflag & ~CU_AUTOSPACE;
copy_v3_v3(me->loc, cu->loc);
copy_v3_v3(me->size, cu->size);
me->texspace_flag = cu->texspace_flag & ~CU_TEXSPACE_FLAG_AUTO;
copy_v3_v3(me->texspace_location, cu->texspace_location);
copy_v3_v3(me->texspace_size, cu->texspace_size);
BKE_mesh_texspace_calc(me);
}

View File

@ -1131,7 +1131,11 @@ void BKE_ntree_update_tag_node_removed(bNodeTree *ntree)
void BKE_ntree_update_tag_node_reordered(bNodeTree *ntree)
{
add_tree_tag(ntree, NTREE_CHANGED_ANY);
/* Don't add a tree update tag to avoid reevaluations for trivial operations like selection or
* parenting that typically influence the node order. This means the node order can be different
* for original and evaluated trees. A different solution might avoid sorting nodes based on UI
* states like selection, which would require not tying the node order to the drawing order. */
ntree->runtime->topology_cache_mutex.tag_dirty();
}
void BKE_ntree_update_tag_node_mute(bNodeTree *ntree, bNode *node)

View File

@ -4360,42 +4360,45 @@ void BKE_object_sculpt_data_create(Object *ob)
ob->sculpt->mode_type = (eObjectMode)ob->mode;
}
bool BKE_object_obdata_texspace_get(Object *ob, char **r_texflag, float **r_loc, float **r_size)
bool BKE_object_obdata_texspace_get(Object *ob,
char **r_texspace_flag,
float **r_texspace_location,
float **r_texspace_size)
{
if (ob->data == nullptr) {
return false;
}
switch (GS(((ID *)ob->data)->name)) {
case ID_ME: {
BKE_mesh_texspace_get_reference((Mesh *)ob->data, r_texflag, r_loc, r_size);
BKE_mesh_texspace_get_reference(
(Mesh *)ob->data, r_texspace_flag, r_texspace_location, r_texspace_size);
break;
}
case ID_CU_LEGACY: {
Curve *cu = (Curve *)ob->data;
BKE_curve_texspace_ensure(cu);
if (r_texflag) {
*r_texflag = &cu->texflag;
if (r_texspace_flag) {
*r_texspace_flag = &cu->texspace_flag;
}
if (r_loc) {
*r_loc = cu->loc;
if (r_texspace_location) {
*r_texspace_location = cu->texspace_location;
}
if (r_size) {
*r_size = cu->size;
if (r_texspace_size) {
*r_texspace_size = cu->texspace_size;
}
break;
}
case ID_MB: {
MetaBall *mb = (MetaBall *)ob->data;
if (r_texflag) {
*r_texflag = &mb->texflag;
if (r_texspace_flag) {
*r_texspace_flag = &mb->texspace_flag;
}
if (r_loc) {
*r_loc = mb->loc;
if (r_texspace_location) {
*r_texspace_location = mb->texspace_location;
}
if (r_size) {
*r_size = mb->size;
if (r_texspace_size) {
*r_texspace_size = mb->texspace_size;
}
break;
}

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