This feature greatly increase depth buffer precision.
This is very noticeable in large view distance scenes.
This is enabled by default on GPUs that supports it (most of the hardware we
support already supports this). This makes rendering different on the GPUs
that do not support that feature (`glClipControl`).
While this give much better depth precision as before, we also have a lot of
imprecision caused by our vertex transformations. This can be improved in
another task.
Pull Request: https://projects.blender.org/blender/blender/pulls/138898
Allows basic support for using `namespace X {}` and `X::symbol`
syntax.
Benefit:
- More sharing possible with host C++ code.
- Isolation of symbols when including shader files as C++.
Requirements:
- Nesting must be done using `namespace A::B{}` rather than
`namespace A{ namespace B {}}`, which is unsupported.
- No support for `using namespace`.
- Support of `using X` and `using X = Y` inside of function scope.
- Support of `using X` and `using X = Y` inside of namespace scope.
However, this is only to bring symbols from the same namespace
declared in another block (potentially inside another file).
- Only support namespace elision for symbols defined and used
inside of the same namespace scope.
Note that this is currently limited to blender GLSL files and
not for the shared headers. This is because we need to port a lot
of code to use namespaces before allowing this.
### Follow Up:
Nesting like `namespace A{ namespace B {}}` shouldn't be hard to
support and could be added if needed.
Rel #137446
Pull Request: https://projects.blender.org/blender/blender/pulls/137445
Implementation of #137341
This adds support for using references to any variable in a local scope
inside the shader codebase.
Example:
```cpp
int a = 0;
int &b = a;
b++; /* a == 1 */
```
Using `auto` is supported for reference definition as the type is not
preserved by the copy paste procedure. Type checking is done by the
C++ shader compilation or after the copy paste procedure during shader
compilation. `auto` is still unsupported for other variable declarations.
Reference to opaque types (`image`, `sampler`) are supported since
they are never really assigned to a temp variable.
This implements all safety feature related to the implementation being
copy pasting the definition string. That is:
- No `--`, `++` operators.
- No function calls.
- Array subscript index needs to be int constants or constant variable.
The copy pasting does not replace member access:
`auto &a = b; a.a = c;` becomes `b.a = c;`
The copy pasting does not replace function calls:
`auto &a = b; a = a();` becomes `b = a();`
While limited, this already allows for nicer syntax (aliasing) for
accessing SSBOs and the potential overhead of a copy semantic:
```cpp
ViewMatrices matrices = drw_view_buf[0];
matrices.viewmat = float4x4(1);
drw_view_buf[0] = matrices;
```
Can now be written as;
```cpp
ViewMatrices &matrices = drw_view_buf[0];
matrices.viewmat = float4x4(1);
```
Which expands to;
```cpp
drw_view_buf[0].viewmat = float4x4(1);
```
Note that the reference semantic is not carried through function call
because arguments are transformed to `inout` in GLSL. `inout` has
copy semantic but it is often implemented as reference by some
implementations.
Another important note is that this copy-pasting doesn't check if a
symbol is a variable. It can match a typename. But given that our
typenames have different capitalizations style this is unlikely to be
an issue. If that issue arise, we can add a check for it.
Rel #137446
Pull Request: https://projects.blender.org/blender/blender/pulls/138412
Allows basic usage of templated functions.
There is no support for templated struct.
Benefit:
- More readable than macros in shader sources.
- Compatible with C++ tools.
- More sharing possible with host C++ code.
Requirements/Limitations:
- No default arguments to template parameters.
- Must use explicit instantiation for all variant needed.
- Explicit instantiation needs to **not** use argument deduction.
- Calls to template needs to have all template argument explicit
or all implicit.
- Template overload is not supported (redefining the same template
with different template argument or function argument types).
Currently implemented as Macros inside the build-time pre-pocessor,
but that could change to copy-paste to allow better error reporting.
However, the Macros keep the shader code reduced in the final binary
and allow different file to declare different instantiation.
The implementation is done by declaring overloads for each explicit
instantiation.
If a template has arguments not present in function
arguments, then all arguments **values** are appended to the
function name. The explicit template callsite is then modified to use
`TEMPLATE_GLUE` which will call the correct function. This is
why template argument deduction is not supported in this case.
Rel #137446
Pull Request: https://projects.blender.org/blender/blender/pulls/137441
This adds basic unrolling support for 2 syntax:
- `[[gpu::unroll]]` which does full loop unrolling
- `[[gpu::unroll(x)]]` which unrolls `x` iteration
Nesting is supported.
This change is motivated by the added cost in compilation
and execution time that some loops have even if they have
compile time defined iteration counts.
The syntax is inspired by `GL_EXT_control_flow_attributes`.
However, we might want to have our own prefix to show it is
a blender specific feature and that it differs from the standard.
I propose `[[gpu::unroll]]`.
In the future, we could extend this to support more directives that
can be expanded to backend specific extension / syntax. This would
avoid readability issue an error prone copy paste of large amount
of preprocessor directives.
Currently, given that GL's GLSL flavor doesn't support
any of these attributes, the preprocessor does some copy-pasting
that does the unrolling at the source level. Note that the added
`#line` allow for correct error logging.
For the `[[gpu::unroll]]` syntax, the `for` declaration
needs to follow a specific syntax to deduce the number
of loop iteration.
This variant removes the continue condition between iteration,
so all iterations are evaluated. This could be modified
using a special keyword.
For the `[[gpu::unroll(n)]]` syntax, the usercode needs
to make sure that `n` is large enough to cover all iterations
as the loop is completely removed.
We could add shader `assert` to make sure that there is
never a remaining iteration.
This behavior is usually different from what you see in other
implementation as we do not keep a loop at all. Usually, compilers
still keep the loop if it is not unrolled fully. But given we don't
have IR, this is the best we can do.
`break` and `continue` statement are forbidden at the unrolled loop
scope level. Nested loop and switch can contain these keywords.
This is accounted for by checks in the pre-processor.
Only `for` loops are supported for now. There are no real
incentive to add support for `while` given how rare it is
in the shader codebase.
Rel #137446
Pull Request: https://projects.blender.org/blender/blender/pulls/137444
This avoid having to guards functions that are
only available in fragment shader stage.
Calling the function inside another stage is still
invalid and will yield a compile error on Metal.
The vulkan and opengl glsl patch need to be modified
per stage to allow the fragment specific function
to be defined.
This is not yet widely used, but a good example is
the change in `film_display_depth_amend`.
Rel #137261
Pull Request: https://projects.blender.org/blender/blender/pulls/138280
This implement the design detailed in #135935.
A new per object property called `Shadow Terminator Normal Offset` is
introduced to shift the shadowed position along the shading normal.
The amount of shift is defined in object space on the object datablock.
This amount is modulated by the facing ratio to the light. Faces
already facing the light will get no offset. This avoids most light
leaking artifacts.
In case of multiple shading normal, the normal used for the shift
is arbitrary. Note that this is the same behavior for other biases.
The magnitude of the bias is controlled by `Shadow Terminator Normal Offset`.
The amount of faces affected by the bias is controlled using
`Shadow Terminator Geometry Offset` just like cycles.
Tweaking the `Shadow Terminator Geometry Offset` allows to avoid too much
shadow distortion on surfaces with bump mapping.
Cycles properties are copied from the Cycles object datablock to the
blender datablock. This break the python API for Cycles.
The defaults are set to no bias because:
- There is no good default. The best value depends on the geometry.
- The best value might depend on real-time displacement.
- Any bias will introduce light leaking on surfaces that do not need it.
- There is an additional cost of enabling it, which is proportional
to the amount of pixels on screen using it.
Pull Request: https://projects.blender.org/blender/blender/pulls/136935
This makes no sense to have in the draw namespace.
Also take the opportunity for making the coordinates
a float2 and rename them to something more descriptive.
This was caused by the shadow map Z range loosing too much
precision on the large object.
This can be replicated by adding a very large object in the scene.
The normaly un-shadowed objects gets shadowed because the
float precision is not enough to represent their depth correctly.
To fix this, we bias the shadow depth by 2 ULP to make sure that
there is no self shadowing.
This bias has already been there, but was somehow removed because
of other fixes that simingly fixed this issue. But they did not.
Pull Request: https://projects.blender.org/blender/blender/pulls/137555
This make the shadow rays always multiply the lighting,
which can make renders with large light sources darker.
This bias introduced too many light leaking issues. And
these issues are made more visible since the introduction
of 410282e156.
Its first use was to avoid self shadowing artifacts from
large light sources. Since the shading was already
integrated over the visible hemisphere, it made sense
that the shadowing was also in the visible hemisphere.
However this only works if the shading is actually
clipped to the visible hemisphere above the geometric
normal, which might not always be the case.
Given it is better to have self shadowing noise than
light leaking, it is better to just removing this trick.
Self shadow noise can be mitigated by increasing the
sample count or by increasing the terminator bias.
Light leaking, on the other hand, has no known workaround.
Fix#136594
Pull Request: https://projects.blender.org/blender/blender/pulls/137485
Do this only when applicable.
This allow better compile time checking in Shader C++ compilation.
Moreover, this allows to have `constexpr` in shared code between
C++ and GLSL.
After investigation the `const` keyword in GLSL has the same
semantic than C/C++.
Rel #137333 and #137446
Pull Request: https://projects.blender.org/blender/blender/pulls/137497
This unify the C++ and GLSL codebase style.
The GLSL types are still in the backend compatibility
layers to support python shaders. However, the C++
shader compilation layer doesn't have them to enforce
correct type usage.
Note that this is going to break pretty much all PRs
in flight that targets shader code.
Rel #137261
Pull Request: https://projects.blender.org/blender/blender/pulls/137369
They are actually already some literals with the `f` suffix
that are in our shader codebase and we never had problem in
the past 5 years (or even 8 years).
So I think it is safe to do and improves convergence of codestyles.
Pull Request: https://projects.blender.org/blender/blender/pulls/137352
This was caused by the cross product changing
sign in view space during planar lightprobe capture.
This can be avoided by making sure the view matrix
doesn't change handedness.
Pull Request: https://projects.blender.org/blender/blender/pulls/137092
This allow to store the full object ID inside a `uint32`
buffer. This allows to get the per object data in deferred
passes and avoid to store object data inside the Gbuffer.
This data is only written if needed.
This had to modify the implementation of subpass input
for all backend to be able to bind layered texture.
This currently work because only the layer 0 is bound to the
framebuffer. This is fragile but I don't see a good builtin way
to fix it.
Rel #135935
#### Tasks
- [x] Replace light linking bits in Gbuffer
- [x] Replace Object ID in GBuffer for SSS
- [x] Conditional storage
- [x] Dummy storage if not needed
Pull Request: https://projects.blender.org/blender/blender/pulls/136428
This makes it possible to restore previous Blender 4.3 behavior of bump
mapping, where the large filter width was sometimes (ab)used to get a bevel
like effect on stepwise textures.
For bump from the displacement socket, filter width remains fixed at 0.1.
Ref #133991, #135841
Pull Request: https://projects.blender.org/blender/blender/pulls/136465
This improves the situations where the shading normal is far from the
best shadow bias direction. This is particularly noticeable on low poly
meshes with smooth normals.
This patch fixes the issue by storing a quantized version of the
geometric normal in the Gbuffer.
Only 6 bits are used (each axis uses 2 bits). This is stored inside the
gbuffer header since it is always available and has some spare bits to
store this data.
This quantization is only done if the error introduced by using the
shading normal is higher than using the quantized normal. This means
that flat shaded surfaces will not have any quantization artifact.
For smooth shaded surfaces, the quantization is only effective if the
shading normal is quite different (greater than ~20° difference)
than the geometric normal.
The attached blendfile contains an example Material that shows
how the quantization is done. This was used to find the threshold
value with the least amount of error.
To compensate the quantization error, we increase the normal bias by
~20% which is subpixel if the shadow texel density is high enough.
This also changes the forward shading pipeline to use the geometric
normal for bias.
The first Light closure normal is now used for the attenuation function
since this is the most representative of the final shading. This normal
being inverted for transmission closures, we have to negate the normal
in the attenuation computation.
Pull Request: https://projects.blender.org/blender/blender/pulls/136136
This handles the transition to EEVEE-Next (now EEVEE).
This removes some things that make no sense to keep
even for compatibility.
- Scene.eevee.light_cache_data
- Scene Light cache operators
- Scene Light cache RNA properties
The remaining legacy properties will be removed later
on to avoid python API breakage.
We keep the identifier of EEVEE-Next as `BLENDER_EEVEE_NEXT`
to avoid addons being incorrectly silently made compatible
with the EEVEE-Next where the Python API is different.
This renaming should be done in 5.0 release.
Thank you EEVEE-Legacy, you served us well.
Pull Request: https://projects.blender.org/blender/blender/pulls/122433
EEVEE-Next performes less on integrated GPUs then discrete GPUs.
Most shaders have been analyzed, but there will always be bottlenecks
related to architectural differences.
In order to make EEVEE-Next run smooth on integrated GPUs this change
will implement viewport pixel size option similar to Cycles. The main difference
is that the samples will still be weighted and up-sampled to the final film
resolution. This makes the pixels not look squared in the viewport but will
resolve to something close to the results without up-scaling.
This improves the performance especially on integrated GPUs. The improvement
for discrete GPUs are less noticeable. See here the stats when playing
`rain_restaurant.blend` back on a RAPHAEL_MENDOCINO iGPU.
| Pixel size | Frames per second |
|------------|-------------------|
| 1x | 0.25 FPS |
| 2x | 4.14 FPS |
| 4x | 6.90 FPS |
| 8x | 9.95 FPS |
Related to: #114597
See PR for some example images.
Pull Request: https://projects.blender.org/blender/blender/pulls/118903
This define all aliases for supported types,
document which one to use in C++ shared code,
move relevant defines to their backend file.
Rename `bool1` to `bool32_t` and cleanup
its usage as mentioned in #118961.
Rel. #118961
Pull Request: https://projects.blender.org/blender/blender/pulls/119098
Add new "Soft Falloff" option on point and spot light that uses
the old light behavior from Blender versions before 4.0. Blend
files saved with those older versions will use the option.
This option is enabled by default on new lights.
Fix#114241
Co-authored-by: Weizhen Huang <weizhen@blender.org>
Co-authored-by: Clément Foucault <foucault.clem@gmail.com>
Pull Request: https://projects.blender.org/blender/blender/pulls/117832
When drawing curves or particle hair, the hair is refined using GPU
shaders. See eParticleRefineShaderType. OpenGL since Blender 4.0
always uses compute shaders. Metal since Blender 4.1 always uses
compute shaders. Vulkan will only uses compute shaders.
The transform feedback isn't used and not supported by our vulkan backend.
Transform feedback workaround was a Apple specific solution as they didn't
support transform feedback. Metal didn't use Compute shaders in
EEVEE-Legacy for performance reasons. Since EEVEE-Next/Workbench-Next
Metal uses compute shaders.
Fixes: #117497
Pull Request: https://projects.blender.org/blender/blender/pulls/117507
Even if related, they don't have the same performance
impact.
To avoid any performance hit, we replace the Diffuse
by a Subsurface Closure for legacy EEVEE and
use the subsurface closure only where needed for
EEVEE-Next leveraging the random sampling.
This increases the compatibility with cycles that
doesn't modulate the radius of the subsurface anymore.
This change is only present in EEVEE-Next.
This commit changes the principled BSDF code so that
it is easier to follow the flow of data.
For legacy EEVEE, the SSS switch is moved to a
`radius == -1` check.
This adds support for Translucent BSDF.
This also fixes a bug to allow correct
shadowing.
The input normal had to be set back to
non-inverted in the node function to allow
for correct interpretation of the Normal
by Screen Space Reflections.
This add the necessary optimization
and code deduplication to hybrid deferred
and forward pipeline.
Pull Request: https://projects.blender.org/blender/blender/pulls/116070