Files
cup_edit/thermion_dart/test/unlit_material_tests.dart
2025-06-09 18:15:17 +08:00

243 lines
8.8 KiB
Dart

import 'dart:io';
import 'dart:math';
import 'package:thermion_dart/thermion_dart.dart';
import 'package:test/test.dart';
import 'helpers.dart';
Future<
({
ThermionAsset blueCube,
MaterialInstance blueMaterialInstance,
ThermionAsset greenCube,
MaterialInstance greenMaterialInstance
})> setup(ThermionViewer viewer) async {
var blueMaterialInstance =
await FilamentApp.instance!.createUnlitMaterialInstance();
final blueCube = await viewer.createGeometry(GeometryHelper.cube(),
materialInstances: [blueMaterialInstance]);
await blueMaterialInstance.setParameterFloat4(
"baseColorFactor", 0.0, 0.0, 1.0, 1.0);
// Position blue cube slightly behind/below/right
await blueCube.setTransform(Matrix4.translation(Vector3(1.0, -1.0, -1.0)));
var greenMaterialInstance =
await FilamentApp.instance!.createUnlitMaterialInstance();
final greenCube = await viewer.createGeometry(GeometryHelper.cube(),
materialInstances: [greenMaterialInstance]);
await greenMaterialInstance.setParameterFloat4(
"baseColorFactor", 0.0, 1.0, 0.0, 1.0);
return (
blueCube: blueCube,
blueMaterialInstance: blueMaterialInstance,
greenCube: greenCube,
greenMaterialInstance: greenMaterialInstance
);
}
void main() async {
final testHelper = TestHelper("material");
await testHelper.setup();
test('unlit + baseColorFactor', () async {
await testHelper.withViewer((viewer) async {
await viewer.setPostProcessing(true);
await viewer.setToneMapping(ToneMapper.LINEAR);
var materialInstance =
await FilamentApp.instance!.createUnlitMaterialInstance();
var cube = await viewer.createGeometry(
GeometryHelper.cube(normals: false, uvs: false),
materialInstances: [materialInstance]);
await materialInstance.setParameterFloat4(
"baseColorFactor", 0.0, 1.0, 0.0, 1.0);
await materialInstance.setParameterInt("baseColorIndex", -1);
await testHelper.capture(viewer.view, "unlit_material_base_color");
await materialInstance.destroy();
}, bg: kRed);
});
test('unlit + baseColorMap', () async {
await testHelper.withViewer((viewer) async {
var materialInstance =
await await FilamentApp.instance!.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_texture_512x512.png")
.readAsBytesSync();
final image = await await FilamentApp.instance!.decodeImage(data);
final texture = await await FilamentApp.instance!.createTexture(
await image.getWidth(), await image.getHeight(),
textureFormat: TextureFormat.RGBA32F);
await texture.setLinearImage(
image, PixelDataFormat.RGBA, PixelDataType.FLOAT);
final sampler = await await FilamentApp.instance!.createTextureSampler();
await materialInstance.setParameterTexture(
"baseColorMap", texture, sampler);
await testHelper.capture(viewer.view, "unlit_baseColorMap");
await image.destroy();
await texture.dispose();
await sampler.dispose();
await materialInstance.destroy();
});
});
test('unlit + baseColorMap (apply material after creation)', () async {
await testHelper.withViewer((viewer) async {
var cube = await viewer
.createGeometry(GeometryHelper.cube(), materialInstances: []);
var materialInstance =
await FilamentApp.instance!.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_texture_512x512.png")
.readAsBytesSync();
final image = await FilamentApp.instance!.decodeImage(data);
final texture = await FilamentApp.instance!.createTexture(
await image.getWidth(), await image.getHeight(),
textureFormat: TextureFormat.RGBA32F);
await texture.setLinearImage(
image, PixelDataFormat.RGBA, PixelDataType.FLOAT);
final sampler = await FilamentApp.instance!.createTextureSampler();
await materialInstance.setParameterTexture(
"baseColorMap", texture, sampler);
await cube.setMaterialInstanceAt(materialInstance);
await testHelper.capture(
viewer.view, "unlit_baseColorMap_material_created_after");
await image.destroy();
await texture.dispose();
await sampler.dispose();
await materialInstance.destroy();
});
});
test('unlit + baseColorMap (fetch material after creation)', () async {
await testHelper.withViewer((viewer) async {
var materialInstance =
await FilamentApp.instance!.createUnlitMaterialInstance();
var cube = await viewer.createGeometry(GeometryHelper.cube(),
materialInstances: [materialInstance]);
materialInstance = await cube.getMaterialInstanceAt(index: 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_texture_512x512.png")
.readAsBytesSync();
final image = await FilamentApp.instance!.decodeImage(data);
final texture = await FilamentApp.instance!.createTexture(
await image.getWidth(), await image.getHeight(),
textureFormat: TextureFormat.RGBA32F);
await texture.setLinearImage(
image, PixelDataFormat.RGBA, PixelDataType.FLOAT);
final sampler = await FilamentApp.instance!.createTextureSampler();
await materialInstance.setParameterTexture(
"baseColorMap", texture, sampler);
await cube.setMaterialInstanceAt(materialInstance);
await testHelper.capture(
viewer.view, "unlit_baseColorMap_fetch_material");
await image.destroy();
await texture.dispose();
await sampler.dispose();
await materialInstance.destroy();
});
});
test('unlit material with color + alpha', () async {
await testHelper.withViewer((viewer) async {
await viewer.setPostProcessing(true);
await viewer.setToneMapping(ToneMapper.LINEAR);
var materialInstance =
await FilamentApp.instance!.createUnlitMaterialInstance();
var cube = await viewer.createGeometry(
GeometryHelper.cube(normals: false, uvs: false),
materialInstances: [materialInstance]);
await materialInstance.setParameterFloat4(
"baseColorFactor", 0.0, 1.0, 0.0, 0.1);
await materialInstance.setParameterInt("baseColorIndex", -1);
await testHelper.capture(viewer.view, "unlit_material_base_color_alpha");
await materialInstance.destroy();
}, bg: kRed);
});
test('unlit fixed size material', () async {
var viewer = await testHelper.createViewer();
await viewer.setCameraPosition(0, 0, 6);
await viewer.setBackgroundColor(1.0, 0.0, 0.0, 1.0);
await viewer.setPostProcessing(true);
await viewer.setToneMapping(ToneMapper.LINEAR);
var materialInstance = await viewer.createUnlitFixedSizeMaterialInstance();
var cube = await viewer.createGeometry(GeometryHelper.cube(),
materialInstances: [materialInstance]);
await materialInstance.setParameterFloat4(
"baseColorFactor", 0.0, 1.0, 0.0, 1.0);
await testHelper.capture(viewer.view, "unlit_fixed_size_default_scale");
await materialInstance.setParameterFloat("scale", 10.0);
await testHelper.capture(viewer.view, "unlit_fixed_size_scale_10");
await viewer.dispose();
});
test('disable depth write', () async {
await testHelper.withViewer((viewer) async {
final (
:blueCube,
:blueMaterialInstance,
:greenCube,
:greenMaterialInstance
) = await setup(viewer);
// With depth write enabled on both materials, green cube renders behind the blue cube
await testHelper.capture(
viewer.view, "material_instance_depth_write_enabled");
// Disable depth write on green cube
// Blue cube will always appear in front
await greenMaterialInstance.setDepthWriteEnabled(false);
await testHelper.capture(
viewer.view, "material_instance_depth_write_disabled");
// Set priority for greenCube to render last, making it appear in front
await viewer.setPriority(greenCube.entity, 7);
await testHelper.capture(
viewer.view, "material_instance_depth_write_disabled_with_priority");
});
});
}