Implementation of the design task #142969. This adds the following: - Exact GPU interpolation of curves of all types. - Radius attribute support. - Cyclic curve support. - Resolution attribute support. - New Cylinder hair shape type.  What changed: - EEVEE doesn't compute random normals for strand hairs anymore. These are considered legacy now. - EEVEE now have an internal shadow bias to avoid self shadowing on hair. - Workbench Curves Strip display option is no longer flat and has better shading. - Legacy Hair particle system evaluates radius at control points before applying additional subdivision. This now matches Cycles. - Color Attribute Node without a name do not fetch the active color attribute anymore. This now matches Cycles. Notes: - This is not 100% matching the CPU implementation for interpolation (see the epsilons in the tests). - Legacy Hair Particle points is now stored in local space after interpolation. The new cylinder shape allows for more correct hair shading in workbench and better intersection in EEVEE. | | Strand | Strip | Cylinder | | ---- | --- | --- | --- | | Main |  |  | N/A | | PR |  |  |  | | | Strand | Strip | Cylinder | | ---- | --- | --- | --- | | Main |  | | N/A | | PR | ||  | Cyclic Curve, Mixed curve type, and proper radius support:  Test file for attribute lookup: [test_attribute_lookup.blend](/attachments/1d54dd06-379b-4480-a1c5-96adc1953f77) Follow Up Tasks: - Correct full tube segments orientation based on tangent and normal attributes - Correct V resolution property per object - More attribute type support (currently only color) TODO: - [x] Attribute Loading Changes - [x] Generic Attributes - [x] Length Attribute - [x] Intercept Attribute - [x] Original Coordinate Attribute - [x] Cyclic Curves - [x] Legacy Hair Particle conversion - [x] Attribute Loading - [x] Additional Subdivision - [x] Move some function to generic headers (VertBuf, OffsetIndices) - [x] Fix default UV/Color attribute assignment Pull Request: https://projects.blender.org/blender/blender/pulls/143180
101 lines
2.6 KiB
C++
101 lines
2.6 KiB
C++
/* SPDX-FileCopyrightText: 2025 Blender Foundation
|
|
*
|
|
* SPDX-License-Identifier: GPL-2.0-or-later */
|
|
|
|
#pragma once
|
|
|
|
#include "GPU_storage_buffer.hh"
|
|
|
|
#include <opensubdiv/version.h>
|
|
|
|
#include <opensubdiv/osd/nonCopyable.h>
|
|
#include <opensubdiv/osd/types.h>
|
|
|
|
using OpenSubdiv::Far::PatchTable;
|
|
using OpenSubdiv::Osd::NonCopyable;
|
|
using OpenSubdiv::Osd::PatchArrayVector;
|
|
|
|
namespace blender::opensubdiv {
|
|
|
|
// TODO: use Blenlib NonCopyable.
|
|
class GPUPatchTable : private OpenSubdiv::Osd::NonCopyable<GPUPatchTable> {
|
|
public:
|
|
~GPUPatchTable();
|
|
|
|
static GPUPatchTable *Create(PatchTable const *farPatchTable, void *deviceContext = NULL);
|
|
|
|
/// Returns the patch arrays for vertex index buffer data
|
|
PatchArrayVector const &GetPatchArrays() const
|
|
{
|
|
return _patchArrays;
|
|
}
|
|
|
|
/// Returns the GL index buffer containing the patch control vertices
|
|
gpu::StorageBuf *GetPatchIndexBuffer() const
|
|
{
|
|
return _patchIndexBuffer;
|
|
}
|
|
|
|
/// Returns the GL index buffer containing the patch parameter
|
|
gpu::StorageBuf *GetPatchParamBuffer() const
|
|
{
|
|
return _patchParamBuffer;
|
|
}
|
|
|
|
/// Returns the patch arrays for varying index buffer data
|
|
PatchArrayVector const &GetVaryingPatchArrays() const
|
|
{
|
|
return _varyingPatchArrays;
|
|
}
|
|
|
|
/// Returns the GL index buffer containing the varying control vertices
|
|
gpu::StorageBuf *GetVaryingPatchIndexBuffer() const
|
|
{
|
|
return _varyingIndexBuffer;
|
|
}
|
|
|
|
/// Returns the number of face-varying channel buffers
|
|
int GetNumFVarChannels() const
|
|
{
|
|
return (int)_fvarPatchArrays.size();
|
|
}
|
|
|
|
/// Returns the patch arrays for face-varying index buffer data
|
|
PatchArrayVector const &GetFVarPatchArrays(int fvarChannel = 0) const
|
|
{
|
|
return _fvarPatchArrays[fvarChannel];
|
|
}
|
|
|
|
/// Returns the GL index buffer containing face-varying control vertices
|
|
gpu::StorageBuf *GetFVarPatchIndexBuffer(int fvarChannel = 0) const
|
|
{
|
|
return _fvarIndexBuffers[fvarChannel];
|
|
}
|
|
|
|
/// Returns the GL index buffer containing face-varying patch params
|
|
gpu::StorageBuf *GetFVarPatchParamBuffer(int fvarChannel = 0) const
|
|
{
|
|
return _fvarParamBuffers[fvarChannel];
|
|
}
|
|
|
|
protected:
|
|
GPUPatchTable() {}
|
|
|
|
// allocate buffers from patchTable
|
|
bool allocate(PatchTable const *farPatchTable);
|
|
|
|
PatchArrayVector _patchArrays;
|
|
|
|
gpu::StorageBuf *_patchIndexBuffer = nullptr;
|
|
gpu::StorageBuf *_patchParamBuffer = nullptr;
|
|
|
|
PatchArrayVector _varyingPatchArrays;
|
|
gpu::StorageBuf *_varyingIndexBuffer = nullptr;
|
|
|
|
std::vector<PatchArrayVector> _fvarPatchArrays;
|
|
std::vector<gpu::StorageBuf *> _fvarIndexBuffers;
|
|
std::vector<gpu::StorageBuf *> _fvarParamBuffers;
|
|
};
|
|
|
|
} // namespace blender::opensubdiv
|