Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
d47f656
Merge branch 'update-main' into 'main'
lilleyse Feb 19, 2025
603116c
Merge remote-tracking branch 'upstream/main' into update-main
j9liu Mar 3, 2025
3e99096
Merge remote-tracking branch 'upstream/more-metadata-reorg' into upda…
j9liu Mar 6, 2025
d07af74
Merge remote-tracking branch 'upstream/more-metadata-reorg' into upda…
j9liu Mar 6, 2025
6b44d96
Add metadata component and shader
j9liu Mar 6, 2025
828cd43
Add barebones glTF voxel component
j9liu Mar 6, 2025
f9366e9
Add rendering architecture for voxels
j9liu Mar 6, 2025
c7a4b0d
Implement load pipeline, add material files
j9liu Mar 7, 2025
cb3a0e1
Support connection remapping, fix property bug
j9liu Mar 7, 2025
3110cf1
Add missing line
j9liu Mar 7, 2025
2d49893
Feedback from review
j9liu May 12, 2025
a35b1f0
Merge branch 'main' of https://github.com/CesiumGS/cesium-unreal
j9liu May 15, 2025
e457c44
Merge branch 'main' into basic-voxel-support
j9liu May 19, 2025
4043265
Merge branch 'main' into basic-voxel-support
j9liu May 29, 2025
86e9a15
Update cesium-native
j9liu May 29, 2025
4871a1d
Update for changes in cesium-native and other bugs
j9liu May 30, 2025
5ae3b8f
Simplify voxel material/shader for review.
j9liu Jun 2, 2025
8cb8185
Pass on cleanup, correctness, etc.
j9liu Jun 3, 2025
ebb5b69
Merge branch 'property-attributes' into basic-voxel-support
j9liu Jun 9, 2025
f7e80a3
Refactor to use PropertyAttributeProperty
j9liu Jun 11, 2025
714a0b6
Implement direct copy method
j9liu Jun 12, 2025
3a3665a
Fold VoxelResources into component, add fences, fix pointers
j9liu Jun 17, 2025
d41d68c
Delete files
j9liu Jun 17, 2025
6f9637c
Remove custom texture resource implementations
j9liu Jun 17, 2025
bf11646
Add fence to VoxelOctree, other edits
j9liu Jun 18, 2025
ea3b491
Add WIP destroy checks
j9liu Jun 26, 2025
f38741f
Add polling behavior for proper octree updates
j9liu Jun 26, 2025
59e8b37
Fix extra destroy bug
j9liu Jun 27, 2025
a4830d8
Merge branch 'main' into basic-voxel-support
j9liu Jul 2, 2025
739298a
Merge branch 'property-attributes' into basic-voxel-support
j9liu Jul 2, 2025
d5494f2
Fix weird memory corruption errors
j9liu Jul 2, 2025
526d358
Merge branch 'property-attributes' into basic-voxel-support
j9liu Jul 3, 2025
8fbf9fd
Cleanup
j9liu Jul 3, 2025
ed28637
Use different native commit
j9liu Jul 3, 2025
d52a0f9
Refactor megatextures to use known tile count
j9liu Jul 3, 2025
cf8701a
Formatting and minor tweaks
j9liu Jul 3, 2025
b991b71
Refactor shaders
j9liu Jul 9, 2025
5aa80eb
Improve shader documention [skip ci]
j9liu Jul 9, 2025
13252d8
Merge branch 'main' into basic-voxel-support
j9liu Jul 9, 2025
bc36cde
Attempt to fix CI
j9liu Jul 9, 2025
ebb5282
Fix CI errors for non-Windows
j9liu Jul 9, 2025
1d31423
More CI appeasement
j9liu Jul 10, 2025
dd65ade
Formatting and packaging fix
j9liu Jul 10, 2025
deef0ce
Fixes to voxel metadata component
j9liu Jul 14, 2025
cb3a77f
More voxel component fixes
j9liu Jul 14, 2025
c51f48c
Merge branch 'main' into basic-voxel-support
j9liu Aug 4, 2025
46f9c4b
Add missing header
j9liu Aug 8, 2025
eb73fa4
Merge branch 'main' into basic-voxel-support
j9liu Aug 20, 2025
13c3fc8
Merge branch 'main' into basic-voxel-support
j9liu Sep 3, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Change Log {#changes}

### ? - ?

##### Additions :tada:

- Added support for tilesets containing `3DTILES_content_voxels`. Voxel metadata can be styled with materials generated by `UCesiumVoxelMetadataComponent`.

### v2.19.1 - 2025-09-02

##### Fixes :wrench:
Expand Down
Binary file added Content/Materials/Instances/MI_CesiumVoxel.uasset
Binary file not shown.
Binary file added Content/Materials/Layers/ML_CesiumVoxel.uasset
Binary file not shown.
68 changes: 68 additions & 0 deletions Shaders/Private/CesiumBox.usf
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
#pragma once

// Copyright 2020-2025 CesiumGS, Inc. and Contributors

/*=============================================================================
CesiumBox.usf: An implicit box shape that may be intersected by a ray.
=============================================================================*/

#include "CesiumRayIntersection.usf"

struct Box
{
float3 MinBounds;
float3 MaxBounds;

/**
* Tests whether the input ray (Unit Space) intersects the box. Outputs the intersections in Unit Space.
*/
RayIntersections Intersect(in Ray R)
{
// Consider the box as the intersection of the space between 3 pairs of parallel planes.

// Compute the distance along the ray to each plane.
float3 t0 = (MinBounds - R.Origin) / R.Direction;
float3 t1 = (MaxBounds - R.Origin) / R.Direction;

// Identify candidate entries/exits based on distance from ray position.
float3 entries = min(t0, t1);
float3 exits = max(t0, t1);

// The actual intersection points are the furthest entry and the closest exit.
// Do not allow intersections to go behind the shape (negative t).
RayIntersections result = (RayIntersections) 0;
float entryT = max(MaxComponent(entries), 0);
float exitT = max(MinComponent(exits), 0);

if (entryT > exitT)
{
Intersection miss = NewMissedIntersection();
return NewRayIntersections(miss, miss);
}

// Compute normals
float3 directions = sign(R.Direction);
bool3 isLastEntry = bool3(Equal(entries, float3(entryT, entryT, entryT)));
result.Entry.Normal = -1.0 * float3(isLastEntry) * directions;
result.Entry.t = entryT;

bool3 isFirstExit = bool3(Equal(exits, float3(exitT, exitT, exitT)));
result.Exit.Normal = float3(isFirstExit) * directions;
result.Exit.t = exitT;

return result;
}

/**
* Converts the input position (vanilla UV Space) to its Shape UV Space relative to the
* box geometry. Also outputs the Jacobian transpose for future use.
*/
float3 ConvertUVToShapeUVSpace(in float3 PositionUV, out float3x3 JacobianT)
{
// For Box, Cartesian UV space = UV shape space, so we can use PositionUV as-is.
// The Jacobian is the identity matrix, except that a step of 1 only spans half the shape
// space [-1, 1], so the identity is scaled.
JacobianT = float3x3(0.5f, 0, 0, 0, 0.5f, 0, 0, 0, 0.5f);
return PositionUV;
}
};
103 changes: 103 additions & 0 deletions Shaders/Private/CesiumRayIntersection.usf
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
#pragma once

// Copyright 2020-2025 CesiumGS, Inc. and Contributors

/*===========================
CesiumRayIntersection.usf: Ray-intersection definitions and utility.
=============================*/

#include "CesiumShaderConstants.usf"
#include "CesiumVectorUtility.usf"

#define NO_HIT -CZM_INFINITY
#define INF_HIT (CZM_INFINITY * 0.5)

struct Ray
{
float3 Origin;
float3 Direction;
};

struct Intersection
{
float t;
float3 Normal;
};

// Represents where a ray enters and leaves a volume.
struct RayIntersections
{
Intersection Entry;
Intersection Exit;
};

Intersection NewMissedIntersection()
{
Intersection result = (Intersection) 0;
result.t = NO_HIT;
return result;
}

Intersection NewIntersection(float t, float3 Normal)
{
Intersection result = (Intersection) 0;
result.t = t;
result.Normal = Normal;
return result;
}

RayIntersections NewRayIntersections(Intersection Entry, Intersection Exit)
{
RayIntersections result = (RayIntersections) 0;
result.Entry = Entry;
result.Exit = Exit;
return result;
}

Intersection Min(in Intersection A, in Intersection B)
{
if (A.t <= B.t)
{
return A;
}
return B;
}

Intersection Max(in Intersection A, in Intersection B)
{
if (A.t >= B.t)
{
return A;
}
return B;
}

Intersection Multiply(in Intersection intersection, in float scalar)
{
return NewIntersection(intersection.t * scalar, intersection.Normal * scalar);
}

/*
* Resolves two intersection ranges of the ray by computing their overlap.
* For example:
* A |---------|
* B |-------------|
* Ray: O =========================>
* Output: |---|
*/
RayIntersections ResolveIntersections(in RayIntersections A, in RayIntersections B)
{
bool missed = (A.Entry.t == NO_HIT) || (B.Entry.t == NO_HIT) ||
(A.Exit.t < B.Entry.t) || (A.Entry.t > B.Exit.t);

if (missed)
{
Intersection miss = NewMissedIntersection();
return NewRayIntersections(miss, miss);
}

Intersection entry = Max(A.Entry, B.Entry);
Intersection exit = Min(A.Exit, B.Exit);

return NewRayIntersections(entry, exit);
}
10 changes: 10 additions & 0 deletions Shaders/Private/CesiumShaderConstants.usf
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// Copyright 2020-2024 CesiumGS, Inc. and Contributors

/*===========================
CesiumShaderConstants.usf: Definitions of common constants for Cesium shaders.
=============================*/

#define CZM_INFINITY 5906376272000.0 // Distance from the Sun to Pluto in meters.
#define CZM_PI_OVER_TWO 1.5707963267948966
#define CZM_PI 3.141592653589793
#define CZM_TWO_PI 6.283185307179586
98 changes: 98 additions & 0 deletions Shaders/Private/CesiumShape.usf
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
#pragma once

// Copyright 2020-2025 CesiumGS, Inc. and Contributors

/*=============================================================================
CesiumShape.usf: An implicit shape that can be intersected by a ray.
=============================================================================*/

#include "CesiumShapeConstants.usf"
#include "CesiumBox.usf"

/**
* Converts a position from Unit Shape Space coordinates to UV Space.
* [-1, -1] => [0, 1]
*/
float3 UnitToUV(float3 UnitPosition)
{
return 0.5 * UnitPosition + 0.5;
}

/**
* Converts a position from UV Space coordinates to Unit Shape Space.
* [0, 1] => [-1, -1]
*/
float3 UVToUnit(float3 UVPosition)
{
return 2.0 * UVPosition - 1.0;
}

struct Shape
{
int ShapeConstant;
Box BoxShape;

/**
* Interpret the input parameters according to the voxel grid shape.
*/
void Initialize(in int InShapeConstant)
{
ShapeConstant = InShapeConstant;

if (ShapeConstant == BOX)
{
// Initialize with default unit box bounds.
BoxShape.MinBounds = -1;
BoxShape.MaxBounds = 1;
}
}

/**
* Tests whether the input ray (Unit Space) intersects the shape.
*/
RayIntersections Intersect(in Ray R)
{
RayIntersections result;

[branch]
switch (ShapeConstant)
{
case BOX:
result = BoxShape.Intersect(R);
break;
default:
return NewRayIntersections(NewMissedIntersection(), NewMissedIntersection());
}

// Set start to 0.0 when ray is inside the shape.
result.Entry.t = max(result.Entry.t, 0.0);

return result;
}

/**
* Scales the input UV coordinates from [0, 1] to their values in UV Shape Space.
*/
float3 ScaleUVToShapeUVSpace(in float3 UV)
{
// This is trivial for boxes, but will become relevant for more complex shapes.
return UV;
}

/**
* Converts the input position (vanilla UV Space) to its Shape UV Space relative to the
* voxel grid geometry. Also outputs the Jacobian transpose for future use.
*/
float3 ConvertUVToShapeUVSpace(in float3 UVPosition, out float3x3 JacobianT)
{
switch (ShapeConstant)
{
case BOX:
return BoxShape.ConvertUVToShapeUVSpace(UVPosition, JacobianT);
default:
// Default return
JacobianT = float3x3(1, 0, 0, 0, 1, 0, 0, 0, 1);
return UVPosition;
}
}
};
11 changes: 11 additions & 0 deletions Shaders/Private/CesiumShapeConstants.usf
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#pragma once

// Copyright 2020-2025 CesiumGS, Inc. and Contributors

/*=============================================================================
CesiumShapeConstants.usf: Constants for supported shape types. (See CesiumShape.usf)
=============================================================================*/

#define BOX 1
#define CYLINDER 2
#define ELLIPSOID 3
36 changes: 36 additions & 0 deletions Shaders/Private/CesiumVectorUtility.usf
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#pragma once

// Copyright 2020-2025 CesiumGS, Inc. and Contributors

/*===========================
CesiumVectorUtility.usf: General utility for handling vectors (e.g., float3s).
=============================*/

float MaxComponent(float3 v)
{
return max(max(v.x, v.y), v.z);
}

float MinComponent(float3 v)
{
return min(min(v.x, v.y), v.z);
}

bool3 Equal(float3 v1, float3 v2)
{
return bool3(v1.x == v2.x, v1.y == v2.y, v1.z == v2.z);
}

bool IsInRange(in float3 v, in float3 min, in float3 max)
{
bool3 inRange = (clamp(v, min, max) == v);
return inRange.x && inRange.y && inRange.z;
}

/**
* Construct an integer value (little endian) from two normalized uint8 values.
*/
int ConstructInt(in float2 value)
{
return int(value.x * 255.0) + (256 * int(value.y * 255.0));
}
Loading
Loading