64 if (used >=
ubos.size()) {
65 ubos.append(std::make_unique<CurvesInfosBuf>());
89 const float vert[4] = {0.0f, 0.0f, 0.0f, 0.0f};
102 drw_data->
curves_ubos = MEM_new<CurvesUniformBufPool>(
"CurvesUniformBufPool");
128 const int curves_num,
140 int strands_start = 0;
141 while (strands_start < curves_num) {
142 int batch_strands_len = std::min(curves_num - strands_start, max_strands_per_call);
146 strands_start += batch_strands_len;
154 if (final_points_len == 0) {
179 &curves, &cache, gpu_material, subdiv, thickness_res);
211 if (
STREQ(gpu_attr->name, name)) {
229 Curves &curves_id = *
static_cast<Curves *
>(
object->data);
231 const int subdiv = scene->r.hair_subdiv;
235 curves_id, gpu_material, subdiv, thickness_res);
248 float hair_rad_shape = 0.0f;
249 float hair_rad_root = 0.005f;
250 float hair_rad_tip = 0.0f;
251 bool hair_close_tip =
true;
256 if (curves.curves_num() >= 1) {
257 VArray<float> radii = *curves.attributes().lookup_or_default(
259 const IndexRange first_curve_points = curves.points_by_curve()[0];
260 const float first_radius = radii[first_curve_points.
first()];
261 const float last_radius = radii[first_curve_points.
last()];
262 const float middle_radius = radii[first_curve_points.
size() / 2];
263 hair_rad_root = radii[first_curve_points.
first()];
264 hair_rad_tip = radii[first_curve_points.
last()];
265 hair_rad_shape = std::clamp(
266 math::safe_divide(middle_radius - first_radius, last_radius - first_radius) * 2.0f - 1.0f,
276 int curve_data_render_uv = 0;
277 int point_data_render_uv = 0;
290 char sampler_name[32];
381 g_pass = MEM_new<PassSimple>(
"drw_curves g_pass",
"Update Curves Pass");
394 &curves, &cache, gpu_material, subdiv, thickness_res);
415 int strands_start = 0;
416 while (strands_start < curves_num) {
417 int batch_strands_len = std::min(curves_num - strands_start, max_strands_per_call);
421 strands_start += batch_strands_len;
425 if (final_points_len > 0) {
442 const int subdiv = scene->r.hair_subdiv;
463template<
typename PassT>
476 const int subdiv = scene->r.hair_subdiv;
480 curves_id, gpu_material, subdiv, thickness_res);
491 float hair_rad_shape = 0.0f;
492 float hair_rad_root = 0.005f;
493 float hair_rad_tip = 0.0f;
494 bool hair_close_tip =
true;
499 if (curves.curves_num() >= 1) {
500 VArray<float> radii = *curves.attributes().lookup_or_default(
502 const IndexRange first_curve_points = curves.points_by_curve()[0];
503 const float first_radius = radii[first_curve_points.
first()];
504 const float last_radius = radii[first_curve_points.
last()];
505 const float middle_radius = radii[first_curve_points.
size() / 2];
506 hair_rad_root = radii[first_curve_points.
first()];
507 hair_rad_tip = radii[first_curve_points.
last()];
508 hair_rad_shape = std::clamp(
509 math::safe_divide(middle_radius - first_radius, last_radius - first_radius) * 2.0f - 1.0f,
514 sub_ps.bind_texture(
"hairPointBuffer", curves_cache->
final.
proc_buf);
519 int curve_data_render_uv = 0;
520 int point_data_render_uv = 0;
533 char sampler_name[32];
567 sub_ps.bind_ubo(
"drw_curves", curves_infos);
569 sub_ps.push_constant(
"hairStrandsRes", &curves_cache->
final.
resolution, 1);
570 sub_ps.push_constant(
"hairThicknessRes", thickness_res);
571 sub_ps.push_constant(
"hairRadShape", hair_rad_shape);
572 sub_ps.push_constant(
"hairDupliMatrix", ob->object_to_world());
573 sub_ps.push_constant(
"hairRadRoot", hair_rad_root);
574 sub_ps.push_constant(
"hairRadTip", hair_rad_tip);
575 sub_ps.push_constant(
"hairCloseTip", hair_close_tip);
Low-level operations for curves.
CustomData interface, see also DNA_customdata_types.h.
bool CustomData_has_layer(const CustomData *data, eCustomDataType type)
int CustomData_get_render_layer(const CustomData *data, eCustomDataType type)
#define LISTBASE_FOREACH(type, var, list)
#define DRW_shgroup_vertex_buffer(shgroup, name, vert)
#define DRW_shgroup_call_no_cull(shgroup, geom, ob)
#define DRW_shgroup_uniform_block(shgroup, name, ubo)
int GPU_max_work_group_count(int index)
ListBase GPU_material_attributes(const GPUMaterial *material)
void GPU_memory_barrier(eGPUBarrier barrier)
@ GPU_BARRIER_SHADER_STORAGE
void GPU_vertbuf_use(blender::gpu::VertBuf *)
void GPU_vertbuf_attr_fill(blender::gpu::VertBuf *, uint a_idx, const void *data)
blender::gpu::VertBuf * GPU_vertbuf_create_with_format_ex(const GPUVertFormat &format, GPUUsageType usage)
#define GPU_VERTBUF_DISCARD_SAFE(verts)
void GPU_vertbuf_data_alloc(blender::gpu::VertBuf &verts, uint v_len)
@ GPU_USAGE_FLAG_BUFFER_TEXTURE_ONLY
struct GPUShader GPUShader
constexpr int64_t first() const
constexpr int64_t last(const int64_t n=0) const
constexpr int64_t size() const
void submit(PassSimple &pass, View &view)
void bind_texture(const char *name, GPUTexture *texture, GPUSamplerState state=sampler_auto)
PassBase< DrawCommandBufType > & sub(const char *name)
void dispatch(int group_len)
void state_set(DRWState state, int clip_plane_count=0)
void push_constant(const char *name, const float &data)
void bind_ssbo(const char *name, GPUStorageBuf *buffer)
void shader_set(GPUShader *shader)
detail::PassBase< command::DrawCommandBuf > Sub
const DRWContextState * DRW_context_state_get()
const DRWView * DRW_view_default_get()
DRWShadingGroup * DRW_shgroup_create(GPUShader *shader, DRWPass *pass)
void DRW_shgroup_uniform_float_copy(DRWShadingGroup *shgroup, const char *name, const float value)
void DRW_shgroup_buffer_texture(DRWShadingGroup *shgroup, const char *name, blender::gpu::VertBuf *vertex_buffer)
DRWPass * DRW_pass_create(const char *name, DRWState state)
DRWShadingGroup * DRW_shgroup_create_sub(DRWShadingGroup *shgroup)
void DRW_shgroup_call_compute(DRWShadingGroup *shgroup, int groups_x_len, int groups_y_len, int groups_z_len)
void DRW_shgroup_uniform_int_copy(DRWShadingGroup *shgroup, const char *name, const int value)
void DRW_shgroup_uniform_int(DRWShadingGroup *shgroup, const char *name, const int *value, int arraysize)
void DRW_shgroup_add_material_resources(DRWShadingGroup *grp, GPUMaterial *material)
void DRW_shgroup_uniform_bool_copy(DRWShadingGroup *shgroup, const char *name, const bool value)
void DRW_shgroup_uniform_mat4_copy(DRWShadingGroup *shgroup, const char *name, const float(*value)[4])
void DRW_view_default_set(const DRWView *view)
DRWView * DRW_view_create(const float viewmat[4][4], const float winmat[4][4], const float(*culling_viewmat)[4], const float(*culling_winmat)[4], DRWCallVisibilityFn *visibility_fn)
void DRW_draw_pass(DRWPass *pass)
void DRW_view_set_active(const DRWView *view)
const DRWView * DRW_view_get_active()
GPUShader * DRW_shader_curves_refine_get(blender::draw::CurvesEvalShader type)
static PassSimple * g_pass
void DRW_curves_init(DRWData *drw_data)
void DRW_curves_ubos_pool_free(CurvesUniformBufPool *pool)
static CurvesEvalCache * drw_curves_cache_get(Curves &curves, GPUMaterial *gpu_material, int subdiv, int thickness_res)
gpu::VertBuf * curves_pos_buffer_get(Scene *scene, Object *object)
static int attribute_index_in_material(GPUMaterial *gpu_material, const char *name)
static CurvesEvalCache * curves_cache_get(Curves &curves, GPUMaterial *gpu_material, int subdiv, int thickness_res)
void drw_curves_get_attribute_sampler_name(const char *layer_name, char r_sampler_name[32])
gpu::Batch * curves_sub_pass_setup(PassMain::Sub &ps, const Scene *scene, Object *ob, GPUMaterial *gpu_material=nullptr)
static DRWPass * g_tf_pass
static void drw_curves_cache_update_compute(CurvesEvalCache *cache, const int curves_num, gpu::VertBuf *output_buf, gpu::VertBuf *input_buf)
gpu::Batch * curves_sub_pass_setup_implementation(PassT &sub_ps, const Scene *scene, Object *ob, GPUMaterial *gpu_material)
void curves_update(Manager &manager)
static gpu::VertBuf * g_dummy_vbo
@ CURVES_EVAL_CATMULL_ROM
DRWShadingGroup * DRW_shgroup_curves_create_sub(Object *object, DRWShadingGroup *shgrp, GPUMaterial *gpu_material)
bool curves_ensure_procedural_data(Curves *curves_id, CurvesEvalCache **r_cache, const GPUMaterial *gpu_material, const int subdiv, const int thickness_res)
static void drw_curves_ensure_dummy_vbo()
static void drw_curves_cache_shgrp_attach_resources(DRWShadingGroup *shgrp, CurvesEvalCache *cache, gpu::VertBuf *point_buf)
gpu::VertBuf * DRW_curves_pos_buffer_get(Object *object)
T safe_divide(const T &a, const T &b)
VecBase< int32_t, 3 > int3
static void update(bNodeTree *ntree)
blender::draw::CurvesUniformBufPool * curves_ubos
static MatBase identity()
gpu::VertBuf * proc_strand_seg_buf
CurvesEvalFinalCache final
gpu::VertBuf * proc_length_buf
gpu::VertBuf * proc_attributes_buf[GPU_MAX_ATTR]
gpu::VertBuf * proc_point_buf
gpu::VertBuf * proc_strand_buf
gpu::VertBuf * attributes_buf[GPU_MAX_ATTR]
blender::bke::AttrDomain domain
DRW_AttributeRequest requests[GPU_MAX_ATTR]