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 168 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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 2 additions & 2 deletions 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 Expand Up @@ -51,4 +51,4 @@ style guidelines.

If you're adding new Mixin patches to the project, please ensure that you have created appropriate entries to disable
them in the config file. Mixins should always be self-contained and grouped into "patch sets" which are easy to isolate,
and where that is not possible, they should be placed into the "core" package.
and where that is not possible, they should be placed into the "core" package.
2 changes: 2 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@ dependencies {
mappings "net.fabricmc:yarn:${project.yarn_mappings}:v2"
modImplementation "net.fabricmc:fabric-loader:${project.loader_version}"

modIncludeImplementation "com.lodborg:interval-tree:1.0.0"

// Fabric API
modIncludeImplementation(fabricApi.module("fabric-api-base", project.fabric_version))
modIncludeImplementation(fabricApi.module("fabric-block-view-api-v2", project.fabric_version))
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
import org.lwjgl.opengl.GL;
import org.lwjgl.opengl.GLCapabilities;

import javax.sound.sampled.BooleanControl;
import java.util.ArrayList;
import java.util.List;

Expand Down Expand Up @@ -260,8 +259,7 @@ public static OptionPage performance() {
.setBinding((opts, value) -> opts.performance.alwaysDeferChunkUpdates = value, opts -> opts.performance.alwaysDeferChunkUpdates)
.setFlags(OptionFlag.REQUIRES_RENDERER_UPDATE)
.build())
.build()
);
.build());

