Skip to content

Commit 5dcd199

Browse files
committed
material preview
1 parent 8b9a253 commit 5dcd199

9 files changed

Lines changed: 330 additions & 59 deletions

File tree

sources/RenderSystem/Assets/AssetExplorer.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -133,8 +133,10 @@ namespace GUI
133133

134134

135135
};
136-
auto texture = loaded_asset->get_ptr<TextureAsset>();
137-
auto binary = loaded_asset->get_ptr<BinaryAsset>();
136+
auto texture = loaded_asset->get_ptr<TextureAsset>();
137+
auto binary = loaded_asset->get_ptr<BinaryAsset>();
138+
auto mesh = loaded_asset->get_ptr<MeshAsset>();
139+
auto material = loaded_asset->get_ptr<MaterialAsset>();
138140

139141
if (texture)
140142
menu->add_item("Compress")->on_click = [this](menu_list_element::ptr e)
@@ -143,7 +145,7 @@ namespace GUI
143145
texture->compress();
144146
};
145147

146-
if ((texture || binary) && on_open_preview)
148+
if ((texture || binary || mesh || material) && on_open_preview)
147149
menu->add_item("Preview")->on_click = [this](menu_list_element::ptr e)
148150
{
149151
if (on_open_preview) on_open_preview(asset->get_asset());

sources/RenderSystem/Assets/AssetRenderer.cpp

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,3 +248,120 @@ AssetRenderer::AssetRenderer()
248248
// ssgi = std::make_shared<SSGI>(*gbuffer);
249249

250250
}
251+
252+
253+
// ===========================================================================
254+
// SceneTextureRenderer — copy of AssetRenderer's scene-to-texture core.
255+
// (AssetRenderer left intact; it will later be rewritten to use this.)
256+
// ===========================================================================
257+
258+
SceneTextureRenderer::SceneTextureRenderer()
259+
{
260+
std::lock_guard<std::mutex> g(lock);
261+
262+
scene_renderer = std::make_shared<main_renderer>();
263+
scene_renderer->register_renderer(meshes_renderer = std::make_shared<mesh_renderer>());
264+
cam.position = vec3(0, 5, -30);
265+
266+
mesh_plane.reset(new MeshAssetInstance(EngineAssets::plane.get_asset()));
267+
material_tester.reset(new MeshAssetInstance(EngineAssets::material_tester.get_asset()));
268+
269+
scene = std::make_shared<Scene>();
270+
271+
rendering = std::make_shared<SceneRenderWorkflow>();
272+
rendering->scene_renderer = scene_renderer;
273+
}
274+
275+
void SceneTextureRenderer::draw(Scene::ptr scene, HAL::Texture::ptr result)
276+
{
277+
graph.start_new_frame();
278+
279+
scene->update_transforms();
280+
281+
auto mn = scene->get_min();
282+
auto mx = scene->get_max();
283+
scene->add_child(mesh_plane);
284+
scene->update(*graph.builder.current_frame);
285+
286+
float x = mx.x - mn.x;
287+
float y = mx.y - mn.y;
288+
289+
mesh_plane->local_transform.scaling(std::max(x, y));
290+
291+
mesh_plane->local_transform.a42 = mn.y;
292+
scene->update_transforms();
293+
294+
auto& time = graph.get_context<TimeInfo>();
295+
auto& skyinfo = graph.get_context<SkyInfo>();
296+
auto& caminfo = graph.get_context<CameraInfo>();
297+
auto& sceneinfo = graph.get_context<SceneInfo>();
298+
auto& vp = graph.get_context<ViewportInfo>();
299+
300+
auto rsize = result->get_size().xy;
301+
float aspect = float(rsize.x) / float(rsize.y);
302+
303+
float base_dist = (mx - mn).length();
304+
if (base_dist < 0.001f) base_dist = 1.0f;
305+
306+
// Orbit direction from yaw/pitch; distance scaled by zoom.
307+
vec3 dir;
308+
dir.x = Math::cos(m_orbit.y) * Math::sin(m_orbit.x);
309+
dir.y = Math::sin(m_orbit.y);
310+
dir.z = Math::cos(m_orbit.y) * Math::cos(m_orbit.x);
311+
312+
cam.target = (mn + mx) / 2;
313+
cam.position = cam.target + dir * (base_dist * m_zoom);
314+
cam.set_projection_params(Math::pi / 4, aspect, 1, 100 + (mn - mx).length());
315+
cam.update();
316+
317+
skyinfo.sunDir = float3(1, 1, 1).normalize();
318+
319+
graph.builder.debug = true;
320+
vp.frame_size = rsize / 2;
321+
vp.upscale_size = rsize;
322+
323+
sceneinfo.scene = scene;
324+
sceneinfo.renderer = scene_renderer;
325+
caminfo.cam = &cam;
326+
327+
rendering->render(graph);
328+
graph.builder.pass_texture(FrameGraph::ResourceID::swapchain, result->resource, {}, ResourceFlags::Required);
329+
330+
graph.setup();
331+
graph.compile(frame++);
332+
graph.render();
333+
graph.commit_command_lists();
334+
graph.reset();
335+
mesh_plane->remove_from_parent();
336+
}
337+
338+
void SceneTextureRenderer::draw(scene_object::ptr obj, HAL::Texture::ptr result)
339+
{
340+
std::lock_guard<std::mutex> g(lock);
341+
342+
scene->add_child(obj);
343+
draw(scene, result);
344+
obj->remove_from_parent();
345+
}
346+
347+
void SceneTextureRenderer::draw(MaterialAsset::ptr mat, HAL::Texture::ptr result)
348+
{
349+
std::lock_guard<std::mutex> g(lock);
350+
351+
scene->add_child(material_tester);
352+
material_tester->override_material(1, mat);
353+
354+
draw(scene, result);
355+
material_tester->remove_from_parent();
356+
}
357+
358+
void SceneTextureRenderer::orbit(vec2 delta)
359+
{
360+
m_orbit += delta;
361+
m_orbit.y = Math::clamp(m_orbit.y, -Math::m_pi_2 + Math::eps2, Math::m_pi_2 - Math::eps2);
362+
}
363+
364+
void SceneTextureRenderer::zoom(float amount)
365+
{
366+
m_zoom = Math::clamp(m_zoom * (1.0f - amount * 0.1f), 0.05f, 10.0f);
367+
}

