Loading...
Searching...
No Matches
PBRMesh.hpp
1#pragma once
2#include "TransformHelper.hpp"
3
4#include <ossia/dataflow/geometry_port.hpp>
5
6#include <Gfx/Graph/GpuResourceRegistry.hpp>
7
8#include <Threedim/TinyObj.hpp>
9#include <halp/controls.hpp>
10#include <halp/geometry.hpp>
11#include <halp/meta.hpp>
12#include <halp/texture.hpp>
13
14#include <cstdint>
15#include <memory>
16
17class QRhiResourceUpdateBatch;
18
19namespace score::gfx
20{
21class RenderList;
22struct Edge;
23}
24
25namespace Threedim
26{
27
28// Wraps a GPU-resident geometry (the output of a compute-shader framework
29// node — `halp::dynamic_gpu_geometry`) as a one-node scene_spec with a
30// PBR material attached. The bridge between "CSF produces a geometry"
31// and "scene-graph pipeline consumes scene_spec".
32//
33// Typical wiring:
34// CSFNode(mesh_out) → PBRMesh(mesh_in, texture_in) → ScenePreprocessor
35//
36// The node emits a single scene_node at the root holding:
37// - a scene_transform built from the TRS controls
38// - a mesh_component wrapping the GPU geometry into one mesh_primitive
39// - a direct material_component_ptr, also published into the scene's
40// material list: one material_component carrying the factor controls
41// plus any wired-in runtime textures
42//
43// Texture inputs route through the Dynamic Texture pathway in
44// ScenePreprocessor: non-null handles become `*Dyn<slot>` auxiliary-texture
45// bindings that classic_pbr_full samples directly, no CPU upload, no
46// array-layer copy. Unwired inputs fall through to the scalar factors.
48{
49public:
50 halp_meta(name, "PBR Mesh")
51 halp_meta(category, "Visuals/3D/Scene")
52 halp_meta(c_name, "pbr_mesh")
53 halp_meta(authors, "ossia team")
54 halp_meta(
55 manual_url, "https://ossia.io/score-docs/processes/pbr-mesh.html")
56 halp_meta(uuid, "d7a2f5c9-3e8b-4b1d-a6f2-5c8e9d1f3b7a")
57
58 struct ins
59 {
60 struct
61 {
62 halp_meta(name, "Mesh");
63 halp::dynamic_gpu_geometry mesh;
64 float transform[16]{};
65 bool dirty_mesh = false;
66 bool dirty_transform = false;
67 } geometry_in;
68
69 // Texture slots. Non-null handle → emitted as a dynamic texture
70 // on the material; null → shader falls back to the scalar factor.
71 halp::gpu_texture_input<"Base Color Tex"> base_color_tex;
72 halp::gpu_texture_input<"Metal Rough Tex"> metal_rough_tex;
73 halp::gpu_texture_input<"Normal Tex"> normal_tex;
74 halp::gpu_texture_input<"Emissive Tex"> emissive_tex;
75
76 // PBR factors — used as-is by the material (no per-factor toggle:
77 // defaults here match glTF defaults, so "untouched" controls produce
78 // a reasonable neutral material).
79 halp::hslider_f32<"Color R", halp::range{0., 1., 1.}> base_r;
80 halp::hslider_f32<"Color G", halp::range{0., 1., 1.}> base_g;
81 halp::hslider_f32<"Color B", halp::range{0., 1., 1.}> base_b;
82 halp::hslider_f32<"Color A", halp::range{0., 1., 1.}> base_a;
83 halp::hslider_f32<"Metallic", halp::range{0., 1., 0.}> metallic;
84 halp::hslider_f32<"Roughness", halp::range{0., 1., 0.5}> roughness;
85 halp::hslider_f32<"Emissive R", halp::range{0., 10., 0.}> em_r;
86 halp::hslider_f32<"Emissive G", halp::range{0., 10., 0.}> em_g;
87 halp::hslider_f32<"Emissive B", halp::range{0., 10., 0.}> em_b;
88 halp::hslider_f32<"Emissive strength", halp::range{0., 10., 1.}> em_strength;
89
90 // Root-node placement. Same TRS controls as Transform3D / Instancer
91 // so the node stands alone without a separate transform upstream.
92 PositionControl position;
93 RotationControl rotation;
94 ScaleControl scale;
95 } inputs;
96
97 struct outs
98 {
99 struct
100 {
101 halp_meta(name, "Scene Out");
102 ossia::scene_spec scene;
103 uint8_t dirty{0};
104 } scene_out;
105 } outputs;
106
107 void operator()();
108
109 // Render-thread hooks. init allocates a Material arena slot and seeds
110 // it with default bytes; update packs the factor fields from the
111 // control inputs into a MaterialGPU and uploads to the slot; release
112 // returns the slot. Texture references (textureRefs[]) are left at
113 // tex_ref_none() here — the preprocessor resolves those during its
114 // material-channel upload pass because only it knows the per-channel
115 // dynamic-slot / static-layer assignments for the upstream handles.
116 void init(score::gfx::RenderList& r, QRhiResourceUpdateBatch& res);
117 void update(
118 score::gfx::RenderList& r, QRhiResourceUpdateBatch& res,
120 void release(score::gfx::RenderList& r);
121
122 // Republished stable shared_ptr when nothing changed, so ScenePreprocessor's
123 // identity/fingerprint caches stay warm.
124 std::shared_ptr<const ossia::scene_state> m_wrapped_state;
125 CachedTRS m_cachedTRS{};
126
127 // Identity cache: upstream mesh-buffer handles + vertex/index count +
128 // texture handles + factor values. Dirty if any change.
129 void* m_cached_buf0{};
130 int64_t m_cached_vertices{-1};
131 int64_t m_cached_indices{-1};
132 void* m_cached_tex[4]{};
133 float m_cached_factors[10]{};
134 int64_t m_version_counter{0};
135
136 // Stable ids minted once on first rebuild and reused across every
137 // subsequent rebuild so downstream fingerprint / SER / BVH caches stay
138 // identity-stable.
139 uint64_t m_material_stable_id{};
140 uint64_t m_primitive_stable_id{};
141 uint64_t m_xform_stable_id{};
142
143 // Slots: one in the Material arena, one in RawTransform for the
144 // emitted scene_transform. Allocated in init(), written in update(),
145 // freed in release().
147 score::gfx::GpuResourceRegistry::Slot raw_transform_slot;
148
149 // Ossia-facing snapshots. Written once in init() on the render
150 // thread; copied onto the emitted material_component /
151 // scene_transform raw_slot in operator()().
152 ossia::gpu_slot_ref m_material_ref{};
153 ossia::gpu_slot_ref m_xform_ref{};
154};
155
156}
Definition PBRMesh.hpp:48
List of nodes to be rendered to an output.
Definition RenderList.hpp:30
Graphics rendering pipeline for ossia score.
Definition Filter/PreviewWidget.hpp:11
Definition TransformHelper.hpp:26
Definition PBRMesh.hpp:59
Definition PBRMesh.hpp:98
Definition TinyObj.hpp:98
Definition TinyObj.hpp:103
Definition TinyObj.hpp:107
Definition TinyObj.hpp:27
Connection between two score::gfx::Port.
Definition score-plugin-gfx/Gfx/Graph/Utils.hpp:103
Definition GpuResourceRegistry.hpp:84