update TextureProjection to accept material instances and render multiple target entities
This commit is contained in:
@@ -31,13 +31,13 @@ class TextureProjection {
|
|||||||
required this.depthWriteColorTexture,
|
required this.depthWriteColorTexture,
|
||||||
required this.sampler}) {}
|
required this.sampler}) {}
|
||||||
|
|
||||||
static Future<TextureProjection> create(View sourceView) async {
|
static Future<TextureProjection> create(View sourceView, Uint8List depthWriteMaterial, Uint8List captureUvMaterial) async {
|
||||||
final viewport = await sourceView.getViewport();
|
final viewport = await sourceView.getViewport();
|
||||||
var depthWriteMat = await FilamentApp.instance!.createMaterial(
|
var depthWriteMat = await FilamentApp.instance!.createMaterial(depthWriteMaterial);
|
||||||
File(
|
// File(
|
||||||
"/Users/nickfisher/Documents/thermion/materials/linear_depth.filamat",
|
// "/Users/nickfisher/Documents/thermion/materials/linear_depth.filamat",
|
||||||
).readAsBytesSync(),
|
// ).readAsBytesSync(),
|
||||||
);
|
// );
|
||||||
var depthWriteMi = await depthWriteMat.createInstance();
|
var depthWriteMi = await depthWriteMat.createInstance();
|
||||||
|
|
||||||
final depthView = await FilamentApp.instance!.createView() as FFIView;
|
final depthView = await FilamentApp.instance!.createView() as FFIView;
|
||||||
@@ -62,11 +62,11 @@ class TextureProjection {
|
|||||||
) as FFIRenderTarget;
|
) as FFIRenderTarget;
|
||||||
await depthView.setRenderTarget(depthWriteRenderTarget);
|
await depthView.setRenderTarget(depthWriteRenderTarget);
|
||||||
|
|
||||||
final captureMat = await FilamentApp.instance!.createMaterial(
|
final captureMat = await FilamentApp.instance!.createMaterial(captureUvMaterial)
|
||||||
File(
|
// File(
|
||||||
"/Users/nickfisher/Documents/thermion/materials/capture_uv.filamat",
|
// "/Users/nickfisher/Documents/thermion/materials/capture_uv.filamat",
|
||||||
).readAsBytesSync(),
|
// ).readAsBytesSync(),
|
||||||
) as FFIMaterial;
|
as FFIMaterial;
|
||||||
var captureMi = await captureMat.createInstance() as FFIMaterialInstance;
|
var captureMi = await captureMat.createInstance() as FFIMaterialInstance;
|
||||||
await captureMi.setParameterBool("flipUVs", true);
|
await captureMi.setParameterBool("flipUVs", true);
|
||||||
|
|
||||||
@@ -117,23 +117,35 @@ class TextureProjection {
|
|||||||
/// b) colors each fragment blue
|
/// b) colors each fragment blue
|
||||||
/// 5) Use the render target color buffer as the input to a
|
/// 5) Use the render target color buffer as the input to a
|
||||||
/// 6) Render this "projection view" and capture the output
|
/// 6) Render this "projection view" and capture the output
|
||||||
Future<TextureProjectionResult> project(Texture texture, ThermionAsset target,
|
Future<TextureProjectionResult> project(
|
||||||
{bool renderSourceView = true}) async {
|
Texture texture, List<ThermionEntity> targets) async {
|
||||||
await FilamentApp.instance!.setClearOptions(0, 0, 0, 1,
|
|
||||||
clearStencil: 0, discard: false, clear: true);
|
|
||||||
|
|
||||||
final viewport = await sourceView.getViewport();
|
final viewport = await sourceView.getViewport();
|
||||||
|
|
||||||
final originalMi = await target.getMaterialInstanceAt();
|
|
||||||
|
|
||||||
final camera = (await sourceView.getCamera()) as FFICamera;
|
final camera = (await sourceView.getCamera()) as FFICamera;
|
||||||
final originalScene = await sourceView.getScene() as FFIScene;
|
final originalScene = await sourceView.getScene() as FFIScene;
|
||||||
|
|
||||||
|
// since we will be creating a single (unlit) scene, we need
|
||||||
|
// to replace the target asset's material with an unlit material
|
||||||
|
// (otherwise nothing will be visible in the initial output colour buffer).
|
||||||
|
final unlit = await FilamentApp.instance!.createUnlitMaterialInstance()
|
||||||
|
as FFIMaterialInstance;
|
||||||
|
await unlit.setParameterFloat4("baseColorFactor", 1.0, 1.0, 1.0, 1.0);
|
||||||
|
|
||||||
final projectionScene =
|
final projectionScene =
|
||||||
(await FilamentApp.instance!.createScene()) as FFIScene;
|
(await FilamentApp.instance!.createScene()) as FFIScene;
|
||||||
await projectionScene.add(target as FFIAsset);
|
|
||||||
|
|
||||||
await sourceView.setScene(projectionScene);
|
final restoreMaterials = <ThermionEntity, List<MaterialInstance>>{};
|
||||||
|
for (final target in targets) {
|
||||||
|
await projectionScene.addEntity(target);
|
||||||
|
restoreMaterials[target] = [];
|
||||||
|
for (int i = 0;
|
||||||
|
i < await FilamentApp.instance!.getPrimitiveCount(target);
|
||||||
|
i++) {
|
||||||
|
final mi = await FilamentApp.instance!.getMaterialInstanceAt(target, i);
|
||||||
|
restoreMaterials[target]!.add(mi);
|
||||||
|
await FilamentApp.instance!.setMaterialInstanceAt(target, i, unlit);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
await depthView.setCamera(camera);
|
await depthView.setCamera(camera);
|
||||||
await depthView.setScene(projectionScene);
|
await depthView.setScene(projectionScene);
|
||||||
@@ -141,40 +153,68 @@ class TextureProjection {
|
|||||||
|
|
||||||
await projectionView.setCamera(camera);
|
await projectionView.setCamera(camera);
|
||||||
await projectionView.setScene(projectionScene);
|
await projectionView.setScene(projectionScene);
|
||||||
|
await projectionView.setViewport(viewport.width, viewport.height);
|
||||||
|
|
||||||
var _pixelBuffers = <View, Uint8List>{};
|
var sourceViewCapture = (await FilamentApp.instance!
|
||||||
|
.capture(null, view: sourceView, captureRenderTarget: true))
|
||||||
|
.first
|
||||||
|
.$2;
|
||||||
|
|
||||||
if (renderSourceView) {
|
for (final target in targets) {
|
||||||
_pixelBuffers[sourceView] =
|
for (int i = 0;
|
||||||
(await FilamentApp.instance!.capture(null, view: sourceView))
|
i < await FilamentApp.instance!.getPrimitiveCount(target);
|
||||||
.first
|
i++) {
|
||||||
.$2;
|
await FilamentApp.instance!
|
||||||
|
.setMaterialInstanceAt(target, i, depthWriteMaterialInstance);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
await target.setMaterialInstanceAt(depthWriteMaterialInstance);
|
var depthViewCapture =
|
||||||
_pixelBuffers[depthView] =
|
|
||||||
(await FilamentApp.instance!.capture(null, view: depthView)).first.$2;
|
(await FilamentApp.instance!.capture(null, view: depthView)).first.$2;
|
||||||
|
|
||||||
await projectionMaterialInstance.setParameterTexture(
|
await projectionMaterialInstance.setParameterTexture(
|
||||||
"color", texture as FFITexture, sampler);
|
"color", texture as FFITexture, sampler);
|
||||||
await target.setMaterialInstanceAt(projectionMaterialInstance);
|
|
||||||
|
|
||||||
_pixelBuffers[projectionView] =
|
for (final target in targets) {
|
||||||
(await FilamentApp.instance!.capture(null, view: projectionView)).first.$2;
|
for (int i = 0;
|
||||||
|
i < await FilamentApp.instance!.getPrimitiveCount(target);
|
||||||
|
i++) {
|
||||||
|
await FilamentApp.instance!
|
||||||
|
.setMaterialInstanceAt(target, i, projectionMaterialInstance);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final projectionViewCaptures = <Uint8List>[];
|
||||||
|
|
||||||
await target.setMaterialInstanceAt(originalMi as FFIMaterialInstance);
|
var projectionViewCapture =
|
||||||
|
(await FilamentApp.instance!.capture(null, view: projectionView))
|
||||||
|
.first
|
||||||
|
.$2;
|
||||||
|
projectionViewCaptures.add(projectionViewCapture);
|
||||||
|
|
||||||
|
for (final target in targets) {
|
||||||
|
await projectionScene.removeEntity(target);
|
||||||
|
for (int i = 0;
|
||||||
|
i < await FilamentApp.instance!.getPrimitiveCount(target);
|
||||||
|
i++) {
|
||||||
|
await FilamentApp.instance!
|
||||||
|
.setMaterialInstanceAt(target, i, restoreMaterials[target]![i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
await sourceView.setScene(originalScene);
|
await sourceView.setScene(originalScene);
|
||||||
return TextureProjectionResult(_pixelBuffers[sourceView],
|
|
||||||
_pixelBuffers[depthView]!, _pixelBuffers[projectionView]!);
|
await FilamentApp.instance!.destroyScene(projectionScene);
|
||||||
|
|
||||||
|
return TextureProjectionResult(
|
||||||
|
sourceViewCapture, depthViewCapture, projectionViewCaptures);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class TextureProjectionResult {
|
class TextureProjectionResult {
|
||||||
final Uint8List? sourceView;
|
final Uint8List? sourceView;
|
||||||
final Uint8List depth;
|
final Uint8List depth;
|
||||||
final Uint8List projected;
|
final List<Uint8List> projected;
|
||||||
|
|
||||||
TextureProjectionResult(this.sourceView, this.depth, this.projected);
|
TextureProjectionResult(this.sourceView, this.depth, this.projected);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user