jmonkeyengine icon indicating copy to clipboard operation
jmonkeyengine copied to clipboard

DDS Loader issue with DXT3/DXT35 volume textures

Open dreamwagon opened this issue 5 years ago • 25 comments

I believe there is a problem loading DXT3/DXT5 volume textures exported from the NVidia Photoshop DDS plugin.

Issue 1: Loaded file appears to be very low quality and is perhaps missing the alpha channel. (just a guess).

Issue 2: When mips are generated through the plugin, texture is rendered all black.

Edit: These issues only occur when depth greater than 1. I found this when exporting a texture strip to volume. DDS plugin automatically creates z slices on the x axis

These issues where tested with the code snipped supplied by 1000ml here

I am supplying 4 files. DXT3/DXT5 are for the first issue, DXT5-MIPS is for the second. ARGB8888 is the expected result.

DDS issue.zip

dreamwagon avatar Feb 22 '20 18:02 dreamwagon

Thank you for bringing this issue to our attention.

stephengold avatar Feb 22 '20 18:02 stephengold

Question: does TestTexture3DLoading work on your system?

stephengold avatar Feb 22 '20 18:02 stephengold

Do you mean this?

I could give it a try. I used the sample code 1000ml provided on the hub to verify the issue

dreamwagon avatar Feb 22 '20 18:02 dreamwagon

That's what I meant, yes.

stephengold avatar Feb 22 '20 20:02 stephengold

I get the same results as my other test. The DXT3/DXT5 volumes appear very low quality and as if they are being scaled incorrectly.

Here is the expected result with rows = 8

image

Here is the result of loading the DXT3 and DXT5 Volumes (no mips generated) with rows = 8

image

As before, The DXT5 with generated MIPS is all black.

dreamwagon avatar Feb 22 '20 20:02 dreamwagon

Here's what I see when I run TestTexture3DLoading on my Linux desktop: TestTexture3DLoading

stephengold avatar Feb 22 '20 21:02 stephengold

I've looked into this, i think i have an idea of what the issue could be. However, when i try all your compressed textures, the resulting quad is black. So i am afraid there might be another issue somewhere.

Do you confirm that the following code does not give black screen to you?


import com.jme3.app.SimpleApplication;
import com.jme3.asset.TextureKey;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Vector2f;
import com.jme3.math.Vector3f;
import com.jme3.scene.Geometry;
import com.jme3.scene.shape.Quad;
import com.jme3.texture.Texture;
import com.jme3.texture.Texture.MagFilter;
import com.jme3.texture.Texture.MinFilter;

public class TestTexture3DLoading extends SimpleApplication {

    public static void main(String[] args) {
        TestTexture3DLoading app = new TestTexture3DLoading();
        app.start();
    }

    @Override
    public void simpleInitApp() {
        viewPort.setBackgroundColor(ColorRGBA.DarkGray);
        flyCam.setEnabled(false);


        Quad q = new Quad(10, 10);

        Geometry geom = new Geometry("Quad", q);
        Material material = new Material(assetManager, "jme3test/texture/tex3DThumb.j3md");
        TextureKey key = new TextureKey("Textures/3D/CloudShapeGeneratedDXT5.dds");
        key.setGenerateMips(false);
        key.setTextureTypeHint(Texture.Type.ThreeDimensional);

        Texture t = assetManager.loadTexture(key);
        t.setMinFilter(MinFilter.NearestNoMipMaps);
        t.setMagFilter(MagFilter.Nearest);
        int rows = 8;//4 * 4

        q.scaleTextureCoordinates(new Vector2f(rows, rows));

        //The image only have 8 pictures and we have 16 thumbs, the data will be interpolated by the GPU
        material.setFloat("InvDepth", 1f / 16f);
        material.setInt("Rows", rows);
        material.setTexture("Texture", t);
        geom.setMaterial(material);

        rootNode.attachChild(geom);

        cam.setLocation(new Vector3f(4.7444625f, 5.160054f, 13.1939f));
    }
}

riccardobl avatar Feb 23 '20 08:02 riccardobl

When I test with that exact snippet I get the second image posted above. Only the DXT5-MIPS image is all black for me.

dreamwagon avatar Feb 23 '20 15:02 dreamwagon

Can you enable assersions (-ea ) and run again the tests that give you black screen? They should give you an exception, maybe that could be useful to debug the problem.

riccardobl avatar Feb 24 '20 09:02 riccardobl

I tested with the -ea VM argument and none of the attached files throw an exception.

dreamwagon avatar Feb 25 '20 15:02 dreamwagon

I've tested with flame.dds and I get a black picture, but with app.settings.put("GraphicsDebug", true); I get the error:

[JME3] OpenGL debug message
       ID: 5
       Source: API
       Type: ERROR
       Severity: HIGH
       Message: GL_INVALID_ENUM in glCompressedTexImage3D(target)
java.lang.Exception: Stack trace
	at java.lang.Thread.dumpStack(Thread.java:1329)
	at com.jme3.system.lwjgl.LwjglGLDebugOutputHandler.handleMessage(LwjglGLDebugOutputHandler.java:76)
	at org.lwjgl.opengl.GL13.nglCompressedTexImage3D(Native Method)
	at org.lwjgl.opengl.GL13.glCompressedTexImage3D(GL13.java:194)
	at com.jme3.renderer.lwjgl.LwjglGL.glCompressedTexImage3D(LwjglGL.java:126)
	at com.jme3.renderer.opengl.GLDebugDesktop.glCompressedTexImage3D(GLDebugDesktop.java:51)
	at com.jme3.renderer.opengl.TextureUtil.uploadTextureLevel(TextureUtil.java:144)
