Commit Graph

407 Commits

Author SHA1 Message Date
Weizhen Huang
a7283fc1d5 Cycles: Shade volume with null scattering
The distance sampling is mostly based on weighted delta tracking from
[Monte Carlo Methods for Volumetric Light Transport Simulation]
(http://iliyan.com/publications/VolumeSTAR/VolumeSTAR_EG2018.pdf).

The recursive Monte Carlo estimation of the Radiative Transfer Equation is
\[\langle L \rangle=\frac{\bar T(x\rightarrow y)}{\bar p(x\rightarrow
y)}(L_e+\sigma_s L_s + \sigma_n L).\]
where \(\bar T(x\rightarrow y) = e^{-\bar\sigma\Vert x-y\Vert}\) is the
majorant transmittance between points \(x\) and \(y\), \(p(x\rightarrow
y) = \bar\sigma e^{-\bar\sigma\Vert x-y\Vert}\) is the probability of
sampling point \(y\) from point \(x\) following exponential
distribution.

At each recursive step, we randomly pick one of the two events
proportional to their weights:
* If \(\xi < \frac{\sigma_s}{\sigma_s+\vert\sigma_n\vert}\), we sample
scatter event and evaluate \(L_s\).
* Otherwise, no real collision happens and we continue the recursive
process.

The emission \(L_e\) is evaluated at each step.

This also removes some unused volume settings from the UI:

* "Max Steps" is removed, because the step size is automatically specified
by the volume octree. There is a hard-coded threshold `VOLUME_MAX_STEPS`
to prevent numerical issues.
* "Homogeneous" is automatically detected during density evaluation

An option "Unbiased" is added to the UI. When enabled, densities above
the majorant are clamped.
2025-08-13 10:28:50 +02:00
Campbell Barton
cccc2c77c5 Cleanup: consistent for C-style comment blocks 2025-08-08 07:37:33 +10:00
Lukas Stockner
793040ad1c Cycles: Improve parameter packing for the Principled BSDF
The Principled BSDF has a ton of inputs, and the previous SVM code just always
allocated stack space for all of them. This results in a ton of additional
NODE_VALUE_x SVM nodes, which slow down execution.

However, this is not really needed for two reasons:
- First, many inputs are only used consitionally. For example, if the
  subsurface weight is zero, none of the other subsurface inputs are used.
- Many of the inputs have a "usual" value that they will have in most
  materials, so if they happen to have that value we can just indicate that
  by not allocating space for them.
  This is a bit similar to the standard "pack the fixed value and provide
  a stack offset if there's a link" pattern, except that the fixed value
  is a constant in the code and we allocate a NODE_VALUE_x if a different
  fixed value is used.

Therefore, this PR re-implements the parameter packing in a more efficient way:
- If we can determine that a component is disabled, all conditional inputs are
  disconnected (to avoid generating upstream nodes).
- If we can determine that a component is disabled, we skip allocating all
  conditional inputs on the stack.
- The inputs for which a reasonable "usual" value exists are changed to
  respect that, and to only be allocated if they differ.
- param1 and param2 (which are fixed-value-packed as on all BSDF nodes) are
  used to store IOR and roughness, which have a decent chance to be fixed
  values.
- The parameter packing is more aggressive about using uchar4, which allows
  to get rid of two SVM nodes while still storing the same inputs.

The result is a considerable speedup in scenes that make heavy use of the
Principled BSDF:

| Scene | CPU speedup | OptiX speedup |
| --- | --- | --- |
| attic | 5% | 9% |
| bistro | 5% | 8% |
| junkshop | 5% | 10% |
| monster | 3% | 4% |
| spring | 1% | 6% |

Pull Request: https://projects.blender.org/blender/blender/pulls/143910
2025-08-04 18:34:58 +02:00
Amogh Shivaram
ff4d840cf8 Cycles: Add polarized Fresnel function for conductors
This PR adds a new `fresnel_conductor_polarized` function, which calculates reflectance and phase shift (if requested) for both parallel and perpendicular polarized light. This is needed for applying thin film iridescence to conductors (see !141131).

For consistency, this PR also makes `fresnel_conductor` call `fresnel_conductor_polarized` instead of using a fast approximation of the Fresnel equations that is inaccurate at lower n and k values. This will change the output of some Metallic BSDF renders using Physical Conductor and prevent discrepancies when enabling thin film iridescence.

I didn't do any rigorous performance testing, but from timing the functions outside of Blender, `fresnel_conductor_polarized` is significantly slower than the approximation, between 1.5-3x depending on the compiler. This makes sense because it has three square roots and the approximation has none. In some informal tests with metallic_multiggx_physical.blend modified to have more spheres, the new renders took around 1-2% longer on both CPU and GPU.

There are some avoidable inefficiencies in this approach of just calling `fresnel_conductor_polarized`:

- one of the three square roots could be saved since `fresnel_conductor` never needs the phase shift and there are simplifications possible when only calculating the reflectance
- there are several unnecessary multiplications by 1.0 since `fresnel_conductor` uses relative IOR and `fresnel_conductor_polarized` doesn't, though those could get optimized out if inlined

Pull Request: https://projects.blender.org/blender/blender/pulls/143903
2025-08-04 15:36:36 +02:00
Patrick Mours
6487395fa5 Cycles: Add linear curve shape
Add new "Linear 3D Curves" option in the Curves panel in the render
properties. This renders curves as linear segments rather than smooth
curves, for faster render time at the cost of accuracy.

On NVIDIA Blackwell GPUs, this can give a 6x speedup compared to smooth
curves, due to hardware acceleration. On NVIDIA Ada there is still
a 3x speedup, and CPU and other GPU backends will also render this
faster.

A difference with smooth curves is that these have end caps, as this
was simpler to implement and they are usually helpful anyway.

In the future this functionality will also be used to properly support
the CURVE_TYPE_POLY on the new curves object.

Pull Request: https://projects.blender.org/blender/blender/pulls/139735
2025-07-29 17:05:01 +02:00
Weizhen Huang
5a27edcf79 Fix #141136: Cycles Hair black artifacts with direct coloring
fixed by clamping negative input colors

Pull Request: https://projects.blender.org/blender/blender/pulls/142667
2025-07-21 12:15:04 +02:00
Lukas Stockner
eaa5f63ba2 Cycles: Replace thin-film basis function approximation with accurate LUTs
Previously, we used precomputed Gaussian fits to the XYZ CMFs, performed
the spectral integration in that space, and then converted the result
to the RGB working space.

That worked because we're only supporting dielectric base layers for
the thin film code, so the inputs to the spectral integration
(reflectivity and phase) are both constant w.r.t. wavelength.

However, this will no longer work for conductive base layers.
We could handle reflectivity by converting to XYZ, but that won't work
for phase since its effect on the output is nonlinear.

Therefore, it's time to do this properly by performing the spectral
integration directly in the RGB primaries. To do this, we need to:
- Compute the RGB CMFs from the XYZ CMFs and XYZ-to-RGB matrix
- Resample the RGB CMFs to be parametrized by frequency instead of wavelength
- Compute the FFT of the CMFs
- Store it as a LUT to be used by the kernel code

However, there's two optimizations we can make:
- Both the resampling and the FFT are linear operations, as is the
  XYZ-to-RGB conversion. Therefore, we can resample and Fourier-transform
  the XYZ CMFs once, store the result in a precomputed table, and then just
  multiply the entries by the XYZ-to-RGB matrix at runtime.
  - I've included the Python script used to compute the table under
    `intern/cycles/doc/precompute`.
- The reference implementation by the paper authors [1] simply stores the
  real and imaginary parts in the LUT, and then computes
  `cos(shift)*real + sin(shift)*imag`. However, the real and imaginary parts
  are oscillating, so the LUT with linear interpolation is not particularly
  good at representing them. Instead, we can convert the table to
  Magnitude/Phase representation, which is much smoother, and do
  `mag * cos(phase - shift)` in the kernel.
  - Phase needs to be unwrapped to handle the interpolation decently,
    but that's easy.
  - This requires an extra trig operation in the kernel in the dielectric case,
    but for the conductive case we'll actually save three.

Rendered output is mostly the same, just slightly different because we're
no longer using the Gaussian approximation.

[1] "A Practical Extension to Microfacet Theory for the Modeling of
    Varying Iridescence" by Laurent Belcour and Pascal Barla,
    https://belcour.github.io/blog/research/publication/2017/05/01/brdf-thin-film.html

Pull Request: https://projects.blender.org/blender/blender/pulls/140944
2025-07-09 22:10:28 +02:00
Lukas Stockner
bfcfe730ed Cleanup: Cycles: Move F82 Fresnel model into helper function 2025-07-08 01:23:33 +02:00
Campbell Barton
776dbe942c Cleanup: spelling (make check_spelling_*) 2025-06-22 11:34:32 +00:00
Brecht Van Lommel
17bda2cf3f Cycles: Enable multi-bounce random walk subsurface scattering
Multi-bounce was mainly disabled for disk sampling where the probability of
hitting something is relatively low even with high albedo, but this is not so
much an issue with random walk.

This reduces darkening artifacts at the cost of some extra render time. The
difference is mainly visible when using a high radius.

Pull Request: https://projects.blender.org/blender/blender/pulls/140665
2025-06-19 20:04:49 +02:00
Lukas Stockner
49ae867de4 Fix #139870: Cycles: Some objects with normal maps leak light
This was broken by !138632, the refactor of the microfacet code to no longer
check the "geometric normal", which in reality was the smoothed normal.

Since the logic is now the same for all closure types, it seemed weird that
the light leak only affects Microfacet closures, not Diffuse.

Turns out that for diffuse closures, the relevant paths were rejected by
the initial hemisphere check in the smooth bump terminator code, which also
incorporates the smoothed but non-bump/normal-mapped normal sd->N.

So, we can detect and prevent the new light leaks by extending this check to
all closure types for the eval case. Sampling already has stricter checks,
so this doesn't apply there.

With this change, we can revert the two test cases back to their pre-refactor
version. In hindsight it was a mistake to just shrug off these changes as okay,
I should have looked closer into the difference.

Pull Request: https://projects.blender.org/blender/blender/pulls/140415
2025-06-19 19:20:06 +02:00
Brecht Van Lommel
50b554e1aa Cleanup: Unused parameter warning 2025-06-02 13:59:14 +02:00
Brecht Van Lommel
0e7a696819 Cleanup: Unused arguments in Cycles kernel
And add back the compiler flag that hid them.

Pull Request: https://projects.blender.org/blender/blender/pulls/139497
2025-05-27 21:30:45 +02:00
Lukas Stockner
a6015e1411 Cycles: Fix inconsistency in Ng handling between Microfacets and other closures
In Cycles, the convention is that reflection vs. refraction are classified
based on the hemisphere defined by the *shading* normal (N).

In general, most closure code uses the shading normal for most operations,
as is expected since using the geometric normal (Ng) would break normal maps
and smooth shading.

However, there are two places that use Ng: On the one hand, BSDF sampling
functions generally reject reflections that fall below the Ng hemisphere, since
they'd intersect the geometry when tracing the bounce. This is required, and
we can't do much about it.
On the other hand, the Microfacet evaluation code also checked that the ray
is in the same hemisphere w.r.t. both shading and geometric normal.

Theoretically, this is the right thing to do, since sampling and evaluation code
are supposed to be consistent. However, doing so breaks smooth shading, since
now direct light evaluation near the terminator will sometimes be rejected.

This didn't cause problems in practice because of another inconsistency: While
the parameter of the eval functions was named Ng, the caller actually provided
N (unclear whether by mistake or as a hacky workaround to the terminator).
When this was fixed in 063a9e89, users quickly reported issues with the shadow
terminator, so it was reverted to the hacky inconsistency in 1c50dd8b.

So, let's clean this mess up properly. If we don't want to do the Ng hemisphere
check in _eval, then instead of passing in a misleading value that ends up
making it a no-op, just remove the check. After all, the other closures don't
perform it either.

This way, we avoid the mislabeled Ng, we get rid of the special case for
microfacets, and the shadow terminator continues to be fine.

Technically, we still have the _sample vs. _eval mismatch. However, this is just
unavoidable, and is irrelevant in practice: For a strongly directional light
that makes the shadow terminator noticeable, the MIS weights will be massively
in favor of eval, to the point that it doesn't really matter what sample does.

To support this argument: You can actually reproduce a broken shadow terminator
in pretty much every Cycles version going back to 2011 by just setting up a
small intense mesh emitter, turning off MIS on it to disable _eval, and then
rendering a diffuse smooth-shaded sphere with >100000 samples so that the
fireflies resolve into somewhat consistent lighting.
If nobody has complained about this affecting all closures for 11 years,
I guess it's fine.

Pull Request: https://projects.blender.org/blender/blender/pulls/138632
2025-05-18 17:20:32 +02:00
Weizhen Huang
69c194ee5a Cleanup: Cycles: safer division in volume sample channel 2025-05-05 18:35:24 +02:00
Weizhen Huang
4e36a31871 Cleanup: Cycles: split volume_sample_channel() into two functions 2025-05-05 18:35:24 +02:00
Campbell Barton
c90e8bae0b Cleanup: spelling in comments & replace some use of single quotes
Previously spell checker ignored text in single quotes however this
meant incorrect spelling was ignored in text where it shouldn't have
been.

In cases single quotes were used for literal strings
(such as variables, code & compiler flags),
replace these with back-ticks.

In cases they were used for UI labels,
replace these with double quotes.

In cases they were used to reference symbols,
replace them with doxygens symbol link syntax (leading hash).

Apply some spelling corrections & tweaks (for check_spelling_* targets).
2025-04-26 11:17:13 +00:00
nubnubbud
5e2afb3f6f Cycles: Replace bump correction algorithm to better respect normal maps
The new correction avoids washed out areas near the shadow terminator,
preserving more detail from normal and bump maps.

It implements the method from the paper "A Microfacet-Based Shadowing
Function to Solve the Bump Terminator Problem" by Alejandro Conty Estevez,
Pascal Lecocq, and Clifford Stein.

Pull Request: https://projects.blender.org/blender/blender/pulls/135380
2025-03-25 18:01:01 +01:00
Brecht Van Lommel
48398b223b Cleanup: Fix various divisions by zero reported by ASAN
Pull Request: https://projects.blender.org/blender/blender/pulls/135326
2025-03-06 22:34:23 +01:00
Lukas Stockner
9254532b8b Fix #129306: Cycles: Principled coat doesn't pass furnace test
This implements three improvements to the energy preservation and albedo
scaling logic, which help the Principled BSDF pass the white-furnace test
when using the coat layers at high roughness.

Specifically, at roughness 0.3, the albedo scaling brings it from 60% at
the edge to 95%, and with the energy preservation it's 99.8%.

Pull Request: https://projects.blender.org/blender/blender/pulls/134620
2025-02-26 15:47:21 +01:00
Weizhen Huang
b76fbb285e Cycles: Change the integration measure in Huang Hair from gamma to h
To align better with the pixel and reduce the samples needed.

The paper was using gamma because the jacobian |d_gamma/d_h| approaches
infinity at the boundaries, but it seems that clamping at 0.999 is
enough for numerical stability.

In practice I did not notice a change in the noise level, but it
simplifies the range computation and renders faster due to reduced
sample amount.

Co-authored-by: Olivier Maury <omaury@meta.com>

Ref: !129616

Pull Request: https://projects.blender.org/blender/blender/pulls/134130
2025-02-10 14:58:26 +01:00
Weizhen Huang
8e4d5a47d7 Cleanup: Cycles: add utility function is_circular() for Huang Hair
Pull Request: https://projects.blender.org/blender/blender/pulls/134129
2025-02-05 18:44:04 +01:00
Weizhen Huang
f22bfc46d1 Cleanup: Cycles: use utility struct Interval to improve readability 2025-02-05 18:44:03 +01:00
Alex
c6d7bee181 Cycles: Burley diffuse closure for MaterialX compatibility
Add Burley diffuse to OSL for MaterialX compatibility. It is OSL only and
isn't a closure that will be looked for in SVM.

Pull Request: https://projects.blender.org/blender/blender/pulls/133845
2025-02-04 19:38:56 +01:00
Alex
e39b2ee816 Cycles: OSL oren_nayar_diffuse_bsdf compatibility for MaterialX
The oren_nayar_diffuse_bsdf closure in OSL had two issues:
- It broke when used with roughness of zero
- It only used the provided albedo for energy compensation, so it still
  required the user to multiply with the albedo

Therefore, this handles the zero roughness corner case and includes
the albedo in the closure weight.
This makes no difference when using the closure through the Diffuse
or Principled BSDF nodes, only for custom OSL shaders.

Pull Request: https://projects.blender.org/blender/blender/pulls/133597
2025-01-27 17:58:20 +01:00
Weizhen Huang
e6645bf06b Fix #131240: Cycles: Negative integration range in Huang Hair
It is possible that the valid range computed from `theta` and the range
visible to the current pixel do not overlap. In this case the hair
section has no contribution.

Pull Request: https://projects.blender.org/blender/blender/pulls/133337
2025-01-21 11:48:45 +01:00
Alaska
b9ebd96539 Fix #133229: Remove camera size optimization from SSS shader in Cycles
In Cycles, the subsurface scattering shader will switch to a
diffuse shader under a few different conditions to improve performance
and reduce noise.

This commit removes the "switch back to diffuse if the scattering
radius is less than a quarter of a pixel" optimization because in some
scenes, this can result in noticable lines as the shader transitions
between subsurface scattering and diffuse.

Pull Request: https://projects.blender.org/blender/blender/pulls/133245
2025-01-21 04:31:43 +01:00
Brecht Van Lommel
57ff24cb99 Refactor: Cycles: Add const keyword to more function parameters
Pull Request: https://projects.blender.org/blender/blender/pulls/132361
2025-01-03 10:23:24 +01:00
Brecht Van Lommel
dd51c8660b Refactor: Cycles: Add const keyword where possible, using clang-tidy
Check was misc-const-correctness, combined with readability-isolate-declaration
as suggested by the docs.

Temporarily clang-format "QualifierAlignment: Left" was used to get consistency
with the prevailing order of keywords.

Pull Request: https://projects.blender.org/blender/blender/pulls/132361
2025-01-03 10:23:20 +01:00
Brecht Van Lommel
d0c2e68e5f Refactor: Cycles: Automated clang-tidy fixups in Cycles
* Use .empty() and .data()
* Use nullptr instead of 0
* No else after return
* Simple class member initialization
* Add override for virtual methods
* Include C++ instead of C headers
* Remove some unused includes
* Use default constructors
* Always use braces
* Consistent names in definition and declaration
* Change typedef to using

Pull Request: https://projects.blender.org/blender/blender/pulls/132361
2025-01-03 10:22:55 +01:00
Brecht Van Lommel
5c46063607 Refactor: Cycles: Make kernel headers work by themselves
Shuffle around some code and add more includes so that individual
header files compile without errors.

Pull Request: https://projects.blender.org/blender/blender/pulls/132361
2025-01-03 10:22:50 +01:00
Brecht Van Lommel
7db0bc2e64 Refactor: Cycles: Make math and type headers work by themselves
Remove separate impl.h headers, shuffle around some code and add more
includes so that individual header files compile without errors.

Pull Request: https://projects.blender.org/blender/blender/pulls/132361
2025-01-03 10:22:47 +01:00
Brecht Van Lommel
3c2a6fbb9c Refactor: Cycles: Use nullptr instead of NULL
Pull Request: https://projects.blender.org/blender/blender/pulls/132361
2025-01-03 10:22:43 +01:00
Sergey Sharybin
ba4c79feee Fix: Huang hair sampling does not advance LCG
The reason for this probably was the const nature of the shader data.
However, this is something counter-intuitive, as it potentially leads
to multiple BSDFs re-using the same LCG state.

Pull Request: https://projects.blender.org/blender/blender/pulls/132456
2024-12-31 10:25:19 +01:00
Thomas Dinges
1be75e86aa Cleanup: replace floatX_to_floatY() with make_floatY()
Now that function overloads are usable on all GPUs, replace the former explicit functions.

Pull Request: https://projects.blender.org/blender/blender/pulls/132067
2024-12-19 09:41:55 +01:00
Aras Pranckevicius
35d7477371 Cycles: fix accuracy issues in fast_sin/fast_cos/fast_sincos
Most of these originate from OIIO of about 10 years ago. Integrate
the upstream fix from OIIO:
https://github.com/AcademySoftwareFoundation/OpenImageIO/commit/88feb65fc992

Cover them with unit tests. Before the fix, fast_sinf(1.57085085f)
was returning 0.0 instead of 1.0 as expected.

Revert previous hair workaround (a16879a5f0)

Co-authored-by: Sergey Sharybin <sergey@blender.org>
Pull Request: https://projects.blender.org/blender/blender/pulls/131957
2024-12-16 10:05:47 +01:00
Weizhen Huang
c99b7e66b2 Cycles: support Mie Scattering with particle size smaller than 5um
Previous implemenation of 5 < d < 50 was taken from the main paper,
fitting for smaller sizes are found in the supplemental. They are less
forward-scattering.

Pull Request: https://projects.blender.org/blender/blender/pulls/130234
2024-12-13 15:50:54 +01:00
Weizhen Huang
16132f8c79 Fix #117667: Remove volume density weight cutoff
`CLOSURE_WEIGHT_CUTOFF` avoids allocating a closure when its weight is
too small. It makes sense for surface closures, but for volume closures
the contribution also depends on the object size/ray length, such a
cutoff seems random and is causing problem in atmospheric scatterings.

Therefore remove the cutoff for volume, just make sure the weight is
positive.

Pull Request: https://projects.blender.org/blender/blender/pulls/131696
2024-12-13 10:28:49 +01:00
Weizhen Huang
a16879a5f0 Fix #131240: Cycles: Negative integration range in Huang Hair
The cause is numerical issues with `fast_sinf()`. While fixing
`fast_sinf()` would ultimately fix the problem, it involves more
complications in other code paths, and it is safer to clamp the
integration range anyway.

Pull Request: https://projects.blender.org/blender/blender/pulls/131689
2024-12-10 21:56:04 +01:00
Thomas Dinges
5ddf8a6495 Merge branch 'blender-v4.3-release' 2024-11-18 19:14:10 +01:00
Lukas Stockner
1a40efbded Fix #130389: Cycles: Numerical issues in GGX_D with associative math flag
Turns out that with `-fassociative-math`, GCC turns
`(1.0f - cos_NH2) + alpha2 * cos_NH2` into
`cos_NH2 * (alpha2 - 1.0f) + 1.0f`.

Not sure why since the operation count is the same, but if alpha2 is very
small, `alpha2 - 1.0f` will be exactly -1.0f, which then causes issues.

Luckily, having one_minus_cos_NH2 as its own variable appears to be enough to
make GCC keep the original formulation.
Just to be safe, I've also used one_minus_cos_NH2 in the other branch to
hopefully reduce the chance of it being folded in again. Also turns a
division into a reciprocal, which is in theory slightly faster.

Pull Request: https://projects.blender.org/blender/blender/pulls/130469
2024-11-18 19:12:22 +01:00
Weizhen Huang
60b8fd005d Merge branch 'blender-v4.3-release' 2024-10-22 15:38:48 +02:00
Weizhen Huang
afd629bffc Cycles: make switching of sampling techniques in Draine less noticeable
Draine phase function sampling internally use Henyey-Greenstein and
Rayleigh sampling for degenerated cases, but the sampling pattern was
different between Draine and Rayleigh. The commit effectively replace
`rand` with `1 - rand` in Rayleigh sampling.

Pull Request: https://projects.blender.org/blender/blender/pulls/129261
2024-10-22 15:38:06 +02:00
Weizhen Huang
ee6f27a100 Fix: Cycles: NaN in Draine phase function when g == 0
When `g == 0`, the Draine phase function from
https://doi.org/10.1051/0004-6361/202142437 simplifies to
\[\Phi(\theta)=\frac{3}{4\pi(3+\alpha)}(1+\alpha\cos^2\theta).\]
Similar as Rayleigh sampling in https://doi.org/10.1364/JOSAA.28.002436,
The solution to the CDF of the marginal density function is
\[\cos^3\theta+a\cos\theta+b=0,\]
with
\[a=\frac{3}{\alpha},\quad b=\frac{3+\alpha}{\alpha}(2\xi_1-1),\]
which has only one real root since \(\alpha > 0\),
resulting in the sample technique
\[\cos\theta=u-\frac{1}{\alpha u}.\]

Pull Request: https://projects.blender.org/blender/blender/pulls/129259
2024-10-22 15:37:37 +02:00
Lukas Stockner
b8d0bef3b4 Cleanup: Cycles: Consolidate coordinate system conversions
- Deduplicate Fisheye projection code
- Replace spherical/cartesian conversions with shared helpers
- Replace transforms from/to local coordinate systems with shared helpers

The main type of repeated transform that's not covered here is `to/from_coords`, but with separate values for xy and z (e.g. BSDFs that already computed `dot(wi, N)` earlier, so they only need `dot(wi, X)` and `dot(wi, Y)` later). Could also be replaced, but it would feel weirdly specific for a helper function.

Pull Request: https://projects.blender.org/blender/blender/pulls/125999
2024-10-07 02:18:49 +02:00
Campbell Barton
4fa3dc0dd4 Cleanup: spelling in comments, use uppercase tags 2024-10-03 12:11:52 +10:00
Alexandre Cardaillac
0315eae536 Cycles: Add more scattering phase functions
Previously, Cycles only supported the Henyey-Greenstein phase function for volume scattering.
While HG is flexible and works for a wide range of effects, sometimes a more physically accurate
phase function may be needed for realism.

Therefore, this adds three new phase functions to the code:
Rayleigh: For particles with a size below the wavelength of light, mostly athmospheric scattering.
Fournier-Forand: For realistic underwater scattering.
Draine: Fairly specific on its own (mostly for interstellar dust), but useful for the next entry.
Mie: Approximates Mie scattering in water droplets using a mix of Draine and HG phase functions.

These phase functions can be combined using Mix nodes as usual.

Co-authored-by: Lukas Stockner <lukas@lukasstockner.de>
Pull Request: https://projects.blender.org/blender/blender/pulls/123532
2024-10-02 11:12:53 +02:00
Weizhen Huang
ee2fe7fa6c Fix: Cycles: reuse random number for sampling color channel in volume
The same random number was used for sampling color channel at each step,
which leads to bias. Fixed by rescaling the random number.

Another possibility would be to scramble `rng_offset` and use a new
random number each time, similar as in subsurface scattering, but
rescaling random number should be faster than computing a new one, and
is favorable here since the precision here is not very important

Pull Request: https://projects.blender.org/blender/blender/pulls/127454
2024-09-12 14:27:56 +02:00
David Murmann
df4df3cd52 Fix #114940: Cycles: GGX roughness has abrupt cutoff
This decreases BSDF_ROUGHNESS_SQ_THRESH so that the microfacet
roughness has a cutoff at much lower values and fixes a precision
issue in the bsdf_sample code that prevented this previously.

Pull Request: https://projects.blender.org/blender/blender/pulls/125919
2024-08-07 16:53:07 +02:00
Lukas Stockner
9ed7d38aac Cycles: Improve numerical precision of Beckmann distribution at low roughness 2024-08-06 23:04:16 +02:00