groups.add(OptionGroup.createBuilder()
.add(OptionImpl.createBuilder(boolean.class, sodiumOpts)
Expand Down Expand Up @@ -310,6 +308,17 @@ public static OptionPage performance() {
.build())
.build());

groups.add(OptionGroup.createBuilder()
.add(OptionImpl.createBuilder(SodiumGameOptions.SortBehavior.class, sodiumOpts)
.setName(Text.translatable("sodium.options.sort_behavior.name"))
.setTooltip(Text.translatable("sodium.options.sort_behavior.tooltip"))
.setControl(option -> new CyclingControl<>(option, SodiumGameOptions.SortBehavior.class))
.setBinding((opts, value) -> opts.performance.sortBehavior = value, opts -> opts.performance.sortBehavior)
.setImpact(OptionImpact.MEDIUM)
.setFlags(OptionFlag.REQUIRES_RENDERER_RELOAD)
.build())
.build());

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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,25 @@ public static class PerformanceSettings {
public boolean useFogOcclusion = true;
public boolean useBlockFaceCulling = true;
public boolean useNoErrorGLContext = true;

public SortBehavior sortBehavior = SortBehavior.DYNAMIC;
}

public enum SortBehavior implements TextProvider {
OFF("options.off"),
STATIC("options.clouds.fast"),
DYNAMIC("options.clouds.fancy");

private final Text name;

SortBehavior(String name) {
this.name = Text.translatable(name);
}

@Override
public Text getLocalizedName() {
return this.name;
}
}

public static class AdvancedSettings {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
import static me.jellysquid.mods.sodium.client.util.ModelQuadUtil.*;

/**
* A simple implementation of the {@link ModelQuadViewMutable} interface which can provide an on-heap scratch area
* A simple implementation of the {@link ModelQuadViewMutable} interface which
* can provide an on-heap scratch area
* for storing quad vertex data.
*/
public class ModelQuad implements ModelQuadViewMutable {
Expand All @@ -15,6 +16,9 @@ public class ModelQuad implements ModelQuadViewMutable {
private Sprite sprite;
private int colorIdx;
private int normal;
private int GFNINormX;
private int GFNINormY;
private int GFNINormZ;

@Override
public void setX(int idx, float x) {
Expand Down Expand Up @@ -120,4 +124,26 @@ public Sprite getSprite() {
public int getNormal() {
return this.normal;
}

@Override
public int getGFNINormX() {
return this.GFNINormX;
}

@Override
public int getGFNINormY() {
return this.GFNINormY;
}

@Override
public int getGFNINormZ() {
return this.GFNINormZ;
}

@Override
public void setGFNINormal(int x, int y, int z) {
this.GFNINormX = x;
this.GFNINormY = y;
this.GFNINormZ = z;
}
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
package me.jellysquid.mods.sodium.client.model.quad;

import me.jellysquid.mods.sodium.client.model.quad.properties.ModelQuadFlags;
import me.jellysquid.mods.sodium.client.render.chunk.translucent_sorting.TranslucentSorting;
import net.caffeinemc.mods.sodium.api.util.NormI8;
import net.minecraft.client.texture.Sprite;

/**
* Provides a read-only view of a model quad. For mutable access to a model quad, see {@link ModelQuadViewMutable}.
* Provides a read-only view of a model quad. For mutable access to a model
* quad, see {@link ModelQuadViewMutable}.
*/
public interface ModelQuadView {
/**
Expand Down Expand Up @@ -38,7 +41,8 @@ public interface ModelQuadView {
float getTexV(int idx);

/**
* @return The integer bit flags containing the {@link ModelQuadFlags} for this quad
* @return The integer bit flags containing the {@link ModelQuadFlags} for this
* quad
*/
int getFlags();

Expand All @@ -57,6 +61,91 @@ public interface ModelQuadView {
*/
int getNormal();

/**
* @return The x coordinate of the unit normal vector
*/
int getGFNINormX();

/**
* @return The y coordinate of the unit normal vector
*/
int getGFNINormY();

/**
* @return The z coordinate of the unit normal vector
*/
int getGFNINormZ();

/**
* Sets an accurate normal vector for this quad. This is used for GFNI.
*
* @param x The normal's x component
* @param y The normal's y component
* @param z The normal's z component
*/
void setGFNINormal(int x, int y, int z);

default int calculateNormals(boolean calculateUnitNormal) {
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;

int packedNormal = -1;
if (calculateUnitNormal) {
// normalize by length for the packed normal
float length = (float) Math.sqrt(normX * normX + normY * normY + normZ * normZ);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you are still at risk of dividing by "almost zero" which will create grossly inaccurate results

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this part of the code is actually just transferred from what sodium was doing previously. I don't know what this normal is used for or if that would be a problem.

if (length != 0.0 && length != 1.0) {
normX /= length;
normY /= length;
normZ /= length;
}

packedNormal = NormI8.pack(normX, normY, normZ);
}

// normalize onto the surface of a cube by dividing by the length of the longest
// component
float infNormLength = Math.max(Math.abs(normX), Math.max(Math.abs(normY), Math.abs(normZ)));
if (infNormLength != 0 && infNormLength != 1) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you are still at risk of dividing by "almost zero" which will create grossly inaccurate results

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This part is not Sodium's code but where I make my own (heavily quantized) normal for GFNI triggering and translucency sorting. Since I'm projecting onto the surface of a unit cube anyways, this is probably fine. Unless it generates non-unit length normals it doesn't really matter if the result is weird if the input is weird.

normX /= infNormLength;
normY /= infNormLength;
normZ /= infNormLength;
}

// quantize the coordinates on the surface of the cube.
// in each axis the number of values is 2 * QUANTIZATION_FACTOR + 1.
// the total number of normals is the number of points on that cube's surface.
this.setGFNINormal(
(int) (normX * TranslucentSorting.QUANTIZATION_FACTOR),
(int) (normY * TranslucentSorting.QUANTIZATION_FACTOR),
(int) (normZ * TranslucentSorting.QUANTIZATION_FACTOR));

return packedNormal;
}

default boolean hasColor() {
return this.getColorIndex() != -1;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
package me.jellysquid.mods.sodium.client.model.quad.properties;

import org.joml.Vector3f;
import org.joml.Vector3fc;

import net.minecraft.util.math.Direction;

public enum ModelQuadFacing {
Expand All @@ -14,18 +17,31 @@ 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[] NORMALS = new Vector3fc[ModelQuadFacing.DIRECTIONS];

static {
for (int i = 0; i < ModelQuadFacing.DIRECTIONS; i++) {
NORMALS[i] = new Vector3f(ModelQuadFacing.VALUES[i].toDirection().getUnitVector());
}
}

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;
case UP -> POS_Y;
case NORTH -> NEG_Z;
case SOUTH -> POS_Z;
case WEST -> NEG_X;
case EAST -> POS_X;
case DOWN -> NEG_Y;
case UP -> POS_Y;
case NORTH -> NEG_Z;
case SOUTH -> POS_Z;
case WEST -> NEG_X;
case EAST -> POS_X;
};
}

Expand All @@ -40,4 +56,24 @@ 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 Direction toDirection() {
return switch (this) {
case POS_Y -> Direction.UP;
case NEG_Y -> Direction.DOWN;
case POS_X -> Direction.EAST;
case NEG_X -> Direction.WEST;
case POS_Z -> Direction.SOUTH;
case NEG_Z -> Direction.NORTH;
default -> Direction.UP;
};
}
}