sources/RenderSystem/Assets/AssetRenderer.ixx

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,4 +39,44 @@ export class AssetRenderer : public Singleton<AssetRenderer>
3939
virtual void draw(MaterialAsset::ptr m, HAL::Texture::ptr result);
4040
virtual void draw(scene_object::ptr scene, HAL::Texture::ptr result);
4141

42+
};
43+
44+
45+
// Generic offscreen "render a scene into a target texture" engine. Owns its own
46+
// FrameGraph so it can run alongside the main UI graph (which only fits one main
47+
// pipeline). Copied from AssetRenderer's implementation; AssetRenderer will later
48+
// be rewritten to build on this. Not a Singleton — each user owns an instance
49+
// (own graph / scene / camera).
50+
export class SceneTextureRenderer
51+
{
52+
FrameGraph::Graph graph;
53+
UINT frame = 0;
54+
55+
main_renderer::ptr scene_renderer;
56+
camera cam;
57+
mesh_renderer::ptr meshes_renderer;
58+
std::shared_ptr<SceneRenderWorkflow> rendering;
59+
60+
MeshAssetInstance::ptr mesh_plane;
61+
MeshAssetInstance::ptr material_tester; // test mesh for material previews
62+
63+
Scene::ptr scene;
64+
std::mutex lock;
65+
66+
// Orbit camera around the auto-fit center: yaw/pitch + zoom distance.
67+
vec2 m_orbit = { 0.785398f, 0.35f }; // ~pi/4 yaw, slight pitch
68+
float m_zoom = 1.0f;
69+
70+
public:
71+
SceneTextureRenderer();
72+
73+
camera& get_camera() { return cam; }
74+
75+
// Drag to orbit, wheel to zoom (forwarded from the preview widget).
76+
void orbit(vec2 delta);
77+
void zoom(float amount);
78+
79+
void draw(Scene::ptr scene, HAL::Texture::ptr result);
80+
void draw(scene_object::ptr obj, HAL::Texture::ptr result);
81+
void draw(MaterialAsset::ptr m, HAL::Texture::ptr result);
4282
};

sources/RenderSystem/GUI/Elements/FlowGraph/ComponentWindow.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ GUI::Elements::FlowGraph::component_window::component_window(canvas* canva, ::Fl
132132
contents_preview->width_size = size_type::MATCH_CHILDREN;
133133
contents_preview->height_size = size_type::MATCH_CHILDREN;
134134
visual_graph = dynamic_cast<VisualGraph*>(node);
135-
if (visual_graph)
135+
if (visual_graph && type != window_type::GRAPH_IN) // input side never shows the editor/preview
136136
{
137137
auto p = visual_graph->create_editor_window();
138138

sources/RenderSystem/Materials/Values.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -741,6 +741,14 @@ void VectorNode::operator()(MaterialContext* c)
741741
o_value->put(res);
742742
}
743743

744+
GUI::base::ptr MaterialGraph::create_editor_window()
745+
{
746+
// Live material preview on the graph-output node (widget built by the app).
747+
if (create_preview_hook && preview_material)
748+
return create_preview_hook(preview_material->get_ptr<Asset>());
749+
return nullptr;
750+
}
751+
744752
GUI::base::ptr VectorNode::create_editor_window()
745753
{
746754
auto picker = std::make_shared<GUI::Elements::color_picker>();

sources/RenderSystem/Materials/Values.ixx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -402,8 +402,16 @@ class MaterialGraph : public MaterialFunction
402402
public:
403403
using ptr = s_ptr<MaterialGraph>;
404404

405+
// The owning material (set by universal_material); used to build a live
406+
// preview on the graph-output node.
407+
Asset* preview_material = nullptr;
408+
// Filled by the app layer (which can build a preview widget above the
409+
// Materials module — Materials can't import the renderer without a cycle).
410+
static inline std::function<GUI::base::ptr(std::shared_ptr<Asset>)> create_preview_hook;
411+
405412
MaterialGraph();
406413
virtual ~MaterialGraph();
414+
virtual GUI::base::ptr create_editor_window() override;
407415
FlowGraph::input::ptr get_texcoord();
408416

409417
FlowGraph::output::ptr get_base_color();

sources/RenderSystem/Materials/universal_material.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -413,6 +413,7 @@ materials::universal_material::universal_material(MaterialGraph::ptr graph) : in
413413
include_file_raytacing = EngineAssets::material_raytracing_header.get_asset();
414414
this->graph = BinaryData<MaterialGraph>(graph);
415415
graph->add_listener(this, false);
416+
graph->preview_material = this; // let the graph-output node build a live preview
416417
need_regenerate_material = true;
417418
need_update_uniforms = true;
418419
generate_material();

sources/RenderSystem/Materials/universal_material.events.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@ size_t materials::universal_material::get_id()
1616

1717
MaterialGraph::ptr materials::universal_material::get_graph()
1818
{
19-
return graph.get();
19+
auto g = graph.get();
20+
if (g) g->preview_material = this; // ensure the editor's graph can build a live preview
21+
return g;
2022
}
2123

2224
void materials::universal_material::test()

0 commit comments

Comments
 (0)