private void setUpTerrainMaterial(AssetManager assetManager) {
                // advanced PBR terrain matdef
                matTerrain = new Material(assetManager, "Common/MatDefs/Terrain/AdvancedPBRTerrain.j3md");

                matTerrain.setBoolean("useTriPlanarMapping", false);

                // ALPHA map (for splat textures)
                matTerrain.setTexture("AlphaMap", assetManager.loadTexture("Textures/Terrain/splat/alpha1.png"));
                matTerrain.setTexture("AlphaMap_1", assetManager.loadTexture("Textures/Terrain/splat/alpha2.png"));

                // load textures for texture arrays
                // These MUST all have the same dimensions and format in order to be put into a texture array.
                //ALBEDO MAPS
                Texture dirt = assetManager.loadTexture("Textures/Terrain/PBR/Ground037_1K_Color.png");
                Texture darkRock = assetManager.loadTexture("Textures/Terrain/PBR/Rock035_1K_Color.png");
                Texture snow = assetManager.loadTexture("Textures/Terrain/PBR/Snow006_1K_Color.png");
                Texture tileRoad = assetManager.loadTexture("Textures/Terrain/PBR/Tiles083_1K_Color.png");
                Texture grass = assetManager.loadTexture("Textures/Terrain/PBR/Ground037_1K_Color.png");
                Texture marble = assetManager.loadTexture("Textures/Terrain/PBR/Marble013_1K_Color.png");
                Texture gravel = assetManager.loadTexture("Textures/Terrain/PBR/Gravel015_1K_Color.png");

                // NORMAL MAPS
                Texture normalMapDirt = assetManager.loadTexture("Textures/Terrain/PBR/Ground036_1K_Normal.png");
                Texture normalMapDarkRock = assetManager.loadTexture("Textures/Terrain/PBR/Rock035_1K_Normal.png");
                Texture normalMapSnow = assetManager.loadTexture("Textures/Terrain/PBR/Snow006_1K_Normal.png");
                Texture normalMapGravel = assetManager.loadTexture("Textures/Terrain/PBR/Gravel015_1K_Normal.png");
                Texture normalMapGrass = assetManager.loadTexture("Textures/Terrain/PBR/Ground037_1K_Normal.png");
                Texture normalMapMarble = assetManager.loadTexture("Textures/Terrain/PBR/Marble013_1K_Normal.png");
                Texture normalMapRoad = assetManager.loadTexture("Textures/Terrain/PBR/Tiles083_1K_Normal.png");

                //PACKED METALLIC/ROUGHNESS / AMBIENT OCCLUSION / EMISSIVE INTENSITY MAPS
                Texture metallicRoughnessAoEiMapDirt = assetManager.loadTexture("Textures/Terrain/PBR/Ground036_PackedMetallicRoughnessMap.png");
                Texture metallicRoughnessAoEiMapDarkRock = assetManager.loadTexture("Textures/Terrain/PBR/Rock035_PackedMetallicRoughnessMap.png");
                Texture metallicRoughnessAoEiMapSnow = assetManager.loadTexture("Textures/Terrain/PBR/Snow006_PackedMetallicRoughnessMap.png");
                Texture metallicRoughnessAoEiMapGravel = assetManager.loadTexture("Textures/Terrain/PBR/Gravel_015_PackedMetallicRoughnessMap.png");
                Texture metallicRoughnessAoEiMapGrass = assetManager.loadTexture("Textures/Terrain/PBR/Ground037_PackedMetallicRoughnessMap.png");
                Texture metallicRoughnessAoEiMapMarble = assetManager.loadTexture("Textures/Terrain/PBR/Marble013_PackedMetallicRoughnessMap.png");
                Texture metallicRoughnessAoEiMapRoad = assetManager.loadTexture("Textures/Terrain/PBR/Tiles083_PackedMetallicRoughnessMap.png");

                // put all images into lists to create texture arrays.
                List<Image> albedoImages = new ArrayList<>();
                List<Image> normalMapImages = new ArrayList<>();
                List<Image> metallicRoughnessAoEiMapImages = new ArrayList<>();

                albedoImages.add(dirt.getImage());  //0
                albedoImages.add(darkRock.getImage()); //1
                albedoImages.add(snow.getImage()); //2
                albedoImages.add(tileRoad.getImage()); //3
                albedoImages.add(grass.getImage()); //4
                albedoImages.add(marble.getImage()); //5
                albedoImages.add(gravel.getImage()); //6

                normalMapImages.add(normalMapDirt.getImage());  //0
                normalMapImages.add(normalMapDarkRock.getImage());  //1
                normalMapImages.add(normalMapSnow.getImage());  //2
                normalMapImages.add(normalMapRoad.getImage());   //3
                normalMapImages.add(normalMapGrass.getImage());   //4
                normalMapImages.add(normalMapMarble.getImage());   //5
                normalMapImages.add(normalMapGravel.getImage());   //6

                metallicRoughnessAoEiMapImages.add(metallicRoughnessAoEiMapDirt.getImage());  //0
                metallicRoughnessAoEiMapImages.add(metallicRoughnessAoEiMapDarkRock.getImage());  //1
                metallicRoughnessAoEiMapImages.add(metallicRoughnessAoEiMapSnow.getImage());  //2
                metallicRoughnessAoEiMapImages.add(metallicRoughnessAoEiMapRoad.getImage());   //3
                metallicRoughnessAoEiMapImages.add(metallicRoughnessAoEiMapGrass.getImage());   //4
                metallicRoughnessAoEiMapImages.add(metallicRoughnessAoEiMapMarble.getImage());   //5
                metallicRoughnessAoEiMapImages.add(metallicRoughnessAoEiMapGravel.getImage());   //6

                //initiate texture arrays
                TextureArray albedoTextureArray = new TextureArray(albedoImages);
                TextureArray normalParallaxTextureArray = new TextureArray(normalMapImages); // parallax is not used currently
                TextureArray metallicRoughnessAoEiTextureArray = new TextureArray(metallicRoughnessAoEiMapImages);

                //apply wrapMode to the whole texture array, rather than each individual texture in the array
                setWrapAndMipMaps(albedoTextureArray);
                setWrapAndMipMaps(normalParallaxTextureArray);
                setWrapAndMipMaps(metallicRoughnessAoEiTextureArray);
                
                //assign texture array to materials
                matTerrain.setParam("AlbedoTextureArray", VarType.TextureArray, albedoTextureArray);
                matTerrain.setParam("NormalParallaxTextureArray", VarType.TextureArray, normalParallaxTextureArray);
                matTerrain.setParam("MetallicRoughnessAoEiTextureArray", VarType.TextureArray, metallicRoughnessAoEiTextureArray);

                //set up texture slots:
                matTerrain.setInt("AlbedoMap_0", 0); // dirt is index 0 in the albedo image list
                matTerrain.setFloat("AlbedoMap_0_scale", dirtScale);
                matTerrain.setFloat("Roughness_0", 1);
                matTerrain.setFloat("Metallic_0", 0.02f);

                matTerrain.setInt("AlbedoMap_1", 1);   // darkRock is index 1 in the albedo image list
                matTerrain.setFloat("AlbedoMap_1_scale", darkRockScale);
                matTerrain.setFloat("Roughness_1", 1);
                matTerrain.setFloat("Metallic_1", 0.04f);

                matTerrain.setInt("AlbedoMap_2", 2);
                matTerrain.setFloat("AlbedoMap_2_scale", snowScale);
                matTerrain.setFloat("Roughness_2", 0.72f);
                matTerrain.setFloat("Metallic_2", 0.12f);

                matTerrain.setInt("AlbedoMap_3", 3);
                matTerrain.setFloat("AlbedoMap_3_scale", tileRoadScale);
                matTerrain.setFloat("Roughness_3", 1);
                matTerrain.setFloat("Metallic_3", 0.04f);

                matTerrain.setInt("AlbedoMap_4", 4);
                matTerrain.setFloat("AlbedoMap_4_scale", grassScale);
                matTerrain.setFloat("Roughness_4", 1);
                matTerrain.setFloat("Metallic_4", 0);

                matTerrain.setInt("AlbedoMap_5", 5);
                matTerrain.setFloat("AlbedoMap_5_scale", marbleScale);
                matTerrain.setFloat("Roughness_5", 1);
                matTerrain.setFloat("Metallic_5", 0.2f);

                matTerrain.setInt("AlbedoMap_6", 6);
                matTerrain.setFloat("AlbedoMap_6_scale", gravelScale);
                matTerrain.setFloat("Roughness_6", 1);
                matTerrain.setFloat("Metallic_6", 0.01f);

                // NORMAL MAPS
                matTerrain.setInt("NormalMap_0", 0);
                matTerrain.setInt("NormalMap_1", 1);
                matTerrain.setInt("NormalMap_2", 2);
                matTerrain.setInt("NormalMap_3", 3);
                matTerrain.setInt("NormalMap_4", 4);
                matTerrain.setInt("NormalMap_5", 5);
                matTerrain.setInt("NormalMap_6", 6);

                //METALLIC/ROUGHNESS/AO/EI MAPS
                matTerrain.setInt("MetallicRoughnessMap_0", 0);
                matTerrain.setInt("MetallicRoughnessMap_1", 1);
                matTerrain.setInt("MetallicRoughnessMap_2", 2);
                matTerrain.setInt("MetallicRoughnessMap_3", 3);
                matTerrain.setInt("MetallicRoughnessMap_4", 4);
                matTerrain.setInt("MetallicRoughnessMap_5", 5);
                matTerrain.setInt("MetallicRoughnessMap_6", 6);

                //EMISSIVE
                matTerrain.setColor("EmissiveColor_5", marbleEmissiveColor);
                matTerrain.setColor("EmissiveColor_3", tilesEmissiveColor);

                terrain.setMaterial(matTerrain);
            }
Test advanced PBR terrain with different debug modes

@param testName The name of the test (used for screenshot filename)
@param debugMode The debug mode to use
jme3-screenshot-tests/src/test/java/org/jmonkeyengine/screenshottests/terrain/TestPBRTerrainAdvanced.java