Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Efficient CPU Translucency Sorting with BSP Trees and Heuristics #2016

Merged
merged 284 commits into from
Feb 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
284 commits
Select commit Hold shift + click to select a range
bd49744
refactor translucent data classes to re-use code
douira Sep 12, 2023
3158324
rough attempt at using index buffers
douira Sep 12, 2023
712b44b
comments
douira Sep 12, 2023
609ff79
temp things
douira Sep 16, 2023
a422a08
fix translucent data to use correct factor
douira Sep 16, 2023
eaf28dd
cleanup delete
douira Sep 16, 2023
cba72f4
fix indexed rendering
douira Sep 16, 2023
795087e
use manhattan distance for by distance vertex sorting
douira Sep 16, 2023
2b6b140
reeneable debugging disabled things
douira Sep 16, 2023
e95bbd3
fix sort order by rearranging centers,
douira Sep 16, 2023
ad391ee
Merge branch 'dev' into gfni
douira Sep 16, 2023
9219840
refactor tessellation method into two
douira Sep 16, 2023
12fb105
remove spammy print
douira Sep 16, 2023
42777d8
add sort tasks
douira Sep 16, 2023
5c59309
fix bit array out of bounds
douira Sep 16, 2023
6d7f036
gfni settings
douira Sep 16, 2023
0d724d9
better sort type and GFNI statistics
douira Sep 16, 2023
ca6594d
fix sort type counters
douira Sep 16, 2023
941c97b
refactor translucent data construction into the respective classes
douira Sep 16, 2023
3e652b1
fix static normal sorting
douira Sep 16, 2023
9ee5dca
fix memory leaks
douira Sep 17, 2023
5bbc235
javadoc
douira Sep 17, 2023
f23dd15
fix issues with sort behaviors
douira Sep 17, 2023
699d3c7
actually JiJ the interval tree dependency
douira Sep 17, 2023
54d4be7
rename camera pos parameter to clarify absolute
douira Sep 19, 2023
2aa2bf1
fix quads being interpreted in the wrong order,
douira Sep 19, 2023
7b8f7a1
use quad count directly when determining buffer size
douira Sep 20, 2023
48d2682
fix normal relative index buffer being wrong with offset of vertex st…
douira Sep 20, 2023
5885875
make translucency sorting options more user friendly
douira Sep 21, 2023
d3090ab
cleanup comments
douira Sep 21, 2023
42e8502
more cleanup
douira Sep 21, 2023
40f91db
better explanation in the settings
douira Sep 22, 2023
6999fa4
refactor sorting algorithms into their respective classes,
douira Sep 23, 2023
8ad7df5
skip inactive directions in topo sort
douira Sep 23, 2023
8327e3b
implement full graph topo sort
douira Sep 24, 2023
07559a1
fix issues with sorting 1-long sections
douira Sep 24, 2023
1cc32c5
remove end of list tracking
douira Sep 24, 2023
1684ac1
fix missing return that leads to buffer overflow
douira Sep 24, 2023
7a714e9
fully disable translucent sorting with option OFF
douira Sep 24, 2023
6c5e180
fix translucent data not being returned from builder threads
douira Sep 24, 2023
5197f26
explicitly use NONE and remove unnecessary enum field
douira Sep 24, 2023
d0e719e
add index buffer generation for sections where sorting doesn't matter
douira Sep 25, 2023
c1c3242
formatting
douira Sep 25, 2023
bf89a38
rename group builder to TranslucentGeometryCollector
douira Sep 25, 2023
198a438
comment
douira Sep 25, 2023
29e05c7
Merge branch 'dev' into gfni
douira Sep 25, 2023
24bbb4d
this appears to be an int to byte conversion and not qua to vertices
douira Sep 26, 2023
ffc3677
rename sort behavior to off, avoids confusion
douira Sep 26, 2023
c68f711
don't do comparisons of quads with themselves
douira Oct 2, 2023
70ea0e6
use sorted array of doubles instead of avl tree
douira Oct 2, 2023
a8ec8b6
use separator plane-based visibility graph refinement
douira Oct 3, 2023
81a62ab
implement and use depth first search sorting
douira Oct 6, 2023
1894154
do sorts immediately if they are close
douira Oct 6, 2023
2abc011
split tesselation deletion into two methods
douira Oct 9, 2023
c29428f
rename index buffer writing methods for clarity
douira Oct 10, 2023
c0d4606
rename last task time on render section to something more useful
douira Oct 10, 2023
20341da
fix issues with topo sort by introducing epsilon uncertainty
douira Oct 10, 2023
a0050e8
fix chunk task promotion
douira Oct 10, 2023
a8e9433
fix SNR sort order
douira Oct 13, 2023
2c5d97c
fix rendering corruption and index buffer generation,
douira Oct 13, 2023
692bd9a
make the bottom face of flowing liquids UNASSIGNED to fix translucenc…
douira Oct 13, 2023
8d7b9f5
make sorting non-dynamic data not an error
douira Oct 14, 2023
9b424a2
notes
douira Oct 17, 2023
f1590db
add cancellation opportunity right before translucent sorting
douira Oct 19, 2023
035000e
implement angle-based triggering as fallback, WIP
douira Oct 19, 2023
00e5756
use 20 degrees as a reasonable sorting threshold,
douira Oct 20, 2023
7c9ed48
combine vertex and index buffer storage management, WIP since broken atm
douira Oct 21, 2023
470890a
use neg y facing for water inside face if it's actually aligned
douira Oct 21, 2023
bb71f22
use separate buffer arenas for geometry and indices because their str…
douira Oct 21, 2023
8e7baef
documentation comments
douira Oct 21, 2023
0cf0783
implement better give-up heuristic for dynamic sort
douira Oct 21, 2023
2c058dd
fix quad visibility geometry
douira Oct 21, 2023
f74eb8a
better give up heuristic
douira Oct 21, 2023
e099aa8
fix not clearing trigger changes
douira Oct 21, 2023
6cf840a
Merge branch 'dev' into gfni
douira Oct 22, 2023
8c53247
update notes
douira Oct 22, 2023
6a1047e
use a new position vector every time
douira Oct 26, 2023
1099eb9
fix direct triggering and rename from angle triggering,
douira Oct 26, 2023
37d7ee5
rename is angle trigger to direct trigger
douira Oct 27, 2023
273ede4
reduce amount of work done in geometry collection
douira Oct 27, 2023
f91474c
more compact code
douira Oct 27, 2023
3fa6bd7
de-epsilon geometry for translucent sorting
douira Oct 27, 2023
efc122a
don't bother removing null data from gfni
douira Oct 28, 2023
96c0b19
delete job task outputs if they're discarded in output filtering
douira Oct 28, 2023
0b8f5c1
better info message when section fails to sort
douira Oct 28, 2023
d75cb68
refactor chunk build outputs to fix flaw in logic,
douira Oct 28, 2023
4338afb
fix issues with sort failures by falling back to dynamic
douira Oct 29, 2023
ab21da0
more consistent gfni statistics formatting
douira Nov 4, 2023
b292841
fix typo in contributing docs
douira Nov 4, 2023
f7279a0
enable separate index and vertex data handling
douira Nov 4, 2023
cc50496
fix the static topo sort heuristic to always attempt to sort small am…
douira Nov 4, 2023
a5475c7
use this. for instance method access
douira Nov 5, 2023
e571c36
cleanup unused code
douira Nov 5, 2023
166522b
refactor gfni and direct triggering into separate classes
douira Nov 6, 2023
ac3d1de
use a more reasonable linked list approach for direct trigger collisions
douira Nov 6, 2023
3e83520
documentation
douira Nov 7, 2023
9eef8fb
fix separator plane selection breaking
douira Nov 8, 2023
f86f80b
update documentation
douira Nov 8, 2023
cbee812
typo
douira Nov 16, 2023
88b6c09
Merge branch 'dev' into gfni
douira Nov 16, 2023
90462a9
rename gfni package to translucent_sorting
douira Nov 16, 2023
34361aa
fix separator condition
douira Nov 17, 2023
455dd9c
refactor fast sorting mode to not use static topo sorting at all
douira Nov 17, 2023
57535a6
fix concurrent modification of normal list map
douira Nov 17, 2023
0fc6573
fix slow initial sorts throwing off the heuristic,
douira Nov 17, 2023
244c7ae
keep distance sorting indices around for faster re-sorting,
douira Nov 17, 2023
84e4c3d
use better quad hashing algorithm
douira Nov 17, 2023
90d6f62
remove unused import
douira Nov 22, 2023
560693d
implement BSP tree sorting and integrate
douira Nov 24, 2023
3d51295
do gfni trigger before section update to avoid artifacts
douira Nov 24, 2023
4738b96
consistent formatting
douira Nov 24, 2023
a55c4bf
fix bug with interval tree sync with hash map
douira Nov 24, 2023
2d9d749
remove collector from bsp data constructor
douira Nov 24, 2023
06152c5
detect and ignore intersecting geometry
douira Nov 25, 2023
10456c6
no need to prefix inner classes
douira Nov 25, 2023
a3fc9f3
move special case for two quads to BSPNode
douira Nov 25, 2023
5257cc8
improve bsp build performance
douira Nov 25, 2023
9c009f8
update render section manager camera position so that sorting tasks h…
douira Nov 25, 2023
2ae3c62
better names for job collectors
douira Nov 25, 2023
a1b3862
limit number of intersection tests when bsp partitioning fails
douira Nov 25, 2023
53426bd
distance sort method is private
douira Nov 27, 2023
128406c
add two quad special case bsp node to avoid array allocation
douira Nov 28, 2023
75217fa
note on flat array optimization
douira Nov 28, 2023
2aabb0a
avoid allocating record objects by compressing interval points into a…
douira Nov 28, 2023
492503a
note that avoiding new points array allocations doesn't help
douira Nov 28, 2023
b5289da
all the axis offset depth
douira Nov 28, 2023
fd8c576
better name of trailing plane
douira Nov 28, 2023
e880b53
note that bucketization doesn't work
douira Nov 28, 2023
c600e8c
note on convex box test
douira Nov 28, 2023
f256bbc
Merge branch 'dev' into gfni
douira Nov 29, 2023
4f1fb35
improve performance of interval point sorting
douira Nov 29, 2023
437f768
make size conversion methods more accessible
douira Nov 30, 2023
a4d8473
remove unused class
douira Nov 30, 2023
06ae489
remove unused file
douira Nov 30, 2023
3493b89
deduplicate createRegionTessellation method
douira Nov 30, 2023
75b4733
fix model quad facing code alignment
douira Dec 1, 2023
0d9cb83
change the setting states off/reduced/accurate
douira Dec 1, 2023
83aaf42
update notes with findings
douira Dec 1, 2023
ae539a8
replace quantization with quad shrinking
douira Dec 2, 2023
2d5ee2c
impl notes, lazy sort doesn't work well
douira Dec 2, 2023
96b41f2
implement partial bsp tree updates
douira Dec 5, 2023
a25ee38
start partition on the y axis
douira Dec 5, 2023
07ba709
reinstane minimum node reuse threshold
douira Dec 5, 2023
bb6b623
fix quad hash code
douira Dec 5, 2023
7563bdd
only start preparing node reuse on the second build of a section
douira Dec 5, 2023
9cefff3
note for a rare bug
douira Dec 5, 2023
1cd003b
add missing prepare node reuse flag
douira Dec 5, 2023
4eafa13
Merge branch 'dev' into gfni
douira Dec 5, 2023
a14c2d9
Merge branch 'dev' into gfni
douira Dec 5, 2023
1dc97f3
index array compression
douira Dec 6, 2023
c18520a
fix compression of indexes in node reuse
douira Dec 7, 2023
f1cff76
Update fabric.mod.json
jellysquid3 Dec 8, 2023
629eef1
Merge branch 'dev' into gfni
douira Dec 9, 2023
ca94675
Merge branch 'dev' into gfni
douira Dec 10, 2023
1a447b8
fix translucent rendering in previously empty sections
douira Dec 10, 2023
d2c3167
use euclidean distance for vertex sorting,
douira Dec 10, 2023
81e6513
fix trigger planes of reused nodes missing from the new bsp workspace…
douira Dec 10, 2023
f446ea1
formatting
douira Dec 10, 2023
8268ef6
fix various small compression related bugs
douira Dec 11, 2023
1409949
remove debug logging
douira Dec 11, 2023
8f244a1
enable compression on reuse index data
douira Dec 11, 2023
3bfe91d
fix more issues with compression and node reuse.
douira Dec 12, 2023
cccb206
notes on possible optimization to direct sorting
douira Dec 15, 2023
90c3632
also add the child nodes partition distances to the workspace for tri…
douira Dec 15, 2023
60e1216
note that coplanar quad detection doesn't work
douira Dec 16, 2023
c5ff99a
note on why there is compression min length
douira Dec 16, 2023
94a52a0
fix direct trigger angle calculation, tune thresholds
douira Dec 16, 2023
1907cdd
clarify comments and todos
douira Dec 16, 2023
97b3854
make the intersecting quad test more lenient
douira Dec 16, 2023
7b19249
cleanup resolved todos and todos that are tracked elsewhere
douira Dec 17, 2023
4ae774e
fix imports
douira Dec 17, 2023
11d2bc6
remove reuse of index data (doesn't appear to help) and
douira Dec 17, 2023
db94236
remove scanning topo sort,
douira Dec 17, 2023
58b7b34
refactor translucent geometry collection and remove unnecessary changes,
douira Dec 20, 2023
0f0ef22
rename TranslucentSorting to SortTriggering and some field names
douira Dec 20, 2023
450c9b1
fix distance sort to sort distance descending
douira Dec 20, 2023
df31c70
clean up todos and comments, add some javadoc
douira Dec 22, 2023
7f1d340
use proper logger for bsp build failures
douira Dec 22, 2023
a6f3fe0
fix naming and comments
douira Dec 22, 2023
b96977b
fix quantized normal normalization (to make unit normal)
douira Dec 22, 2023
16c24cf
fix aligned facing bitmap
douira Dec 22, 2023
63bff3a
Merge branch 'dev' into gfni
douira Dec 22, 2023
939159a
fix mod json messed up by upstream force push
douira Dec 22, 2023
5ff8740
rename and clean up sort types, fix reduced sorting
douira Dec 22, 2023
0413472
display current sorting mode in debug info
douira Dec 22, 2023
4f8e721
remove todo about indium compat as it's fixed
douira Dec 22, 2023
c10f822
documentation
douira Dec 22, 2023
49c551e
indexed rendering cleanup minor details
douira Dec 23, 2023
80c2a4d
don't submit tasks if sections are not in a matching queue, potential…
douira Dec 24, 2023
f02a17e
change when what jobs are scheduled, fixes flawless frames, makes imp…
douira Dec 24, 2023
70d2f5e
reorder RSM to be more coherent
douira Dec 25, 2023
97c108f
add option to control how much sorting is deferred
douira Dec 25, 2023
bb3098c
defer sorting feels like medium impact
douira Dec 25, 2023
94d83c3
fix float sorting in SNR
douira Dec 25, 2023
c81f53a
remove unused mixed and split direction data fields
douira Dec 25, 2023
8ff7cfe
remove unused vertex sorters code
douira Dec 25, 2023
405e922
unused import
douira Dec 25, 2023
9873b05
formatting
douira Dec 25, 2023
deeaa6f
fix snr sorting
douira Dec 25, 2023
04ee500
static topo sort is taken care of by heuristic already
douira Dec 25, 2023
ba00170
add sort defer mode to debug string
douira Dec 25, 2023
9376d9c
clearly label as absolute camera pos in meshing task
douira Dec 26, 2023
9dc0eac
catch up rebuilt sections on movement that happened during their buil…
douira Dec 26, 2023
ac0d986
cleanup comment
douira Dec 26, 2023
ef490ba
avoid NPE when a section doesn't have all normals
douira Dec 26, 2023
f7c84b0
fix SNR sorting by handling negative zero dot products
douira Dec 27, 2023
d411598
comment on why float.compare is necessary
douira Dec 28, 2023
f9121f3
fix sections going missing in rare scenarios where the dynamic data o…
douira Dec 28, 2023
dad0063
fix wrong assumption about null jobs
douira Dec 28, 2023
83ab7d2
fix display of chunk queues with sort task types
douira Jan 3, 2024
b9865b5
Merge branch 'dev' into gfni
douira Jan 4, 2024
7899b93
allow scheduling more sort tasks, broken on world load (too many NONE…
douira Jan 5, 2024
0af463d
only mark as needing a graph update if the uploads could have changed…
douira Jan 8, 2024
f10dfba
use radix sort for sorting large arrays,
douira Jan 14, 2024
fd42f5f
fix box test heuristic
douira Jan 14, 2024
497d1ff
fix wrong handling of array lengths in SNR
douira Jan 15, 2024
2bb135c
Merge branch 'dev' into gfni
douira Jan 18, 2024
e0e8f47
Merge branch 'dev' into gfni
douira Jan 20, 2024
4eb2be9
Merge branch 'dev' into gfni
douira Jan 23, 2024
864ff12
expand sort type to differentiate between the three different NONE si…
douira Jan 24, 2024
04a3979
remove unused field in sort type enum
douira Jan 24, 2024
8da93ae
Merge branch 'gfni' into gfni-sort-scheduling-changes
douira Jan 24, 2024
c7141ee
add setting options to customize defer mode
douira Jan 25, 2024
a410311
implement separate effort categories to fix issues when thread count …
douira Jan 25, 2024
ab364cf
remove debug print
douira Jan 25, 2024
79f1ee8
fix unlimited budget collectors having integer overlow
douira Jan 25, 2024
d14571c
simplify sort settings without removing options
douira Jan 26, 2024
bffe18d
typo
douira Jan 26, 2024
ae789c2
make translucency sorting a binary option
douira Jan 26, 2024
875cc61
fix javadoc
douira Jan 28, 2024
b1e9c7e
Merge branch 'dev' into gfni
douira Jan 28, 2024
91c8b9a
fix merge
douira Jan 28, 2024
3a0be73
use remove if instead
douira Jan 28, 2024
30d689a
fix buildscript
douira Jan 28, 2024
a8a0c6b
fix javadoc
douira Jan 29, 2024
cca2fe2
Merge branch 'dev' into gfni
douira Jan 29, 2024
aac4478
fix javadoc, missing this. qualifiers, fix use of sort mode
douira Jan 29, 2024
b0c8510
Merge branch 'dev' into gfni
douira Jan 31, 2024
8a857dc
Migrate to official mappings
embeddedt Feb 2, 2024
d04025f
Merge remote-tracking branch 'embeddedt/fabric/mojmap' into gfni-mojm…
douira Feb 6, 2024
a0b7b17
fix INorm8.isOpposite being super wrong
douira Feb 9, 2024
69995bf
change handling of intersecting geometry, avoid some cases of UNASSIG…
douira Feb 9, 2024
05c6c48
fix including of interval tree dependency
douira Feb 9, 2024
03b6d24
static topo sorting within partition tree nodes avoids using the fall…
douira Feb 10, 2024
6338fee
typo
douira Feb 12, 2024
ce425b7
simplify control flow to be less confusing
douira Feb 12, 2024
a989f7e
package rename from me.jellysquid to net.caffeinemc to better match u…
douira Feb 12, 2024
032909f
Merge branch 'dev' into gfni-package-rename
douira Feb 12, 2024
bb1a241
reintroduce quadCount tracking in topo sort that went missing in the …
douira Feb 14, 2024
4176843
Clean-up handling of chunk draw command generation
jellysquid3 Feb 15, 2024
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
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ with some minor changes, as described below.
- If you are using more than three levels of indentation, you should likely consider restructuring your code.
- Branches which are only exceptionally or very rarely taken should remain concise. When this is not possible,
prefer breaking out to a new method (where it makes sense) as this helps the compiler better optimize the code.
- Use `this` to qualify member and field access, as it avoids some ambiguity in certain contexts.
- Use `this` to qualify method and field access, as it avoids some ambiguity in certain contexts.

We also provide these code styles as [EditorConfig](https://editorconfig.org/) files, which most Java IDEs will
automatically detect and make use of.
Expand Down
1 change: 1 addition & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ dependencies {
minecraft(group = "com.mojang", name = "minecraft", version = Constants.MINECRAFT_VERSION)
mappings(loom.officialMojangMappings())
modImplementation(group = "net.fabricmc", name = "fabric-loader", version = Constants.FABRIC_LOADER_VERSION)
include(implementation(group = "com.lodborg", name = "interval-tree", version = "1.0.0"))

fun addEmbeddedFabricModule(name: String) {
val module = fabricApi.module(name, Constants.FABRIC_API_VERSION)
Expand Down
40 changes: 38 additions & 2 deletions src/api/java/net/caffeinemc/mods/sodium/api/util/NormI8.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package net.caffeinemc.mods.sodium.api.util;

import net.minecraft.util.Mth;
import org.joml.Vector3f;
import org.joml.Vector3fc;

/**
* Provides some utilities for working with packed normal vectors. Each normal component provides 8 bits of
Expand All @@ -27,7 +27,7 @@ public class NormI8 {
*/
private static final float NORM = 1.0f / COMPONENT_RANGE;

public static int pack(Vector3f normal) {
public static int pack(Vector3fc normal) {
return pack(normal.x(), normal.y(), normal.z());
}

Expand Down Expand Up @@ -78,4 +78,40 @@ public static float unpackY(int norm) {
public static float unpackZ(int norm) {
return ((byte) ((norm >> Z_COMPONENT_OFFSET) & 0xFF)) * NORM;
}

/**
* Flips the direction of a packed normal by negating each component. (multiplication by -1)
* @param norm The packed normal
*/
public static int flipPacked(int norm) {
int normX = (((norm >> X_COMPONENT_OFFSET) & 0xFF) * -1) & 0xFF;
int normY = (((norm >> Y_COMPONENT_OFFSET) & 0xFF) * -1) & 0xFF;
int normZ = (((norm >> Z_COMPONENT_OFFSET) & 0xFF) * -1) & 0xFF;

return (normZ << Z_COMPONENT_OFFSET) | (normY << Y_COMPONENT_OFFSET) | (normX << X_COMPONENT_OFFSET);
}

/**
* Returns true if the two packed normals are opposite directions.
*
* TODO: this could possibly be faster by using normA == (~normB + 0x010101) but
* that has to special case when a component is zero since that wouldn't
* overflow correctly back to zero. (~0+1 == 0 but not if it's somewhere inside
* th int)
*
* @param normA The first packed normal
* @param normB The second packed normal
*/
public static boolean isOpposite(int normA, int normB) {
// use byte to automatically sign extend the components
byte normAX = (byte) (normA >> X_COMPONENT_OFFSET);
byte normAY = (byte) (normA >> Y_COMPONENT_OFFSET);
byte normAZ = (byte) (normA >> Z_COMPONENT_OFFSET);

byte normBX = (byte) (normB >> X_COMPONENT_OFFSET);
byte normBY = (byte) (normB >> Y_COMPONENT_OFFSET);
byte normBZ = (byte) (normB >> Z_COMPONENT_OFFSET);

return normAX == -normBX && normAY == -normBY && normAZ == -normBZ;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,17 @@ public static OptionPage performance() {
.build())
.build());

groups.add(OptionGroup.createBuilder()
.add(OptionImpl.createBuilder(boolean.class, sodiumOpts)
.setName(Component.translatable("sodium.options.sort_behavior.name"))
.setTooltip(Component.translatable("sodium.options.sort_behavior.tooltip"))
.setControl(TickBoxControl::new)
.setBinding((opts, value) -> opts.performance.sortingEnabled = value, opts -> opts.performance.sortingEnabled)
.setImpact(OptionImpact.LOW)
.setFlags(OptionFlag.REQUIRES_RENDERER_RELOAD)
.build())
.build());

return new OptionPage(Component.translatable("sodium.options.pages.performance"), ImmutableList.copyOf(groups));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import com.google.gson.annotations.SerializedName;
import net.caffeinemc.mods.sodium.client.gui.options.TextProvider;
import net.caffeinemc.mods.sodium.client.util.FileUtil;
import net.caffeinemc.mods.sodium.client.render.chunk.translucent_sorting.SortBehavior;
import net.fabricmc.loader.api.FabricLoader;
import net.minecraft.client.GraphicsStatus;
import net.minecraft.network.chat.Component;
Expand Down Expand Up @@ -44,6 +45,12 @@ public static class PerformanceSettings {
public boolean useFogOcclusion = true;
public boolean useBlockFaceCulling = true;
public boolean useNoErrorGLContext = true;

public boolean sortingEnabled = true;

public SortBehavior getSortBehavior() {
return this.sortingEnabled ? SortBehavior.DYNAMIC_DEFER_NEARBY_ONE_FRAME : SortBehavior.OFF;
}
}

public static class AdvancedSettings {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

public interface BakedQuadView extends ModelQuadView {
ModelQuadFacing getNormalFace();


int getNormal();

boolean hasShade();
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package net.caffeinemc.mods.sodium.client.model.quad;

import net.caffeinemc.mods.sodium.client.model.quad.properties.ModelQuadFlags;
import net.caffeinemc.mods.sodium.api.util.NormI8;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.core.Direction;

Expand Down Expand Up @@ -61,4 +62,43 @@ public interface ModelQuadView {
default boolean hasColor() {
return this.getColorIndex() != -1;
}

default int calculateNormal() {
final float x0 = getX(0);
final float y0 = getY(0);
final float z0 = getZ(0);

final float x1 = getX(1);
final float y1 = getY(1);
final float z1 = getZ(1);

final float x2 = getX(2);
final float y2 = getY(2);
final float z2 = getZ(2);

final float x3 = getX(3);
final float y3 = getY(3);
final float z3 = getZ(3);

final float dx0 = x2 - x0;
final float dy0 = y2 - y0;
final float dz0 = z2 - z0;
final float dx1 = x3 - x1;
final float dy1 = y3 - y1;
final float dz1 = z3 - z1;

float normX = dy0 * dz1 - dz0 * dy1;
float normY = dz0 * dx1 - dx0 * dz1;
float normZ = dx0 * dy1 - dy0 * dx1;

// normalize by length for the packed normal
float length = (float) Math.sqrt(normX * normX + normY * normY + normZ * normZ);
if (length != 0.0 && length != 1.0) {
normX /= length;
normY /= length;
normZ /= length;
}

return NormI8.pack(normX, normY, normZ);
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
package net.caffeinemc.mods.sodium.client.model.quad.properties;

import net.caffeinemc.mods.sodium.client.util.DirectionUtil;
import net.caffeinemc.mods.sodium.api.util.NormI8;
import net.minecraft.core.Direction;
import net.minecraft.util.Mth;
import org.joml.Math;
import org.joml.Vector3f;
import org.joml.Vector3fc;

import java.util.Arrays;

public enum ModelQuadFacing {
POS_X,
Expand All @@ -14,10 +22,28 @@ public enum ModelQuadFacing {
public static final ModelQuadFacing[] VALUES = ModelQuadFacing.values();

public static final int COUNT = VALUES.length;
public static final int DIRECTIONS = VALUES.length - 1;

public static final int NONE = 0;
public static final int ALL = (1 << COUNT) - 1;

public static final Vector3fc[] ALIGNED_NORMALS = new Vector3fc[] {
new Vector3f(1, 0, 0),
new Vector3f(0, 1, 0),
new Vector3f(0, 0, 1),
new Vector3f(-1, 0, 0),
new Vector3f(0, -1, 0),
new Vector3f(0, 0, -1),
};

public static final int[] PACKED_ALIGNED_NORMALS = Arrays.stream(ALIGNED_NORMALS)
.mapToInt(NormI8::pack)
.toArray();

public static final int OPPOSING_X = 1 << ModelQuadFacing.POS_X.ordinal() | 1 << ModelQuadFacing.NEG_X.ordinal();
public static final int OPPOSING_Y = 1 << ModelQuadFacing.POS_Y.ordinal() | 1 << ModelQuadFacing.NEG_Y.ordinal();
public static final int OPPOSING_Z = 1 << ModelQuadFacing.POS_Z.ordinal() | 1 << ModelQuadFacing.NEG_Z.ordinal();

public static ModelQuadFacing fromDirection(Direction dir) {
return switch (dir) {
case DOWN -> NEG_Y;
Expand All @@ -40,4 +66,58 @@ public ModelQuadFacing getOpposite() {
default -> UNASSIGNED;
};
}

public int getSign() {
return switch (this) {
case POS_Y, POS_X, POS_Z -> 1;
case NEG_Y, NEG_X, NEG_Z -> -1;
default -> 0;
};
}

public int getAxis() {
return switch (this) {
case POS_X, NEG_X -> 0;
case POS_Y, NEG_Y -> 1;
case POS_Z, NEG_Z -> 2;
default -> -1;
};
}

public boolean isAligned() {
return this != UNASSIGNED;
}

public Vector3fc getAlignedNormal() {
if (!this.isAligned()) {
throw new IllegalStateException("Cannot get aligned normal for unassigned facing");
}
return ALIGNED_NORMALS[this.ordinal()];
}

public int getPackedAlignedNormal() {
if (!this.isAligned()) {
throw new IllegalStateException("Cannot get packed aligned normal for unassigned facing");
}
return PACKED_ALIGNED_NORMALS[this.ordinal()];
}

public static ModelQuadFacing fromNormal(float x, float y, float z) {
if (!(Math.isFinite(x) && Math.isFinite(y) && Math.isFinite(z))) {
return ModelQuadFacing.UNASSIGNED;
}

for (Direction face : DirectionUtil.ALL_DIRECTIONS) {
var step = face.step();
if (Mth.equal(Math.fma(x, step.x(), Math.fma(y, step.y(), z * step.z())), 1.0f)) {
return ModelQuadFacing.fromDirection(face);
}
}

return ModelQuadFacing.UNASSIGNED;
}

public static ModelQuadFacing fromPackedNormal(int normal) {
return fromNormal(NormI8.unpackX(normal), NormI8.unpackY(normal), NormI8.unpackZ(normal));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import net.caffeinemc.mods.sodium.client.render.chunk.map.ChunkTracker;
import net.caffeinemc.mods.sodium.client.render.chunk.map.ChunkTrackerHolder;
import net.caffeinemc.mods.sodium.client.render.chunk.terrain.DefaultTerrainRenderPasses;
import net.caffeinemc.mods.sodium.client.render.chunk.translucent_sorting.trigger.CameraMovement;
import net.caffeinemc.mods.sodium.client.render.viewport.Viewport;
import net.caffeinemc.mods.sodium.client.util.NativeBuffer;
import net.caffeinemc.mods.sodium.client.world.LevelRendererExtension;
Expand All @@ -42,6 +43,8 @@
import java.util.Iterator;
import java.util.SortedSet;

import org.joml.Vector3d;

/**
* Provides an extension to vanilla's {@link LevelRenderer}.
*/
Expand All @@ -51,7 +54,7 @@ public class SodiumWorldRenderer {
private ClientLevel level;
private int renderDistance;

private double lastCameraX, lastCameraY, lastCameraZ;
private Vector3d lastCameraPos;
private double lastCameraPitch, lastCameraYaw;
private float lastFogDistance;

Expand Down Expand Up @@ -174,44 +177,50 @@ public void setupTerrain(Camera camera,
throw new IllegalStateException("Client instance has no active player entity");
}

Vec3 pos = camera.getPosition();
Vec3 posRaw = camera.getPosition();
Vector3d pos = new Vector3d(posRaw.x(), posRaw.y(), posRaw.z());
float pitch = camera.getXRot();
float yaw = camera.getYRot();
float fogDistance = RenderSystem.getShaderFogEnd();

boolean dirty = pos.x != this.lastCameraX || pos.y != this.lastCameraY || pos.z != this.lastCameraZ ||
pitch != this.lastCameraPitch || yaw != this.lastCameraYaw || fogDistance != this.lastFogDistance;

if (dirty) {
this.renderSectionManager.markGraphDirty();
if (this.lastCameraPos == null) {
this.lastCameraPos = new Vector3d(pos);
}
boolean cameraLocationChanged = !pos.equals(this.lastCameraPos);
boolean cameraAngleChanged = pitch != this.lastCameraPitch || yaw != this.lastCameraYaw || fogDistance != this.lastFogDistance;

this.lastCameraX = pos.x;
this.lastCameraY = pos.y;
this.lastCameraZ = pos.z;
this.lastCameraPitch = pitch;
this.lastCameraYaw = yaw;
this.lastFogDistance = fogDistance;

profiler.popPush("chunk_update");
if (cameraLocationChanged || cameraAngleChanged) {
this.renderSectionManager.markGraphDirty();
}

this.renderSectionManager.updateChunks(updateChunksImmediately);
this.lastFogDistance = fogDistance;

profiler.popPush("chunk_upload");
this.renderSectionManager.updateCameraState(pos, camera);

this.renderSectionManager.uploadChunks();
if (cameraLocationChanged) {
profiler.popPush("translucent_triggering");

this.renderSectionManager.processGFNIMovement(new CameraMovement(this.lastCameraPos, pos));
this.lastCameraPos = new Vector3d(pos);
}

if (this.renderSectionManager.needsUpdate()) {
profiler.popPush("chunk_render_lists");

this.renderSectionManager.update(camera, viewport, frame, spectator);
}

if (updateChunksImmediately) {
profiler.popPush("chunk_upload_immediately");
profiler.popPush("chunk_update");

this.renderSectionManager.uploadChunks();
}
this.renderSectionManager.cleanupAndFlip();
this.renderSectionManager.updateChunks(updateChunksImmediately);

profiler.popPush("chunk_upload");

this.renderSectionManager.uploadChunks();

profiler.popPush("chunk_render_tick");

Expand Down
Loading
Loading