Black textures based on camera position jme3

Hello, I’m new to JME in general, so i decided to jump in at the front of the curve and start with the alpha of jme3.



I’m working on a terrain rendering subsystem for a game and have been moving ahead pretty steadily, but i still have this odd issue. The system i’ve been working on renders 10x10 “tile” blocks and then tiles those together to create a continuous terrain. Textures are mapped to these 10x10 chunks. The two issues i’m seeing are:

  1. At certain angles certain textures turn solid black.
  2. The first blocks texture is noticeably darker (and on this video card, half of it is black no matter what).





    EDIT: the screenshots dont seem to be working, maybe it doesn’t allow PNGs, i’ll keep trying to get something to show up. Sorry.



    Screen shots:



    i71.photobucket.com/albums/i160/last_liven/Terrafirma/Example_of_tiling.jpg

    Tiling Example, with dark first chunk.



    i71.photobucket.com/albums/i160/last_liven/Terrafirma/Broken_Texturing.jpg

    Example of blackened tiles



    Related code:



    This is the function that loads the source heightmap image and parses it, creating the terrain chunks.



    public void loadTerrainFromHeightMap(AssetManager assetManager, String file){

    if(logger.isInfoEnabled())logger.info("Loading height map from file: " + file);



    Texture image = assetManager.loadTexture(file);





    height = image.getImage().getHeight();

    width = image.getImage().getWidth();





    int numChunksWidth = ((width-1) / TerrainChunk.WIDTH_TILES);

    int numChunksHeight = ((height-1) / TerrainChunk.HEIGHT_TILES);

    chunks = new TerrainChunk[numChunksWidth][numChunksHeight];



    ByteBuffer buffer = image.getImage().getData(0);

    buffer.position(0);



    short [] heightData = new short [buffer.limit()];



    for(int i=0;i<buffer.limit();i++){

    int y = i / width;

    int x = i % width;



    y = height - y -1;



    int flippedYPos = y * width + x;

    heightData[flippedYPos] = (short)(128 - (buffer.get() & 0xff));

    }



    // create a list of empty terrain chunks

    List<short [][]> chunksDatas = new ArrayList<short [][]>();

    for(int i=0;i<numChunksWidth * numChunksHeight;i++){

    chunksDatas.add(TerrainChunk.getChunkDefinition());

    }



    for(int cy = 0; cy < numChunksHeight; cy++){

    for(int cx = 0; cx < numChunksWidth; cx++){



    short [][] currentChunkData = chunksDatas.get( cy * numChunksWidth + cx );



    for(int ty = 0; ty <= TerrainChunk.HEIGHT_TILES; ty++){

    for(int tx = 0; tx <= TerrainChunk.WIDTH_TILES; tx++){



    int index = width * (cy * TerrainChunk.HEIGHT_VERTEXES + (cy * -1)) + (width * ty)
  • ((cx * TerrainChunk.WIDTH_VERTEXES) + (cx * -1) + tx);



    currentChunkData[tx][ty] = heightData[index];

    }

    }



    TerrainChunk chunk = new TerrainChunk();

    chunk.init(currentChunkData);

    this.chunks[cx][cy] = chunk;

    }

    }



    }





    And this is the terrain chunk code that builds the actual mesh objects:



    public void init(short [][] definition){

    if(logger.isInfoEnabled())logger.info(“Loading terrain chunk”);



    Vector3f[] verts = new Vector3f[WIDTH_VERTEXESHEIGHT_VERTEXES];



    int numTiles = WIDTH_TILES * HEIGHT_TILES;

    IntBuffer indices = BufferUtils.createIntBuffer(numTiles * 6);

    FloatBuffer normals = BufferUtils.createFloatBuffer(numTiles * 6);



    float [] texturepos = new float [WIDTH_VERTEXES * HEIGHT_VERTEXES * 2];



    int y=0;

    int x=0;



    for(y = 0; y < HEIGHT_VERTEXES; y++){

    for(x = 0; x < WIDTH_VERTEXES; x++){

    int c = y * WIDTH_VERTEXES + x;

    //logger.debug( definition[x][y] * heightScaleFactor);`

    verts[c] = new Vector3f(x, definition[x][y] * heightScaleFactor, y);

    BufferUtils.addInBuffer(verts[c], vertices, c);



    texturepos[c
    2] = x * textureStepX;

    texturepos[c*2+1] = y * textureStepY;

    }

    }





    int c=0;

    for(y=0;y<HEIGHT_TILES;y++){

    for(x=0;x<WIDTH_TILES;x++){

    c = y * WIDTH_VERTEXES + x;



    indices.put©;

    indices.put(c+WIDTH_VERTEXES);

    indices.put(c+1);

    indices.put(c+1);

    indices.put(c+WIDTH_VERTEXES);

    indices.put(c+WIDTH_VERTEXES+1);



    Vector3f n0 = new Triangle(verts[c], verts[c+WIDTH_VERTEXES], verts[c+1]).getNormal();

    Vector3f n1 = new Triangle(verts[c+1], verts[c+WIDTH_VERTEXES], verts[c+WIDTH_VERTEXES+1]).getNormal();



    c = (y * (WIDTH_TILES) + x) * 2;

    BufferUtils.addInBuffer(n0, normals, c);

    BufferUtils.addInBuffer(n1, normals, c+1);



    }



    }



    setBuffer(VertexBuffer.Type.Position, 3, vertices);

    setBuffer(VertexBuffer.Type.Normal, 3, normals);

    setBuffer(VertexBuffer.Type.Index, 1, indices);

    setBuffer(VertexBuffer.Type.TexCoord, 2, texturepos);

    }





    Thanks for any help, i apologize if this is the wrong forum, and let me know if there’s any other information or code that would help to figure this out.

Hi, it looks as the same issue i had on the terrain for light scattering.

Empire Phoenix found a solution in this thread

http://hub.jmonkeyengine.org/groups/development-discussion-jme3/forum/topic/light-scattering-effect-filter-for-jme3/#post-104143



Maybe you should give it a try

Yes, this fixed the issue. Thanks very much.



I’d love to know specifically what the issue is, and why this fixes it, if anyone knowledgeable feels like spending a few minutes to write it up.

I think the lighting material is using the tangents to compute specular lighting.

If your tangents are not correctly generated, so do your specular lighting.