...
com.jme3.renderer.RendererException: An OpenGL error occurred - Invalid enum argument (Error Code: 1280)
at com.jme3.renderer.opengl.GLDebug.checkError(GLDebug.java:46)
	at com.jme3.renderer.opengl.GLDebugDesktop.glCompressedTexImage3D(GLDebugDesktop.java:52)
	at com.jme3.renderer.opengl.TextureUtil.uploadTextureLevel(TextureUtil.java:144)

It seems uploading compressed 3D dxt5 is either not supported by this card or there is some issue.

TehLeo avatar Feb 25 '20 21:02 TehLeo

Are you on latest master? Can you try with #1276 enabled @TehLeo ? It looks like you don't suffer from this but just to be sure.

MeFisto94 avatar Feb 25 '20 22:02 MeFisto94

I've made some researches, it seems s3tc 3d textures are not supported or partially supported in many drivers. I've looked at mesa source and it seems they are not supported there (it would explain why i get black screen with all the tests). However it is weird you guys are getting issues with flame.dds, since it is not compressed.

riccardobl avatar Feb 25 '20 22:02 riccardobl

I just tested on an AMD RX580 card and both the flame and cloud textures render as expected. This is definitely not an issue with the DDS loader. What would the work around for this issue be? Simply export only uncompressed formats? The strange thing is this only appears to be an issue when the depth > 1. If I export square volume textures they render correctly on both machines.

dreamwagon avatar Feb 26 '20 01:02 dreamwagon

@MeFisto94 nope, not on latest master, but the issue is with 3d tex compression support, in my case, as @riccardobl mentioned, i used Mesa for the test, which as he pointed out does not seem to support it. @riccardobl Well the flame.dds I tried is 3D texture in DXT5 format and thus compressed. How come yours is not compressed? What format is it in?

TehLeo avatar Feb 26 '20 09:02 TehLeo

@TehLeo I am asking because at least when using Debug, we have the problem of falling back into "OpenGL ES Mode", which could mess with your results there.

So either applying that PR or using some third party tool might help.

MeFisto94 avatar Feb 26 '20 09:02 MeFisto94

With or without GraphicsDebug, my renderer info is

INFO: OpenGL Renderer Information
 * Vendor: Intel Open Source Technology Center
 * Renderer: Mesa DRI Intel(R) Haswell Mobile 
 * OpenGL Version: 3.3 (Core Profile) Mesa 17.2.8
 * GLSL Version: 3.30
 * Profile: Core

Plus, I tried without GraphicsDebug, but wrapped the method with gl.glGetError and the same result is produced.

TehLeo avatar Feb 26 '20 10:02 TehLeo

@TehLeo

$ file '/DEV/jmonkeyengine/jme3-testdata/src/main/resources/Textures/3D/flame.dds' 
/DEV/jmonkeyengine/jme3-testdata/src/main/resources/Textures/3D/flame.dds: Microsoft DirectDraw Surface (DDS), 128 x 128, 

Also opening the file with an hex editor confirms it doesn't have a valid DXT fourcc field. Am i testing the wrong file?

riccardobl avatar Feb 26 '20 10:02 riccardobl

Oh, i see, you are testing the img from an old snapshot. It was decompressed by this commit 663c9776e8b65f95beaf8db1e39f0ac244816fe2

riccardobl avatar Feb 26 '20 10:02 riccardobl

Does JME use: GL_EXT_texture_compression_s3tc internally? Or GL_EXT_texture_compression_DXT5 (1, 3). If the latter, isn't it possible that some drivers do not support but some do? I think EXT_texture_compression_s3tc is more widely supported?

dreamwagon avatar Feb 26 '20 15:02 dreamwagon

Yes, but those ext I think do not say they support 3D texture compression.

TehLeo avatar Feb 26 '20 16:02 TehLeo

Yes, but I thought the GL EXT s3tc one does? Am I wrong about that?

https://www.khronos.org/registry/OpenGL/extensions/EXT/EXT_texture_compression_s3tc.txt

dreamwagon avatar Feb 26 '20 16:02 dreamwagon

Well did you read the above link well?

Since the S3TC texture compression algorithm supports only 2D
    images, CompressedTexSubImage1DARB and CompressedTexSubImage3DARB produce
    an INVALID_ENUM error if <format> is an S3TC format. 

While it is supported in

Interactions of extended OpenGL ES 2.0.25 with NV_texture_array

    If NV_texture_array is supported, the S3TC compressed formats may
    also be used as the internal formats given to
    CompressedTexImage3DNV and CompressedTexSubImage3DNV. The
    restrictions for the <width>, <height>, <xoffset>, and <yoffset>
    parameters of the CompressedTexSubImage2D function when used with
    S3TC compressed texture formats, described in this extension, also
    apply to the identically named parameters of
    CompressedTexSubImage3DNV.
Additions to Chapter 3 of the OpenGL ES 3.0.2 Specification

TehLeo avatar Feb 26 '20 19:02 TehLeo

So i think this settles it. Is there more to discuss about this issue? Should we maybe raise an exception when 3d s3tc textures are used with opengl?

riccardobl avatar Mar 01 '20 10:03 riccardobl

I would't raise an exception if they are supported. I'd add a check to see if they are supported and only if they are not I would throw an exception.

TehLeo avatar Mar 04 '20 09:03 TehLeo