Skip to content

Commit

Permalink
Failing test cases for emission from semi-transparent voxels.
Browse files Browse the repository at this point in the history
  • Loading branch information
kpreid committed Aug 17, 2024
1 parent e2fb463 commit f5ed049
Show file tree
Hide file tree
Showing 6 changed files with 63 additions and 9 deletions.
35 changes: 34 additions & 1 deletion all-is-cubes/src/block/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

#![allow(clippy::bool_assert_comparison)]

use euclid::Vector3D;
use pretty_assertions::assert_eq;

use crate::block::{
Expand All @@ -17,7 +18,7 @@ use crate::block::{
use crate::content::make_some_blocks;
use crate::listen::{self, NullListener, Sink};
use crate::math::{
notnan, Cube, Face6, FaceMap, GridAab, GridPoint, GridRotation, GridVector, NotNan,
notnan, Cube, Face6, FaceMap, GridAab, GridPoint, GridRotation, GridVector, Intensity, NotNan,
OpacityCategory, Rgb, Rgba, Vol,
};
use crate::space::{Space, SpaceTransaction};
Expand Down Expand Up @@ -280,6 +281,38 @@ mod eval {
);
}

/// Test that light emission from voxels doesn't depend on resolution, or rather, the emission
/// is taken as an intensive property rather than an extensive property.
#[test]
fn voxels_emission_equivalence() {
let mut universe = Universe::new();

let atom_emission = Rgb::new(1.0, 2.0, 3.0);
for reflectance in [Rgba::TRANSPARENT, Rgba::new(0.0, 0.5, 1.0, 0.5)] {
let atom = Block::builder()
.color(reflectance)
.light_emission(atom_emission)
.build();

for resolution in [R1, R2, R4, R32] {
let voxel_block = Block::builder()
.voxels_fn(resolution, |_| &atom)
.unwrap()
.build_into(&mut universe);

let total_emission = voxel_block.evaluate().unwrap().light_emission();
let difference: Vector3D<f32, Intensity> = (total_emission - atom_emission).into();
assert!(
difference.length() < 0.0001,
"reflectance = {reflectance:?}\n\
resolution = {resolution}\n\
expected = {atom_emission:?}\n\
actual = {total_emission:?}"
);
}
}
}

#[test]
fn transparent_voxels_simple() {
let mut universe = Universe::new();
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
37 changes: 29 additions & 8 deletions test-renderers/src/test_cases.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ pub fn all_tests(c: &mut TestCaseCollector<'_>) {
c.insert("cursor_basic", None, cursor_basic);
c.insert("emission", None, emission);
c.insert_variants("emission_only", &None, emission_only, ["surf", "vol"]);
c.insert_variants("emission_semi", &None, emission_semi, ["surf", "vol"]);
c.insert("error_character_gone", None, error_character_gone);
c.insert(
"error_character_unavailable",
Expand Down Expand Up @@ -296,17 +297,37 @@ async fn emission(mut context: RenderTestContext) {
.await;
}

/// Test rendering of emitted light from a block that is otherwise invisible.
async fn emission_only(mut context: RenderTestContext, transparency_option: &str) {
let mut universe = Universe::new();
let emissive_atom = Block::builder()
/// Test rendering of emitted light from atoms that are otherwise invisible.
async fn emission_only(context: RenderTestContext, transparency_option: &str) {
let atom = Block::builder()
.color(Rgba::TRANSPARENT)
.light_emission(Rgb::from_srgb8([0, 200, 0]))
.build();
let emissive_voxels = Block::builder()
voxel_shape_test(context, atom, transparency_option).await;
}

/// Test rendering of emitted light from atoms that are also semi-transparent.
async fn emission_semi(context: RenderTestContext, transparency_option: &str) {
let atom = Block::builder()
// pure black means we're dealing with only absorption, not reflection, which is simplifying
.color(Rgba::new(0.0, 0.0, 0.0, 1.0 - 2.0f32.powi(-3)))
.light_emission(Rgb::from_srgb8([0, 200, 0]))
.build();
voxel_shape_test(context, atom, transparency_option).await;
}

/// Test rendering of a specific atom in different shapes.
/// Used for testing emission rendering.
async fn voxel_shape_test(
mut context: RenderTestContext,
atom_block: Block,
transparency_option: &str,
) {
let mut universe = Universe::new();
let voxel_block = Block::builder()
.voxels_fn(R2, |cube| {
if cube.x == 0 || cube.y == 0 || cube.z == 0 {
&emissive_atom
&atom_block
} else {
&AIR
}
Expand All @@ -319,8 +340,8 @@ async fn emission_only(mut context: RenderTestContext, transparency_option: &str
.sky_color(Rgb::from_srgb8([0, 0, 127]))
.spawn(looking_at_one_cube_spawn(bounds))
.build();
space.set([-1, 0, 0], emissive_atom).unwrap();
space.set([1, 0, 0], emissive_voxels).unwrap();
space.set([-1, 0, 0], atom_block).unwrap();
space.set([1, 0, 0], voxel_block).unwrap();

finish_universe_from_space(&mut universe, space);

Expand Down

0 comments on commit f5ed049

Please sign in to comment.