Render engine support for curves data-block #96455

Open
opened 2022-03-14 14:47:00 +01:00 by Dalai Felinto · 9 comments

Several features need to be supported in Cycles, workbench and EEVEE.
Most of the relevant code is shared between EEVEE and workbench as part of the draw manager.
Initially at least, NURBS curves can be supported by computing the weights for each evaluated
point on the CPU (see blender::bke::curves::nurbs::BasisCache), and just doing interpolation
of attributes on the GPU.

For EEVEE/Viewport, supporting different curve types, segment counts, and cyclic values
could be done by batching curves with similar data. For example, all curves with segment
counts in between two powers of 2 could be batched together, with padding triangles added
at the final point.

Curves have a resolution attribute which makes the current "subdivisions" settings redundant.
Render engines should support the resolution instead. Further changes to the evaluation
resolution can be part of the standard "Simplify" options.

  • EEVEE/Viewport
    • Curve types
      • Camull Rom
      • Bezier
      • Poly
      • NURBS
    • Cyclic
    • Radius Attribute Support
    • Generic attribute rendering
    • Curve segment count
      • Remove drawing pass that resamples curves
      • Support drawing arbitrary segment length curves
    • Tube/cylinder drawing
    • Resolution attribute support
  • Cycles
    • Curve types
      • Camull Rom
      • Bezier
      • Poly
      • NURBS
    • Cyclic
    • Radius attribute Support
    • Generic attribute rendering
      • Curve domain generic attributes
      • Point domain attributes
    • Resolution attribute support
  • Move curve render settings from scene to object data
  • Add curve resolution limit to render "simplify" settings
Several features need to be supported in Cycles, workbench and EEVEE. Most of the relevant code is shared between EEVEE and workbench as part of the draw manager. Initially at least, NURBS curves can be supported by computing the weights for each evaluated point on the CPU (see `blender::bke::curves::nurbs::BasisCache`), and just doing interpolation of attributes on the GPU. For EEVEE/Viewport, supporting different curve types, segment counts, and cyclic values could be done by batching curves with similar data. For example, all curves with segment counts in between two powers of 2 could be batched together, with padding triangles added at the final point. Curves have a resolution attribute which makes the current "subdivisions" settings redundant. Render engines should support the resolution instead. Further changes to the evaluation resolution can be part of the standard "Simplify" options. - [ ] EEVEE/Viewport - [ ] Curve types - [x] Camull Rom - [ ] Bezier - [ ] Poly - [ ] NURBS - [ ] Cyclic - [ ] Radius Attribute Support - [x] Generic attribute rendering - [x] Curve domain generic attributes cd968a3273 - [x] Point domain attributes cd968a3273 - [ ] Curve segment count - [ ] Remove drawing pass that resamples curves - [ ] Support drawing arbitrary segment length curves - [ ] Tube/cylinder drawing - [ ] Resolution attribute support - [ ] Cycles - [ ] Curve types - [x] Camull Rom - [ ] Bezier - [ ] Poly - [ ] NURBS - [ ] Cyclic - [x] Radius attribute Support - [x] Generic attribute rendering - [x] Curve domain generic attributes - [x] Point domain attributes - [ ] Resolution attribute support - [ ] Move curve render settings from scene to object data - [ ] Add curve resolution limit to render "simplify" settings

#101952 was marked as duplicate of this issue

#101952 was marked as duplicate of this issue

#101750 was marked as duplicate of this issue

#101750 was marked as duplicate of this issue

#100082 was marked as duplicate of this issue

#100082 was marked as duplicate of this issue
Jacques Lucke changed title from Drawing of evaluated curves - curves edit mode to Drawing of evaluated curves 2022-03-28 14:10:21 +02:00
Member

Okay, it seems this is much more complicated than I expected. After talking with the #eevee_viewport people, it seems that it's quite important that the evaluation happens on the GPU rather than the CPU.
Of course we probably still need CPU evaluation for various algorithms implemented on the CPU, but apparently the GPU evaluation is important since uploading attribute data to the GPU has a significant performance impact.

  • Currently accelerated drawing is supported for Catmull Rom curves, though apparently it is only hooked up to the old particle system, not the new object type.
  • Support for Bezier curves, poly curves, and NURBS curves still needs implementing.
  • Support for generic attributes on curves is a known TODO in drawing code.
  • Grouping/batching curves by their length (number of control points) might be important. Batching by curve type may or may not be helpful.
  • Support for cyclic curves should also be implemented.

For Cycles, at least it's in an "initially functional" state. But many of the same TODOs apply, including support for other curve types, and cyclic curves.

