test updates

This commit is contained in:
Nick Fisher
2025-03-20 18:56:10 +08:00
parent e6bdcb687a
commit 1177a71f73
14 changed files with 1142 additions and 900 deletions

View File

@@ -1,12 +1,9 @@
import 'dart:io';
import 'dart:math';
import 'dart:typed_data';
import 'package:thermion_dart/src/viewer/src/ffi/src/thermion_viewer_ffi.dart';
import 'package:thermion_dart/thermion_dart.dart';
import 'package:test/test.dart';
import 'package:vector_math/vector_math_64.dart';
import 'helpers.dart';
Future<
@@ -43,8 +40,8 @@ Future<
void main() async {
final testHelper = TestHelper("material");
group("unlit material tests", () {
test('unlit material with color only', () async {
group("unlit material", () {
test('unlit + baseColorFactor', () async {
await testHelper.withViewer((viewer) async {
await viewer.setPostProcessing(true);
await viewer.setToneMapping(ToneMapper.LINEAR);
@@ -62,6 +59,116 @@ void main() async {
}, bg: kRed);
});
test('unlit + baseColorMap', () async {
await testHelper.withViewer((viewer) async {
var materialInstance = await viewer.createUnlitMaterialInstance();
var cube = await viewer.createGeometry(GeometryHelper.cube(),
materialInstances: [materialInstance]);
await materialInstance.setParameterFloat4(
"baseColorFactor", 1.0, 1.0, 1.0, 1.0);
await materialInstance.setParameterFloat2("uvScale", 1.0, 1.0);
await materialInstance.setParameterInt("baseColorIndex", 0);
var data =
File("${testHelper.testDir}/assets/cube_texture2_512x512.png")
.readAsBytesSync();
final image = await viewer.decodeImage(data);
final texture = await viewer.createTexture(
await image.getWidth(), await image.getHeight(),
textureFormat: TextureFormat.RGBA32F);
await texture.setLinearImage(
image, PixelDataFormat.RGBA, PixelDataType.FLOAT);
final sampler = await viewer.createTextureSampler();
await materialInstance.setParameterTexture(
"baseColorMap", texture, sampler);
await testHelper.capture(viewer, "unlit_baseColorMap");
await image.destroy();
await texture.dispose();
await sampler.dispose();
await viewer.destroyMaterialInstance(materialInstance);
});
});
test('unlit + baseColorMap (apply material after creation)', () async {
await testHelper.withViewer((viewer) async {
var cube = await viewer
.createGeometry(GeometryHelper.cube(), materialInstances: []);
var materialInstance = await viewer.createUnlitMaterialInstance();
await materialInstance.setParameterFloat4(
"baseColorFactor", 1.0, 1.0, 1.0, 1.0);
await materialInstance.setParameterFloat2("uvScale", 1.0, 1.0);
await materialInstance.setParameterInt("baseColorIndex", 0);
var data =
File("${testHelper.testDir}/assets/cube_texture2_512x512.png")
.readAsBytesSync();
final image = await viewer.decodeImage(data);
final texture = await viewer.createTexture(
await image.getWidth(), await image.getHeight(),
textureFormat: TextureFormat.RGBA32F);
await texture.setLinearImage(
image, PixelDataFormat.RGBA, PixelDataType.FLOAT);
final sampler = await viewer.createTextureSampler();
await materialInstance.setParameterTexture(
"baseColorMap", texture, sampler);
await cube.setMaterialInstanceAt(materialInstance);
await testHelper.capture(
viewer, "unlit_baseColorMap_material_created_after");
await image.destroy();
await texture.dispose();
await sampler.dispose();
await viewer.destroyMaterialInstance(materialInstance);
});
});
test('unlit + baseColorMap (fetch material after creation)', () async {
await testHelper.withViewer((viewer) async {
var materialInstance = await viewer.createUnlitMaterialInstance();
var cube = await viewer.createGeometry(GeometryHelper.cube(),
materialInstances: [materialInstance]);
materialInstance = await viewer.getMaterialInstanceAt(cube.entity, 0);
await materialInstance.setParameterFloat4(
"baseColorFactor", 1.0, 1.0, 1.0, 1.0);
await materialInstance.setParameterInt("baseColorIndex", 0);
var data =
File("${testHelper.testDir}/assets/cube_texture2_512x512.png")
.readAsBytesSync();
final image = await viewer.decodeImage(data);
final texture = await viewer.createTexture(
await image.getWidth(), await image.getHeight(),
textureFormat: TextureFormat.RGBA32F);
await texture.setLinearImage(
image, PixelDataFormat.RGBA, PixelDataType.FLOAT);
final sampler = await viewer.createTextureSampler();
await materialInstance.setParameterTexture(
"baseColorMap", texture, sampler);
await cube.setMaterialInstanceAt(materialInstance);
await testHelper.capture(
viewer, "unlit_baseColorMap_fetch_material");
await image.destroy();
await texture.dispose();
await sampler.dispose();
await viewer.destroyMaterialInstance(materialInstance);
});
});
test('unlit material with color + alpha', () async {
await testHelper.withViewer((viewer) async {
await viewer.setPostProcessing(true);
@@ -123,18 +230,13 @@ void main() async {
}, bg: kRed, postProcessing: true);
});
test('set ubershader texture', () async {
test('ubershader + baseColorMap texture', () async {
await testHelper.withViewer((viewer) async {
await viewer.addLight(LightType.SUN, 6500, 1000000, 0, 0, 0, 0, 0, -1);
await viewer.setCameraPosition(0, 2, 6);
await viewer
.setCameraRotation(Quaternion.axisAngle(Vector3(1, 0, 0), -pi / 8));
var materialInstance = await viewer.createUbershaderMaterialInstance();
var materialInstance = await viewer.createUbershaderMaterialInstance(unlit: true);
final cube = await viewer.createGeometry(
GeometryHelper.cube(uvs: true, normals: true),
GeometryHelper.cube(),
materialInstances: [materialInstance]);
var data = File("${testHelper.testDir}/assets/cube_texture_512x512.png")
var data = File("${testHelper.testDir}/assets/cube_texture2_512x512_flipped.png")
.readAsBytesSync();
final image = await viewer.decodeImage(data);
final texture = await viewer.createTexture(
@@ -153,7 +255,7 @@ void main() async {
viewer, "geometry_cube_with_custom_material_ubershader_texture");
await viewer.destroyAsset(cube);
await viewer.destroyMaterialInstance(materialInstance);
await viewer.destroyTexture(texture);
await texture.dispose();
});
});
@@ -340,159 +442,6 @@ void main() async {
}, postProcessing: true);
});
});
group('projection', () {
test('apply projection material', () async {
await testHelper.withViewer((viewer) async {
await viewer
.setCameraModelMatrix4(Matrix4.translation(Vector3(0, 0, 5)));
// // Rotate the camera in 30-degree increments and capture at each position
// for (int i = 0; i <= 180; i += 30) {
// int i = 60;
// final angle = i * (pi / 180); // Convert to radians
// // Calculate camera position
// // Start at (0, 1, 5) (facing the sphere from +z) and rotate around to (-5, 1, 0)
// final radius = 5.0;
// final x = -radius * sin(angle);
// final z = radius * cos(angle);
// // Create view matrix for this camera position
// final matrix = makeViewMatrix(
// Vector3(x, 1, z),
// Vector3.zero(), // Looking at origin
// Vector3(0, 1, 0) // Up vector
// )
// ..invert();
// await viewer.setCameraModelMatrix4(matrix);
// // Take a snapshot at this position
// await testHelper.capture(viewer, "projection_${i}deg");
// }
final view = await viewer.getViewAt(0);
final rtTextureHandle = await testHelper.createTexture(512, 512);
final rt = await viewer.createRenderTarget(
512, 512, rtTextureHandle.metalTextureAddress);
await view.setRenderTarget(rt);
final rtTexture = await rt.getColorTexture();
final ppuvMaterial = await viewer.createMaterial(File(
"/Users/nickfisher/Documents/thermion/materials/postprocess_uv.filamat")
.readAsBytesSync());
final ppuvInstance = await ppuvMaterial.createInstance();
// Setup the scene (lighting, materials, etc.)
await viewer.loadIbl(
"file://${testHelper.testDir}/assets/default_env_ibl.ktx",
intensity: 1000);
await viewer.addDirectLight(DirectLight.sun(
intensity: 500000,
castShadows: true,
direction: Vector3(1, -0.5, 0).normalized()));
// input texture
var inputTextureData =
File("${testHelper.testDir}/assets/cube_texture_512x512.png")
.readAsBytesSync();
var inputImage = await viewer.decodeImage(inputTextureData);
var inputTexture = await viewer.createTexture(
await inputImage.getWidth(), await inputImage.getHeight(),
textureFormat: TextureFormat.RGBA32F);
await inputTexture.setLinearImage(
inputImage, PixelDataFormat.RGBA, PixelDataType.FLOAT);
var captureUvMaterial = await viewer.createMaterial(File(
"/Users/nickfisher/Documents/thermion/materials/capture_uv.filamat")
.readAsBytesSync());
var captureUvMaterialInstance =
await captureUvMaterial.createInstance();
var sampler = await viewer.createTextureSampler();
// Create sphere and plane
final sphere = await viewer.createGeometry(
GeometryHelper.sphere(normals: true, uvs: true),
materialInstances: []);
// await viewer.setTransform(
// sphere.entity, Matrix4.compose(Vector3(2, 1, -1), Quaternion.identity(), Vector3(1.0,1.0,1.0)));
await sphere.addToScene();
await testHelper.capture(viewer, "color", renderTarget: rt);
await captureUvMaterialInstance.setParameterTexture(
"color", rtTexture, sampler);
await sphere.setMaterialInstanceAt(captureUvMaterialInstance);
await testHelper.capture(viewer, "uv_capture", renderTarget: rt);
// await ppuvInstance.setParameterTexture("uvTexture", rtTexture, sampler);
await sphere.setMaterialInstanceAt(ppuvInstance);
await testHelper.capture(viewer, "ppuv", renderTarget: rt);
// final quad = await viewer.createGeometry(
// GeometryHelper.plane(width: 100.0, height: 100.0),
// materialInstances: [materialInstance]);
// await viewer.setTransform(
// quad.entity, Matrix4.translation(Vector3(0, -1, 0)));
// await quad.addToScene();
var bytePixelBuffer = await viewer.capture(renderTarget: rt);
var floatPixelBuffer = Float32List.fromList(
bytePixelBuffer.map((p) => p.toDouble() / 255.0).toList());
print("pixelBuffer ${floatPixelBuffer.lengthInBytes} bytes");
var output = unprojectTexture(
renderTarget: await inputImage.getData(),
uvCoordinates: floatPixelBuffer,
renderTargetWidth: 512,
renderTargetHeight: 512,
renderTargetChannels: 4,
uvWidth: 512,
uvHeight: 512,
uvChannels: 4,
outputWidth: 512,
outputHeight: 512);
var byteOutput =
Uint8List.fromList(output.map((o) => (o * 255.0).toInt()).toList());
await savePixelBufferToBmp(byteOutput, 512, 512, "/tmp/foo.bmp");
final reappliedImage = await viewer.createImage(512, 512, 4);
final data = await reappliedImage.getData();
data.setRange(0, data.length, output);
final reappliedTexture = await viewer.createTexture(512, 512,
textureFormat: TextureFormat.RGBA32F);
await reappliedTexture.setLinearImage(
reappliedImage, PixelDataFormat.RGBA, PixelDataType.FLOAT);
var newMaterialInstance =
await viewer.createUbershaderMaterialInstance(unlit: true);
await newMaterialInstance.setParameterInt("baseColorIndex", 0);
await newMaterialInstance.setParameterTexture(
"baseColorMap",
reappliedTexture,
// inputTexture,
sampler);
await newMaterialInstance.setParameterFloat4(
"baseColorFactor", 1.0, 1.0, 1.0, 1.0);
await sphere.setMaterialInstanceAt(newMaterialInstance);
await testHelper.capture(viewer, "capture2");
// final view = await viewer.getViewAt(0);
// final renderTargetTexture = await testHelper.createTexture(512, 512);
// final rt = await viewer.createRenderTarget(
// 512, 512, renderTargetTexture.metalTextureAddress);
// await view.setRenderTarget(rt);
// pixelBuffer = await viewer.capture(renderTarget: rt);
}, viewportDimensions: (width: 512, height: 512));
});
});
}
Float32List unprojectTexture({