2022-02-11 09:07:11 +11:00
|
|
|
/* SPDX-License-Identifier: GPL-2.0-or-later
|
|
|
|
|
* Copyright 2017 Blender Foundation. All rights reserved. */
|
2020-03-17 14:41:48 +01:00
|
|
|
|
|
|
|
|
/** \file
|
|
|
|
|
* \ingroup draw
|
|
|
|
|
*
|
2022-03-30 18:25:06 -05:00
|
|
|
* \brief Curves API for render engines
|
2020-03-17 14:41:48 +01:00
|
|
|
*/
|
|
|
|
|
|
2021-12-23 11:46:45 -06:00
|
|
|
#include <cstring>
|
2020-03-17 14:41:48 +01:00
|
|
|
|
|
|
|
|
#include "MEM_guardedalloc.h"
|
|
|
|
|
|
2021-09-24 10:45:36 +02:00
|
|
|
#include "BLI_listbase.h"
|
2020-03-17 14:41:48 +01:00
|
|
|
#include "BLI_math_base.h"
|
2022-02-03 10:49:51 -06:00
|
|
|
#include "BLI_math_vec_types.hh"
|
2020-03-17 14:41:48 +01:00
|
|
|
#include "BLI_math_vector.h"
|
2022-02-03 10:49:51 -06:00
|
|
|
#include "BLI_math_vector.hh"
|
|
|
|
|
#include "BLI_span.hh"
|
2020-03-17 14:41:48 +01:00
|
|
|
#include "BLI_utildefines.h"
|
|
|
|
|
|
Curves: Rename "Hair" types, variables, and functions to "Curves"
Based on discussions from T95355 and T94193, the plan is to use
the name "Curves" to describe the data-block container for multiple
curves. Eventually this will replace the existing "Curve" data-block.
However, it will be a while before the curve data-block can be replaced
so in order to distinguish the two curve types in the UI, "Hair Curves"
will be used, but eventually changed back to "Curves".
This patch renames "hair-related" files, functions, types, and variable
names to this convention. A deep rename is preferred to keep code
consistent and to avoid any "hair" terminology from leaking, since the
new data-block is meant for all curve types, not just hair use cases.
The downside of this naming is that the difference between "Curve"
and "Curves" has become important. That was considered during
design discussons and deemed acceptable, especially given the
non-permanent nature of the somewhat common conflict.
Some points of interest:
- All DNA compatibility is lost, just like rBf59767ff9729.
- I renamed `ID_HA` to `ID_CV` so there is no complete mismatch.
- `hair_curves` is used where necessary to distinguish from the
existing "curves" plural.
- I didn't rename any of the cycles/rendering code function names,
since that is also used by the old hair particle system.
Differential Revision: https://developer.blender.org/D14007
2022-02-07 11:55:54 -06:00
|
|
|
#include "DNA_curves_types.h"
|
2020-03-17 14:41:48 +01:00
|
|
|
#include "DNA_object_types.h"
|
2022-04-08 18:23:40 +02:00
|
|
|
#include "DNA_scene_types.h"
|
2020-03-17 14:41:48 +01:00
|
|
|
|
2022-02-16 11:32:37 -06:00
|
|
|
#include "BKE_curves.hh"
|
EEVEE: support Curves attributes rendering
This adds support to render Curves attributes in EEVEE.
Each attribute is stored in a texture derived from a VBO. As the
shading group needs the textures to be valid upon creation, the
attributes are created and setup during its very creation, instead
of doing it lazily via create_requested which we cannot rely on
anyway as contrary to the mesh batch, we do cannot really tell if
attributes need to be updated or else via some `DRW_batch_requested`.
Since point attributes need refinement, and since attributes are all
cast to vec4/float4 to account for differences in type conversions
between Blender and OpenGL, the refinement shader for points is
used as is. The point attributes are stored for each subdivision level
in CurvesEvalFinalCache. Each subdivision level also keeps track of the
attributes already in use so they are properly updated when needed.
Some basic garbage collection was added similar to what is done
for meshes: if the attributes used over time have been different
from the currently used attributes for too long, then the buffers
are freed, ensuring that stale attributesare removed.
This adds `CurvesInfos` to the shader creation info, which stores
the scope in which the attributes are defined. Scopes are stored
as booleans, in an array indexed by attribute loading order which
is also the order in which the attributes were added to the material.
A mapping is necessary between the indices used for the scoping, and
the ones used in the Curves cache, as this may contain stale
attributes which have not been garbage collected yet.
Common utilities with the mesh code for handling requested
attributes were moved to a separate file.
Differential Revision: https://developer.blender.org/D14916
2022-05-24 05:02:57 +02:00
|
|
|
#include "BKE_geometry_set.hh"
|
2020-03-17 14:41:48 +01:00
|
|
|
|
|
|
|
|
#include "GPU_batch.h"
|
2021-09-24 07:42:36 +02:00
|
|
|
#include "GPU_material.h"
|
2021-09-24 10:45:36 +02:00
|
|
|
#include "GPU_texture.h"
|
2020-03-17 14:41:48 +01:00
|
|
|
|
2022-04-22 10:43:48 -05:00
|
|
|
#include "DRW_render.h"
|
|
|
|
|
|
EEVEE: support Curves attributes rendering
This adds support to render Curves attributes in EEVEE.
Each attribute is stored in a texture derived from a VBO. As the
shading group needs the textures to be valid upon creation, the
attributes are created and setup during its very creation, instead
of doing it lazily via create_requested which we cannot rely on
anyway as contrary to the mesh batch, we do cannot really tell if
attributes need to be updated or else via some `DRW_batch_requested`.
Since point attributes need refinement, and since attributes are all
cast to vec4/float4 to account for differences in type conversions
between Blender and OpenGL, the refinement shader for points is
used as is. The point attributes are stored for each subdivision level
in CurvesEvalFinalCache. Each subdivision level also keeps track of the
attributes already in use so they are properly updated when needed.
Some basic garbage collection was added similar to what is done
for meshes: if the attributes used over time have been different
from the currently used attributes for too long, then the buffers
are freed, ensuring that stale attributesare removed.
This adds `CurvesInfos` to the shader creation info, which stores
the scope in which the attributes are defined. Scopes are stored
as booleans, in an array indexed by attribute loading order which
is also the order in which the attributes were added to the material.
A mapping is necessary between the indices used for the scoping, and
the ones used in the Curves cache, as this may contain stale
attributes which have not been garbage collected yet.
Common utilities with the mesh code for handling requested
attributes were moved to a separate file.
Differential Revision: https://developer.blender.org/D14916
2022-05-24 05:02:57 +02:00
|
|
|
#include "draw_attributes.h"
|
2022-04-08 18:23:40 +02:00
|
|
|
#include "draw_cache_impl.h" /* own include */
|
|
|
|
|
#include "draw_cache_inline.h"
|
2022-04-22 10:43:48 -05:00
|
|
|
#include "draw_curves_private.h" /* own include */
|
EEVEE: support Curves attributes rendering
This adds support to render Curves attributes in EEVEE.
Each attribute is stored in a texture derived from a VBO. As the
shading group needs the textures to be valid upon creation, the
attributes are created and setup during its very creation, instead
of doing it lazily via create_requested which we cannot rely on
anyway as contrary to the mesh batch, we do cannot really tell if
attributes need to be updated or else via some `DRW_batch_requested`.
Since point attributes need refinement, and since attributes are all
cast to vec4/float4 to account for differences in type conversions
between Blender and OpenGL, the refinement shader for points is
used as is. The point attributes are stored for each subdivision level
in CurvesEvalFinalCache. Each subdivision level also keeps track of the
attributes already in use so they are properly updated when needed.
Some basic garbage collection was added similar to what is done
for meshes: if the attributes used over time have been different
from the currently used attributes for too long, then the buffers
are freed, ensuring that stale attributesare removed.
This adds `CurvesInfos` to the shader creation info, which stores
the scope in which the attributes are defined. Scopes are stored
as booleans, in an array indexed by attribute loading order which
is also the order in which the attributes were added to the material.
A mapping is necessary between the indices used for the scoping, and
the ones used in the Curves cache, as this may contain stale
attributes which have not been garbage collected yet.
Common utilities with the mesh code for handling requested
attributes were moved to a separate file.
Differential Revision: https://developer.blender.org/D14916
2022-05-24 05:02:57 +02:00
|
|
|
#include "draw_shader.h"
|
2020-03-17 14:41:48 +01:00
|
|
|
|
EEVEE: support Curves attributes rendering
This adds support to render Curves attributes in EEVEE.
Each attribute is stored in a texture derived from a VBO. As the
shading group needs the textures to be valid upon creation, the
attributes are created and setup during its very creation, instead
of doing it lazily via create_requested which we cannot rely on
anyway as contrary to the mesh batch, we do cannot really tell if
attributes need to be updated or else via some `DRW_batch_requested`.
Since point attributes need refinement, and since attributes are all
cast to vec4/float4 to account for differences in type conversions
between Blender and OpenGL, the refinement shader for points is
used as is. The point attributes are stored for each subdivision level
in CurvesEvalFinalCache. Each subdivision level also keeps track of the
attributes already in use so they are properly updated when needed.
Some basic garbage collection was added similar to what is done
for meshes: if the attributes used over time have been different
from the currently used attributes for too long, then the buffers
are freed, ensuring that stale attributesare removed.
This adds `CurvesInfos` to the shader creation info, which stores
the scope in which the attributes are defined. Scopes are stored
as booleans, in an array indexed by attribute loading order which
is also the order in which the attributes were added to the material.
A mapping is necessary between the indices used for the scoping, and
the ones used in the Curves cache, as this may contain stale
attributes which have not been garbage collected yet.
Common utilities with the mesh code for handling requested
attributes were moved to a separate file.
Differential Revision: https://developer.blender.org/D14916
2022-05-24 05:02:57 +02:00
|
|
|
using blender::ColorGeometry4f;
|
2022-02-03 10:49:51 -06:00
|
|
|
using blender::float3;
|
|
|
|
|
using blender::IndexRange;
|
2022-05-09 18:32:23 +02:00
|
|
|
using blender::MutableSpan;
|
2022-02-03 10:49:51 -06:00
|
|
|
using blender::Span;
|
|
|
|
|
|
2020-03-17 14:41:48 +01:00
|
|
|
/* ---------------------------------------------------------------------- */
|
2022-03-30 18:25:06 -05:00
|
|
|
/* Curves GPUBatch Cache */
|
2020-03-17 14:41:48 +01:00
|
|
|
|
2022-03-30 18:25:06 -05:00
|
|
|
struct CurvesBatchCache {
|
2022-04-22 10:43:48 -05:00
|
|
|
CurvesEvalCache curves_cache;
|
2020-03-17 14:41:48 +01:00
|
|
|
|
2022-04-08 18:23:40 +02:00
|
|
|
GPUBatch *edit_points;
|
|
|
|
|
|
2022-06-07 11:55:52 +02:00
|
|
|
/* Whether the cache is invalid. */
|
2020-03-17 14:41:48 +01:00
|
|
|
bool is_dirty;
|
EEVEE: support Curves attributes rendering
This adds support to render Curves attributes in EEVEE.
Each attribute is stored in a texture derived from a VBO. As the
shading group needs the textures to be valid upon creation, the
attributes are created and setup during its very creation, instead
of doing it lazily via create_requested which we cannot rely on
anyway as contrary to the mesh batch, we do cannot really tell if
attributes need to be updated or else via some `DRW_batch_requested`.
Since point attributes need refinement, and since attributes are all
cast to vec4/float4 to account for differences in type conversions
between Blender and OpenGL, the refinement shader for points is
used as is. The point attributes are stored for each subdivision level
in CurvesEvalFinalCache. Each subdivision level also keeps track of the
attributes already in use so they are properly updated when needed.
Some basic garbage collection was added similar to what is done
for meshes: if the attributes used over time have been different
from the currently used attributes for too long, then the buffers
are freed, ensuring that stale attributesare removed.
This adds `CurvesInfos` to the shader creation info, which stores
the scope in which the attributes are defined. Scopes are stored
as booleans, in an array indexed by attribute loading order which
is also the order in which the attributes were added to the material.
A mapping is necessary between the indices used for the scoping, and
the ones used in the Curves cache, as this may contain stale
attributes which have not been garbage collected yet.
Common utilities with the mesh code for handling requested
attributes were moved to a separate file.
Differential Revision: https://developer.blender.org/D14916
2022-05-24 05:02:57 +02:00
|
|
|
|
2022-06-07 11:55:52 +02:00
|
|
|
/**
|
|
|
|
|
* The draw cache extraction is currently not multi-threaded for multiple objects, but if it was,
|
|
|
|
|
* some locking would be necessary because multiple objects can use the same curves data with
|
|
|
|
|
* different materials, etc. This is a placeholder to make multi-threading easier in the future.
|
|
|
|
|
*/
|
EEVEE: support Curves attributes rendering
This adds support to render Curves attributes in EEVEE.
Each attribute is stored in a texture derived from a VBO. As the
shading group needs the textures to be valid upon creation, the
attributes are created and setup during its very creation, instead
of doing it lazily via create_requested which we cannot rely on
anyway as contrary to the mesh batch, we do cannot really tell if
attributes need to be updated or else via some `DRW_batch_requested`.
Since point attributes need refinement, and since attributes are all
cast to vec4/float4 to account for differences in type conversions
between Blender and OpenGL, the refinement shader for points is
used as is. The point attributes are stored for each subdivision level
in CurvesEvalFinalCache. Each subdivision level also keeps track of the
attributes already in use so they are properly updated when needed.
Some basic garbage collection was added similar to what is done
for meshes: if the attributes used over time have been different
from the currently used attributes for too long, then the buffers
are freed, ensuring that stale attributesare removed.
This adds `CurvesInfos` to the shader creation info, which stores
the scope in which the attributes are defined. Scopes are stored
as booleans, in an array indexed by attribute loading order which
is also the order in which the attributes were added to the material.
A mapping is necessary between the indices used for the scoping, and
the ones used in the Curves cache, as this may contain stale
attributes which have not been garbage collected yet.
Common utilities with the mesh code for handling requested
attributes were moved to a separate file.
Differential Revision: https://developer.blender.org/D14916
2022-05-24 05:02:57 +02:00
|
|
|
ThreadMutex render_mutex;
|
2021-12-23 11:46:45 -06:00
|
|
|
};
|
2020-03-17 14:41:48 +01:00
|
|
|
|
2022-03-30 18:25:06 -05:00
|
|
|
static bool curves_batch_cache_valid(const Curves &curves)
|
2020-03-17 14:41:48 +01:00
|
|
|
{
|
2022-03-30 18:25:06 -05:00
|
|
|
const CurvesBatchCache *cache = static_cast<CurvesBatchCache *>(curves.batch_cache);
|
2020-03-17 14:41:48 +01:00
|
|
|
return (cache && cache->is_dirty == false);
|
|
|
|
|
}
|
|
|
|
|
|
2022-03-30 18:25:06 -05:00
|
|
|
static void curves_batch_cache_init(Curves &curves)
|
2020-03-17 14:41:48 +01:00
|
|
|
{
|
2022-03-30 18:25:06 -05:00
|
|
|
CurvesBatchCache *cache = static_cast<CurvesBatchCache *>(curves.batch_cache);
|
2020-03-17 14:41:48 +01:00
|
|
|
|
|
|
|
|
if (!cache) {
|
2022-03-30 18:25:06 -05:00
|
|
|
cache = MEM_cnew<CurvesBatchCache>(__func__);
|
EEVEE: support Curves attributes rendering
This adds support to render Curves attributes in EEVEE.
Each attribute is stored in a texture derived from a VBO. As the
shading group needs the textures to be valid upon creation, the
attributes are created and setup during its very creation, instead
of doing it lazily via create_requested which we cannot rely on
anyway as contrary to the mesh batch, we do cannot really tell if
attributes need to be updated or else via some `DRW_batch_requested`.
Since point attributes need refinement, and since attributes are all
cast to vec4/float4 to account for differences in type conversions
between Blender and OpenGL, the refinement shader for points is
used as is. The point attributes are stored for each subdivision level
in CurvesEvalFinalCache. Each subdivision level also keeps track of the
attributes already in use so they are properly updated when needed.
Some basic garbage collection was added similar to what is done
for meshes: if the attributes used over time have been different
from the currently used attributes for too long, then the buffers
are freed, ensuring that stale attributesare removed.
This adds `CurvesInfos` to the shader creation info, which stores
the scope in which the attributes are defined. Scopes are stored
as booleans, in an array indexed by attribute loading order which
is also the order in which the attributes were added to the material.
A mapping is necessary between the indices used for the scoping, and
the ones used in the Curves cache, as this may contain stale
attributes which have not been garbage collected yet.
Common utilities with the mesh code for handling requested
attributes were moved to a separate file.
Differential Revision: https://developer.blender.org/D14916
2022-05-24 05:02:57 +02:00
|
|
|
BLI_mutex_init(&cache->render_mutex);
|
2022-03-30 18:25:06 -05:00
|
|
|
curves.batch_cache = cache;
|
2020-03-17 14:41:48 +01:00
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
memset(cache, 0, sizeof(*cache));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
cache->is_dirty = false;
|
|
|
|
|
}
|
|
|
|
|
|
EEVEE: support Curves attributes rendering
This adds support to render Curves attributes in EEVEE.
Each attribute is stored in a texture derived from a VBO. As the
shading group needs the textures to be valid upon creation, the
attributes are created and setup during its very creation, instead
of doing it lazily via create_requested which we cannot rely on
anyway as contrary to the mesh batch, we do cannot really tell if
attributes need to be updated or else via some `DRW_batch_requested`.
Since point attributes need refinement, and since attributes are all
cast to vec4/float4 to account for differences in type conversions
between Blender and OpenGL, the refinement shader for points is
used as is. The point attributes are stored for each subdivision level
in CurvesEvalFinalCache. Each subdivision level also keeps track of the
attributes already in use so they are properly updated when needed.
Some basic garbage collection was added similar to what is done
for meshes: if the attributes used over time have been different
from the currently used attributes for too long, then the buffers
are freed, ensuring that stale attributesare removed.
This adds `CurvesInfos` to the shader creation info, which stores
the scope in which the attributes are defined. Scopes are stored
as booleans, in an array indexed by attribute loading order which
is also the order in which the attributes were added to the material.
A mapping is necessary between the indices used for the scoping, and
the ones used in the Curves cache, as this may contain stale
attributes which have not been garbage collected yet.
Common utilities with the mesh code for handling requested
attributes were moved to a separate file.
Differential Revision: https://developer.blender.org/D14916
2022-05-24 05:02:57 +02:00
|
|
|
static void curves_discard_attributes(CurvesEvalCache &curves_cache)
|
|
|
|
|
{
|
2022-06-17 15:11:10 +02:00
|
|
|
for (const int i : IndexRange(GPU_MAX_ATTR)) {
|
EEVEE: support Curves attributes rendering
This adds support to render Curves attributes in EEVEE.
Each attribute is stored in a texture derived from a VBO. As the
shading group needs the textures to be valid upon creation, the
attributes are created and setup during its very creation, instead
of doing it lazily via create_requested which we cannot rely on
anyway as contrary to the mesh batch, we do cannot really tell if
attributes need to be updated or else via some `DRW_batch_requested`.
Since point attributes need refinement, and since attributes are all
cast to vec4/float4 to account for differences in type conversions
between Blender and OpenGL, the refinement shader for points is
used as is. The point attributes are stored for each subdivision level
in CurvesEvalFinalCache. Each subdivision level also keeps track of the
attributes already in use so they are properly updated when needed.
Some basic garbage collection was added similar to what is done
for meshes: if the attributes used over time have been different
from the currently used attributes for too long, then the buffers
are freed, ensuring that stale attributesare removed.
This adds `CurvesInfos` to the shader creation info, which stores
the scope in which the attributes are defined. Scopes are stored
as booleans, in an array indexed by attribute loading order which
is also the order in which the attributes were added to the material.
A mapping is necessary between the indices used for the scoping, and
the ones used in the Curves cache, as this may contain stale
attributes which have not been garbage collected yet.
Common utilities with the mesh code for handling requested
attributes were moved to a separate file.
Differential Revision: https://developer.blender.org/D14916
2022-05-24 05:02:57 +02:00
|
|
|
GPU_VERTBUF_DISCARD_SAFE(curves_cache.proc_attributes_buf[i]);
|
|
|
|
|
DRW_TEXTURE_FREE_SAFE(curves_cache.proc_attributes_tex[i]);
|
|
|
|
|
}
|
|
|
|
|
|
2022-06-17 15:11:10 +02:00
|
|
|
for (const int i : IndexRange(MAX_HAIR_SUBDIV)) {
|
|
|
|
|
for (const int j : IndexRange(GPU_MAX_ATTR)) {
|
EEVEE: support Curves attributes rendering
This adds support to render Curves attributes in EEVEE.
Each attribute is stored in a texture derived from a VBO. As the
shading group needs the textures to be valid upon creation, the
attributes are created and setup during its very creation, instead
of doing it lazily via create_requested which we cannot rely on
anyway as contrary to the mesh batch, we do cannot really tell if
attributes need to be updated or else via some `DRW_batch_requested`.
Since point attributes need refinement, and since attributes are all
cast to vec4/float4 to account for differences in type conversions
between Blender and OpenGL, the refinement shader for points is
used as is. The point attributes are stored for each subdivision level
in CurvesEvalFinalCache. Each subdivision level also keeps track of the
attributes already in use so they are properly updated when needed.
Some basic garbage collection was added similar to what is done
for meshes: if the attributes used over time have been different
from the currently used attributes for too long, then the buffers
are freed, ensuring that stale attributesare removed.
This adds `CurvesInfos` to the shader creation info, which stores
the scope in which the attributes are defined. Scopes are stored
as booleans, in an array indexed by attribute loading order which
is also the order in which the attributes were added to the material.
A mapping is necessary between the indices used for the scoping, and
the ones used in the Curves cache, as this may contain stale
attributes which have not been garbage collected yet.
Common utilities with the mesh code for handling requested
attributes were moved to a separate file.
Differential Revision: https://developer.blender.org/D14916
2022-05-24 05:02:57 +02:00
|
|
|
GPU_VERTBUF_DISCARD_SAFE(curves_cache.final[i].attributes_buf[j]);
|
|
|
|
|
DRW_TEXTURE_FREE_SAFE(curves_cache.final[i].attributes_tex[j]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
drw_attributes_clear(&curves_cache.final[i].attr_used);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-04-22 10:43:48 -05:00
|
|
|
static void curves_batch_cache_clear_data(CurvesEvalCache &curves_cache)
|
|
|
|
|
{
|
|
|
|
|
/* TODO: more granular update tagging. */
|
|
|
|
|
GPU_VERTBUF_DISCARD_SAFE(curves_cache.proc_point_buf);
|
|
|
|
|
GPU_VERTBUF_DISCARD_SAFE(curves_cache.proc_length_buf);
|
|
|
|
|
DRW_TEXTURE_FREE_SAFE(curves_cache.point_tex);
|
|
|
|
|
DRW_TEXTURE_FREE_SAFE(curves_cache.length_tex);
|
|
|
|
|
|
|
|
|
|
GPU_VERTBUF_DISCARD_SAFE(curves_cache.proc_strand_buf);
|
|
|
|
|
GPU_VERTBUF_DISCARD_SAFE(curves_cache.proc_strand_seg_buf);
|
|
|
|
|
DRW_TEXTURE_FREE_SAFE(curves_cache.strand_tex);
|
|
|
|
|
DRW_TEXTURE_FREE_SAFE(curves_cache.strand_seg_tex);
|
|
|
|
|
|
2022-06-17 15:11:10 +02:00
|
|
|
for (const int i : IndexRange(MAX_HAIR_SUBDIV)) {
|
2022-04-22 10:43:48 -05:00
|
|
|
GPU_VERTBUF_DISCARD_SAFE(curves_cache.final[i].proc_buf);
|
|
|
|
|
DRW_TEXTURE_FREE_SAFE(curves_cache.final[i].proc_tex);
|
2022-06-17 15:11:10 +02:00
|
|
|
for (const int j : IndexRange(MAX_THICKRES)) {
|
2022-04-22 10:43:48 -05:00
|
|
|
GPU_BATCH_DISCARD_SAFE(curves_cache.final[i].proc_hairs[j]);
|
|
|
|
|
}
|
|
|
|
|
}
|
EEVEE: support Curves attributes rendering
This adds support to render Curves attributes in EEVEE.
Each attribute is stored in a texture derived from a VBO. As the
shading group needs the textures to be valid upon creation, the
attributes are created and setup during its very creation, instead
of doing it lazily via create_requested which we cannot rely on
anyway as contrary to the mesh batch, we do cannot really tell if
attributes need to be updated or else via some `DRW_batch_requested`.
Since point attributes need refinement, and since attributes are all
cast to vec4/float4 to account for differences in type conversions
between Blender and OpenGL, the refinement shader for points is
used as is. The point attributes are stored for each subdivision level
in CurvesEvalFinalCache. Each subdivision level also keeps track of the
attributes already in use so they are properly updated when needed.
Some basic garbage collection was added similar to what is done
for meshes: if the attributes used over time have been different
from the currently used attributes for too long, then the buffers
are freed, ensuring that stale attributesare removed.
This adds `CurvesInfos` to the shader creation info, which stores
the scope in which the attributes are defined. Scopes are stored
as booleans, in an array indexed by attribute loading order which
is also the order in which the attributes were added to the material.
A mapping is necessary between the indices used for the scoping, and
the ones used in the Curves cache, as this may contain stale
attributes which have not been garbage collected yet.
Common utilities with the mesh code for handling requested
attributes were moved to a separate file.
Differential Revision: https://developer.blender.org/D14916
2022-05-24 05:02:57 +02:00
|
|
|
|
|
|
|
|
curves_discard_attributes(curves_cache);
|
2022-04-22 10:43:48 -05:00
|
|
|
}
|
|
|
|
|
|
2022-03-30 18:25:06 -05:00
|
|
|
static void curves_batch_cache_clear(Curves &curves)
|
|
|
|
|
{
|
|
|
|
|
CurvesBatchCache *cache = static_cast<CurvesBatchCache *>(curves.batch_cache);
|
|
|
|
|
if (!cache) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2022-04-22 10:43:48 -05:00
|
|
|
curves_batch_cache_clear_data(cache->curves_cache);
|
|
|
|
|
|
2022-04-08 18:23:40 +02:00
|
|
|
GPU_BATCH_DISCARD_SAFE(cache->edit_points);
|
2022-03-30 18:25:06 -05:00
|
|
|
}
|
|
|
|
|
|
Curves: Rename "Hair" types, variables, and functions to "Curves"
Based on discussions from T95355 and T94193, the plan is to use
the name "Curves" to describe the data-block container for multiple
curves. Eventually this will replace the existing "Curve" data-block.
However, it will be a while before the curve data-block can be replaced
so in order to distinguish the two curve types in the UI, "Hair Curves"
will be used, but eventually changed back to "Curves".
This patch renames "hair-related" files, functions, types, and variable
names to this convention. A deep rename is preferred to keep code
consistent and to avoid any "hair" terminology from leaking, since the
new data-block is meant for all curve types, not just hair use cases.
The downside of this naming is that the difference between "Curve"
and "Curves" has become important. That was considered during
design discussons and deemed acceptable, especially given the
non-permanent nature of the somewhat common conflict.
Some points of interest:
- All DNA compatibility is lost, just like rBf59767ff9729.
- I renamed `ID_HA` to `ID_CV` so there is no complete mismatch.
- `hair_curves` is used where necessary to distinguish from the
existing "curves" plural.
- I didn't rename any of the cycles/rendering code function names,
since that is also used by the old hair particle system.
Differential Revision: https://developer.blender.org/D14007
2022-02-07 11:55:54 -06:00
|
|
|
void DRW_curves_batch_cache_validate(Curves *curves)
|
2020-03-17 14:41:48 +01:00
|
|
|
{
|
2022-03-30 18:25:06 -05:00
|
|
|
if (!curves_batch_cache_valid(*curves)) {
|
|
|
|
|
curves_batch_cache_clear(*curves);
|
|
|
|
|
curves_batch_cache_init(*curves);
|
2020-03-17 14:41:48 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-03-30 18:25:06 -05:00
|
|
|
static CurvesBatchCache &curves_batch_cache_get(Curves &curves)
|
2020-03-17 14:41:48 +01:00
|
|
|
{
|
2022-03-30 18:25:06 -05:00
|
|
|
DRW_curves_batch_cache_validate(&curves);
|
|
|
|
|
return *static_cast<CurvesBatchCache *>(curves.batch_cache);
|
2020-03-17 14:41:48 +01:00
|
|
|
}
|
|
|
|
|
|
Curves: Rename "Hair" types, variables, and functions to "Curves"
Based on discussions from T95355 and T94193, the plan is to use
the name "Curves" to describe the data-block container for multiple
curves. Eventually this will replace the existing "Curve" data-block.
However, it will be a while before the curve data-block can be replaced
so in order to distinguish the two curve types in the UI, "Hair Curves"
will be used, but eventually changed back to "Curves".
This patch renames "hair-related" files, functions, types, and variable
names to this convention. A deep rename is preferred to keep code
consistent and to avoid any "hair" terminology from leaking, since the
new data-block is meant for all curve types, not just hair use cases.
The downside of this naming is that the difference between "Curve"
and "Curves" has become important. That was considered during
design discussons and deemed acceptable, especially given the
non-permanent nature of the somewhat common conflict.
Some points of interest:
- All DNA compatibility is lost, just like rBf59767ff9729.
- I renamed `ID_HA` to `ID_CV` so there is no complete mismatch.
- `hair_curves` is used where necessary to distinguish from the
existing "curves" plural.
- I didn't rename any of the cycles/rendering code function names,
since that is also used by the old hair particle system.
Differential Revision: https://developer.blender.org/D14007
2022-02-07 11:55:54 -06:00
|
|
|
void DRW_curves_batch_cache_dirty_tag(Curves *curves, int mode)
|
2020-03-17 14:41:48 +01:00
|
|
|
{
|
2022-03-30 18:25:06 -05:00
|
|
|
CurvesBatchCache *cache = static_cast<CurvesBatchCache *>(curves->batch_cache);
|
2021-12-23 11:46:45 -06:00
|
|
|
if (cache == nullptr) {
|
2020-03-17 14:41:48 +01:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
switch (mode) {
|
Curves: Rename "Hair" types, variables, and functions to "Curves"
Based on discussions from T95355 and T94193, the plan is to use
the name "Curves" to describe the data-block container for multiple
curves. Eventually this will replace the existing "Curve" data-block.
However, it will be a while before the curve data-block can be replaced
so in order to distinguish the two curve types in the UI, "Hair Curves"
will be used, but eventually changed back to "Curves".
This patch renames "hair-related" files, functions, types, and variable
names to this convention. A deep rename is preferred to keep code
consistent and to avoid any "hair" terminology from leaking, since the
new data-block is meant for all curve types, not just hair use cases.
The downside of this naming is that the difference between "Curve"
and "Curves" has become important. That was considered during
design discussons and deemed acceptable, especially given the
non-permanent nature of the somewhat common conflict.
Some points of interest:
- All DNA compatibility is lost, just like rBf59767ff9729.
- I renamed `ID_HA` to `ID_CV` so there is no complete mismatch.
- `hair_curves` is used where necessary to distinguish from the
existing "curves" plural.
- I didn't rename any of the cycles/rendering code function names,
since that is also used by the old hair particle system.
Differential Revision: https://developer.blender.org/D14007
2022-02-07 11:55:54 -06:00
|
|
|
case BKE_CURVES_BATCH_DIRTY_ALL:
|
2020-03-17 14:41:48 +01:00
|
|
|
cache->is_dirty = true;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
2022-06-15 09:07:26 +02:00
|
|
|
BLI_assert_unreachable();
|
2020-03-17 14:41:48 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
Curves: Rename "Hair" types, variables, and functions to "Curves"
Based on discussions from T95355 and T94193, the plan is to use
the name "Curves" to describe the data-block container for multiple
curves. Eventually this will replace the existing "Curve" data-block.
However, it will be a while before the curve data-block can be replaced
so in order to distinguish the two curve types in the UI, "Hair Curves"
will be used, but eventually changed back to "Curves".
This patch renames "hair-related" files, functions, types, and variable
names to this convention. A deep rename is preferred to keep code
consistent and to avoid any "hair" terminology from leaking, since the
new data-block is meant for all curve types, not just hair use cases.
The downside of this naming is that the difference between "Curve"
and "Curves" has become important. That was considered during
design discussons and deemed acceptable, especially given the
non-permanent nature of the somewhat common conflict.
Some points of interest:
- All DNA compatibility is lost, just like rBf59767ff9729.
- I renamed `ID_HA` to `ID_CV` so there is no complete mismatch.
- `hair_curves` is used where necessary to distinguish from the
existing "curves" plural.
- I didn't rename any of the cycles/rendering code function names,
since that is also used by the old hair particle system.
Differential Revision: https://developer.blender.org/D14007
2022-02-07 11:55:54 -06:00
|
|
|
void DRW_curves_batch_cache_free(Curves *curves)
|
2020-03-17 14:41:48 +01:00
|
|
|
{
|
2022-03-30 18:25:06 -05:00
|
|
|
curves_batch_cache_clear(*curves);
|
EEVEE: support Curves attributes rendering
This adds support to render Curves attributes in EEVEE.
Each attribute is stored in a texture derived from a VBO. As the
shading group needs the textures to be valid upon creation, the
attributes are created and setup during its very creation, instead
of doing it lazily via create_requested which we cannot rely on
anyway as contrary to the mesh batch, we do cannot really tell if
attributes need to be updated or else via some `DRW_batch_requested`.
Since point attributes need refinement, and since attributes are all
cast to vec4/float4 to account for differences in type conversions
between Blender and OpenGL, the refinement shader for points is
used as is. The point attributes are stored for each subdivision level
in CurvesEvalFinalCache. Each subdivision level also keeps track of the
attributes already in use so they are properly updated when needed.
Some basic garbage collection was added similar to what is done
for meshes: if the attributes used over time have been different
from the currently used attributes for too long, then the buffers
are freed, ensuring that stale attributesare removed.
This adds `CurvesInfos` to the shader creation info, which stores
the scope in which the attributes are defined. Scopes are stored
as booleans, in an array indexed by attribute loading order which
is also the order in which the attributes were added to the material.
A mapping is necessary between the indices used for the scoping, and
the ones used in the Curves cache, as this may contain stale
attributes which have not been garbage collected yet.
Common utilities with the mesh code for handling requested
attributes were moved to a separate file.
Differential Revision: https://developer.blender.org/D14916
2022-05-24 05:02:57 +02:00
|
|
|
CurvesBatchCache *cache = static_cast<CurvesBatchCache *>(curves->batch_cache);
|
|
|
|
|
BLI_mutex_end(&cache->render_mutex);
|
Curves: Rename "Hair" types, variables, and functions to "Curves"
Based on discussions from T95355 and T94193, the plan is to use
the name "Curves" to describe the data-block container for multiple
curves. Eventually this will replace the existing "Curve" data-block.
However, it will be a while before the curve data-block can be replaced
so in order to distinguish the two curve types in the UI, "Hair Curves"
will be used, but eventually changed back to "Curves".
This patch renames "hair-related" files, functions, types, and variable
names to this convention. A deep rename is preferred to keep code
consistent and to avoid any "hair" terminology from leaking, since the
new data-block is meant for all curve types, not just hair use cases.
The downside of this naming is that the difference between "Curve"
and "Curves" has become important. That was considered during
design discussons and deemed acceptable, especially given the
non-permanent nature of the somewhat common conflict.
Some points of interest:
- All DNA compatibility is lost, just like rBf59767ff9729.
- I renamed `ID_HA` to `ID_CV` so there is no complete mismatch.
- `hair_curves` is used where necessary to distinguish from the
existing "curves" plural.
- I didn't rename any of the cycles/rendering code function names,
since that is also used by the old hair particle system.
Differential Revision: https://developer.blender.org/D14007
2022-02-07 11:55:54 -06:00
|
|
|
MEM_SAFE_FREE(curves->batch_cache);
|
2020-03-17 14:41:48 +01:00
|
|
|
}
|
|
|
|
|
|
EEVEE: support Curves attributes rendering
This adds support to render Curves attributes in EEVEE.
Each attribute is stored in a texture derived from a VBO. As the
shading group needs the textures to be valid upon creation, the
attributes are created and setup during its very creation, instead
of doing it lazily via create_requested which we cannot rely on
anyway as contrary to the mesh batch, we do cannot really tell if
attributes need to be updated or else via some `DRW_batch_requested`.
Since point attributes need refinement, and since attributes are all
cast to vec4/float4 to account for differences in type conversions
between Blender and OpenGL, the refinement shader for points is
used as is. The point attributes are stored for each subdivision level
in CurvesEvalFinalCache. Each subdivision level also keeps track of the
attributes already in use so they are properly updated when needed.
Some basic garbage collection was added similar to what is done
for meshes: if the attributes used over time have been different
from the currently used attributes for too long, then the buffers
are freed, ensuring that stale attributesare removed.
This adds `CurvesInfos` to the shader creation info, which stores
the scope in which the attributes are defined. Scopes are stored
as booleans, in an array indexed by attribute loading order which
is also the order in which the attributes were added to the material.
A mapping is necessary between the indices used for the scoping, and
the ones used in the Curves cache, as this may contain stale
attributes which have not been garbage collected yet.
Common utilities with the mesh code for handling requested
attributes were moved to a separate file.
Differential Revision: https://developer.blender.org/D14916
2022-05-24 05:02:57 +02:00
|
|
|
void DRW_curves_batch_cache_free_old(Curves *curves, int ctime)
|
|
|
|
|
{
|
|
|
|
|
CurvesBatchCache *cache = static_cast<CurvesBatchCache *>(curves->batch_cache);
|
|
|
|
|
if (cache == nullptr) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool do_discard = false;
|
|
|
|
|
|
2022-06-17 15:11:10 +02:00
|
|
|
for (const int i : IndexRange(MAX_HAIR_SUBDIV)) {
|
EEVEE: support Curves attributes rendering
This adds support to render Curves attributes in EEVEE.
Each attribute is stored in a texture derived from a VBO. As the
shading group needs the textures to be valid upon creation, the
attributes are created and setup during its very creation, instead
of doing it lazily via create_requested which we cannot rely on
anyway as contrary to the mesh batch, we do cannot really tell if
attributes need to be updated or else via some `DRW_batch_requested`.
Since point attributes need refinement, and since attributes are all
cast to vec4/float4 to account for differences in type conversions
between Blender and OpenGL, the refinement shader for points is
used as is. The point attributes are stored for each subdivision level
in CurvesEvalFinalCache. Each subdivision level also keeps track of the
attributes already in use so they are properly updated when needed.
Some basic garbage collection was added similar to what is done
for meshes: if the attributes used over time have been different
from the currently used attributes for too long, then the buffers
are freed, ensuring that stale attributesare removed.
This adds `CurvesInfos` to the shader creation info, which stores
the scope in which the attributes are defined. Scopes are stored
as booleans, in an array indexed by attribute loading order which
is also the order in which the attributes were added to the material.
A mapping is necessary between the indices used for the scoping, and
the ones used in the Curves cache, as this may contain stale
attributes which have not been garbage collected yet.
Common utilities with the mesh code for handling requested
attributes were moved to a separate file.
Differential Revision: https://developer.blender.org/D14916
2022-05-24 05:02:57 +02:00
|
|
|
CurvesEvalFinalCache &final_cache = cache->curves_cache.final[i];
|
|
|
|
|
|
|
|
|
|
if (drw_attributes_overlap(&final_cache.attr_used_over_time, &final_cache.attr_used)) {
|
|
|
|
|
final_cache.last_attr_matching_time = ctime;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (ctime - final_cache.last_attr_matching_time > U.vbotimeout) {
|
|
|
|
|
do_discard = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
drw_attributes_clear(&final_cache.attr_used_over_time);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (do_discard) {
|
|
|
|
|
curves_discard_attributes(cache->curves_cache);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-04-22 10:43:48 -05:00
|
|
|
static void ensure_seg_pt_count(const Curves &curves, CurvesEvalCache &curves_cache)
|
2020-03-17 14:41:48 +01:00
|
|
|
{
|
2022-04-22 11:48:38 -05:00
|
|
|
if (curves_cache.proc_point_buf != nullptr) {
|
2020-03-17 14:41:48 +01:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-11 09:58:39 +10:00
|
|
|
curves_cache.strands_len = curves.geometry.curve_num;
|
|
|
|
|
curves_cache.elems_len = curves.geometry.point_num + curves.geometry.curve_num;
|
|
|
|
|
curves_cache.point_len = curves.geometry.point_num;
|
2020-03-17 14:41:48 +01:00
|
|
|
}
|
|
|
|
|
|
2022-05-09 18:32:23 +02:00
|
|
|
struct PositionAndParameter {
|
|
|
|
|
float3 position;
|
|
|
|
|
float parameter;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static void curves_batch_cache_fill_segments_proc_pos(
|
|
|
|
|
const Curves &curves_id,
|
|
|
|
|
MutableSpan<PositionAndParameter> posTime_data,
|
|
|
|
|
MutableSpan<float> hairLength_data)
|
2020-03-17 14:41:48 +01:00
|
|
|
{
|
|
|
|
|
/* TODO: use hair radius layer if available. */
|
2022-05-11 09:58:39 +10:00
|
|
|
const int curve_num = curves_id.geometry.curve_num;
|
2022-03-30 18:25:06 -05:00
|
|
|
const blender::bke::CurvesGeometry &curves = blender::bke::CurvesGeometry::wrap(
|
|
|
|
|
curves_id.geometry);
|
|
|
|
|
Span<float3> positions = curves.positions();
|
2022-02-03 10:49:51 -06:00
|
|
|
|
2022-05-11 09:58:39 +10:00
|
|
|
for (const int i_curve : IndexRange(curve_num)) {
|
2022-05-09 18:32:23 +02:00
|
|
|
const IndexRange points = curves.points_for_curve(i_curve);
|
|
|
|
|
|
|
|
|
|
Span<float3> curve_positions = positions.slice(points);
|
|
|
|
|
MutableSpan<PositionAndParameter> curve_posTime_data = posTime_data.slice(points);
|
2022-02-03 10:49:51 -06:00
|
|
|
|
2020-03-17 14:41:48 +01:00
|
|
|
float total_len = 0.0f;
|
2022-05-09 18:32:23 +02:00
|
|
|
for (const int i_point : curve_positions.index_range()) {
|
|
|
|
|
if (i_point > 0) {
|
|
|
|
|
total_len += blender::math::distance(curve_positions[i_point - 1],
|
|
|
|
|
curve_positions[i_point]);
|
2020-03-17 14:41:48 +01:00
|
|
|
}
|
2022-05-09 18:32:23 +02:00
|
|
|
curve_posTime_data[i_point].position = curve_positions[i_point];
|
|
|
|
|
curve_posTime_data[i_point].parameter = total_len;
|
2020-03-17 14:41:48 +01:00
|
|
|
}
|
2022-05-09 18:32:23 +02:00
|
|
|
hairLength_data[i_curve] = total_len;
|
|
|
|
|
|
2022-01-24 14:29:19 +11:00
|
|
|
/* Assign length value. */
|
2020-03-17 14:41:48 +01:00
|
|
|
if (total_len > 0.0f) {
|
2022-05-09 18:32:23 +02:00
|
|
|
const float factor = 1.0f / total_len;
|
2020-03-17 14:41:48 +01:00
|
|
|
/* Divide by total length to have a [0-1] number. */
|
2022-05-09 18:32:23 +02:00
|
|
|
for (const int i_point : curve_positions.index_range()) {
|
|
|
|
|
curve_posTime_data[i_point].parameter *= factor;
|
2020-03-17 14:41:48 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-06-22 16:57:57 -05:00
|
|
|
static void curves_batch_cache_ensure_procedural_pos(const Curves &curves,
|
2022-04-22 10:43:48 -05:00
|
|
|
CurvesEvalCache &cache,
|
Curves: Rename "Hair" types, variables, and functions to "Curves"
Based on discussions from T95355 and T94193, the plan is to use
the name "Curves" to describe the data-block container for multiple
curves. Eventually this will replace the existing "Curve" data-block.
However, it will be a while before the curve data-block can be replaced
so in order to distinguish the two curve types in the UI, "Hair Curves"
will be used, but eventually changed back to "Curves".
This patch renames "hair-related" files, functions, types, and variable
names to this convention. A deep rename is preferred to keep code
consistent and to avoid any "hair" terminology from leaking, since the
new data-block is meant for all curve types, not just hair use cases.
The downside of this naming is that the difference between "Curve"
and "Curves" has become important. That was considered during
design discussons and deemed acceptable, especially given the
non-permanent nature of the somewhat common conflict.
Some points of interest:
- All DNA compatibility is lost, just like rBf59767ff9729.
- I renamed `ID_HA` to `ID_CV` so there is no complete mismatch.
- `hair_curves` is used where necessary to distinguish from the
existing "curves" plural.
- I didn't rename any of the cycles/rendering code function names,
since that is also used by the old hair particle system.
Differential Revision: https://developer.blender.org/D14007
2022-02-07 11:55:54 -06:00
|
|
|
GPUMaterial *gpu_material)
|
2020-03-17 14:41:48 +01:00
|
|
|
{
|
2022-04-08 18:23:40 +02:00
|
|
|
if (cache.proc_point_buf == nullptr || DRW_vbo_requested(cache.proc_point_buf)) {
|
2022-03-30 18:25:06 -05:00
|
|
|
/* Initialize vertex format. */
|
2021-09-24 07:42:36 +02:00
|
|
|
GPUVertFormat format = {0};
|
2022-05-09 18:32:23 +02:00
|
|
|
GPU_vertformat_attr_add(&format, "posTime", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
|
2022-04-08 18:23:40 +02:00
|
|
|
GPU_vertformat_alias_add(&format, "pos");
|
2020-03-17 14:41:48 +01:00
|
|
|
|
2022-03-30 18:25:06 -05:00
|
|
|
cache.proc_point_buf = GPU_vertbuf_create_with_format(&format);
|
|
|
|
|
GPU_vertbuf_data_alloc(cache.proc_point_buf, cache.point_len);
|
2020-03-17 14:41:48 +01:00
|
|
|
|
2022-05-09 18:32:23 +02:00
|
|
|
MutableSpan posTime_data{
|
|
|
|
|
reinterpret_cast<PositionAndParameter *>(GPU_vertbuf_get_data(cache.proc_point_buf)),
|
|
|
|
|
cache.point_len};
|
2020-03-17 14:41:48 +01:00
|
|
|
|
2021-09-24 07:42:36 +02:00
|
|
|
GPUVertFormat length_format = {0};
|
2022-05-09 18:32:23 +02:00
|
|
|
GPU_vertformat_attr_add(&length_format, "hairLength", GPU_COMP_F32, 1, GPU_FETCH_FLOAT);
|
2020-03-17 14:41:48 +01:00
|
|
|
|
2022-03-30 18:25:06 -05:00
|
|
|
cache.proc_length_buf = GPU_vertbuf_create_with_format(&length_format);
|
|
|
|
|
GPU_vertbuf_data_alloc(cache.proc_length_buf, cache.strands_len);
|
2020-03-17 14:41:48 +01:00
|
|
|
|
2022-05-09 18:32:23 +02:00
|
|
|
MutableSpan hairLength_data{
|
|
|
|
|
reinterpret_cast<float *>(GPU_vertbuf_get_data(cache.proc_length_buf)), cache.strands_len};
|
2021-09-24 07:42:36 +02:00
|
|
|
|
2022-05-09 18:32:23 +02:00
|
|
|
curves_batch_cache_fill_segments_proc_pos(curves, posTime_data, hairLength_data);
|
2020-03-17 14:41:48 +01:00
|
|
|
|
2021-09-24 07:42:36 +02:00
|
|
|
/* Create vbo immediately to bind to texture buffer. */
|
2022-03-30 18:25:06 -05:00
|
|
|
GPU_vertbuf_use(cache.proc_point_buf);
|
|
|
|
|
cache.point_tex = GPU_texture_create_from_vertbuf("hair_point", cache.proc_point_buf);
|
2021-09-24 07:42:36 +02:00
|
|
|
}
|
|
|
|
|
|
2022-03-30 18:25:06 -05:00
|
|
|
if (gpu_material && cache.proc_length_buf != nullptr && cache.length_tex) {
|
2021-09-24 07:42:36 +02:00
|
|
|
ListBase gpu_attrs = GPU_material_attributes(gpu_material);
|
|
|
|
|
LISTBASE_FOREACH (GPUMaterialAttribute *, attr, &gpu_attrs) {
|
|
|
|
|
if (attr->type == CD_HAIRLENGTH) {
|
2022-03-30 18:25:06 -05:00
|
|
|
GPU_vertbuf_use(cache.proc_length_buf);
|
|
|
|
|
cache.length_tex = GPU_texture_create_from_vertbuf("hair_length", cache.proc_length_buf);
|
2021-09-24 07:42:36 +02:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2020-03-17 14:41:48 +01:00
|
|
|
}
|
|
|
|
|
|
EEVEE: support Curves attributes rendering
This adds support to render Curves attributes in EEVEE.
Each attribute is stored in a texture derived from a VBO. As the
shading group needs the textures to be valid upon creation, the
attributes are created and setup during its very creation, instead
of doing it lazily via create_requested which we cannot rely on
anyway as contrary to the mesh batch, we do cannot really tell if
attributes need to be updated or else via some `DRW_batch_requested`.
Since point attributes need refinement, and since attributes are all
cast to vec4/float4 to account for differences in type conversions
between Blender and OpenGL, the refinement shader for points is
used as is. The point attributes are stored for each subdivision level
in CurvesEvalFinalCache. Each subdivision level also keeps track of the
attributes already in use so they are properly updated when needed.
Some basic garbage collection was added similar to what is done
for meshes: if the attributes used over time have been different
from the currently used attributes for too long, then the buffers
are freed, ensuring that stale attributesare removed.
This adds `CurvesInfos` to the shader creation info, which stores
the scope in which the attributes are defined. Scopes are stored
as booleans, in an array indexed by attribute loading order which
is also the order in which the attributes were added to the material.
A mapping is necessary between the indices used for the scoping, and
the ones used in the Curves cache, as this may contain stale
attributes which have not been garbage collected yet.
Common utilities with the mesh code for handling requested
attributes were moved to a separate file.
Differential Revision: https://developer.blender.org/D14916
2022-05-24 05:02:57 +02:00
|
|
|
void drw_curves_get_attribute_sampler_name(const char *layer_name, char r_sampler_name[32])
|
|
|
|
|
{
|
|
|
|
|
char attr_safe_name[GPU_MAX_SAFE_ATTR_NAME];
|
|
|
|
|
GPU_vertformat_safe_attr_name(layer_name, attr_safe_name, GPU_MAX_SAFE_ATTR_NAME);
|
|
|
|
|
/* Attributes use auto-name. */
|
|
|
|
|
BLI_snprintf(r_sampler_name, 32, "a%s", attr_safe_name);
|
|
|
|
|
}
|
|
|
|
|
|
2022-06-22 16:57:57 -05:00
|
|
|
static void curves_batch_cache_ensure_procedural_final_attr(CurvesEvalCache &cache,
|
|
|
|
|
const GPUVertFormat *format,
|
|
|
|
|
const int subdiv,
|
|
|
|
|
const int index,
|
|
|
|
|
const char *name)
|
EEVEE: support Curves attributes rendering
This adds support to render Curves attributes in EEVEE.
Each attribute is stored in a texture derived from a VBO. As the
shading group needs the textures to be valid upon creation, the
attributes are created and setup during its very creation, instead
of doing it lazily via create_requested which we cannot rely on
anyway as contrary to the mesh batch, we do cannot really tell if
attributes need to be updated or else via some `DRW_batch_requested`.
Since point attributes need refinement, and since attributes are all
cast to vec4/float4 to account for differences in type conversions
between Blender and OpenGL, the refinement shader for points is
used as is. The point attributes are stored for each subdivision level
in CurvesEvalFinalCache. Each subdivision level also keeps track of the
attributes already in use so they are properly updated when needed.
Some basic garbage collection was added similar to what is done
for meshes: if the attributes used over time have been different
from the currently used attributes for too long, then the buffers
are freed, ensuring that stale attributesare removed.
This adds `CurvesInfos` to the shader creation info, which stores
the scope in which the attributes are defined. Scopes are stored
as booleans, in an array indexed by attribute loading order which
is also the order in which the attributes were added to the material.
A mapping is necessary between the indices used for the scoping, and
the ones used in the Curves cache, as this may contain stale
attributes which have not been garbage collected yet.
Common utilities with the mesh code for handling requested
attributes were moved to a separate file.
Differential Revision: https://developer.blender.org/D14916
2022-05-24 05:02:57 +02:00
|
|
|
{
|
|
|
|
|
CurvesEvalFinalCache &final_cache = cache.final[subdiv];
|
|
|
|
|
final_cache.attributes_buf[index] = GPU_vertbuf_create_with_format_ex(format,
|
|
|
|
|
GPU_USAGE_DEVICE_ONLY);
|
|
|
|
|
|
|
|
|
|
/* Create a destination buffer for the transform feedback. Sized appropriately */
|
|
|
|
|
/* Those are points! not line segments. */
|
|
|
|
|
GPU_vertbuf_data_alloc(final_cache.attributes_buf[index],
|
|
|
|
|
final_cache.strands_res * cache.strands_len);
|
|
|
|
|
|
|
|
|
|
/* Create vbo immediately to bind to texture buffer. */
|
|
|
|
|
GPU_vertbuf_use(final_cache.attributes_buf[index]);
|
|
|
|
|
|
|
|
|
|
final_cache.attributes_tex[index] = GPU_texture_create_from_vertbuf(
|
|
|
|
|
name, final_cache.attributes_buf[index]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void curves_batch_ensure_attribute(const Curves &curves,
|
|
|
|
|
CurvesEvalCache &cache,
|
|
|
|
|
const DRW_AttributeRequest &request,
|
2022-06-22 16:57:57 -05:00
|
|
|
const int subdiv,
|
|
|
|
|
const int index)
|
EEVEE: support Curves attributes rendering
This adds support to render Curves attributes in EEVEE.
Each attribute is stored in a texture derived from a VBO. As the
shading group needs the textures to be valid upon creation, the
attributes are created and setup during its very creation, instead
of doing it lazily via create_requested which we cannot rely on
anyway as contrary to the mesh batch, we do cannot really tell if
attributes need to be updated or else via some `DRW_batch_requested`.
Since point attributes need refinement, and since attributes are all
cast to vec4/float4 to account for differences in type conversions
between Blender and OpenGL, the refinement shader for points is
used as is. The point attributes are stored for each subdivision level
in CurvesEvalFinalCache. Each subdivision level also keeps track of the
attributes already in use so they are properly updated when needed.
Some basic garbage collection was added similar to what is done
for meshes: if the attributes used over time have been different
from the currently used attributes for too long, then the buffers
are freed, ensuring that stale attributesare removed.
This adds `CurvesInfos` to the shader creation info, which stores
the scope in which the attributes are defined. Scopes are stored
as booleans, in an array indexed by attribute loading order which
is also the order in which the attributes were added to the material.
A mapping is necessary between the indices used for the scoping, and
the ones used in the Curves cache, as this may contain stale
attributes which have not been garbage collected yet.
Common utilities with the mesh code for handling requested
attributes were moved to a separate file.
Differential Revision: https://developer.blender.org/D14916
2022-05-24 05:02:57 +02:00
|
|
|
{
|
|
|
|
|
GPU_VERTBUF_DISCARD_SAFE(cache.proc_attributes_buf[index]);
|
|
|
|
|
DRW_TEXTURE_FREE_SAFE(cache.proc_attributes_tex[index]);
|
|
|
|
|
|
|
|
|
|
char sampler_name[32];
|
|
|
|
|
drw_curves_get_attribute_sampler_name(request.attribute_name, sampler_name);
|
|
|
|
|
|
|
|
|
|
GPUVertFormat format = {0};
|
|
|
|
|
GPU_vertformat_deinterleave(&format);
|
|
|
|
|
/* All attributes use vec4, see comment below. */
|
|
|
|
|
GPU_vertformat_attr_add(&format, sampler_name, GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
|
|
|
|
|
|
|
|
|
|
cache.proc_attributes_buf[index] = GPU_vertbuf_create_with_format(&format);
|
|
|
|
|
GPUVertBuf *attr_vbo = cache.proc_attributes_buf[index];
|
|
|
|
|
|
|
|
|
|
GPU_vertbuf_data_alloc(attr_vbo,
|
|
|
|
|
request.domain == ATTR_DOMAIN_POINT ? curves.geometry.point_num :
|
|
|
|
|
curves.geometry.curve_num);
|
|
|
|
|
|
|
|
|
|
CurveComponent component;
|
|
|
|
|
component.replace(const_cast<Curves *>(&curves), GeometryOwnershipType::ReadOnly);
|
|
|
|
|
|
|
|
|
|
/* TODO(@kevindietrich): float4 is used for scalar attributes as the implicit conversion done
|
|
|
|
|
* by OpenGL to vec4 for a scalar `s` will produce a `vec4(s, 0, 0, 1)`. However, following
|
|
|
|
|
* the Blender convention, it should be `vec4(s, s, s, 1)`. This could be resolved using a
|
|
|
|
|
* similar texture state swizzle to map the attribute correctly as for volume attributes, so we
|
|
|
|
|
* can control the conversion ourselves. */
|
|
|
|
|
blender::VArray<ColorGeometry4f> attribute = component.attribute_get_for_read<ColorGeometry4f>(
|
|
|
|
|
request.attribute_name, request.domain, {0.0f, 0.0f, 0.0f, 1.0f});
|
|
|
|
|
|
|
|
|
|
MutableSpan<ColorGeometry4f> vbo_span{
|
|
|
|
|
static_cast<ColorGeometry4f *>(GPU_vertbuf_get_data(attr_vbo)),
|
|
|
|
|
component.attribute_domain_num(request.domain)};
|
|
|
|
|
|
|
|
|
|
attribute.materialize(vbo_span);
|
|
|
|
|
|
|
|
|
|
GPU_vertbuf_use(attr_vbo);
|
|
|
|
|
cache.proc_attributes_tex[index] = GPU_texture_create_from_vertbuf(sampler_name, attr_vbo);
|
|
|
|
|
|
|
|
|
|
/* Existing final data may have been for a different attribute (with a different name or domain),
|
|
|
|
|
* free the data. */
|
|
|
|
|
GPU_VERTBUF_DISCARD_SAFE(cache.final[subdiv].attributes_buf[index]);
|
|
|
|
|
DRW_TEXTURE_FREE_SAFE(cache.final[subdiv].attributes_tex[index]);
|
|
|
|
|
|
|
|
|
|
/* Ensure final data for points. */
|
|
|
|
|
if (request.domain == ATTR_DOMAIN_POINT) {
|
|
|
|
|
curves_batch_cache_ensure_procedural_final_attr(cache, &format, subdiv, index, sampler_name);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-03-30 18:25:06 -05:00
|
|
|
static void curves_batch_cache_fill_strands_data(const Curves &curves_id,
|
|
|
|
|
GPUVertBufRaw &data_step,
|
|
|
|
|
GPUVertBufRaw &seg_step)
|
2020-03-17 14:41:48 +01:00
|
|
|
{
|
2022-03-30 18:25:06 -05:00
|
|
|
const blender::bke::CurvesGeometry &curves = blender::bke::CurvesGeometry::wrap(
|
|
|
|
|
curves_id.geometry);
|
2022-02-03 10:49:51 -06:00
|
|
|
|
2022-03-30 18:25:06 -05:00
|
|
|
for (const int i : IndexRange(curves.curves_num())) {
|
|
|
|
|
const IndexRange curve_range = curves.points_for_curve(i);
|
2022-02-03 10:49:51 -06:00
|
|
|
|
2022-03-30 18:25:06 -05:00
|
|
|
*(uint *)GPU_vertbuf_raw_step(&data_step) = curve_range.start();
|
|
|
|
|
*(ushort *)GPU_vertbuf_raw_step(&seg_step) = curve_range.size() - 1;
|
2020-03-17 14:41:48 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-03-30 18:25:06 -05:00
|
|
|
static void curves_batch_cache_ensure_procedural_strand_data(Curves &curves,
|
2022-04-22 10:43:48 -05:00
|
|
|
CurvesEvalCache &cache)
|
2020-03-17 14:41:48 +01:00
|
|
|
{
|
|
|
|
|
GPUVertBufRaw data_step, seg_step;
|
|
|
|
|
|
|
|
|
|
GPUVertFormat format_data = {0};
|
|
|
|
|
uint data_id = GPU_vertformat_attr_add(&format_data, "data", GPU_COMP_U32, 1, GPU_FETCH_INT);
|
|
|
|
|
|
|
|
|
|
GPUVertFormat format_seg = {0};
|
|
|
|
|
uint seg_id = GPU_vertformat_attr_add(&format_seg, "data", GPU_COMP_U16, 1, GPU_FETCH_INT);
|
|
|
|
|
|
2022-03-30 18:25:06 -05:00
|
|
|
/* Curve Data. */
|
|
|
|
|
cache.proc_strand_buf = GPU_vertbuf_create_with_format(&format_data);
|
|
|
|
|
GPU_vertbuf_data_alloc(cache.proc_strand_buf, cache.strands_len);
|
|
|
|
|
GPU_vertbuf_attr_get_raw_data(cache.proc_strand_buf, data_id, &data_step);
|
2020-03-17 14:41:48 +01:00
|
|
|
|
2022-03-30 18:25:06 -05:00
|
|
|
cache.proc_strand_seg_buf = GPU_vertbuf_create_with_format(&format_seg);
|
|
|
|
|
GPU_vertbuf_data_alloc(cache.proc_strand_seg_buf, cache.strands_len);
|
|
|
|
|
GPU_vertbuf_attr_get_raw_data(cache.proc_strand_seg_buf, seg_id, &seg_step);
|
2020-03-17 14:41:48 +01:00
|
|
|
|
2022-03-30 18:25:06 -05:00
|
|
|
curves_batch_cache_fill_strands_data(curves, data_step, seg_step);
|
2020-03-17 14:41:48 +01:00
|
|
|
|
|
|
|
|
/* Create vbo immediately to bind to texture buffer. */
|
2022-03-30 18:25:06 -05:00
|
|
|
GPU_vertbuf_use(cache.proc_strand_buf);
|
|
|
|
|
cache.strand_tex = GPU_texture_create_from_vertbuf("curves_strand", cache.proc_strand_buf);
|
2020-03-17 14:41:48 +01:00
|
|
|
|
2022-03-30 18:25:06 -05:00
|
|
|
GPU_vertbuf_use(cache.proc_strand_seg_buf);
|
|
|
|
|
cache.strand_seg_tex = GPU_texture_create_from_vertbuf("curves_strand_seg",
|
|
|
|
|
cache.proc_strand_seg_buf);
|
2020-03-17 14:41:48 +01:00
|
|
|
}
|
|
|
|
|
|
2022-04-22 10:43:48 -05:00
|
|
|
static void curves_batch_cache_ensure_procedural_final_points(CurvesEvalCache &cache, int subdiv)
|
2020-03-17 14:41:48 +01:00
|
|
|
{
|
|
|
|
|
/* Same format as point_tex. */
|
|
|
|
|
GPUVertFormat format = {0};
|
|
|
|
|
GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
|
|
|
|
|
|
2022-03-30 18:25:06 -05:00
|
|
|
cache.final[subdiv].proc_buf = GPU_vertbuf_create_with_format_ex(&format, GPU_USAGE_DEVICE_ONLY);
|
2020-03-17 14:41:48 +01:00
|
|
|
|
|
|
|
|
/* Create a destination buffer for the transform feedback. Sized appropriately */
|
|
|
|
|
/* Those are points! not line segments. */
|
2022-03-30 18:25:06 -05:00
|
|
|
GPU_vertbuf_data_alloc(cache.final[subdiv].proc_buf,
|
|
|
|
|
cache.final[subdiv].strands_res * cache.strands_len);
|
2020-03-17 14:41:48 +01:00
|
|
|
|
|
|
|
|
/* Create vbo immediately to bind to texture buffer. */
|
2022-03-30 18:25:06 -05:00
|
|
|
GPU_vertbuf_use(cache.final[subdiv].proc_buf);
|
2020-03-17 14:41:48 +01:00
|
|
|
|
2022-03-30 18:25:06 -05:00
|
|
|
cache.final[subdiv].proc_tex = GPU_texture_create_from_vertbuf("hair_proc",
|
|
|
|
|
cache.final[subdiv].proc_buf);
|
2020-03-17 14:41:48 +01:00
|
|
|
}
|
|
|
|
|
|
2022-03-30 18:25:06 -05:00
|
|
|
static void curves_batch_cache_fill_segments_indices(const Curves &curves,
|
Curves: Rename "Hair" types, variables, and functions to "Curves"
Based on discussions from T95355 and T94193, the plan is to use
the name "Curves" to describe the data-block container for multiple
curves. Eventually this will replace the existing "Curve" data-block.
However, it will be a while before the curve data-block can be replaced
so in order to distinguish the two curve types in the UI, "Hair Curves"
will be used, but eventually changed back to "Curves".
This patch renames "hair-related" files, functions, types, and variable
names to this convention. A deep rename is preferred to keep code
consistent and to avoid any "hair" terminology from leaking, since the
new data-block is meant for all curve types, not just hair use cases.
The downside of this naming is that the difference between "Curve"
and "Curves" has become important. That was considered during
design discussons and deemed acceptable, especially given the
non-permanent nature of the somewhat common conflict.
Some points of interest:
- All DNA compatibility is lost, just like rBf59767ff9729.
- I renamed `ID_HA` to `ID_CV` so there is no complete mismatch.
- `hair_curves` is used where necessary to distinguish from the
existing "curves" plural.
- I didn't rename any of the cycles/rendering code function names,
since that is also used by the old hair particle system.
Differential Revision: https://developer.blender.org/D14007
2022-02-07 11:55:54 -06:00
|
|
|
const int res,
|
2022-03-30 18:25:06 -05:00
|
|
|
GPUIndexBufBuilder &elb)
|
2020-03-17 14:41:48 +01:00
|
|
|
{
|
2022-05-11 09:58:39 +10:00
|
|
|
const int curves_num = curves.geometry.curve_num;
|
2022-02-03 10:49:51 -06:00
|
|
|
|
2020-03-17 14:41:48 +01:00
|
|
|
uint curr_point = 0;
|
2022-02-03 10:49:51 -06:00
|
|
|
|
2022-03-30 18:25:06 -05:00
|
|
|
for ([[maybe_unused]] const int i : IndexRange(curves_num)) {
|
2020-03-17 14:41:48 +01:00
|
|
|
for (int k = 0; k < res; k++) {
|
2022-03-30 18:25:06 -05:00
|
|
|
GPU_indexbuf_add_generic_vert(&elb, curr_point++);
|
2020-03-17 14:41:48 +01:00
|
|
|
}
|
2022-03-30 18:25:06 -05:00
|
|
|
GPU_indexbuf_add_primitive_restart(&elb);
|
2020-03-17 14:41:48 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-03-30 18:25:06 -05:00
|
|
|
static void curves_batch_cache_ensure_procedural_indices(Curves &curves,
|
2022-04-22 10:43:48 -05:00
|
|
|
CurvesEvalCache &cache,
|
2022-03-30 18:25:06 -05:00
|
|
|
const int thickness_res,
|
|
|
|
|
const int subdiv)
|
2020-03-17 14:41:48 +01:00
|
|
|
{
|
|
|
|
|
BLI_assert(thickness_res <= MAX_THICKRES); /* Cylinder strip not currently supported. */
|
|
|
|
|
|
2022-03-30 18:25:06 -05:00
|
|
|
if (cache.final[subdiv].proc_hairs[thickness_res - 1] != nullptr) {
|
2020-03-17 14:41:48 +01:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2022-03-30 18:25:06 -05:00
|
|
|
int verts_per_curve = cache.final[subdiv].strands_res * thickness_res;
|
2020-03-17 14:41:48 +01:00
|
|
|
/* +1 for primitive restart */
|
2022-03-30 18:25:06 -05:00
|
|
|
int element_count = (verts_per_curve + 1) * cache.strands_len;
|
2020-03-17 14:41:48 +01:00
|
|
|
GPUPrimType prim_type = (thickness_res == 1) ? GPU_PRIM_LINE_STRIP : GPU_PRIM_TRI_STRIP;
|
|
|
|
|
|
|
|
|
|
static GPUVertFormat format = {0};
|
|
|
|
|
GPU_vertformat_clear(&format);
|
|
|
|
|
|
|
|
|
|
/* initialize vertex format */
|
|
|
|
|
GPU_vertformat_attr_add(&format, "dummy", GPU_COMP_U8, 1, GPU_FETCH_INT_TO_FLOAT_UNIT);
|
|
|
|
|
|
|
|
|
|
GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format);
|
|
|
|
|
GPU_vertbuf_data_alloc(vbo, 1);
|
|
|
|
|
|
|
|
|
|
GPUIndexBufBuilder elb;
|
|
|
|
|
GPU_indexbuf_init_ex(&elb, prim_type, element_count, element_count);
|
|
|
|
|
|
2022-03-30 18:25:06 -05:00
|
|
|
curves_batch_cache_fill_segments_indices(curves, verts_per_curve, elb);
|
2020-03-17 14:41:48 +01:00
|
|
|
|
2022-03-30 18:25:06 -05:00
|
|
|
cache.final[subdiv].proc_hairs[thickness_res - 1] = GPU_batch_create_ex(
|
2020-03-17 14:41:48 +01:00
|
|
|
prim_type, vbo, GPU_indexbuf_build(&elb), GPU_BATCH_OWNS_VBO | GPU_BATCH_OWNS_INDEX);
|
|
|
|
|
}
|
|
|
|
|
|
EEVEE: support Curves attributes rendering
This adds support to render Curves attributes in EEVEE.
Each attribute is stored in a texture derived from a VBO. As the
shading group needs the textures to be valid upon creation, the
attributes are created and setup during its very creation, instead
of doing it lazily via create_requested which we cannot rely on
anyway as contrary to the mesh batch, we do cannot really tell if
attributes need to be updated or else via some `DRW_batch_requested`.
Since point attributes need refinement, and since attributes are all
cast to vec4/float4 to account for differences in type conversions
between Blender and OpenGL, the refinement shader for points is
used as is. The point attributes are stored for each subdivision level
in CurvesEvalFinalCache. Each subdivision level also keeps track of the
attributes already in use so they are properly updated when needed.
Some basic garbage collection was added similar to what is done
for meshes: if the attributes used over time have been different
from the currently used attributes for too long, then the buffers
are freed, ensuring that stale attributesare removed.
This adds `CurvesInfos` to the shader creation info, which stores
the scope in which the attributes are defined. Scopes are stored
as booleans, in an array indexed by attribute loading order which
is also the order in which the attributes were added to the material.
A mapping is necessary between the indices used for the scoping, and
the ones used in the Curves cache, as this may contain stale
attributes which have not been garbage collected yet.
Common utilities with the mesh code for handling requested
attributes were moved to a separate file.
Differential Revision: https://developer.blender.org/D14916
2022-05-24 05:02:57 +02:00
|
|
|
static bool curves_ensure_attributes(const Curves &curves,
|
|
|
|
|
CurvesBatchCache &cache,
|
|
|
|
|
GPUMaterial *gpu_material,
|
|
|
|
|
int subdiv)
|
|
|
|
|
{
|
|
|
|
|
ThreadMutex *render_mutex = &cache.render_mutex;
|
|
|
|
|
const CustomData *cd_curve = &curves.geometry.curve_data;
|
|
|
|
|
const CustomData *cd_point = &curves.geometry.point_data;
|
|
|
|
|
|
|
|
|
|
DRW_Attributes attrs_needed;
|
|
|
|
|
drw_attributes_clear(&attrs_needed);
|
|
|
|
|
ListBase gpu_attrs = GPU_material_attributes(gpu_material);
|
|
|
|
|
LISTBASE_FOREACH (GPUMaterialAttribute *, gpu_attr, &gpu_attrs) {
|
|
|
|
|
const char *name = gpu_attr->name;
|
|
|
|
|
|
2022-06-17 15:11:10 +02:00
|
|
|
int layer_index;
|
|
|
|
|
eCustomDataType type;
|
|
|
|
|
eAttrDomain domain;
|
|
|
|
|
if (drw_custom_data_match_attribute(cd_curve, name, &layer_index, &type)) {
|
EEVEE: support Curves attributes rendering
This adds support to render Curves attributes in EEVEE.
Each attribute is stored in a texture derived from a VBO. As the
shading group needs the textures to be valid upon creation, the
attributes are created and setup during its very creation, instead
of doing it lazily via create_requested which we cannot rely on
anyway as contrary to the mesh batch, we do cannot really tell if
attributes need to be updated or else via some `DRW_batch_requested`.
Since point attributes need refinement, and since attributes are all
cast to vec4/float4 to account for differences in type conversions
between Blender and OpenGL, the refinement shader for points is
used as is. The point attributes are stored for each subdivision level
in CurvesEvalFinalCache. Each subdivision level also keeps track of the
attributes already in use so they are properly updated when needed.
Some basic garbage collection was added similar to what is done
for meshes: if the attributes used over time have been different
from the currently used attributes for too long, then the buffers
are freed, ensuring that stale attributesare removed.
This adds `CurvesInfos` to the shader creation info, which stores
the scope in which the attributes are defined. Scopes are stored
as booleans, in an array indexed by attribute loading order which
is also the order in which the attributes were added to the material.
A mapping is necessary between the indices used for the scoping, and
the ones used in the Curves cache, as this may contain stale
attributes which have not been garbage collected yet.
Common utilities with the mesh code for handling requested
attributes were moved to a separate file.
Differential Revision: https://developer.blender.org/D14916
2022-05-24 05:02:57 +02:00
|
|
|
domain = ATTR_DOMAIN_CURVE;
|
|
|
|
|
}
|
2022-06-17 15:11:10 +02:00
|
|
|
else if (drw_custom_data_match_attribute(cd_point, name, &layer_index, &type)) {
|
EEVEE: support Curves attributes rendering
This adds support to render Curves attributes in EEVEE.
Each attribute is stored in a texture derived from a VBO. As the
shading group needs the textures to be valid upon creation, the
attributes are created and setup during its very creation, instead
of doing it lazily via create_requested which we cannot rely on
anyway as contrary to the mesh batch, we do cannot really tell if
attributes need to be updated or else via some `DRW_batch_requested`.
Since point attributes need refinement, and since attributes are all
cast to vec4/float4 to account for differences in type conversions
between Blender and OpenGL, the refinement shader for points is
used as is. The point attributes are stored for each subdivision level
in CurvesEvalFinalCache. Each subdivision level also keeps track of the
attributes already in use so they are properly updated when needed.
Some basic garbage collection was added similar to what is done
for meshes: if the attributes used over time have been different
from the currently used attributes for too long, then the buffers
are freed, ensuring that stale attributesare removed.
This adds `CurvesInfos` to the shader creation info, which stores
the scope in which the attributes are defined. Scopes are stored
as booleans, in an array indexed by attribute loading order which
is also the order in which the attributes were added to the material.
A mapping is necessary between the indices used for the scoping, and
the ones used in the Curves cache, as this may contain stale
attributes which have not been garbage collected yet.
Common utilities with the mesh code for handling requested
attributes were moved to a separate file.
Differential Revision: https://developer.blender.org/D14916
2022-05-24 05:02:57 +02:00
|
|
|
domain = ATTR_DOMAIN_POINT;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
2022-06-18 11:48:51 +02:00
|
|
|
drw_attributes_add_request(&attrs_needed, name, type, layer_index, domain);
|
EEVEE: support Curves attributes rendering
This adds support to render Curves attributes in EEVEE.
Each attribute is stored in a texture derived from a VBO. As the
shading group needs the textures to be valid upon creation, the
attributes are created and setup during its very creation, instead
of doing it lazily via create_requested which we cannot rely on
anyway as contrary to the mesh batch, we do cannot really tell if
attributes need to be updated or else via some `DRW_batch_requested`.
Since point attributes need refinement, and since attributes are all
cast to vec4/float4 to account for differences in type conversions
between Blender and OpenGL, the refinement shader for points is
used as is. The point attributes are stored for each subdivision level
in CurvesEvalFinalCache. Each subdivision level also keeps track of the
attributes already in use so they are properly updated when needed.
Some basic garbage collection was added similar to what is done
for meshes: if the attributes used over time have been different
from the currently used attributes for too long, then the buffers
are freed, ensuring that stale attributesare removed.
This adds `CurvesInfos` to the shader creation info, which stores
the scope in which the attributes are defined. Scopes are stored
as booleans, in an array indexed by attribute loading order which
is also the order in which the attributes were added to the material.
A mapping is necessary between the indices used for the scoping, and
the ones used in the Curves cache, as this may contain stale
attributes which have not been garbage collected yet.
Common utilities with the mesh code for handling requested
attributes were moved to a separate file.
Differential Revision: https://developer.blender.org/D14916
2022-05-24 05:02:57 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
CurvesEvalFinalCache &final_cache = cache.curves_cache.final[subdiv];
|
|
|
|
|
|
2022-06-17 15:11:10 +02:00
|
|
|
if (!drw_attributes_overlap(&final_cache.attr_used, &attrs_needed)) {
|
EEVEE: support Curves attributes rendering
This adds support to render Curves attributes in EEVEE.
Each attribute is stored in a texture derived from a VBO. As the
shading group needs the textures to be valid upon creation, the
attributes are created and setup during its very creation, instead
of doing it lazily via create_requested which we cannot rely on
anyway as contrary to the mesh batch, we do cannot really tell if
attributes need to be updated or else via some `DRW_batch_requested`.
Since point attributes need refinement, and since attributes are all
cast to vec4/float4 to account for differences in type conversions
between Blender and OpenGL, the refinement shader for points is
used as is. The point attributes are stored for each subdivision level
in CurvesEvalFinalCache. Each subdivision level also keeps track of the
attributes already in use so they are properly updated when needed.
Some basic garbage collection was added similar to what is done
for meshes: if the attributes used over time have been different
from the currently used attributes for too long, then the buffers
are freed, ensuring that stale attributesare removed.
This adds `CurvesInfos` to the shader creation info, which stores
the scope in which the attributes are defined. Scopes are stored
as booleans, in an array indexed by attribute loading order which
is also the order in which the attributes were added to the material.
A mapping is necessary between the indices used for the scoping, and
the ones used in the Curves cache, as this may contain stale
attributes which have not been garbage collected yet.
Common utilities with the mesh code for handling requested
attributes were moved to a separate file.
Differential Revision: https://developer.blender.org/D14916
2022-05-24 05:02:57 +02:00
|
|
|
/* Some new attributes have been added, free all and start over. */
|
2022-06-17 15:11:10 +02:00
|
|
|
for (const int i : IndexRange(GPU_MAX_ATTR)) {
|
EEVEE: support Curves attributes rendering
This adds support to render Curves attributes in EEVEE.
Each attribute is stored in a texture derived from a VBO. As the
shading group needs the textures to be valid upon creation, the
attributes are created and setup during its very creation, instead
of doing it lazily via create_requested which we cannot rely on
anyway as contrary to the mesh batch, we do cannot really tell if
attributes need to be updated or else via some `DRW_batch_requested`.
Since point attributes need refinement, and since attributes are all
cast to vec4/float4 to account for differences in type conversions
between Blender and OpenGL, the refinement shader for points is
used as is. The point attributes are stored for each subdivision level
in CurvesEvalFinalCache. Each subdivision level also keeps track of the
attributes already in use so they are properly updated when needed.
Some basic garbage collection was added similar to what is done
for meshes: if the attributes used over time have been different
from the currently used attributes for too long, then the buffers
are freed, ensuring that stale attributesare removed.
This adds `CurvesInfos` to the shader creation info, which stores
the scope in which the attributes are defined. Scopes are stored
as booleans, in an array indexed by attribute loading order which
is also the order in which the attributes were added to the material.
A mapping is necessary between the indices used for the scoping, and
the ones used in the Curves cache, as this may contain stale
attributes which have not been garbage collected yet.
Common utilities with the mesh code for handling requested
attributes were moved to a separate file.
Differential Revision: https://developer.blender.org/D14916
2022-05-24 05:02:57 +02:00
|
|
|
GPU_VERTBUF_DISCARD_SAFE(cache.curves_cache.proc_attributes_buf[i]);
|
|
|
|
|
DRW_TEXTURE_FREE_SAFE(cache.curves_cache.proc_attributes_tex[i]);
|
|
|
|
|
}
|
|
|
|
|
drw_attributes_merge(&final_cache.attr_used, &attrs_needed, render_mutex);
|
|
|
|
|
}
|
|
|
|
|
drw_attributes_merge(&final_cache.attr_used_over_time, &attrs_needed, render_mutex);
|
|
|
|
|
|
|
|
|
|
bool need_tf_update = false;
|
|
|
|
|
|
2022-06-17 15:11:10 +02:00
|
|
|
for (const int i : IndexRange(final_cache.attr_used.num_requests)) {
|
EEVEE: support Curves attributes rendering
This adds support to render Curves attributes in EEVEE.
Each attribute is stored in a texture derived from a VBO. As the
shading group needs the textures to be valid upon creation, the
attributes are created and setup during its very creation, instead
of doing it lazily via create_requested which we cannot rely on
anyway as contrary to the mesh batch, we do cannot really tell if
attributes need to be updated or else via some `DRW_batch_requested`.
Since point attributes need refinement, and since attributes are all
cast to vec4/float4 to account for differences in type conversions
between Blender and OpenGL, the refinement shader for points is
used as is. The point attributes are stored for each subdivision level
in CurvesEvalFinalCache. Each subdivision level also keeps track of the
attributes already in use so they are properly updated when needed.
Some basic garbage collection was added similar to what is done
for meshes: if the attributes used over time have been different
from the currently used attributes for too long, then the buffers
are freed, ensuring that stale attributesare removed.
This adds `CurvesInfos` to the shader creation info, which stores
the scope in which the attributes are defined. Scopes are stored
as booleans, in an array indexed by attribute loading order which
is also the order in which the attributes were added to the material.
A mapping is necessary between the indices used for the scoping, and
the ones used in the Curves cache, as this may contain stale
attributes which have not been garbage collected yet.
Common utilities with the mesh code for handling requested
attributes were moved to a separate file.
Differential Revision: https://developer.blender.org/D14916
2022-05-24 05:02:57 +02:00
|
|
|
const DRW_AttributeRequest &request = final_cache.attr_used.requests[i];
|
|
|
|
|
|
|
|
|
|
if (cache.curves_cache.proc_attributes_buf[i] != nullptr) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (request.domain == ATTR_DOMAIN_POINT) {
|
|
|
|
|
need_tf_update = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
curves_batch_ensure_attribute(curves, cache.curves_cache, request, subdiv, i);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return need_tf_update;
|
|
|
|
|
}
|
|
|
|
|
|
2022-06-22 16:57:57 -05:00
|
|
|
bool curves_ensure_procedural_data(Curves *curves,
|
2022-04-22 10:43:48 -05:00
|
|
|
CurvesEvalCache **r_hair_cache,
|
2022-03-30 18:25:06 -05:00
|
|
|
GPUMaterial *gpu_material,
|
|
|
|
|
const int subdiv,
|
|
|
|
|
const int thickness_res)
|
2020-03-17 14:41:48 +01:00
|
|
|
{
|
|
|
|
|
bool need_ft_update = false;
|
|
|
|
|
|
2022-06-22 16:57:57 -05:00
|
|
|
CurvesBatchCache &cache = curves_batch_cache_get(*curves);
|
2022-04-22 10:43:48 -05:00
|
|
|
*r_hair_cache = &cache.curves_cache;
|
2020-03-17 14:41:48 +01:00
|
|
|
|
2022-03-08 10:36:46 +01:00
|
|
|
const int steps = 3; /* TODO: don't hard-code? */
|
2020-03-17 14:41:48 +01:00
|
|
|
(*r_hair_cache)->final[subdiv].strands_res = 1 << (steps + subdiv);
|
|
|
|
|
|
|
|
|
|
/* Refreshed on combing and simulation. */
|
2021-12-23 11:46:45 -06:00
|
|
|
if ((*r_hair_cache)->proc_point_buf == nullptr) {
|
2022-06-22 16:57:57 -05:00
|
|
|
ensure_seg_pt_count(*curves, cache.curves_cache);
|
|
|
|
|
curves_batch_cache_ensure_procedural_pos(*curves, cache.curves_cache, gpu_material);
|
2020-03-17 14:41:48 +01:00
|
|
|
need_ft_update = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Refreshed if active layer or custom data changes. */
|
2021-12-23 11:46:45 -06:00
|
|
|
if ((*r_hair_cache)->strand_tex == nullptr) {
|
2022-06-22 16:57:57 -05:00
|
|
|
curves_batch_cache_ensure_procedural_strand_data(*curves, cache.curves_cache);
|
2020-03-17 14:41:48 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Refreshed only on subdiv count change. */
|
2021-12-23 11:46:45 -06:00
|
|
|
if ((*r_hair_cache)->final[subdiv].proc_buf == nullptr) {
|
2022-04-22 10:43:48 -05:00
|
|
|
curves_batch_cache_ensure_procedural_final_points(cache.curves_cache, subdiv);
|
2020-03-17 14:41:48 +01:00
|
|
|
need_ft_update = true;
|
|
|
|
|
}
|
2021-12-23 11:46:45 -06:00
|
|
|
if ((*r_hair_cache)->final[subdiv].proc_hairs[thickness_res - 1] == nullptr) {
|
2022-04-22 10:43:48 -05:00
|
|
|
curves_batch_cache_ensure_procedural_indices(
|
2022-06-22 16:57:57 -05:00
|
|
|
*curves, cache.curves_cache, thickness_res, subdiv);
|
2020-03-17 14:41:48 +01:00
|
|
|
}
|
|
|
|
|
|
EEVEE: support Curves attributes rendering
This adds support to render Curves attributes in EEVEE.
Each attribute is stored in a texture derived from a VBO. As the
shading group needs the textures to be valid upon creation, the
attributes are created and setup during its very creation, instead
of doing it lazily via create_requested which we cannot rely on
anyway as contrary to the mesh batch, we do cannot really tell if
attributes need to be updated or else via some `DRW_batch_requested`.
Since point attributes need refinement, and since attributes are all
cast to vec4/float4 to account for differences in type conversions
between Blender and OpenGL, the refinement shader for points is
used as is. The point attributes are stored for each subdivision level
in CurvesEvalFinalCache. Each subdivision level also keeps track of the
attributes already in use so they are properly updated when needed.
Some basic garbage collection was added similar to what is done
for meshes: if the attributes used over time have been different
from the currently used attributes for too long, then the buffers
are freed, ensuring that stale attributesare removed.
This adds `CurvesInfos` to the shader creation info, which stores
the scope in which the attributes are defined. Scopes are stored
as booleans, in an array indexed by attribute loading order which
is also the order in which the attributes were added to the material.
A mapping is necessary between the indices used for the scoping, and
the ones used in the Curves cache, as this may contain stale
attributes which have not been garbage collected yet.
Common utilities with the mesh code for handling requested
attributes were moved to a separate file.
Differential Revision: https://developer.blender.org/D14916
2022-05-24 05:02:57 +02:00
|
|
|
if (gpu_material) {
|
2022-06-22 16:57:57 -05:00
|
|
|
need_ft_update |= curves_ensure_attributes(*curves, cache, gpu_material, subdiv);
|
EEVEE: support Curves attributes rendering
This adds support to render Curves attributes in EEVEE.
Each attribute is stored in a texture derived from a VBO. As the
shading group needs the textures to be valid upon creation, the
attributes are created and setup during its very creation, instead
of doing it lazily via create_requested which we cannot rely on
anyway as contrary to the mesh batch, we do cannot really tell if
attributes need to be updated or else via some `DRW_batch_requested`.
Since point attributes need refinement, and since attributes are all
cast to vec4/float4 to account for differences in type conversions
between Blender and OpenGL, the refinement shader for points is
used as is. The point attributes are stored for each subdivision level
in CurvesEvalFinalCache. Each subdivision level also keeps track of the
attributes already in use so they are properly updated when needed.
Some basic garbage collection was added similar to what is done
for meshes: if the attributes used over time have been different
from the currently used attributes for too long, then the buffers
are freed, ensuring that stale attributesare removed.
This adds `CurvesInfos` to the shader creation info, which stores
the scope in which the attributes are defined. Scopes are stored
as booleans, in an array indexed by attribute loading order which
is also the order in which the attributes were added to the material.
A mapping is necessary between the indices used for the scoping, and
the ones used in the Curves cache, as this may contain stale
attributes which have not been garbage collected yet.
Common utilities with the mesh code for handling requested
attributes were moved to a separate file.
Differential Revision: https://developer.blender.org/D14916
2022-05-24 05:02:57 +02:00
|
|
|
}
|
|
|
|
|
|
2020-03-17 14:41:48 +01:00
|
|
|
return need_ft_update;
|
|
|
|
|
}
|
|
|
|
|
|
Curves: Rename "Hair" types, variables, and functions to "Curves"
Based on discussions from T95355 and T94193, the plan is to use
the name "Curves" to describe the data-block container for multiple
curves. Eventually this will replace the existing "Curve" data-block.
However, it will be a while before the curve data-block can be replaced
so in order to distinguish the two curve types in the UI, "Hair Curves"
will be used, but eventually changed back to "Curves".
This patch renames "hair-related" files, functions, types, and variable
names to this convention. A deep rename is preferred to keep code
consistent and to avoid any "hair" terminology from leaking, since the
new data-block is meant for all curve types, not just hair use cases.
The downside of this naming is that the difference between "Curve"
and "Curves" has become important. That was considered during
design discussons and deemed acceptable, especially given the
non-permanent nature of the somewhat common conflict.
Some points of interest:
- All DNA compatibility is lost, just like rBf59767ff9729.
- I renamed `ID_HA` to `ID_CV` so there is no complete mismatch.
- `hair_curves` is used where necessary to distinguish from the
existing "curves" plural.
- I didn't rename any of the cycles/rendering code function names,
since that is also used by the old hair particle system.
Differential Revision: https://developer.blender.org/D14007
2022-02-07 11:55:54 -06:00
|
|
|
int DRW_curves_material_count_get(Curves *curves)
|
2020-03-17 14:41:48 +01:00
|
|
|
{
|
Curves: Rename "Hair" types, variables, and functions to "Curves"
Based on discussions from T95355 and T94193, the plan is to use
the name "Curves" to describe the data-block container for multiple
curves. Eventually this will replace the existing "Curve" data-block.
However, it will be a while before the curve data-block can be replaced
so in order to distinguish the two curve types in the UI, "Hair Curves"
will be used, but eventually changed back to "Curves".
This patch renames "hair-related" files, functions, types, and variable
names to this convention. A deep rename is preferred to keep code
consistent and to avoid any "hair" terminology from leaking, since the
new data-block is meant for all curve types, not just hair use cases.
The downside of this naming is that the difference between "Curve"
and "Curves" has become important. That was considered during
design discussons and deemed acceptable, especially given the
non-permanent nature of the somewhat common conflict.
Some points of interest:
- All DNA compatibility is lost, just like rBf59767ff9729.
- I renamed `ID_HA` to `ID_CV` so there is no complete mismatch.
- `hair_curves` is used where necessary to distinguish from the
existing "curves" plural.
- I didn't rename any of the cycles/rendering code function names,
since that is also used by the old hair particle system.
Differential Revision: https://developer.blender.org/D14007
2022-02-07 11:55:54 -06:00
|
|
|
return max_ii(1, curves->totcol);
|
2020-03-17 14:41:48 +01:00
|
|
|
}
|
2022-04-08 18:23:40 +02:00
|
|
|
|
|
|
|
|
GPUBatch *DRW_curves_batch_cache_get_edit_points(Curves *curves)
|
|
|
|
|
{
|
|
|
|
|
CurvesBatchCache &cache = curves_batch_cache_get(*curves);
|
|
|
|
|
return DRW_batch_request(&cache.edit_points);
|
|
|
|
|
}
|
|
|
|
|
|
2022-06-17 09:44:37 +02:00
|
|
|
void DRW_curves_batch_cache_create_requested(Object *ob)
|
2022-04-08 18:23:40 +02:00
|
|
|
{
|
|
|
|
|
Curves *curves = static_cast<Curves *>(ob->data);
|
|
|
|
|
CurvesBatchCache &cache = curves_batch_cache_get(*curves);
|
|
|
|
|
|
|
|
|
|
if (DRW_batch_requested(cache.edit_points, GPU_PRIM_POINTS)) {
|
2022-04-22 10:43:48 -05:00
|
|
|
DRW_vbo_request(cache.edit_points, &cache.curves_cache.proc_point_buf);
|
2022-04-08 18:23:40 +02:00
|
|
|
}
|
|
|
|
|
|
2022-04-22 10:43:48 -05:00
|
|
|
if (DRW_vbo_requested(cache.curves_cache.proc_point_buf)) {
|
|
|
|
|
curves_batch_cache_ensure_procedural_pos(*curves, cache.curves_cache, nullptr);
|
2022-04-08 18:23:40 +02:00
|
|
|
}
|
|
|
|
|
}
|