Entity models get stretched vertices with shaders: `rawFloatBuffer` is rebuilt from a non-zero `byteBuffer` position
Nobody has claimed this yet.
Assessment
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Newbie friendliness
- 82/100
- Issue type
- Bug
- Clarity
- Clearly specified
- Activity status
- Active
- Tech stack
- java
- Domain
- computer-graphics, game-dev
Research direction
Start by reading MixinBufferBuilder.optiRefine$restoreWritableFloatBuffer and the growBuffer calls from endVertex, then inspect WorldVertexBufferUploader.draw to confirm how byteBuffer.position is left behind. Reproduce with OptiFine and OptiRefine using the reported shader setup or diagnostic mixin. Done means rawFloatBuffer consistently starts at offset 0 and compiled model quads no longer have displaced vertices.
Written by the indexing model from the issue text.
Description
Environment
Cleanroom 0.6.13-alpha (Java 25), OptiFine 1.12.2 HD_U_G5, OptiRefine built from 78ff8ce. Seen with Sildur's Vibrant v2.02 and Mellow v3.4.1.
What happens
With a shader pack on, some entity/tile-entity model parts sometimes get one or more vertices pulled far away when their display list is compiled. Examples: a chest lid with a large triangular "wedge", or a thin strip coming out of a villager's head. The result changes from run to run and then stays until the display lists are rebuilt.
Cause
WorldVertexBufferUploader.drawsetsbyteBuffer.position(format.getOffset(i))for every element and never sets it back to 0.BufferBuilder.reset()andbegin()do not touch the position either. After a Tessellator draw inPOSITION_TEX_COLOR(24 bytes), the Tessellator'sbyteBufferstays at position 20.MixinBufferBuilder.optiRefine$restoreWritableFloatBufferinjects at the TAIL of everygrowBuffercall, andendVertexcallsgrowBufferon every vertex. It doesthis.rawFloatBuffer = this.byteBuffer.asFloatBuffer();. The view starts at the buffer's current position, so it is shifted by 20 bytes.- Under shaders, models use
SVertexFormat.defVertexFormatTextured(56 bytes). After the 4th vertex of a quad,SVertexBuilder.calcNormalreads and writes the quad throughrawFloatBuffer, with indices counted from 0. With the 20-byte shift, themidVwrites (floatBuffer.put(base + i * 14 + 9, midV)) land on bytes 56, 112 and 168. Those are the x coordinates of vertices 1, 2 and 3. The normal and tangent are also computed from shifted reads. - In OptiFine itself the float view is only created inside the "buffer actually grows" branch, after
rewind(), so it always starts at byte 0.
Evidence
We used a diagnostic mixin (a test-only mod) that checks every quad compiled into a model display list:
- The quad positions are correct after the last
endVertexand wrong atTessellator.drawHEAD. Only the x of vertices 1-3 changes. - Every corrupted quad had
rawFloatBufferstarting 20 bytes intobyteBuffer, and the previous Tessellator draw wasPOSITION_TEX_COLOR. - The corruption also happens with only OptiFine + OptiRefine installed: 2 corrupted
ModelPlayerquads per run, in the shadow pass. Other mods only change which model gets hit, depending on draw order. - Re-anchoring the view after OptiRefine's TAIL injection, with
duplicate().clear(), keeps the native order. With that, 1320 of 1320 compiled quads start at offset 0 and none are corrupted.
Suggestion
Only rebuild the view when the buffer actually grew, or build it from position 0, for example:
ByteBuffer whole = this.byteBuffer.duplicate();
whole.clear();
this.rawFloatBuffer = whole.order(this.byteBuffer.order()).asFloatBuffer();
- Dominant language
- Java
- Stars
- 27
- Forks
- 5
- PR merge metrics
- No merged PRs in 30d
Getting set up
This project ships no dev container, Dockerfile or contributing guide, so setting up is up to you: start from its README, and see our first-contribution guide for the general steps.
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from Ecdcaeb/OptiRefine
-
Difficulty 4/5 3-5 days Newbie friendliness 48/100
Ecdcaeb/OptiRefine#7 ·
-
# Crash when releasing the zoom key: `NoSuchFieldError: acc$mouseFilterXAxis` in `getFOVModifier`Open
Difficulty 4/5 3-5 days Newbie friendliness 55/100
Ecdcaeb/OptiRefine#5 ·
-
Difficulty 4/5 3-5 days Newbie friendliness 35/100
Ecdcaeb/OptiRefine#2 ·
All issues in Ecdcaeb/OptiRefine
Similar issues
-
code-maintenance
Difficulty 2/5 1-3 hours Newbie friendliness 77/100
Maintainers usually reply within 1 day
-
bug priority: medium Review effort [1-5]: 3 status: needs-triage type: bug
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
carlos-emr/carlos#5258 ·
Maintainers usually reply within 1 day
-
bug: author create/update with an unknown avatarId returns 404 instead of 400 UNKNOWN_REFERENCEPossibly taken @Vinu2111 claimed this today. Openbug
Difficulty 2/5 1-3 hours Newbie friendliness 74/100
atomityhq/blog-cms#59 · 1 comment ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 70/100
Maintainers usually reply within 1 day
-
dev/release: verify-release-candidate.sh runs 0 Java tests with Debian's MavenPossibly taken @kou claimed this today. OpenType: bug
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
apache/arrow-adbc#4947 ·
Maintainers usually reply within 1 day