texture projection work

This commit is contained in:
Nick Fisher
2025-03-25 12:16:38 +08:00
parent aebaa8425c
commit cac063324d
2 changed files with 66 additions and 80 deletions

View File

@@ -2,6 +2,7 @@ import 'dart:io';
import 'dart:typed_data'; import 'dart:typed_data';
import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_render_target.dart'; import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_render_target.dart';
import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_scene.dart';
import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_view.dart'; import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_view.dart';
import 'package:thermion_dart/thermion_dart.dart'; import 'package:thermion_dart/thermion_dart.dart';
@@ -12,6 +13,7 @@ class TextureProjection {
final Material depthWriteMaterial; final Material depthWriteMaterial;
final MaterialInstance depthWriteMaterialInstance; final MaterialInstance depthWriteMaterialInstance;
final Texture texture; final Texture texture;
final View sourceView;
final View depthView; final View depthView;
final View projectionView; final View projectionView;
@@ -22,6 +24,7 @@ class TextureProjection {
required this.depthWriteMaterial, required this.depthWriteMaterial,
required this.depthWriteMaterialInstance, required this.depthWriteMaterialInstance,
required this.texture, required this.texture,
required this.sourceView,
required this.depthView, required this.depthView,
required this.projectionView}) {} required this.projectionView}) {}
@@ -39,9 +42,23 @@ class TextureProjection {
await depthWriteView.setFrustumCullingEnabled(false); await depthWriteView.setFrustumCullingEnabled(false);
await depthWriteView.setPostProcessing(false); await depthWriteView.setPostProcessing(false);
await depthWriteView.setViewport(viewport.width, viewport.height); await depthWriteView.setViewport(viewport.width, viewport.height);
await depthWriteView.setBlendMode(BlendMode.opaque); await depthWriteView.setBlendMode(BlendMode.opaque);
final depthWriteColorTexture = await FilamentApp.instance!
.createTexture(viewport.width, viewport.height,
flags: {
TextureUsage.TEXTURE_USAGE_COLOR_ATTACHMENT,
TextureUsage.TEXTURE_USAGE_SAMPLEABLE,
TextureUsage.TEXTURE_USAGE_BLIT_SRC
},
textureFormat: TextureFormat.R32F);
await depthWriteView
.setRenderTarget(await FilamentApp.instance!.createRenderTarget(
viewport.width,
viewport.height,
color: depthWriteColorTexture,
) as FFIRenderTarget);
final color = await (await sourceView.getRenderTarget())!.getColorTexture(); final color = await (await sourceView.getRenderTarget())!.getColorTexture();
final depth = final depth =
await (await depthWriteView.getRenderTarget())!.getColorTexture(); await (await depthWriteView.getRenderTarget())!.getColorTexture();
@@ -64,25 +81,11 @@ class TextureProjection {
await projectionView.setPostProcessing(false); await projectionView.setPostProcessing(false);
await projectionView.setViewport(viewport.width, viewport.height); await projectionView.setViewport(viewport.width, viewport.height);
final depthWriteColorTexture = await FilamentApp.instance!
.createTexture(viewport.width, viewport.height,
flags: {
TextureUsage.TEXTURE_USAGE_COLOR_ATTACHMENT,
TextureUsage.TEXTURE_USAGE_SAMPLEABLE,
TextureUsage.TEXTURE_USAGE_BLIT_SRC
},
textureFormat: TextureFormat.R32F);
await depthWriteView
.setRenderTarget(await FilamentApp.instance!.createRenderTarget(
viewport.width,
viewport.height,
color: depthWriteColorTexture,
) as FFIRenderTarget);
await FilamentApp.instance!.register(swapChain, depthWriteView); await FilamentApp.instance!.register(swapChain, depthWriteView);
await FilamentApp.instance!.register(swapChain, projectionView); await FilamentApp.instance!.register(swapChain, projectionView);
return TextureProjection._( return TextureProjection._(
sourceView: sourceView,
swapChain: swapChain, swapChain: swapChain,
depthView: depthWriteView, depthView: depthWriteView,
projectionView: projectionView, projectionView: projectionView,
@@ -100,10 +103,28 @@ class TextureProjection {
await FilamentApp.instance!.destroyView(projectionView); await FilamentApp.instance!.destroyView(projectionView);
} }
Future<Uint8List> execute(ThermionAsset target, View view) async { var _pixelBuffers = <View, Uint8List>{};
Uint8List getDepthWritePixelBuffer() => _pixelBuffers[depthView]!;
Uint8List getProjectedPixelBuffer() => _pixelBuffers[projectionView]!;
Future project(ThermionAsset target) async {
final camera = await sourceView.getCamera();
await depthView.setCamera(camera);
await projectionView.setCamera(camera);
await (depthView as FFIView)
.setScene(await sourceView.getScene() as FFIScene);
await (projectionView as FFIView)
.setScene(await sourceView.getScene() as FFIScene);
await sourceView.setRenderOrder(0);
await depthView.setRenderOrder(1);
await projectionView.setRenderOrder(2);
var originalMi = await target.getMaterialInstanceAt(); var originalMi = await target.getMaterialInstanceAt();
var pixelBuffers = await FilamentApp.instance!
.capture(swapChain, view: view, beforeRender: (view) async { var pixelBuffers = await FilamentApp.instance!.capture(swapChain,
beforeRender: (view) async {
if (view == depthView) { if (view == depthView) {
await target.setMaterialInstanceAt(depthWriteMaterialInstance); await target.setMaterialInstanceAt(depthWriteMaterialInstance);
} else if (view == projectionView) { } else if (view == projectionView) {
@@ -112,7 +133,13 @@ class TextureProjection {
}, },
pixelDataFormat: PixelDataFormat.RGBA, pixelDataFormat: PixelDataFormat.RGBA,
pixelDataType: PixelDataType.FLOAT); pixelDataType: PixelDataType.FLOAT);
await target.setMaterialInstanceAt(originalMi); await target.setMaterialInstanceAt(originalMi);
return pixelBuffers.firstWhere((pb) => pb.$1 == projectionView).$2;
_pixelBuffers.clear();
for (final (view, pixelBuffer) in pixelBuffers) {
_pixelBuffers[view] = pixelBuffer;
}
} }
} }

View File

@@ -3,6 +3,7 @@ import 'dart:async';
import 'dart:io'; import 'dart:io';
import 'dart:math'; import 'dart:math';
import 'package:test/test.dart'; import 'package:test/test.dart';
import 'package:thermion_dart/src/utils/src/texture_projection.dart';
import 'package:thermion_dart/src/viewer/src/ffi/src/callbacks.dart'; import 'package:thermion_dart/src/viewer/src/ffi/src/callbacks.dart';
import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_asset.dart'; import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_asset.dart';
import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_camera.dart'; import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_camera.dart';
@@ -60,49 +61,13 @@ void main() async {
final cube = await _makeCube(testHelper, viewer); final cube = await _makeCube(testHelper, viewer);
final ubershader = await cube.getMaterialInstanceAt(); final ubershader = await cube.getMaterialInstanceAt();
final originalTexture = await createTextureFromImage(testHelper); final originalTexture = await createTextureFromImage(testHelper);
final sampler = final sampler = await FilamentApp.instance!.createTextureSampler();
await FilamentApp.instance!.createTextureSampler();
await ubershader.setParameterTexture("baseColorMap", originalTexture, await ubershader.setParameterTexture(
sampler); "baseColorMap", originalTexture, sampler);
final depthWriteView = await testHelper.createView(testHelper.swapChain, var textureProjection =
textureFormat: TextureFormat.R32F); await TextureProjection.create(viewer.view, testHelper.swapChain);
final captureView = await testHelper.createView(testHelper.swapChain);
await viewer.view.setRenderOrder(0);
await depthWriteView.setRenderOrder(1);
await captureView.setRenderOrder(2);
for (var view in [captureView, depthWriteView]) {
await view.setCamera(camera);
await (view as FFIView)
.setScene(await viewer.view.getScene() as FFIScene);
}
var depthWriteMat = await FilamentApp.instance!.createMaterial(
File(
"/Users/nickfisher/Documents/thermion/materials/linear_depth.filamat",
).readAsBytesSync(),
);
var depthWriteMi = await depthWriteMat.createInstance();
var captureMat = await FilamentApp.instance!.createMaterial(
File(
"/Users/nickfisher/Documents/thermion/materials/capture_uv.filamat",
).readAsBytesSync(),
);
var captureMi = await captureMat.createInstance();
final color =
await (await viewer.view.getRenderTarget())!.getColorTexture();
final depth =
await (await depthWriteView.getRenderTarget())!.getColorTexture();
await captureMi.setParameterBool("flipUVs", true);
await captureMi.setParameterTexture(
"color", color, await FilamentApp.instance!.createTextureSampler());
await captureMi.setParameterTexture(
"depth", depth, await FilamentApp.instance!.createTextureSampler());
await captureMi.setParameterBool("useDepth", true);
await FilamentApp.instance!.setClearOptions(0, 0, 0, 1, await FilamentApp.instance!.setClearOptions(0, 0, 0, 1,
clearStencil: 0, discard: false, clear: true); clearStencil: 0, discard: false, clear: true);
@@ -125,23 +90,17 @@ void main() async {
), ),
); );
var pixelBuffers = await testHelper.capture(null, "capture_uv_$i", await textureProjection.project(cube);
beforeRender: (view) async { final depth = textureProjection.getDepthWritePixelBuffer();
if (view == viewer.view) { await savePixelBufferToBmp(
await ubershader.setParameterTexture("baseColorMap", originalTexture, depth, 512, 512, "${testHelper.outDir.path}/depth_$i.bmp");
sampler); final projected = textureProjection.getProjectedPixelBuffer();
await cube.setMaterialInstanceAt(ubershader); await savePixelBufferToBmp(
} else if (view == depthWriteView) { depth, 512, 512, "${testHelper.outDir.path}/projected_$i.bmp");
await cube.setMaterialInstanceAt(depthWriteMi);
} else if (view == captureView) {
await cube.setMaterialInstanceAt(captureMi);
}
});
await cube.setMaterialInstanceAt(ubershader); await cube.setMaterialInstanceAt(ubershader);
final data = await projectedImage.getData(); final data = await projectedImage.getData();
data.setRange(0, data.length, data.setRange(0, data.length, projected.buffer.asFloat32List());
pixelBuffers[captureView]!.buffer.asFloat32List());
await projectedTexture.setLinearImage( await projectedTexture.setLinearImage(
projectedImage, projectedImage,
@@ -157,8 +116,8 @@ void main() async {
await testHelper.capture(viewer.view, "capture_uv_retextured_$i"); await testHelper.capture(viewer.view, "capture_uv_retextured_$i");
await ubershader.setParameterTexture("baseColorMap", originalTexture, await ubershader.setParameterTexture(
sampler); "baseColorMap", originalTexture, sampler);
} }
}, createRenderTarget: true); }, createRenderTarget: true);
}); });