The next steps seem to be:

  • Split the drawing code for the new curves object from the old particle system. At least splitting the batch cache generation is obvious, probably the shaders also.
  • Proper support for drawing curves with different lengths (don't resample them all to the same length before drawing).
  • Implement support for different curve types, basically porting some of the code from curve_bezier.cc, curve_catmull_rom.cc, and curve_nurbs.cc to a compute shader.
Okay, it seems this is much more complicated than I expected. After talking with the #eevee_viewport people, it seems that it's quite important that the evaluation happens on the GPU rather than the CPU. Of course we probably still need CPU evaluation for various algorithms implemented on the CPU, but apparently the GPU evaluation is important since uploading attribute data to the GPU has a significant performance impact. - Currently accelerated drawing is supported for Catmull Rom curves, though apparently it is only hooked up to the old particle system, not the new object type. - Support for Bezier curves, poly curves, and NURBS curves still needs implementing. - Support for generic attributes on curves is a known TODO in drawing code. - Grouping/batching curves by their length (number of control points) might be important. Batching by curve type may or may not be helpful. - Support for cyclic curves should also be implemented. For Cycles, at least it's in an "initially functional" state. But many of the same TODOs apply, including support for other curve types, and cyclic curves. The next steps seem to be: - Split the drawing code for the new curves object from the old particle system. At least splitting the batch cache generation is obvious, probably the shaders also. - Proper support for drawing curves with different lengths (don't resample them all to the same length before drawing). - Implement support for different curve types, basically porting some of the code from `curve_bezier.cc`, `curve_catmull_rom.cc`, and `curve_nurbs.cc` to a compute shader.

This issue was referenced by f31c3f8114

This issue was referenced by f31c3f8114616bb8964c8e7e67cbcb79e269ffef
Member

Notes from a discussion earlier today:

* Varying segment count
    * The conversion to triangles by the render engine relies on the fact that there are the same number of segments in each curve
    * This may work for hair, but it doesn't work for curves, since the use case is more general
    * Evaluating curves with the same number of segments in batches, and adding padding at the end where necessary should work.
        * The padding points can be added at the same position as the last point for each curve
    * Since all curves potentially have a unique segment count, grouping curves with similar point counts together makes sense.
        * All curves with less than 4 points, less than 8, less than 16, etc.
* Curve types
    * The render engine (i.e. EEVEE/Workbench) just gets a buffer of the final evaluated points, so it doesn't matter how they are generated.
    * Each curve type could have a separate shader, though some of the shader code could be shared.
    * Goal is to support evaluating Bezier curves and Catmull Rom curves on the GPU, and support drawing poly curves. NURBS curves can be evaluated on the CPU for now.
Notes from a discussion earlier today: * Varying segment count * The conversion to triangles by the render engine relies on the fact that there are the same number of segments in each curve * This may work for hair, but it doesn't work for curves, since the use case is more general * Evaluating curves with the same number of segments in batches, and adding padding at the end where necessary should work. * The padding points can be added at the same position as the last point for each curve * Since all curves potentially have a unique segment count, grouping curves with similar point counts together makes sense. * All curves with less than 4 points, less than 8, less than 16, etc. * Curve types * The render engine (i.e. EEVEE/Workbench) just gets a buffer of the final evaluated points, so it doesn't matter how they are generated. * Each curve type could have a separate shader, though some of the shader code could be shared. * Goal is to support evaluating Bezier curves and Catmull Rom curves on the GPU, and support drawing poly curves. NURBS curves can be evaluated on the CPU for now.

This issue was referenced by 5b87862ddc

This issue was referenced by 5b87862ddca2cb1b9351a5e250e1743b7245f38b
Hans Goudey changed title from Drawing of evaluated curves to Render engine support for drawing curves 2022-05-17 10:23:25 +02:00
Hans Goudey changed title from Render engine support for drawing curves to Render engine support for curves data-block 2022-05-17 10:24:20 +02:00

This issue was referenced by cd968a3273

This issue was referenced by cd968a32739587a5baacdd278a670d44570cbd8a
Member

Just dropping a snippet that would take into account the "real" spline resolution for drawing the curves.
This hack just uses the spline resolution (and only the resolution of the first spline) for whole strands though (not per segment), this is still wrong of course, so getting rid of the old particle drawing would still be more work.
P3378: curves_draw_with_spline_resolution

diff --git a/source/blender/draw/intern/draw_cache_impl_curves.cc b/source/blender/draw/intern/draw_cache_impl_curves.cc
index 1fc4d2e1f91..578c6ee8d15 100644
--- a/source/blender/draw/intern/draw_cache_impl_curves.cc
+++ b/source/blender/draw/intern/draw_cache_impl_curves.cc
@@ -576,8 +576,9 @@ bool curves_ensure_procedural_data(Curves *curves,
   CurvesBatchCache &cache = curves_batch_cache_get(*curves);
   *r_hair_cache = &cache.curves_cache;
 
-  const int steps = 3; /* TODO: don't hard-code? */
-  (*r_hair_cache)->final[subdiv].strands_res = 1 << (steps + subdiv);
+  blender::bke::CurvesGeometry &curves_geo = blender::bke::CurvesGeometry::wrap(curves->geometry);
+  blender::VArray<int> resolutions = curves_geo.resolution();
+  (*r_hair_cache)->final[subdiv].strands_res = resolutions- [x] << (subdiv + 1);
 
   /* Refreshed on combing and simulation. */
   if ((*r_hair_cache)->proc_point_buf == nullptr) {
Just dropping a snippet that would take into account the "real" spline resolution for drawing the curves. This hack just uses the spline resolution (and only the resolution of the **first** spline) for **whole strands** though (not per segment), this is still wrong of course, so getting rid of the old particle drawing would still be more work. [P3378: curves_draw_with_spline_resolution](https://archive.blender.org/developer/P3378.txt) ``` diff --git a/source/blender/draw/intern/draw_cache_impl_curves.cc b/source/blender/draw/intern/draw_cache_impl_curves.cc index 1fc4d2e1f91..578c6ee8d15 100644 --- a/source/blender/draw/intern/draw_cache_impl_curves.cc +++ b/source/blender/draw/intern/draw_cache_impl_curves.cc @@ -576,8 +576,9 @@ bool curves_ensure_procedural_data(Curves *curves, CurvesBatchCache &cache = curves_batch_cache_get(*curves); *r_hair_cache = &cache.curves_cache; - const int steps = 3; /* TODO: don't hard-code? */ - (*r_hair_cache)->final[subdiv].strands_res = 1 << (steps + subdiv); + blender::bke::CurvesGeometry &curves_geo = blender::bke::CurvesGeometry::wrap(curves->geometry); + blender::VArray<int> resolutions = curves_geo.resolution(); + (*r_hair_cache)->final[subdiv].strands_res = resolutions- [x] << (subdiv + 1); /* Refreshed on combing and simulation. */ if ((*r_hair_cache)->proc_point_buf == nullptr) { ```
Brecht Van Lommel added this to the Render & Cycles project 2023-02-07 19:08:06 +01:00
Philipp Oeser removed the
Interest
Render & Cycles
label 2023-02-09 14:03:15 +01:00
Philipp Oeser added the
Interest
Nodes & Physics
label 2023-02-10 11:20:19 +01:00
Sign in to join this conversation.
No Label
Interest
Alembic
Interest
Animation & Rigging
Interest
Asset Browser
Interest
Asset Browser Project Overview
Interest
Audio
Interest
Automated Testing
Interest
Blender Asset Bundle
Interest
BlendFile
Interest
Collada
Interest
Compatibility
Interest
Compositing
Interest
Core
Interest
Cycles
Interest
Dependency Graph
Interest
Development Management
Interest
EEVEE
Interest
EEVEE & Viewport
Interest
Freestyle
Interest
Geometry Nodes
Interest
Grease Pencil
Interest
ID Management
Interest
Images & Movies
Interest
Import Export
Interest
Line Art
Interest
Masking
Interest
Metal
Interest
Modeling
Interest
Modifiers
Interest
Motion Tracking
Interest
Nodes & Physics
Interest
OpenGL
Interest
Overlay
Interest
Overrides
Interest
Performance
Interest
Physics
Interest
Pipeline, Assets & IO
Interest
Platforms, Builds & Tests
Interest
Python API
Interest
Render & Cycles
Interest
Render Pipeline
Interest
Sculpt, Paint & Texture
Interest
Text Editor
Interest
Translations
Interest
Triaging
Interest
Undo
Interest
USD
Interest
User Interface
Interest
UV Editing
Interest
VFX & Video
Interest
Video Sequencer
Interest
Virtual Reality
Interest
Vulkan
Interest
Wayland
Interest
Workbench
Interest: X11
Legacy
Blender 2.8 Project
Legacy
Milestone 1: Basic, Local Asset Browser
Legacy
OpenGL Error
Meta
Good First Issue
Meta
Papercut
Meta
Retrospective
Meta
Security
Module
Animation & Rigging
Module
Core
Module
Development Management
Module
EEVEE & Viewport
Module
Grease Pencil
Module
Modeling
Module
Nodes & Physics
Module
Pipeline, Assets & IO
Module
Platforms, Builds & Tests
Module
Python API
Module
Render & Cycles
Module
Sculpt, Paint & Texture
Module
Triaging
Module
User Interface
Module
VFX & Video
Platform
FreeBSD
Platform
Linux
Platform
macOS
Platform
Windows
Priority
High
Priority
Low
Priority
Normal
Priority
Unbreak Now!
Status
Archived
Status
Confirmed
Status
Duplicate
Status
Needs Info from Developers
Status
Needs Information from User
Status
Needs Triage
Status
Resolved
Type
Bug
Type
Design
Type
Known Issue
Type
Patch
Type
Report
Type
To Do
No Milestone
No Assignees
4 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: blender/blender#96455
No description provided.