UI: Asset Shelf (Experimental Feature) #104831
|
@ -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).
|
||||
|
|
@ -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!
|
|
@ -0,0 +1 @@
|
|||
blank_issues_enabled: false
|
|
@ -0,0 +1,9 @@
|
|||
name: Design
|
||||
about: Create a design task (for developers only)
|
||||
labels:
|
||||
- design
|
||||
body:
|
||||
- type: textarea
|
||||
id: body
|
||||
attributes:
|
||||
label: "Description"
|
|
@ -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"
|
|
@ -1,4 +0,0 @@
|
|||
---
|
||||
name: Pull Request
|
||||
about: Submit a pull request
|
||||
---
|
|
@ -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.
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) */
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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: {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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],
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
#pragma once
|
||||
|
||||
struct IDRemapper;
|
||||
struct Main;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
|
|
@ -28,7 +28,6 @@ extern "C" {
|
|||
|
||||
struct ColorManagedDisplay;
|
||||
struct ResultBLF;
|
||||
struct rctf;
|
||||
struct rcti;
|
||||
|
||||
int BLF_init(void);
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -19,7 +19,6 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
struct ID;
|
||||
struct ListBase;
|
||||
struct Main;
|
||||
struct ReportList;
|
||||
|
||||
|
|
|
@ -18,7 +18,6 @@ extern "C" {
|
|||
struct Brush;
|
||||
struct ImBuf;
|
||||
struct ImagePool;
|
||||
struct Object;
|
||||
struct Main;
|
||||
struct MTex;
|
||||
struct Scene;
|
||||
|
|
|
@ -16,7 +16,6 @@ struct CollisionModifierData;
|
|||
struct Depsgraph;
|
||||
struct MVertTri;
|
||||
struct Object;
|
||||
struct Scene;
|
||||
|
||||
////////////////////////////////////////
|
||||
// used for collisions in collision.c
|
||||
|
|
|
@ -15,7 +15,6 @@ extern "C" {
|
|||
|
||||
struct BoundBox;
|
||||
struct Curves;
|
||||
struct CustomDataLayer;
|
||||
struct Depsgraph;
|
||||
struct Main;
|
||||
struct Object;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -43,7 +43,6 @@ enum {
|
|||
|
||||
struct Depsgraph;
|
||||
struct ListBase;
|
||||
struct Mesh;
|
||||
struct Object;
|
||||
struct Scene;
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct Collection;
|
||||
struct GeometrySet;
|
||||
struct Object;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "BLI_float4x4.hh"
|
||||
|
||||
#include "BKE_geometry_set.hh"
|
||||
|
||||
namespace blender::bke {
|
||||
|
|
|
@ -16,7 +16,6 @@ struct Brush;
|
|||
struct CurveMapping;
|
||||
struct Depsgraph;
|
||||
struct GHash;
|
||||
struct GPencilUpdateCache;
|
||||
struct ListBase;
|
||||
struct MDeformVert;
|
||||
struct Main;
|
||||
|
|
|
@ -14,7 +14,6 @@ extern "C" {
|
|||
struct Depsgraph;
|
||||
struct Main;
|
||||
struct Object;
|
||||
struct RegionView3D;
|
||||
struct Scene;
|
||||
struct bGPDcurve;
|
||||
struct bGPDframe;
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -23,7 +23,6 @@
|
|||
#include "DNA_image_types.h"
|
||||
|
||||
extern "C" {
|
||||
struct PartialUpdateRegister;
|
||||
struct PartialUpdateUser;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
/**
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
struct BMEditMesh;
|
||||
struct CustomData_MeshMasks;
|
||||
struct Mesh;
|
||||
struct Object;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
|
|
@ -24,8 +24,6 @@ struct Object;
|
|||
struct Scene;
|
||||
struct SubdivCCG;
|
||||
|
||||
struct MLoop;
|
||||
struct MLoopTri;
|
||||
struct MPoly;
|
||||
|
||||
/**
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -31,7 +31,6 @@ struct CustomData_MeshMasks;
|
|||
struct Depsgraph;
|
||||
struct EdgeHash;
|
||||
struct KDTree_3d;
|
||||
struct LatticeDeformData;
|
||||
struct LinkNode;
|
||||
struct MCol;
|
||||
struct MFace;
|
||||
|
|
|
@ -20,7 +20,6 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
struct BoundBox;
|
||||
struct CustomDataLayer;
|
||||
struct Depsgraph;
|
||||
struct Main;
|
||||
struct Object;
|
||||
|
|
|
@ -24,7 +24,6 @@ struct CCGVert;
|
|||
struct DMFlagMat;
|
||||
struct DerivedMesh;
|
||||
struct EdgeHash;
|
||||
struct MPoly;
|
||||
struct Mesh;
|
||||
struct MeshElemMap;
|
||||
struct Object;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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... */
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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]);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
});
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -32,7 +32,6 @@
|
|||
/* Unused currently. */
|
||||
// static CLG_LogRef LOG = {.identifier = "bke.library"};
|
||||
|
||||
struct BlendWriter;
|
||||
struct BlendDataReader;
|
||||
|
||||
static void library_runtime_reset(Library *lib)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
Loading…
Reference in New Issue