Open ghost opened 4 years ago
I don't know very well how the fourth step is working currently. Are all tiles loaded into OpenGL's memory? How are they accessible from the fragment shader?
The first tile of mip-mapped texture is loaded as a common one-level texture. Tiles from 2 to gSP.texture.level are loaded as single mip-mapped texture. It is necessary because the first tile can be a detailed texture and can have different format. Fragment shader for LOD calculation is ShaderMipmap. It uses texelFetch(tex, coords, lod) to fetch from mip-mapped texture.
I have plans to rewrite LOD implementation using texture array instead of mip-mapped texture. OpenGL requires that size of any tile in mip-mapped texture must be half of size of the previous tile. It is not always the case for N64 mip-mapped textures, and the current code uses some texture size correction.
I have plans to rewrite LOD implementation using texture array instead of mip-mapped texture.
Sounds like a good idea. Good luck.
The N64 handles Level of Detail (LoD) in the following manner:
lod_tile
) is used to select a tiles for each cycle, and the fractional part (lod_frac
) is passed to the combiner to perform a linear interpolation. Probably due to the difficulty computing an accurate logarithm, the RDP MIGHT computelod_tile
by checking the position of the most significant bit andlod_frac
with a linear interpolation. The lod in this formula is before computing the logarithm.lod_tile = (lod - 2^lod_tile)/(2^lod_tile) = lod / 2^lod_tile -1
lod_tile
. In the general case they areprim_tile + lod_tile
for the first cycle andprim_tile + lod_tile + 1
for the second cycle. This values are clamped/modified when magnifying or exceeding the max level, and behave slightly differently for textures with a detail tile. Hereprim_tile
is set bygSPTexture()
command.To emulate this correctly, something similar to this would have to be done.
lod_tile
andlod_frac
at the beggining of the fragment shader.lod_tile
.I believe the third step is incorrect in current master. Subtraction of
(sl,tl)
and shift are applied before lod has been calculated. I believe descriptorsprim_tile
andprim_tile + 1
are used for this reason. This is not too problematic if the shift and (sl,tl) parameters have logical values. I worked around by calculating thelod_scale
variable in the texture engine refactor, and before that normalized coordinates helped the same behaviour. But if (sl,tl) or shift are unexpected, strange things could happen.I don't know very well how the fourth step is working currently. Are all tiles loaded into OpenGL's memory? How are they accessible from the fragment shader?
@gonetz I started refactoring the LoD code. The branch is in very early WIP state and I don't expect to have time to work on it for at least a couple of months. If you want to tackle the issue though, feel free to use any piece you find useful.