projection work + tests
This commit is contained in:
@@ -100,8 +100,8 @@ fragment {
|
||||
//material.baseColor = vec4(sampledDepth.r, 0.0, 0.0, 1.0);
|
||||
//material.baseColor = vec4(vertexDepth, 0.0, 0.0, 1.0);
|
||||
|
||||
if(materialParams.useDepth && abs(vertexDepth - sampledDepth.r) > 0.001) {
|
||||
discard;
|
||||
if(materialParams.useDepth && (sampledDepth.r < 0.0001 || abs(vertexDepth - sampledDepth.r) > 0.001)) {
|
||||
material.baseColor = vec4(0.0, 0.0, 0.0, 0.0);
|
||||
} else {
|
||||
vec2 texSize = vec2(textureSize(materialParams_color, 0));
|
||||
vec4 color = textureLod(materialParams_color, uvToRenderTargetUV(deviceCoords.xy), 0.0f);
|
||||
|
||||
@@ -8,7 +8,7 @@ material {
|
||||
},
|
||||
{
|
||||
type : float3[3],
|
||||
name : cameraPositions
|
||||
name : cameraForwardVectors
|
||||
},
|
||||
{
|
||||
type : bool,
|
||||
@@ -17,8 +17,8 @@ material {
|
||||
],
|
||||
variables : [
|
||||
{
|
||||
type : float3,
|
||||
name : blendWeights,
|
||||
type : float,
|
||||
name : samplerCoord,
|
||||
}
|
||||
],
|
||||
requires : [ position, uv0 ],
|
||||
@@ -43,42 +43,57 @@ material {
|
||||
// Parameters:
|
||||
// - perspectives: 3D texture containing different perspective views of the object
|
||||
// - cameraPositions: Array of camera positions used to render each perspective slice
|
||||
|
||||
vertex {
|
||||
void materialVertex(inout MaterialVertexInputs material) {
|
||||
vec3 worldCameraPos = getWorldCameraPosition();
|
||||
vec4 currentCameraPos = getUserWorldFromWorldMatrix() * vec4(worldCameraPos, 1.0);
|
||||
vec3 forward = -(normalize(getWorldFromViewMatrix()[2].xyz));
|
||||
|
||||
vec3 weights = vec3(0.0, 0.0, 0.0);
|
||||
int idxMax = 0;
|
||||
float weightMax = 0.0;
|
||||
for(int i = 0; i < 3; i++) {
|
||||
weights[i] = dot(forward, materialParams.cameraForwardVectors[i]);
|
||||
if(weights[i] > weightMax) {
|
||||
weightMax = weights[i];
|
||||
idxMax = i;
|
||||
}
|
||||
}
|
||||
|
||||
if(idxMax == 0) {
|
||||
float z = (weights.y * 0.5) + (weights.z * 1.0);
|
||||
}
|
||||
|
||||
//weights /= (weights.x + weights.y + weights.z);
|
||||
|
||||
material.blendWeights.xyz = vec3(0.0f);
|
||||
|
||||
float totalWeight = 0.0;
|
||||
|
||||
for (int i = 0; i < 3; i++) {
|
||||
vec3 cameraPos = materialParams.cameraPositions[i];
|
||||
float dist = distance(currentCameraPos.xyz, cameraPos);
|
||||
material.blendWeights[i] = exp(-dist);
|
||||
totalWeight += material.blendWeights[i];
|
||||
}
|
||||
if (totalWeight > 0.0) {
|
||||
material.blendWeights /= totalWeight;
|
||||
}
|
||||
//material.blendWeights.x = exp(-distance(currentCameraPos.xyz, materialParams.cameraPositions[0]));
|
||||
|
||||
material.samplerCoord.x = z;
|
||||
}
|
||||
}
|
||||
|
||||
fragment {
|
||||
void useMax(vec3 forward) {
|
||||
float maxIdx = 0.0f;
|
||||
float maxWeight = 0.0f;
|
||||
for(int i =0; i < 3; i++) {
|
||||
float weight = dot(forward, materialParams.cameraForwardVectors[i]);
|
||||
if(weight > maxWeight) {
|
||||
maxWeight = weight;
|
||||
maxIdx = float(i) / 2.0f;
|
||||
}
|
||||
}
|
||||
|
||||
float z = maxIdx;
|
||||
|
||||
}
|
||||
void material(inout MaterialInputs material) {
|
||||
prepareMaterial(material);
|
||||
|
||||
vec3 weights = variable_blendWeights.xyz;
|
||||
|
||||
float z = (weights.x * 0.0) + (weights.y * 0.5) + (weights.z * 1.0);
|
||||
|
||||
vec2 uv = getUV0();
|
||||
if(materialParams.flipUVs) {
|
||||
uv = uvToRenderTargetUV(uv);
|
||||
}
|
||||
vec3 texCoord = vec3(uv, z);
|
||||
vec3 texCoord = vec3(uv, variable_samplerCoord.x);
|
||||
material.baseColor = texture(materialParams_perspectives, texCoord);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -9,24 +9,28 @@ void main() async {
|
||||
group("assets", () {
|
||||
test('load/clear skybox', () async {
|
||||
await testHelper.withViewer((viewer) async {
|
||||
final camera = await viewer.getActiveCamera();
|
||||
print(await camera.getModelMatrix());
|
||||
print(await camera.getViewMatrix());
|
||||
print(await camera.getProjectionMatrix());
|
||||
await camera.lookAt(Vector3(0, 0, 10),
|
||||
focus: Vector3.zero(), up: Vector3(0, 1, 0));
|
||||
await viewer.loadSkybox(
|
||||
"file://${testHelper.testDir}/assets/default_env_skybox.ktx");
|
||||
await testHelper.capture(viewer.view, "load_skybox");
|
||||
await viewer.removeSkybox();
|
||||
await testHelper.capture(viewer.view, "remove_skybox");
|
||||
});
|
||||
|
||||
await viewer.setPostProcessing(true);
|
||||
await viewer.setBloom(false, 0.01);
|
||||
await viewer.loadSkybox(
|
||||
"file://${testHelper.testDir}/assets/default_env_skybox.ktx");
|
||||
await testHelper.capture(
|
||||
viewer.view, "load_skybox_with_postprocessing");
|
||||
await viewer.removeSkybox();
|
||||
await testHelper.capture(
|
||||
viewer.view, "remove_skybox_with_postprocessing");
|
||||
}, createRenderTarget: true);
|
||||
});
|
||||
|
||||
test('load/remove ibl', () async {
|
||||
await testHelper.withViewer((viewer) async {
|
||||
var asset = await viewer
|
||||
.loadGlb("file://${testHelper.testDir}/assets/cube.glb");
|
||||
.loadGltf("file://${testHelper.testDir}/assets/cube.glb");
|
||||
await viewer
|
||||
.loadIbl("file://${testHelper.testDir}/assets/default_env_ibl.ktx");
|
||||
await testHelper.capture(viewer.view, "ibl_loaded");
|
||||
@@ -37,8 +41,9 @@ void main() async {
|
||||
|
||||
test('load/remove gltf', () async {
|
||||
await testHelper.withViewer((viewer) async {
|
||||
var asset = await viewer
|
||||
.loadGlb("file://${testHelper.testDir}/assets/cube.gltf", relativeResourcePath: "${testHelper.testDir}/assets");
|
||||
var asset = await viewer.loadGltf(
|
||||
"file://${testHelper.testDir}/assets/cube.gltf",
|
||||
relativeResourcePath: "${testHelper.testDir}/assets");
|
||||
await viewer
|
||||
.loadIbl("file://${testHelper.testDir}/assets/default_env_ibl.ktx");
|
||||
await testHelper.capture(viewer.view, "gltf_loaded");
|
||||
@@ -47,10 +52,26 @@ void main() async {
|
||||
}, cameraPosition: Vector3(0, 0, 5));
|
||||
});
|
||||
|
||||
test('transform gltf to unit cube', () async {
|
||||
await testHelper.withViewer((viewer) async {
|
||||
var asset = await viewer.loadGltf(
|
||||
"file://${testHelper.testDir}/assets/cube.gltf",
|
||||
relativeResourcePath: "${testHelper.testDir}/assets");
|
||||
|
||||
await viewer
|
||||
.loadIbl("file://${testHelper.testDir}/assets/default_env_ibl.ktx");
|
||||
await asset.setTransform(Matrix4.compose(
|
||||
Vector3.zero(), Quaternion.identity(), Vector3.all(2)));
|
||||
await testHelper.capture(viewer.view, "gltf_before_unit_cube");
|
||||
await asset.transformToUnitCube();
|
||||
await testHelper.capture(viewer.view, "gltf_after_unit_cube");
|
||||
}, cameraPosition: Vector3(0, 0, 5));
|
||||
});
|
||||
|
||||
test('add/remove asset from scene ', () async {
|
||||
await testHelper.withViewer((viewer) async {
|
||||
var asset = await viewer
|
||||
.loadGlb("file://${testHelper.testDir}/assets/cube.glb");
|
||||
.loadGltf("file://${testHelper.testDir}/assets/cube.glb");
|
||||
await viewer
|
||||
.loadIbl("file://${testHelper.testDir}/assets/default_env_ibl.ktx");
|
||||
await testHelper.capture(viewer.view, "asset_added");
|
||||
@@ -62,7 +83,7 @@ void main() async {
|
||||
test('destroy assets', () async {
|
||||
await testHelper.withViewer((viewer) async {
|
||||
var asset = await viewer
|
||||
.loadGlb("file://${testHelper.testDir}/assets/cube.glb");
|
||||
.loadGltf("file://${testHelper.testDir}/assets/cube.glb");
|
||||
await viewer
|
||||
.loadIbl("file://${testHelper.testDir}/assets/default_env_ibl.ktx");
|
||||
await testHelper.capture(viewer.view, "assets_present");
|
||||
@@ -70,6 +91,5 @@ void main() async {
|
||||
await testHelper.capture(viewer.view, "assets_destroyed");
|
||||
}, cameraPosition: Vector3(0, 0, 5));
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
181
thermion_dart/test/assets/cube_texture2.svg
Normal file
181
thermion_dart/test/assets/cube_texture2.svg
Normal file
@@ -0,0 +1,181 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
width="200"
|
||||
height="200"
|
||||
viewBox="0 0 1 1"
|
||||
version="1.1"
|
||||
id="svg10"
|
||||
sodipodi:docname="cube_texture2.svg"
|
||||
inkscape:export-filename="cube_texture2_512x512.png"
|
||||
inkscape:export-xdpi="96"
|
||||
inkscape:export-ydpi="96"
|
||||
inkscape:version="1.4 (e7c3feb1, 2024-10-09)"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<defs
|
||||
id="defs10" />
|
||||
<sodipodi:namedview
|
||||
id="namedview10"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#000000"
|
||||
borderopacity="0.25"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#d1d1d1"
|
||||
inkscape:zoom="0.536875"
|
||||
inkscape:cx="-6.5192084"
|
||||
inkscape:cy="390.22119"
|
||||
inkscape:window-width="1200"
|
||||
inkscape:window-height="964"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="25"
|
||||
inkscape:window-maximized="0"
|
||||
inkscape:current-layer="svg10" />
|
||||
<!-- Background Grid (optional, for visual aid) -->
|
||||
<rect
|
||||
x="0"
|
||||
y="0"
|
||||
width="1"
|
||||
height="1"
|
||||
fill="#f0f0f0"
|
||||
id="rect1" />
|
||||
<line
|
||||
x1="0.333"
|
||||
y1="0"
|
||||
x2="0.333"
|
||||
y2="1"
|
||||
stroke="#ccc"
|
||||
stroke-width="0.005"
|
||||
id="line1" />
|
||||
<line
|
||||
x1="0.666"
|
||||
y1="0"
|
||||
x2="0.666"
|
||||
y2="1"
|
||||
stroke="#ccc"
|
||||
stroke-width="0.005"
|
||||
id="line2" />
|
||||
<line
|
||||
y1="0.25"
|
||||
x1="0"
|
||||
y2="0.25"
|
||||
x2="1"
|
||||
stroke="#ccc"
|
||||
stroke-width="0.005"
|
||||
id="line3" />
|
||||
<line
|
||||
y1="0.5"
|
||||
x1="0"
|
||||
y2="0.5"
|
||||
x2="1"
|
||||
stroke="#ccc"
|
||||
stroke-width="0.005"
|
||||
id="line4" />
|
||||
<line
|
||||
y1="0.75"
|
||||
x1="0"
|
||||
y2="0.75"
|
||||
x2="1"
|
||||
stroke="#ccc"
|
||||
stroke-width="0.005"
|
||||
id="line5" />
|
||||
<!-- Front Face -->
|
||||
<rect
|
||||
x="0.333"
|
||||
y="0"
|
||||
width="0.333"
|
||||
height="0.25"
|
||||
fill="#ff0000"
|
||||
id="rect5" />
|
||||
<text
|
||||
x="0.5"
|
||||
y="0.125"
|
||||
text-anchor="middle"
|
||||
dominant-baseline="middle"
|
||||
font-size="0.1"
|
||||
fill="white"
|
||||
id="text5">Front</text>
|
||||
<!-- Back Face -->
|
||||
<rect
|
||||
x="0.333"
|
||||
y="0.5"
|
||||
width="0.333"
|
||||
height="0.25"
|
||||
fill="#00ff00"
|
||||
id="rect6" />
|
||||
<text
|
||||
x="0.5"
|
||||
y="0.625"
|
||||
text-anchor="middle"
|
||||
dominant-baseline="middle"
|
||||
font-size="0.1"
|
||||
fill="white"
|
||||
id="text6">Back</text>
|
||||
<!-- Top Face -->
|
||||
<rect
|
||||
x="0.666"
|
||||
y="0.25"
|
||||
width="0.333"
|
||||
height="0.25"
|
||||
fill="#0000ff"
|
||||
id="rect7" />
|
||||
<text
|
||||
x="0.833"
|
||||
y="0.375"
|
||||
text-anchor="middle"
|
||||
dominant-baseline="middle"
|
||||
font-size="0.1"
|
||||
fill="white"
|
||||
id="text7">Top</text>
|
||||
<!-- Bottom Face -->
|
||||
<rect
|
||||
x="0"
|
||||
y="0.25"
|
||||
width="0.333"
|
||||
height="0.25"
|
||||
fill="#ffff00"
|
||||
id="rect8" />
|
||||
<text
|
||||
x="0.166"
|
||||
y="0.375"
|
||||
text-anchor="middle"
|
||||
dominant-baseline="middle"
|
||||
font-size="0.1"
|
||||
fill="black"
|
||||
id="text8">Bottom</text>
|
||||
<!-- Right Face -->
|
||||
<rect
|
||||
x="0.333"
|
||||
y="0.25"
|
||||
width="0.333"
|
||||
height="0.25"
|
||||
fill="#ff00ff"
|
||||
id="rect9" />
|
||||
<text
|
||||
x="0.5"
|
||||
y="0.375"
|
||||
text-anchor="middle"
|
||||
dominant-baseline="middle"
|
||||
font-size="0.1"
|
||||
fill="white"
|
||||
id="text9">Right</text>
|
||||
<!-- Left Face -->
|
||||
<rect
|
||||
x="0.333"
|
||||
y="0.75"
|
||||
width="0.333"
|
||||
height="0.25"
|
||||
fill="#00ffff"
|
||||
id="rect10" />
|
||||
<text
|
||||
x="0.5"
|
||||
y="0.875"
|
||||
text-anchor="middle"
|
||||
dominant-baseline="middle"
|
||||
font-size="0.1"
|
||||
fill="black"
|
||||
id="text10">Left</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.6 KiB |
BIN
thermion_dart/test/assets/cube_texture2_512x512.png
Normal file
BIN
thermion_dart/test/assets/cube_texture2_512x512.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 5.9 KiB |
BIN
thermion_dart/test/assets/cube_texture2_512x512_flipped.png
Normal file
BIN
thermion_dart/test/assets/cube_texture2_512x512_flipped.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 5.9 KiB |
392
thermion_dart/test/depth_tests.dart
Normal file
392
thermion_dart/test/depth_tests.dart
Normal file
@@ -0,0 +1,392 @@
|
||||
@Timeout(const Duration(seconds: 600))
|
||||
import 'dart:async';
|
||||
import 'dart:io';
|
||||
import 'dart:math';
|
||||
import 'dart:typed_data';
|
||||
import 'package:test/test.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_camera.dart';
|
||||
import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_filament_app.dart';
|
||||
import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_material.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_swapchain.dart';
|
||||
import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_view.dart';
|
||||
import 'package:thermion_dart/thermion_dart.dart';
|
||||
import 'helpers.dart';
|
||||
|
||||
void checkMinMaxPixelValues(Float32List pixelBuffer, int width, int height) {
|
||||
var minVal = 99999.0;
|
||||
var maxVal = 0.0;
|
||||
for (var y = 0; y < height; y++) {
|
||||
for (var x = 0; x < width; x++) {
|
||||
for (int i = 0; i < 3; i++) {
|
||||
final srcIndex = (y * width * 4) + (x * 4) + i;
|
||||
if (pixelBuffer[srcIndex] == 0) {
|
||||
continue;
|
||||
}
|
||||
minVal = min(minVal, pixelBuffer[srcIndex]);
|
||||
maxVal = max(maxVal, pixelBuffer[srcIndex]);
|
||||
}
|
||||
}
|
||||
}
|
||||
print("minVal $minVal maxVal $maxVal");
|
||||
}
|
||||
|
||||
void main() async {
|
||||
final testHelper = TestHelper("depth");
|
||||
await testHelper.setup();
|
||||
|
||||
test('write depth value to R32F texture', () async {
|
||||
final viewportDimensions = (width: 512, height: 512);
|
||||
var swapChain = await FilamentApp.instance!.createHeadlessSwapChain(
|
||||
viewportDimensions.width, viewportDimensions.height) as FFISwapChain;
|
||||
|
||||
var color = await FilamentApp.instance!
|
||||
.createTexture(viewportDimensions.width, viewportDimensions.height,
|
||||
flags: {
|
||||
TextureUsage.TEXTURE_USAGE_BLIT_SRC,
|
||||
TextureUsage.TEXTURE_USAGE_COLOR_ATTACHMENT,
|
||||
TextureUsage.TEXTURE_USAGE_SAMPLEABLE
|
||||
},
|
||||
textureFormat: TextureFormat.R32F);
|
||||
|
||||
var renderTarget = await FilamentApp.instance!.createRenderTarget(
|
||||
viewportDimensions.width, viewportDimensions.height, color: color)
|
||||
as FFIRenderTarget;
|
||||
|
||||
var view = await FilamentApp.instance!.createView() as FFIView;
|
||||
await view.setPostProcessing(false);
|
||||
await view.setRenderTarget(renderTarget);
|
||||
|
||||
await FilamentApp.instance!.setClearOptions(0.0, 1.0, 0.0, 1.0);
|
||||
var scene = await FilamentApp.instance!.createScene() as FFIScene;
|
||||
|
||||
await view.setScene(scene);
|
||||
await view.setViewport(viewportDimensions.width, viewportDimensions.height);
|
||||
final camera = FFICamera(
|
||||
await withPointerCallback<TCamera>((cb) =>
|
||||
Engine_createCameraRenderThread(FilamentApp.instance!.engine, cb)),
|
||||
FilamentApp.instance! as FFIFilamentApp);
|
||||
|
||||
await camera.setLensProjection();
|
||||
|
||||
await view.setCamera(camera);
|
||||
|
||||
await view.setFrustumCullingEnabled(false);
|
||||
await camera.setLensProjection(near: 0.5, far: 10);
|
||||
final dist = 2.0;
|
||||
await camera.lookAt(
|
||||
Vector3(
|
||||
-0.5,
|
||||
dist,
|
||||
dist,
|
||||
),
|
||||
);
|
||||
|
||||
var mat = await FilamentApp.instance!.createMaterial(
|
||||
File(
|
||||
"/Users/nickfisher/Documents/thermion/materials/linear_depth.filamat",
|
||||
).readAsBytesSync(),
|
||||
);
|
||||
var mi = await mat.createInstance();
|
||||
await mi.setDepthCullingEnabled(true);
|
||||
await mi.setDepthWriteEnabled(true);
|
||||
await mi.setCullingMode(CullingMode.BACK);
|
||||
|
||||
var umi = await FilamentApp.instance!
|
||||
.createUbershaderMaterialInstance(unlit: true);
|
||||
var cube = await FilamentApp.instance!
|
||||
.createGeometry(GeometryHelper.cube(), nullptr);
|
||||
await scene.add(cube as FFIAsset);
|
||||
await umi.setParameterFloat4("baseColorFactor", 1, 1, 1, 0);
|
||||
|
||||
await cube.setTransform(
|
||||
Matrix4.compose(Vector3.zero(), Quaternion.identity(), Vector3.all(1)));
|
||||
await cube.setMaterialInstanceAt(mi as FFIMaterialInstance);
|
||||
await FilamentApp.instance!.register(swapChain, view);
|
||||
var pixelBuffers = await testHelper.capture(null, "linear_depth",
|
||||
swapChain: swapChain, pixelDataFormat: PixelDataFormat.R);
|
||||
checkMinMaxPixelValues(pixelBuffers[view]!.buffer.asFloat32List(),
|
||||
viewportDimensions.width, viewportDimensions.height);
|
||||
});
|
||||
|
||||
test('check NDC depth value', () async {
|
||||
final viewportDimensions = (width: 512, height: 512);
|
||||
var swapChain = await FilamentApp.instance!.createHeadlessSwapChain(
|
||||
viewportDimensions.width, viewportDimensions.height) as FFISwapChain;
|
||||
|
||||
var color = await FilamentApp.instance!
|
||||
.createTexture(viewportDimensions.width, viewportDimensions.height,
|
||||
flags: {
|
||||
TextureUsage.TEXTURE_USAGE_BLIT_SRC,
|
||||
TextureUsage.TEXTURE_USAGE_COLOR_ATTACHMENT,
|
||||
TextureUsage.TEXTURE_USAGE_SAMPLEABLE
|
||||
},
|
||||
textureFormat: TextureFormat.R32F);
|
||||
|
||||
var renderTarget = await FilamentApp.instance!.createRenderTarget(
|
||||
viewportDimensions.width, viewportDimensions.height, color: color)
|
||||
as FFIRenderTarget;
|
||||
|
||||
var view = await FilamentApp.instance!.createView() as FFIView;
|
||||
await view.setPostProcessing(false);
|
||||
await view.setRenderTarget(renderTarget);
|
||||
|
||||
await FilamentApp.instance!.setClearOptions(0.0, 1.0, 0.0, 1.0);
|
||||
var scene = await FilamentApp.instance!.createScene() as FFIScene;
|
||||
|
||||
await view.setScene(scene);
|
||||
await view.setViewport(viewportDimensions.width, viewportDimensions.height);
|
||||
final camera = FFICamera(
|
||||
await withPointerCallback<TCamera>((cb) =>
|
||||
Engine_createCameraRenderThread(FilamentApp.instance!.engine, cb)),
|
||||
FilamentApp.instance! as FFIFilamentApp);
|
||||
|
||||
await camera.setLensProjection();
|
||||
|
||||
await view.setCamera(camera);
|
||||
|
||||
await view.setFrustumCullingEnabled(false);
|
||||
await camera.setLensProjection(near: 0.5, far: 10);
|
||||
final dist = 3.0;
|
||||
await camera.lookAt(
|
||||
Vector3(
|
||||
-0.5,
|
||||
dist,
|
||||
dist,
|
||||
),
|
||||
);
|
||||
|
||||
var mat = await FilamentApp.instance!.createMaterial(
|
||||
File(
|
||||
"/Users/nickfisher/Documents/thermion/materials/ndc_depth.filamat",
|
||||
).readAsBytesSync(),
|
||||
);
|
||||
var mi = await mat.createInstance();
|
||||
await mi.setDepthCullingEnabled(true);
|
||||
await mi.setDepthWriteEnabled(true);
|
||||
await mi.setCullingMode(CullingMode.BACK);
|
||||
|
||||
var umi = await FilamentApp.instance!
|
||||
.createUbershaderMaterialInstance(unlit: true);
|
||||
var cube = await FilamentApp.instance!
|
||||
.createGeometry(GeometryHelper.cube(), nullptr);
|
||||
await scene.add(cube as FFIAsset);
|
||||
await umi.setParameterFloat4("baseColorFactor", 1, 1, 1, 0);
|
||||
|
||||
await cube.setTransform(
|
||||
Matrix4.compose(Vector3.zero(), Quaternion.identity(), Vector3.all(1)));
|
||||
await cube.setMaterialInstanceAt(mi as FFIMaterialInstance);
|
||||
await FilamentApp.instance!.register(swapChain, view);
|
||||
var pixelBuffers = await testHelper.capture(null, "ndc_depth",
|
||||
swapChain: swapChain, pixelDataFormat: PixelDataFormat.R);
|
||||
checkMinMaxPixelValues(pixelBuffers[view]!.buffer.asFloat32List(),
|
||||
viewportDimensions.width, viewportDimensions.height);
|
||||
});
|
||||
|
||||
group('depth sampling', () {
|
||||
test("depth sampling", () async {
|
||||
await testHelper.withViewer((viewer) async {
|
||||
await FilamentApp.instance!.setClearOptions(0, 0, 0, 1,
|
||||
clearStencil: 0, discard: false, clear: true);
|
||||
final camera = await viewer.getActiveCamera();
|
||||
await camera.lookAt(Vector3(3, 3, 6));
|
||||
|
||||
final view = await testHelper.createView(testHelper.swapChain);
|
||||
await testHelper.withCube(
|
||||
viewer,
|
||||
(cube) async {
|
||||
var mat = await FilamentApp.instance!.createMaterial(
|
||||
File(
|
||||
"/Users/nickfisher/Documents/thermion/materials/depth_sampler.filamat",
|
||||
).readAsBytesSync(),
|
||||
);
|
||||
final mi = await mat.createInstance();
|
||||
|
||||
await viewer.addToScene(cube);
|
||||
final secondScene = await view.getScene();
|
||||
await secondScene.add(cube);
|
||||
|
||||
final sampler = await FilamentApp.instance!.createTextureSampler();
|
||||
final rt = await view.getRenderTarget();
|
||||
final color = await rt!.getColorTexture();
|
||||
final depth = await rt!.getDepthTexture();
|
||||
await mi.setParameterTexture(
|
||||
"depth",
|
||||
depth,
|
||||
await FilamentApp.instance!.createTextureSampler(
|
||||
compareMode: TextureCompareMode.COMPARE_TO_TEXTURE,
|
||||
),
|
||||
);
|
||||
await cube.setMaterialInstanceAt(mi);
|
||||
|
||||
await testHelper.capture(null, "depth_sampling1");
|
||||
},
|
||||
);
|
||||
}, createRenderTarget: true);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// group('projection', () {
|
||||
// test('project texture & UV unwrap', () async {
|
||||
// await testHelper.withViewer((viewer) async {
|
||||
// final camera = await viewer.getActiveCamera();
|
||||
// await viewer.view.setFrustumCullingEnabled(false);
|
||||
// await camera.setLensProjection(near: 0.01, far: 100);
|
||||
// final dist = 26.0;
|
||||
// await camera.lookAt(
|
||||
// Vector3(
|
||||
// -0.5,
|
||||
// dist,
|
||||
// dist,
|
||||
// ),
|
||||
// );
|
||||
// await FilamentApp.instance!
|
||||
// .unregister(testHelper.swapChain, viewer.view);
|
||||
|
||||
// await withView(testHelper.swapChain, viewer, (linearDepthView) async {
|
||||
// await withView(testHelper.swapChain, viewer, (manualDepthView) async {
|
||||
// await manualDepthView.setRenderOrder(1);
|
||||
// await linearDepthView.setRenderOrder(0);
|
||||
|
||||
// await viewer.view.setRenderOrder(2);
|
||||
// await withManualDepthMaterial(testHelper, viewer, (
|
||||
// manualDepthMi,
|
||||
// ) async {
|
||||
// await withSampledDepthMaterial(testHelper, viewer, (
|
||||
// sampledDepthMi,
|
||||
// ) async {
|
||||
// await sampledDepthMi.setParameterTexture(
|
||||
// "depth",
|
||||
// await (await manualDepthView.getRenderTarget())!
|
||||
// .getColorTexture(),
|
||||
// await FilamentApp.instance!.createTextureSampler());
|
||||
|
||||
// await withLinearDepthMaterial(testHelper, viewer, (
|
||||
// linearDepthMi,
|
||||
// ) async {
|
||||
// await withProjectionMaterial(testHelper, viewer, (
|
||||
// projectMi,
|
||||
// ) async {
|
||||
// await FilamentApp.instance!.setClearOptions(0, 0, 0, 1,
|
||||
// clearStencil: 0, discard: false, clear: true);
|
||||
// await testHelper.withCube(viewer, (cube2) async {
|
||||
// var ubershader = await cube2.getMaterialInstanceAt();
|
||||
// (await manualDepthView.getScene()).remove(cube2);
|
||||
// await ubershader.setParameterFloat4(
|
||||
// "baseColorFactor", 0.0, 1.0, 0.0, 1.0);
|
||||
// await cube2.setTransform(Matrix4.compose(
|
||||
// Vector3(-0.5, 0, -0.5),
|
||||
// Quaternion.identity(),
|
||||
// Vector3.all(1)));
|
||||
// await testHelper.withCube(viewer, (cube) async {
|
||||
// await cube.setTransform(Matrix4.compose(Vector3.zero(),
|
||||
// Quaternion.identity(), Vector3.all(1)));
|
||||
// var divisions = 1;
|
||||
// var ubershader = await cube.getMaterialInstanceAt();
|
||||
// await ubershader.setDepthCullingEnabled(true);
|
||||
// await ubershader.setDepthWriteEnabled(true);
|
||||
// await ubershader.setCullingMode(CullingMode.BACK);
|
||||
// await ubershader.setParameterInt("baseColorIndex", 0);
|
||||
|
||||
// await ubershader.setParameterTexture(
|
||||
// "baseColorMap",
|
||||
// await createTextureFromImage(testHelper),
|
||||
// await FilamentApp.instance!.createTextureSampler());
|
||||
|
||||
// // final color = await (await linearDepthView.getRenderTarget())!
|
||||
// // .getColorTexture();
|
||||
// // final depth = await (await manualDepthView.getRenderTarget())!
|
||||
// // .getColorTexture();
|
||||
|
||||
// // await projectMi.setParameterTexture("color", color,
|
||||
// // await FilamentApp.instance!.createTextureSampler());
|
||||
// // await projectMi.setParameterTexture("depth", depth,
|
||||
// // await FilamentApp.instance!.createTextureSampler());
|
||||
// // await projectMi.setDepthCullingEnabled(true);
|
||||
// // await projectMi.setParameterBool("useDepth", true);
|
||||
|
||||
// // for (int i = 0; i < divisions; i++) {
|
||||
// // await camera.lookAt(
|
||||
// // Vector3(
|
||||
// // sin(i / divisions * pi) * dist,
|
||||
// // dist,
|
||||
// // cos(i / divisions * pi) * dist,
|
||||
// // ),
|
||||
// // );
|
||||
// // await cube.setMaterialInstanceAt(manualDepthMi);
|
||||
|
||||
// var pixelBuffers = await testHelper
|
||||
// .capture(null, "project_texture_color",
|
||||
// beforeRender: (view) async {
|
||||
// if (view == linearDepthView) {
|
||||
// await cube.setMaterialInstanceAt(linearDepthMi);
|
||||
// } else if (view == manualDepthView) {
|
||||
// await cube.setMaterialInstanceAt(manualDepthMi);
|
||||
// } else {
|
||||
// throw Exception();
|
||||
// }
|
||||
// });
|
||||
// // var comparison = comparePixelBuffers(
|
||||
// // pixelBuffers[1], pixelBuffers[2], 512, 512);
|
||||
// // savePixelBufferToBmp(comparison, 512, 512, "cmparison");
|
||||
// // await cube.setMaterialInstanceAt(ubershader);
|
||||
// checkRedFromRGBAPixelBuffer(
|
||||
// pixelBuffers[manualDepthView]!
|
||||
// .buffer
|
||||
// .asFloat32List(),
|
||||
// 512,
|
||||
// 512);
|
||||
// // }
|
||||
// });
|
||||
// });
|
||||
// });
|
||||
// });
|
||||
// });
|
||||
// });
|
||||
// });
|
||||
// });
|
||||
// }, createRenderTarget: true);
|
||||
// });
|
||||
// });
|
||||
// }
|
||||
|
||||
// final projectedImage = await viewer.createImage(512, 512, 4);
|
||||
// final data = await projectedImage.getData();
|
||||
// data.setRange(0, data.length, floatPixelBuffer);
|
||||
// final projectedTexture = await FilamentApp.instance!.createTexture(
|
||||
// 512,
|
||||
// 512,
|
||||
// textureFormat: TextureFormat.RGBA32F,
|
||||
// );
|
||||
// await projectedTexture.setLinearImage(
|
||||
// projectedImage,
|
||||
// PixelDataFormat.RGBA,
|
||||
// PixelDataType.FLOAT,
|
||||
// );
|
||||
|
||||
// await ubershader.setParameterTexture(
|
||||
// "baseColorMap",
|
||||
// projectedTexture,
|
||||
// sampler,
|
||||
// );
|
||||
// await object.setMaterialInstanceAt(ubershader);
|
||||
// await testHelper.capture(
|
||||
// viewer,
|
||||
// "retextured_${key}_$i",
|
||||
// renderTarget: rt,
|
||||
// );
|
||||
// await resetMaterial();
|
||||
// }
|
||||
// await viewer.destroyAsset(object);
|
||||
// }
|
||||
// });
|
||||
// });
|
||||
// });
|
||||
// });
|
||||
// });
|
||||
// }
|
||||
40
thermion_dart/test/postprocessing_tests.dart
Normal file
40
thermion_dart/test/postprocessing_tests.dart
Normal file
@@ -0,0 +1,40 @@
|
||||
@Timeout(const Duration(seconds: 600))
|
||||
import 'package:test/test.dart';
|
||||
import 'package:thermion_dart/src/filament/src/light_options.dart';
|
||||
import 'package:thermion_dart/thermion_dart.dart';
|
||||
|
||||
import 'helpers.dart';
|
||||
|
||||
void main() async {
|
||||
final testHelper = TestHelper("postprocessing");
|
||||
await testHelper.setup();
|
||||
group("assets", () {
|
||||
test('enable/disable postprocessing', () async {
|
||||
await testHelper.withViewer((viewer) async {
|
||||
await viewer.setBackgroundColor(1.0, 0.0, 0.0, 1.0);
|
||||
await testHelper.capture(viewer.view, "empty_scene_no_postprocessing");
|
||||
await viewer.setPostProcessing(true);
|
||||
await testHelper.capture(viewer.view, "empty_scene_postprocessing");
|
||||
}, postProcessing: false, createRenderTarget: true);
|
||||
});
|
||||
|
||||
test('bloom', () async {
|
||||
await testHelper.withViewer((viewer) async {
|
||||
await FilamentApp.instance!.setClearOptions(1, 1, 1, 1, clear: false);
|
||||
var asset = await viewer
|
||||
.loadGltf("file://${testHelper.testDir}/assets/cube.glb");
|
||||
var light = await viewer.addDirectLight(
|
||||
DirectLight.point(intensity: 1000000, falloffRadius: 10));
|
||||
await viewer.setLightPosition(light, 1, 2, 2);
|
||||
await viewer.setBloom(false, 0.5);
|
||||
await testHelper.capture(viewer.view, "postprocessing_no_bloom");
|
||||
await viewer.setBloom(true, 0.5);
|
||||
await testHelper.capture(viewer.view, "postprocessing_bloom_0.5");
|
||||
await viewer.setBloom(true, 1.0);
|
||||
await testHelper.capture(viewer.view, "postprocessing_bloom_1.0");
|
||||
}, postProcessing: true, createRenderTarget: true, bg: kBlue);
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user