PBR Lighting with Texture arrays

Hello,
So, I am working with a smooth voxel terrain, and thought it would be kinda fun to try my hand at modifying the PBRLighting shader to use textures arrays and get PBR lighting working on my terrain.

I decided to use TexCoord8 to store the voxel IDs in for the textures. An initial test with just the BaseColorMap as a texture array worked to an extent. But now that I have converted all the textures to texture arrays, all I get is a black object. Currently I am passing in a array of BaseColorMaps and NormalMaps.

I will continue to work on it to see if I can get it to work, but for reference here is my current work on it.

ArrayPBRLighting.j3md

MaterialDef PBR Lighting {

    MaterialParameters {

        // Alpha threshold for fragment discarding
        Float AlphaDiscardThreshold (AlphaTestFallOff)

        //metalness of the material
        Float Metallic : 1.0
        //Roughness of the material
        Float Roughness : 1.0
        // Base material color
        Color BaseColor : 1.0 1.0 1.0 1.0
        // The emissive color of the object
        Color Emissive
        // the emissive power
        Float EmissivePower : 3.0
        // the emissive intensity
        Float EmissiveIntensity : 2.0

        // BaseColor map
        TextureArray BaseColorMap

        // Metallic map
        TextureArray MetallicMap -LINEAR

        // Roughness Map
        TextureArray RoughnessMap -LINEAR

        //Metallic and Roughness are packed respectively in the b and g channel of a single map
        // r: unspecified
        // g: Roughness
        // b: Metallic
        TextureArray MetallicRoughnessMap -LINEAR

        // Texture of the emissive parts of the material
        TextureArray EmissiveMap

        // Normal map
        TextureArray NormalMap -LINEAR

        //The type of normal map: -1.0 (DirectX), 1.0 (OpenGl)
        Float NormalType : -1.0

        // For Spec gloss pipeline
        Boolean UseSpecGloss
        TextureArray SpecularMap
        TextureArray GlossinessMap
        TextureArray SpecularGlossinessMap
        Color Specular : 1.0 1.0 1.0 1.0
        Float Glossiness : 1.0

        // Parallax/height map
        TextureArray ParallaxMap -LINEAR

        //Set to true if parallax map is stored in the alpha channel of the normal map
        Boolean PackedNormalParallax

        //Sets the relief height for parallax mapping
        Float ParallaxHeight : 0.05

        //Set to true to activate Steep Parallax mapping
        Boolean SteepParallax

        //Horizon fade
        Boolean HorizonFade

        // Set to Use Lightmap
        TextureArray LightMap

        // Set to use TexCoord2 for the lightmap sampling
        Boolean SeparateTexCoord

        // the light map is a gray scale ao map, on ly the r channel will be read.
        Boolean LightMapAsAOMap

        //shadows
        Int FilterMode
        Boolean HardwareShadows

        Texture2D ShadowMap0
        Texture2D ShadowMap1
        Texture2D ShadowMap2
        Texture2D ShadowMap3
        //pointLights
        Texture2D ShadowMap4
        Texture2D ShadowMap5

        Float ShadowIntensity
        Vector4 Splits
        Vector2 FadeInfo

        Matrix4 LightViewProjectionMatrix0
        Matrix4 LightViewProjectionMatrix1
        Matrix4 LightViewProjectionMatrix2
        Matrix4 LightViewProjectionMatrix3
        //pointLight
        Matrix4 LightViewProjectionMatrix4
        Matrix4 LightViewProjectionMatrix5
        Vector3 LightPos
        Vector3 LightDir

        Float PCFEdge
        Float ShadowMapSize

        // For hardware skinning
        Int NumberOfBones
        Matrix4Array BoneMatrices

        // For Morph animation
        FloatArray MorphWeights
        Int NumberOfMorphTargets
        Int NumberOfTargetsBuffers

        // For instancing
        Boolean UseInstancing

        // For Vertex Color
        Boolean UseVertexColor

        Boolean BackfaceShadows : false
    }

    Technique {
        LightMode SinglePassAndImageBased

        VertexShader GLSL110 GLSL150:   Common/MatDefs/Light/PBRLighting.vert
        FragmentShader GLSL110 GLSL150: Common/MatDefs/Light/PBRLighting.frag

        WorldParameters {
            WorldViewProjectionMatrix
            CameraPosition
            WorldMatrix
            WorldNormalMatrix
            ViewProjectionMatrix
            ViewMatrix
        }

        Defines {
            HAS_COLOR_ARRAY : ColorMap
            BASECOLORMAP : BaseColorMap
            NORMALMAP : NormalMap
            METALLICMAP : MetallicMap
            ROUGHNESSMAP : RoughnessMap
            EMISSIVEMAP : EmissiveMap
            EMISSIVE : Emissive
            SPECGLOSSPIPELINE : UseSpecGloss
            PARALLAXMAP : ParallaxMap
            NORMALMAP_PARALLAX : PackedNormalParallax
            STEEP_PARALLAX : SteepParallax
            LIGHTMAP : LightMap
            SEPARATE_TEXCOORD : SeparateTexCoord
            DISCARD_ALPHA : AlphaDiscardThreshold
            NUM_BONES : NumberOfBones
            INSTANCING : UseInstancing
            USE_PACKED_MR: MetallicRoughnessMap
            USE_PACKED_SG: SpecularGlossinessMap
            SPECULARMAP : SpecularMap
            GLOSSINESSMAP : GlossinessMap
            NORMAL_TYPE: NormalType
            VERTEX_COLOR : UseVertexColor
            AO_MAP: LightMapAsAOMap
            NUM_MORPH_TARGETS: NumberOfMorphTargets
            NUM_TARGETS_BUFFERS: NumberOfTargetsBuffers
            HORIZON_FADE: HorizonFade
        }
    }


    Technique PreShadow {

        VertexShader GLSL100 GLSL150 :   Common/MatDefs/Shadow/PreShadow.vert
        FragmentShader GLSL100 GLSL150 : Common/MatDefs/Shadow/PreShadow.frag

        WorldParameters {
            WorldViewProjectionMatrix
            WorldViewMatrix
            ViewProjectionMatrix
            ViewMatrix
        }

        Defines {
            DISCARD_ALPHA : AlphaDiscardThreshold
            NUM_BONES : NumberOfBones
            INSTANCING : UseInstancing
            NUM_MORPH_TARGETS: NumberOfMorphTargets
            NUM_TARGETS_BUFFERS: NumberOfTargetsBuffers
        }

        ForcedRenderState {
            FaceCull Off
            DepthTest On
            DepthWrite On
            PolyOffset 5 3
            ColorWrite Off
        }

    }


    Technique PostShadow{
        VertexShader GLSL150:   Common/MatDefs/Shadow/PostShadow.vert
        FragmentShader GLSL150: Common/MatDefs/Shadow/PostShadow.frag

        WorldParameters {
            WorldViewProjectionMatrix
            WorldMatrix
            ViewProjectionMatrix
            ViewMatrix
        }

        Defines {
            HARDWARE_SHADOWS : HardwareShadows
            FILTER_MODE : FilterMode
            PCFEDGE : PCFEdge
            DISCARD_ALPHA : AlphaDiscardThreshold
            SHADOWMAP_SIZE : ShadowMapSize
            SHADOWMAP_SIZE : ShadowMapSize
            FADE : FadeInfo
            PSSM : Splits
            POINTLIGHT : LightViewProjectionMatrix5
            NUM_BONES : NumberOfBones
            INSTANCING : UseInstancing
            BACKFACE_SHADOWS: BackfaceShadows
            NUM_MORPH_TARGETS: NumberOfMorphTargets
            NUM_TARGETS_BUFFERS: NumberOfTargetsBuffers
        }

        ForcedRenderState {
            Blend Modulate
            DepthWrite Off
            PolyOffset -0.1 0
        }
    }

    Technique PostShadow{
        VertexShader GLSL100:   Common/MatDefs/Shadow/PostShadow.vert
        FragmentShader GLSL100: Common/MatDefs/Shadow/PostShadow.frag

        WorldParameters {
            WorldViewProjectionMatrix
            WorldMatrix
            ViewProjectionMatrix
            ViewMatrix
        }

        Defines {
            HARDWARE_SHADOWS : HardwareShadows
            FILTER_MODE : FilterMode
            PCFEDGE : PCFEdge
            DISCARD_ALPHA : AlphaDiscardThreshold
            SHADOWMAP_SIZE : ShadowMapSize
            FADE : FadeInfo
            PSSM : Splits
            POINTLIGHT : LightViewProjectionMatrix5
            NUM_BONES : NumberOfBones
            INSTANCING : UseInstancing
            BACKFACE_SHADOWS: BackfaceShadows
            NUM_MORPH_TARGETS: NumberOfMorphTargets
            NUM_TARGETS_BUFFERS: NumberOfTargetsBuffers
        }

        ForcedRenderState {
            Blend Modulate
            DepthWrite Off
            PolyOffset -0.1 0
        }
    }

    Technique PreNormalPass {

        VertexShader GLSL100 :   Common/MatDefs/SSAO/normal.vert
        FragmentShader GLSL100 : Common/MatDefs/SSAO/normal.frag

        WorldParameters {
            WorldViewProjectionMatrix
            WorldViewMatrix
            NormalMatrix
            ViewProjectionMatrix
            ViewMatrix
        }

        Defines {
            NUM_BONES : NumberOfBones
            INSTANCING : UseInstancing
            NUM_MORPH_TARGETS: NumberOfMorphTargets
            NUM_TARGETS_BUFFERS: NumberOfTargetsBuffers
        }

    }

    Technique Glow {

        VertexShader GLSL100 GLSL150:   Common/MatDefs/Misc/Unshaded.vert
        FragmentShader GLSL100 GLSL150: Common/MatDefs/Light/Glow.frag

        WorldParameters {
            WorldViewProjectionMatrix
            ViewProjectionMatrix
            ViewMatrix
        }

        Defines {
            NEED_TEXCOORD1
            NUM_BONES : NumberOfBones
            INSTANCING : UseInstancing
            NUM_MORPH_TARGETS: NumberOfMorphTargets
            NUM_TARGETS_BUFFERS: NumberOfTargetsBuffers
        }
    }

}

ArrayPBRLighting.vert

#import "Common/ShaderLib/GLSLCompat.glsllib"
#import "Common/ShaderLib/Instancing.glsllib"
#import "Common/ShaderLib/Skinning.glsllib"
#import "Common/ShaderLib/MorphAnim.glsllib"

uniform vec4 m_BaseColor;
uniform vec4 g_AmbientLightColor;
varying vec2 texCoord;

#if defined(HAS_COLORMAP) || (defined(HAS_LIGHTMAP) && !defined(SEPARATE_TEXCOORD))
    #define NEED_TEXCOORD8
#endif

#ifdef NEED_TEXCOORD8
    in vec3 inTexCoord8;
    out vec3 texCoord8;
    flat out float vid;
#endif

#ifdef SEPARATE_TEXCOORD
  varying vec2 texCoord2;
  attribute vec2 inTexCoord2;
#endif

varying vec4 Color;

attribute vec3 inPosition;
attribute vec2 inTexCoord;
attribute vec3 inNormal;

#ifdef VERTEX_COLOR
  attribute vec4 inColor;
#endif

varying vec3 wNormal;
varying vec3 wPosition;
#if defined(NORMALMAP) || defined(PARALLAXMAP)
    attribute vec4 inTangent;
    varying vec4 wTangent;
#endif

void main(){
    vec4 modelSpacePos = vec4(inPosition, 1.0);
    vec3 modelSpaceNorm = inNormal;

    #if  ( defined(NORMALMAP) || defined(PARALLAXMAP)) && !defined(VERTEX_LIGHTING)
         vec3 modelSpaceTan  = inTangent.xyz;
    #endif

    #ifdef NEED_TEXCOORD8
        texCoord8 = inTexCoord8;
        vid = inTexCoord8.x;
    #endif

    #ifdef NUM_MORPH_TARGETS
         #if defined(NORMALMAP) && !defined(VERTEX_LIGHTING)
            Morph_Compute(modelSpacePos, modelSpaceNorm, modelSpaceTan);
         #else
            Morph_Compute(modelSpacePos, modelSpaceNorm);
         #endif
    #endif

    #ifdef NUM_BONES
         #if defined(NORMALMAP) && !defined(VERTEX_LIGHTING)
            Skinning_Compute(modelSpacePos, modelSpaceNorm, modelSpaceTan);
         #else
            Skinning_Compute(modelSpacePos, modelSpaceNorm);
         #endif
    #endif

    gl_Position = TransformWorldViewProjection(modelSpacePos);
    texCoord = inTexCoord;
    #ifdef SEPARATE_TEXCOORD
       texCoord2 = inTexCoord2;
    #endif

    wPosition = TransformWorld(modelSpacePos).xyz;
    wNormal  = TransformWorldNormal(modelSpaceNorm);

    #if defined(NORMALMAP) || defined(PARALLAXMAP)
      wTangent = vec4(TransformWorldNormal(modelSpaceTan),inTangent.w);
    #endif

    Color = m_BaseColor;

    #ifdef VERTEX_COLOR
        Color *= inColor;
    #endif
}

ArrayPBRLighting.frag

#import "Common/ShaderLib/GLSLCompat.glsllib"
#import "Common/ShaderLib/PBR.glsllib"
#import "Common/ShaderLib/Parallax.glsllib"
#import "Common/ShaderLib/Lighting.glsllib"

varying vec2 texCoord;
#ifdef SEPARATE_TEXCOORD
  varying vec2 texCoord2;
#endif

#if defined(HAS_GLOWMAP) || defined(HAS_COLORMAP) || (defined(HAS_LIGHTMAP) && !defined(SEPARATE_TEXCOORD))
    #define NEED_TEXCOORD8
#endif

#ifdef NEED_TEXCOORD8
    in vec3 texCoord8;
    flat in float vid;
#endif

varying vec4 Color;

uniform vec4 g_LightData[NB_LIGHTS];
uniform vec3 g_CameraPosition;
uniform vec4 g_AmbientLightColor;

uniform float m_Roughness;
uniform float m_Metallic;

varying vec3 wPosition;


#if NB_PROBES >= 1
  uniform samplerCube g_PrefEnvMap;
  uniform vec3 g_ShCoeffs[9];
  uniform mat4 g_LightProbeData;
#endif
#if NB_PROBES >= 2
  uniform samplerCube g_PrefEnvMap2;
  uniform vec3 g_ShCoeffs2[9];
  uniform mat4 g_LightProbeData2;
#endif
#if NB_PROBES == 3
  uniform samplerCube g_PrefEnvMap3;
  uniform vec3 g_ShCoeffs3[9];
  uniform mat4 g_LightProbeData3;
#endif

#ifdef BASECOLORMAP
    #if !defined(GL_EXT_texture_array)
        #error Texture arrays are not supported, but required to use shader.
    #endif

    uniform sampler2DArray m_BaseColorMap;
#endif

#ifdef USE_PACKED_MR
  uniform sampler2DArray m_MetallicRoughnessMap;
#else
    #ifdef METALLICMAP
      uniform sampler2DArray m_MetallicMap;
    #endif
    #ifdef ROUGHNESSMAP
      uniform sampler2DArray m_RoughnessMap;
    #endif
#endif

#ifdef EMISSIVE
  uniform vec4 m_Emissive;
#endif
#ifdef EMISSIVEMAP
  uniform sampler2DArray m_EmissiveMap;
#endif
#if defined(EMISSIVE) || defined(EMISSIVEMAP)
    uniform float m_EmissivePower;
    uniform float m_EmissiveIntensity;
#endif

#ifdef SPECGLOSSPIPELINE

  uniform vec4 m_Specular;
  uniform float m_Glossiness;
  #ifdef USE_PACKED_SG
    uniform sampler2DArray m_SpecularGlossinessMap;
  #else
    uniform sampler2DArray m_SpecularMap;
    uniform sampler2DArray m_GlossinessMap;
  #endif
#endif

#ifdef PARALLAXMAP
  uniform sampler2DArray m_ParallaxMap;
#endif
#if (defined(PARALLAXMAP) || (defined(NORMALMAP_PARALLAX) && defined(NORMALMAP)))
    uniform float m_ParallaxHeight;
#endif

#ifdef LIGHTMAP
  uniform sampler2DArray m_LightMap;
#endif

#if defined(NORMALMAP) || defined(PARALLAXMAP)
  uniform sampler2DArray m_NormalMap;
  varying vec4 wTangent;
#endif
varying vec3 wNormal;

#ifdef DISCARD_ALPHA
  uniform float m_AlphaDiscardThreshold;
#endif

void main(){
    vec2 newTexCoord;
    vec3 viewDir = normalize(g_CameraPosition - wPosition);

    vec3 norm = normalize(wNormal);
    #if defined(NORMALMAP) || defined(PARALLAXMAP)
        vec3 tan = normalize(wTangent.xyz);
        mat3 tbnMat = mat3(tan, wTangent.w * cross( (norm), (tan)), norm);
    #endif

    #if (defined(PARALLAXMAP) || (defined(NORMALMAP_PARALLAX) && defined(NORMALMAP)))
       vec3 vViewDir =  viewDir * tbnMat;
       #ifdef STEEP_PARALLAX
           #ifdef NORMALMAP_PARALLAX
               //parallax map is stored in the alpha channel of the normal map
               newTexCoord = steepParallaxOffset(texture2DArray(m_NormalMap, vid), vViewDir, texCoord, m_ParallaxHeight);
           #else
               //parallax map is a texture
               newTexCoord = steepParallaxOffset(texture2DArray(m_ParallaxMap, vid), vViewDir, texCoord, m_ParallaxHeight);
           #endif
       #else
           #ifdef NORMALMAP_PARALLAX
               //parallax map is stored in the alpha channel of the normal map
               newTexCoord = classicParallaxOffset(texture2DArray(m_NormalMap, vid), vViewDir, texCoord, m_ParallaxHeight);
           #else
               //parallax map is a texture
               newTexCoord = classicParallaxOffset(texture2DArray(m_ParallaxMap, vid), vViewDir, texCoord, m_ParallaxHeight);
           #endif
       #endif
    #else
       newTexCoord = texCoord;
    #endif

    #ifdef BASECOLORMAP
        vec4 albedo = texture2D(texture2DArray(m_BaseColorMap, vid), newTexCoord) * Color;
    #else
        vec4 albedo = Color;
    #endif

    #ifdef USE_PACKED_MR
        vec2 rm = texture2D(texture2DArray(m_MetallicRoughnessMap, vid), newTexCoord).gb;
        float Roughness = rm.x * max(m_Roughness, 1e-4);
        float Metallic = rm.y * max(m_Metallic, 0.0);
    #else
        #ifdef ROUGHNESSMAP
            float Roughness = texture2D(texture2DArray(m_RoughnessMap, vid), newTexCoord).r * max(m_Roughness, 1e-4);
        #else
            float Roughness =  max(m_Roughness, 1e-4);
        #endif
        #ifdef METALLICMAP
            float Metallic = texture2D(texture2DArray(m_MetallicMap, vid), newTexCoord).r * max(m_Metallic, 0.0);
        #else
            float Metallic =  max(m_Metallic, 0.0);
        #endif
    #endif

    float alpha = albedo.a;

    #ifdef DISCARD_ALPHA
        if(alpha < m_AlphaDiscardThreshold){
            discard;
        }
    #endif

    // ***********************
    // Read from textures
    // ***********************
    #if defined(NORMALMAP)
      vec4 normalHeight = texture2D(texture2DArray(m_NormalMap, vid), newTexCoord);
      //Note the -2.0 and -1.0. We invert the green channel of the normal map,
      //as it's complient with normal maps generated with blender.
      //see http://hub.jmonkeyengine.org/forum/topic/parallax-mapping-fundamental-bug/#post-256898
      //for more explanation.
      vec3 normal = normalize((normalHeight.xyz * vec3(2.0, NORMAL_TYPE * 2.0, 2.0) - vec3(1.0, NORMAL_TYPE * 1.0, 1.0)));
      normal = normalize(tbnMat * normal);
      //normal = normalize(normal * inverse(tbnMat));
    #else
      vec3 normal = norm;
    #endif

    #ifdef SPECGLOSSPIPELINE

        #ifdef USE_PACKED_SG
            vec4 specularColor = texture2D(texture2DArray(m_SpecularGlossinessMap, vid), newTexCoord);
            float glossiness = specularColor.a * m_Glossiness;
            specularColor *= m_Specular;
        #else
            #ifdef SPECULARMAP
                vec4 specularColor = texture2D(texture2DArray(m_SpecularMap, vid), newTexCoord);
            #else
                vec4 specularColor = vec4(1.0);
            #endif
            #ifdef GLOSSINESSMAP
                float glossiness = texture2D(texture2DArray(m_GlossinessMap, vid), newTexCoord).r * m_Glossiness;
            #else
                float glossiness = m_Glossiness;
            #endif
            specularColor *= m_Specular;
        #endif
        vec4 diffuseColor = albedo;// * (1.0 - max(max(specularColor.r, specularColor.g), specularColor.b));
        Roughness = 1.0 - glossiness;
        vec3 fZero = specularColor.xyz;
    #else
        float specular = 0.5;
        float nonMetalSpec = 0.08 * specular;
        vec4 specularColor = (nonMetalSpec - nonMetalSpec * Metallic) + albedo * Metallic;
        vec4 diffuseColor = albedo - albedo * Metallic;
        vec3 fZero = vec3(specular);
    #endif

    gl_FragColor.rgb = vec3(0.0);
    vec3 ao = vec3(1.0);

    #ifdef LIGHTMAP
       vec3 lightMapColor;
       #ifdef SEPARATE_TEXCOORD
          lightMapColor = texture2D(texture2DArray(m_LightMap, vid), texCoord2).rgb;
       #else
          lightMapColor = texture2D(texture2DArray(m_LightMap, vid), texCoord).rgb;
       #endif
       #ifdef AO_MAP
         lightMapColor.gb = lightMapColor.rr;
         ao = lightMapColor;
       #else
         gl_FragColor.rgb += diffuseColor.rgb * lightMapColor;
       #endif
       specularColor.rgb *= lightMapColor;
    #endif


    float ndotv = max( dot( normal, viewDir ),0.0);
    for( int i = 0;i < NB_LIGHTS; i+=3){
        vec4 lightColor = g_LightData[i];
        vec4 lightData1 = g_LightData[i+1];
        vec4 lightDir;
        vec3 lightVec;
        lightComputeDir(wPosition, lightColor.w, lightData1, lightDir, lightVec);

        float fallOff = 1.0;
        #if __VERSION__ >= 110
            // allow use of control flow
        if(lightColor.w > 1.0){
        #endif
            fallOff =  computeSpotFalloff(g_LightData[i+2], lightVec);
        #if __VERSION__ >= 110
        }
        #endif
        //point light attenuation
        fallOff *= lightDir.w;

        lightDir.xyz = normalize(lightDir.xyz);
        vec3 directDiffuse;
        vec3 directSpecular;

        float hdotv = PBR_ComputeDirectLight(normal, lightDir.xyz, viewDir,
                            lightColor.rgb, fZero, Roughness, ndotv,
                            directDiffuse,  directSpecular);

        vec3 directLighting = diffuseColor.rgb *directDiffuse + directSpecular;

        gl_FragColor.rgb += directLighting * fallOff;
    }

    #if NB_PROBES >= 1
        vec3 color1 = vec3(0.0);
        vec3 color2 = vec3(0.0);
        vec3 color3 = vec3(0.0);
        float weight1 = 1.0;
        float weight2 = 0.0;
        float weight3 = 0.0;

        float ndf = renderProbe(viewDir, wPosition, normal, norm, Roughness, diffuseColor, specularColor, ndotv, ao, g_LightProbeData, g_ShCoeffs, g_PrefEnvMap, color1);
        #if NB_PROBES >= 2
            float ndf2 = renderProbe(viewDir, wPosition, normal, norm, Roughness, diffuseColor, specularColor, ndotv, ao, g_LightProbeData2, g_ShCoeffs2, g_PrefEnvMap2, color2);
        #endif
        #if NB_PROBES == 3
            float ndf3 = renderProbe(viewDir, wPosition, normal, norm, Roughness, diffuseColor, specularColor, ndotv, ao, g_LightProbeData3, g_ShCoeffs3, g_PrefEnvMap3, color3);
        #endif

        #if NB_PROBES >= 2
            float invNdf =  max(1.0 - ndf,0.0);
            float invNdf2 =  max(1.0 - ndf2,0.0);
            float sumNdf = ndf + ndf2;
            float sumInvNdf = invNdf + invNdf2;
            #if NB_PROBES == 3
                float invNdf3 = max(1.0 - ndf3,0.0);
                sumNdf += ndf3;
                sumInvNdf += invNdf3;
                weight3 =  ((1.0 - (ndf3 / sumNdf)) / (NB_PROBES - 1)) *  (invNdf3 / sumInvNdf);
            #endif

            weight1 = ((1.0 - (ndf / sumNdf)) / (NB_PROBES - 1)) *  (invNdf / sumInvNdf);
            weight2 = ((1.0 - (ndf2 / sumNdf)) / (NB_PROBES - 1)) *  (invNdf2 / sumInvNdf);

            float weightSum = weight1 + weight2 + weight3;

            weight1 /= weightSum;
            weight2 /= weightSum;
            weight3 /= weightSum;
        #endif

        #if USE_AMBIENT_LIGHT
            color1.rgb *= g_AmbientLightColor.rgb;
            color2.rgb *= g_AmbientLightColor.rgb;
            color3.rgb *= g_AmbientLightColor.rgb;
        #endif
        gl_FragColor.rgb += color1 * clamp(weight1,0.0,1.0) + color2 * clamp(weight2,0.0,1.0) + color3 * clamp(weight3,0.0,1.0);

    #endif

    #if defined(EMISSIVE) || defined (EMISSIVEMAP)
        #ifdef EMISSIVEMAP
            vec4 emissive = texture2D(texture2DArray(m_EmissiveMap, vid), newTexCoord);
        #else
            vec4 emissive = m_Emissive;
        #endif
        gl_FragColor += emissive * pow(emissive.a, m_EmissivePower) * m_EmissiveIntensity;
    #endif
    gl_FragColor.a = alpha;

}

I dont know why its “black” for you. (i dont even know why texcoord8? i use texture array different way)

But if you want some reference here was “Non-voxel” terrain PBR+TextureArray+Parallax one. So maybe it will help you somehow.

1 Like

Thanks, I will take a look!

The TexCoord8 is a vec3 that has the texture id that corresponds with each vertex in the mesh.

Ah, ok :slight_smile:

Why not TexCoord3 or TexCoord4? is it some special number? or you just wanted to be sure it will not be used?

BTW: in link i provided code is send in 2 posts, and it ofc require “LWJGL_OPENGL3” for TextureArray.

1 Like

It can be TexCoord3. When I started I was using another very simple shader I wrote for voxel texture arrays that used TexCoord, but the PBR Lighting shader already used TexCoord, TexCoord1, TexCoord2. So just for testing I jumped to 8. I will probably make it use 3 after I have it working.

EDIT: Yeah, opengl3 is a must for texture arrays, not an issue for me though. My current shader also requires it for the same reason.

1 Like

I suspect it has something to do with the PBR library in the fragment shader.

#import "Common/ShaderLib/PBR.glsllib"
texture2D(texture2DArray(m_BaseColorMap, vid), newTexCoord)

is wrong.
It should be

texture2DArray(m_BaseColorMap, vec3(newTexCoord,vid))

or

texture(m_BaseColorMap, vec3(newTexCoord,vid))

with the modern syntax.

1 Like

thanks for the correction. Unfortunately everything is still black. I probably am doing something dumb, but I will keep tinkering on it, still trying to learn how shaders work.

Mhh, you should get some errors in your logs, but i noticed that your j3m (that should actually be a j3md, since it’s a material definition) doesn’t use the shaders you posted here… as you can see

      VertexShader GLSL110 GLSL150:   Common/MatDefs/Light/PBRLighting.vert
      FragmentShader GLSL110 GLSL150: Common/MatDefs/Light/PBRLighting.frag

maybe that’s the reason why you don’t get any…

1 Like

Oh, you are absolutely correct! I forgot to change those!

It is a j3md, just a typo on the post :slight_smile:

OK, now I am getting somewhere! I finally have errors!
unable to find compatible overloaded function "texture2DArray(sampler2DArray, float)"

#extension GL_EXT_texture_array : enable

?

1 Like

It was a typo I had made in the code. I am trying a fix right now.

I had forgot about that!

IT WORKS!
I need to run some more tests, but it looks like it is working. Although I am having trouble seeing the textures, the color looks right, and the lighting works. I think it may just be my poor laptop screen making the detail hard to see.

For anyone interested, here is the shader:
ArrayPBRLighting.j3md

MaterialDef PBR Lighting {

    MaterialParameters {

        // Alpha threshold for fragment discarding
        Float AlphaDiscardThreshold (AlphaTestFallOff)

        //metalness of the material
        Float Metallic : 1.0
        //Roughness of the material
        Float Roughness : 1.0
        // Base material color
        Color BaseColor : 1.0 1.0 1.0 1.0
        // The emissive color of the object
        Color Emissive
        // the emissive power
        Float EmissivePower : 3.0
        // the emissive intensity
        Float EmissiveIntensity : 2.0

        // BaseColor map
        TextureArray BaseColorMap

        // Metallic map
        TextureArray MetallicMap -LINEAR

        // Roughness Map
        TextureArray RoughnessMap -LINEAR

        //Metallic and Roughness are packed respectively in the b and g channel of a single map
        // r: unspecified
        // g: Roughness
        // b: Metallic
        TextureArray MetallicRoughnessMap -LINEAR

        // Texture of the emissive parts of the material
        TextureArray EmissiveMap

        // Normal map
        TextureArray NormalMap -LINEAR

        //The type of normal map: -1.0 (DirectX), 1.0 (OpenGl)
        Float NormalType : -1.0

        // For Spec gloss pipeline
        Boolean UseSpecGloss
        TextureArray SpecularMap
        TextureArray GlossinessMap
        TextureArray SpecularGlossinessMap
        Color Specular : 1.0 1.0 1.0 1.0
        Float Glossiness : 1.0

        // Parallax/height map
        TextureArray ParallaxMap -LINEAR

        //Set to true if parallax map is stored in the alpha channel of the normal map
        Boolean PackedNormalParallax

        //Sets the relief height for parallax mapping
        Float ParallaxHeight : 0.05

        //Set to true to activate Steep Parallax mapping
        Boolean SteepParallax

        //Horizon fade
        Boolean HorizonFade

        // Set to Use Lightmap
        TextureArray LightMap

        // Set to use TexCoord2 for the lightmap sampling
        Boolean SeparateTexCoord

        // the light map is a gray scale ao map, on ly the r channel will be read.
        Boolean LightMapAsAOMap

        //shadows
        Int FilterMode
        Boolean HardwareShadows

        Texture2D ShadowMap0
        Texture2D ShadowMap1
        Texture2D ShadowMap2
        Texture2D ShadowMap3
        //pointLights
        Texture2D ShadowMap4
        Texture2D ShadowMap5

        Float ShadowIntensity
        Vector4 Splits
        Vector2 FadeInfo

        Matrix4 LightViewProjectionMatrix0
        Matrix4 LightViewProjectionMatrix1
        Matrix4 LightViewProjectionMatrix2
        Matrix4 LightViewProjectionMatrix3
        //pointLight
        Matrix4 LightViewProjectionMatrix4
        Matrix4 LightViewProjectionMatrix5
        Vector3 LightPos
        Vector3 LightDir

        Float PCFEdge
        Float ShadowMapSize

        // For hardware skinning
        Int NumberOfBones
        Matrix4Array BoneMatrices

        // For Morph animation
        FloatArray MorphWeights
        Int NumberOfMorphTargets
        Int NumberOfTargetsBuffers

        // For instancing
        Boolean UseInstancing

        // For Vertex Color
        Boolean UseVertexColor

        Boolean BackfaceShadows : false
    }

    Technique {
        LightMode SinglePassAndImageBased

        VertexShader GLSL110 GLSL150:   Shaders/ArrayPBRLighting.vert
        FragmentShader GLSL110 GLSL150: Shaders/ArrayPBRLighting.frag

        WorldParameters {
            WorldViewProjectionMatrix
            CameraPosition
            WorldMatrix
            WorldNormalMatrix
            ViewProjectionMatrix
            ViewMatrix
        }

        Defines {
            BASECOLORMAP : BaseColorMap
            NORMALMAP : NormalMap
            METALLICMAP : MetallicMap
            ROUGHNESSMAP : RoughnessMap
            EMISSIVEMAP : EmissiveMap
            EMISSIVE : Emissive
            SPECGLOSSPIPELINE : UseSpecGloss
            PARALLAXMAP : ParallaxMap
            NORMALMAP_PARALLAX : PackedNormalParallax
            STEEP_PARALLAX : SteepParallax
            LIGHTMAP : LightMap
            SEPARATE_TEXCOORD : SeparateTexCoord
            DISCARD_ALPHA : AlphaDiscardThreshold
            NUM_BONES : NumberOfBones
            INSTANCING : UseInstancing
            USE_PACKED_MR: MetallicRoughnessMap
            USE_PACKED_SG: SpecularGlossinessMap
            SPECULARMAP : SpecularMap
            GLOSSINESSMAP : GlossinessMap
            NORMAL_TYPE: NormalType
            VERTEX_COLOR : UseVertexColor
            AO_MAP: LightMapAsAOMap
            NUM_MORPH_TARGETS: NumberOfMorphTargets
            NUM_TARGETS_BUFFERS: NumberOfTargetsBuffers
            HORIZON_FADE: HorizonFade
        }
    }


    Technique PreShadow {

        VertexShader GLSL100 GLSL150 :   Common/MatDefs/Shadow/PreShadow.vert
        FragmentShader GLSL100 GLSL150 : Common/MatDefs/Shadow/PreShadow.frag

        WorldParameters {
            WorldViewProjectionMatrix
            WorldViewMatrix
            ViewProjectionMatrix
            ViewMatrix
        }

        Defines {
            DISCARD_ALPHA : AlphaDiscardThreshold
            NUM_BONES : NumberOfBones
            INSTANCING : UseInstancing
            NUM_MORPH_TARGETS: NumberOfMorphTargets
            NUM_TARGETS_BUFFERS: NumberOfTargetsBuffers
        }

        ForcedRenderState {
            FaceCull Off
            DepthTest On
            DepthWrite On
            PolyOffset 5 3
            ColorWrite Off
        }

    }


    Technique PostShadow{
        VertexShader GLSL150:   Common/MatDefs/Shadow/PostShadow.vert
        FragmentShader GLSL150: Common/MatDefs/Shadow/PostShadow.frag

        WorldParameters {
            WorldViewProjectionMatrix
            WorldMatrix
            ViewProjectionMatrix
            ViewMatrix
        }

        Defines {
            HARDWARE_SHADOWS : HardwareShadows
            FILTER_MODE : FilterMode
            PCFEDGE : PCFEdge
            DISCARD_ALPHA : AlphaDiscardThreshold
            SHADOWMAP_SIZE : ShadowMapSize
            SHADOWMAP_SIZE : ShadowMapSize
            FADE : FadeInfo
            PSSM : Splits
            POINTLIGHT : LightViewProjectionMatrix5
            NUM_BONES : NumberOfBones
            INSTANCING : UseInstancing
            BACKFACE_SHADOWS: BackfaceShadows
            NUM_MORPH_TARGETS: NumberOfMorphTargets
            NUM_TARGETS_BUFFERS: NumberOfTargetsBuffers
        }

        ForcedRenderState {
            Blend Modulate
            DepthWrite Off
            PolyOffset -0.1 0
        }
    }

    Technique PostShadow{
        VertexShader GLSL100:   Common/MatDefs/Shadow/PostShadow.vert
        FragmentShader GLSL100: Common/MatDefs/Shadow/PostShadow.frag

        WorldParameters {
            WorldViewProjectionMatrix
            WorldMatrix
            ViewProjectionMatrix
            ViewMatrix
        }

        Defines {
            HARDWARE_SHADOWS : HardwareShadows
            FILTER_MODE : FilterMode
            PCFEDGE : PCFEdge
            DISCARD_ALPHA : AlphaDiscardThreshold
            SHADOWMAP_SIZE : ShadowMapSize
            FADE : FadeInfo
            PSSM : Splits
            POINTLIGHT : LightViewProjectionMatrix5
            NUM_BONES : NumberOfBones
            INSTANCING : UseInstancing
            BACKFACE_SHADOWS: BackfaceShadows
            NUM_MORPH_TARGETS: NumberOfMorphTargets
            NUM_TARGETS_BUFFERS: NumberOfTargetsBuffers
        }

        ForcedRenderState {
            Blend Modulate
            DepthWrite Off
            PolyOffset -0.1 0
        }
    }

    Technique PreNormalPass {

        VertexShader GLSL100 :   Common/MatDefs/SSAO/normal.vert
        FragmentShader GLSL100 : Common/MatDefs/SSAO/normal.frag

        WorldParameters {
            WorldViewProjectionMatrix
            WorldViewMatrix
            NormalMatrix
            ViewProjectionMatrix
            ViewMatrix
        }

        Defines {
            NUM_BONES : NumberOfBones
            INSTANCING : UseInstancing
            NUM_MORPH_TARGETS: NumberOfMorphTargets
            NUM_TARGETS_BUFFERS: NumberOfTargetsBuffers
        }

    }

    Technique Glow {

        VertexShader GLSL100 GLSL150:   Common/MatDefs/Misc/Unshaded.vert
        FragmentShader GLSL100 GLSL150: Common/MatDefs/Light/Glow.frag

        WorldParameters {
            WorldViewProjectionMatrix
            ViewProjectionMatrix
            ViewMatrix
        }

        Defines {
            NEED_TEXCOORD1
            NUM_BONES : NumberOfBones
            INSTANCING : UseInstancing
            NUM_MORPH_TARGETS: NumberOfMorphTargets
            NUM_TARGETS_BUFFERS: NumberOfTargetsBuffers
        }
    }

}

ArrayPBRLighting.frag

#extension GL_EXT_texture_array : enable
#import "Common/ShaderLib/GLSLCompat.glsllib"
#import "Common/ShaderLib/PBR.glsllib"
#import "Common/ShaderLib/Parallax.glsllib"
#import "Common/ShaderLib/Lighting.glsllib"

varying vec2 texCoord;
#ifdef SEPARATE_TEXCOORD
  varying vec2 texCoord2;
#endif

flat in float vid;

varying vec4 Color;

uniform vec4 g_LightData[NB_LIGHTS];
uniform vec3 g_CameraPosition;
uniform vec4 g_AmbientLightColor;

uniform float m_Roughness;
uniform float m_Metallic;

varying vec3 wPosition;


#if NB_PROBES >= 1
  uniform samplerCube g_PrefEnvMap;
  uniform vec3 g_ShCoeffs[9];
  uniform mat4 g_LightProbeData;
#endif
#if NB_PROBES >= 2
  uniform samplerCube g_PrefEnvMap2;
  uniform vec3 g_ShCoeffs2[9];
  uniform mat4 g_LightProbeData2;
#endif
#if NB_PROBES == 3
  uniform samplerCube g_PrefEnvMap3;
  uniform vec3 g_ShCoeffs3[9];
  uniform mat4 g_LightProbeData3;
#endif

#ifdef BASECOLORMAP
    #if !defined(GL_EXT_texture_array)
        #error Texture arrays are not supported, but required to use shader.
    #endif

    uniform sampler2DArray m_BaseColorMap;
#endif

#ifdef USE_PACKED_MR
  uniform sampler2DArray m_MetallicRoughnessMap;
#else
    #ifdef METALLICMAP
      uniform sampler2DArray m_MetallicMap;
    #endif
    #ifdef ROUGHNESSMAP
      uniform sampler2DArray m_RoughnessMap;
    #endif
#endif

#ifdef EMISSIVE
  uniform vec4 m_Emissive;
#endif
#ifdef EMISSIVEMAP
  uniform sampler2DArray m_EmissiveMap;
#endif
#if defined(EMISSIVE) || defined(EMISSIVEMAP)
    uniform float m_EmissivePower;
    uniform float m_EmissiveIntensity;
#endif

#ifdef SPECGLOSSPIPELINE

  uniform vec4 m_Specular;
  uniform float m_Glossiness;
  #ifdef USE_PACKED_SG
    uniform sampler2DArray m_SpecularGlossinessMap;
  #else
    uniform sampler2DArray m_SpecularMap;
    uniform sampler2DArray m_GlossinessMap;
  #endif
#endif

#ifdef PARALLAXMAP
  uniform sampler2DArray m_ParallaxMap;
#endif
#if (defined(PARALLAXMAP) || (defined(NORMALMAP_PARALLAX) && defined(NORMALMAP)))
    uniform float m_ParallaxHeight;
#endif

#ifdef LIGHTMAP
  uniform sampler2DArray m_LightMap;
#endif

#if defined(NORMALMAP) || defined(PARALLAXMAP)
  uniform sampler2DArray m_NormalMap;
  varying vec4 wTangent;
#endif
varying vec3 wNormal;

#ifdef DISCARD_ALPHA
  uniform float m_AlphaDiscardThreshold;
#endif

void main(){
    vec2 newTexCoord;
    vec3 viewDir = normalize(g_CameraPosition - wPosition);

    vec3 norm = normalize(wNormal);
    #if defined(NORMALMAP) || defined(PARALLAXMAP)
        vec3 tan = normalize(wTangent.xyz);
        mat3 tbnMat = mat3(tan, wTangent.w * cross( (norm), (tan)), norm);
    #endif

    #if (defined(PARALLAXMAP) || (defined(NORMALMAP_PARALLAX) && defined(NORMALMAP)))
       vec3 vViewDir =  viewDir * tbnMat;
       #ifdef STEEP_PARALLAX
           #ifdef NORMALMAP_PARALLAX
               //parallax map is stored in the alpha channel of the normal map
               newTexCoord = steepParallaxOffset(texture2DArray(m_NormalMap, vid), vViewDir, texCoord, m_ParallaxHeight);
           #else
               //parallax map is a texture
               newTexCoord = steepParallaxOffset(texture2DArray(m_ParallaxMap, vid), vViewDir, texCoord, m_ParallaxHeight);
           #endif
       #else
           #ifdef NORMALMAP_PARALLAX
               //parallax map is stored in the alpha channel of the normal map
               newTexCoord = classicParallaxOffset(texture2DArray(m_NormalMap, vid), vViewDir, texCoord, m_ParallaxHeight);
           #else
               //parallax map is a texture
               newTexCoord = classicParallaxOffset(texture2DArray(m_ParallaxMap, vid), vViewDir, texCoord, m_ParallaxHeight);
           #endif
       #endif
    #else
       newTexCoord = texCoord;
    #endif

    #ifdef BASECOLORMAP
        vec4 albedo = texture(m_BaseColorMap, vec3(newTexCoord,vid)) * Color;
    #else
        vec4 albedo = Color;
    #endif

    #ifdef USE_PACKED_MR
        vec2 rm = texture(m_MetallicRoughnessMap, vec3(newTexCoord,vid)).gb;
        float Roughness = rm.x * max(m_Roughness, 1e-4);
        float Metallic = rm.y * max(m_Metallic, 0.0);
    #else
        #ifdef ROUGHNESSMAP
            float Roughness = texture(m_RoughnessMap, vec3(newTexCoord,vid)).r * max(m_Roughness, 1e-4);
        #else
            float Roughness =  max(m_Roughness, 1e-4);
        #endif
        #ifdef METALLICMAP
            float Metallic = texture(m_MetallicMap, vec3(newTexCoord,vid)).r * max(m_Metallic, 0.0);
        #else
            float Metallic =  max(m_Metallic, 0.0);
        #endif
    #endif

    float alpha = albedo.a;

    #ifdef DISCARD_ALPHA
        if(alpha < m_AlphaDiscardThreshold){
            discard;
        }
    #endif

    // ***********************
    // Read from textures
    // ***********************
    #if defined(NORMALMAP)
      vec4 normalHeight = texture(m_NormalMap, vec3(newTexCoord,vid));
      //Note the -2.0 and -1.0. We invert the green channel of the normal map,
      //as it's complient with normal maps generated with blender.
      //see http://hub.jmonkeyengine.org/forum/topic/parallax-mapping-fundamental-bug/#post-256898
      //for more explanation.
      vec3 normal = normalize((normalHeight.xyz * vec3(2.0, NORMAL_TYPE * 2.0, 2.0) - vec3(1.0, NORMAL_TYPE * 1.0, 1.0)));
      normal = normalize(tbnMat * normal);
      //normal = normalize(normal * inverse(tbnMat));
    #else
      vec3 normal = norm;
    #endif

    #ifdef SPECGLOSSPIPELINE

        #ifdef USE_PACKED_SG
            vec4 specularColor = texture(m_SpecularGlossinessMap, vec3(newTexCoord,vid));
            float glossiness = specularColor.a * m_Glossiness;
            specularColor *= m_Specular;
        #else
            #ifdef SPECULARMAP
                vec4 specularColor = texture(m_SpecularMap, vec3(newTexCoord,vid));
            #else
                vec4 specularColor = vec4(1.0);
            #endif
            #ifdef GLOSSINESSMAP
                float glossiness = texture(m_GlossinessMap, vec3(newTexCoord,vid)).r * m_Glossiness;
            #else
                float glossiness = m_Glossiness;
            #endif
            specularColor *= m_Specular;
        #endif
        vec4 diffuseColor = albedo;// * (1.0 - max(max(specularColor.r, specularColor.g), specularColor.b));
        Roughness = 1.0 - glossiness;
        vec3 fZero = specularColor.xyz;
    #else
        float specular = 0.5;
        float nonMetalSpec = 0.08 * specular;
        vec4 specularColor = (nonMetalSpec - nonMetalSpec * Metallic) + albedo * Metallic;
        vec4 diffuseColor = albedo - albedo * Metallic;
        vec3 fZero = vec3(specular);
    #endif

    gl_FragColor.rgb = vec3(0.0);
    vec3 ao = vec3(1.0);

    #ifdef LIGHTMAP
       vec3 lightMapColor;
       #ifdef SEPARATE_TEXCOORD
          lightMapColor = texture(m_LightMap, vec3(texCoord2,vid)).rgb;
       #else
          lightMapColor = texture(m_LightMap, vec3(texCoord,vid)).rgb;
       #endif
       #ifdef AO_MAP
         lightMapColor.gb = lightMapColor.rr;
         ao = lightMapColor;
       #else
         gl_FragColor.rgb += diffuseColor.rgb * lightMapColor;
       #endif
       specularColor.rgb *= lightMapColor;
    #endif


    float ndotv = max( dot( normal, viewDir ),0.0);
    for( int i = 0;i < NB_LIGHTS; i+=3){
        vec4 lightColor = g_LightData[i];
        vec4 lightData1 = g_LightData[i+1];
        vec4 lightDir;
        vec3 lightVec;
        lightComputeDir(wPosition, lightColor.w, lightData1, lightDir, lightVec);

        float fallOff = 1.0;
        #if __VERSION__ >= 110
            // allow use of control flow
        if(lightColor.w > 1.0){
        #endif
            fallOff =  computeSpotFalloff(g_LightData[i+2], lightVec);
        #if __VERSION__ >= 110
        }
        #endif
        //point light attenuation
        fallOff *= lightDir.w;

        lightDir.xyz = normalize(lightDir.xyz);
        vec3 directDiffuse;
        vec3 directSpecular;

        float hdotv = PBR_ComputeDirectLight(normal, lightDir.xyz, viewDir,
                            lightColor.rgb, fZero, Roughness, ndotv,
                            directDiffuse,  directSpecular);

        vec3 directLighting = diffuseColor.rgb *directDiffuse + directSpecular;

        gl_FragColor.rgb += directLighting * fallOff;
    }

    #if NB_PROBES >= 1
        vec3 color1 = vec3(0.0);
        vec3 color2 = vec3(0.0);
        vec3 color3 = vec3(0.0);
        float weight1 = 1.0;
        float weight2 = 0.0;
        float weight3 = 0.0;

        float ndf = renderProbe(viewDir, wPosition, normal, norm, Roughness, diffuseColor, specularColor, ndotv, ao, g_LightProbeData, g_ShCoeffs, g_PrefEnvMap, color1);
        #if NB_PROBES >= 2
            float ndf2 = renderProbe(viewDir, wPosition, normal, norm, Roughness, diffuseColor, specularColor, ndotv, ao, g_LightProbeData2, g_ShCoeffs2, g_PrefEnvMap2, color2);
        #endif
        #if NB_PROBES == 3
            float ndf3 = renderProbe(viewDir, wPosition, normal, norm, Roughness, diffuseColor, specularColor, ndotv, ao, g_LightProbeData3, g_ShCoeffs3, g_PrefEnvMap3, color3);
        #endif

        #if NB_PROBES >= 2
            float invNdf =  max(1.0 - ndf,0.0);
            float invNdf2 =  max(1.0 - ndf2,0.0);
            float sumNdf = ndf + ndf2;
            float sumInvNdf = invNdf + invNdf2;
            #if NB_PROBES == 3
                float invNdf3 = max(1.0 - ndf3,0.0);
                sumNdf += ndf3;
                sumInvNdf += invNdf3;
                weight3 =  ((1.0 - (ndf3 / sumNdf)) / (NB_PROBES - 1)) *  (invNdf3 / sumInvNdf);
            #endif

            weight1 = ((1.0 - (ndf / sumNdf)) / (NB_PROBES - 1)) *  (invNdf / sumInvNdf);
            weight2 = ((1.0 - (ndf2 / sumNdf)) / (NB_PROBES - 1)) *  (invNdf2 / sumInvNdf);

            float weightSum = weight1 + weight2 + weight3;

            weight1 /= weightSum;
            weight2 /= weightSum;
            weight3 /= weightSum;
        #endif

        #if USE_AMBIENT_LIGHT
            color1.rgb *= g_AmbientLightColor.rgb;
            color2.rgb *= g_AmbientLightColor.rgb;
            color3.rgb *= g_AmbientLightColor.rgb;
        #endif
        gl_FragColor.rgb += color1 * clamp(weight1,0.0,1.0) + color2 * clamp(weight2,0.0,1.0) + color3 * clamp(weight3,0.0,1.0);

    #endif

    #if defined(EMISSIVE) || defined (EMISSIVEMAP)
        #ifdef EMISSIVEMAP
            vec4 emissive = texture(m_EmissiveMap, vec3(newTexCoord,vid));
        #else
            vec4 emissive = m_Emissive;
        #endif
        gl_FragColor += emissive * pow(emissive.a, m_EmissivePower) * m_EmissiveIntensity;
    #endif
    gl_FragColor.a = alpha;

}

ArrayPBRLighting.vert

#import "Common/ShaderLib/GLSLCompat.glsllib"
#import "Common/ShaderLib/Instancing.glsllib"
#import "Common/ShaderLib/Skinning.glsllib"
#import "Common/ShaderLib/MorphAnim.glsllib"

uniform vec4 m_BaseColor;
uniform vec4 g_AmbientLightColor;
varying vec2 texCoord;

#if defined(HAS_COLORMAP) || (defined(HAS_LIGHTMAP) && !defined(SEPARATE_TEXCOORD))
    #define NEED_TEXCOORD8
#endif

#ifdef NEED_TEXCOORD8
    in vec3 inTexCoord8;
    out vec3 texCoord8;
    flat out float vid;
#endif

#ifdef SEPARATE_TEXCOORD
  varying vec2 texCoord2;
  attribute vec2 inTexCoord2;
#endif

varying vec4 Color;

attribute vec3 inPosition;
attribute vec2 inTexCoord;
attribute vec3 inNormal;

#ifdef VERTEX_COLOR
  attribute vec4 inColor;
#endif

varying vec3 wNormal;
varying vec3 wPosition;
#if defined(NORMALMAP) || defined(PARALLAXMAP)
    attribute vec4 inTangent;
    varying vec4 wTangent;
#endif

void main(){
    vec4 modelSpacePos = vec4(inPosition, 1.0);
    vec3 modelSpaceNorm = inNormal;

    #if  ( defined(NORMALMAP) || defined(PARALLAXMAP)) && !defined(VERTEX_LIGHTING)
         vec3 modelSpaceTan  = inTangent.xyz;
    #endif

    #ifdef NEED_TEXCOORD8
        texCoord8 = inTexCoord8;
        vid = inTexCoord8.x;
    #endif

    #ifdef NUM_MORPH_TARGETS
         #if defined(NORMALMAP) && !defined(VERTEX_LIGHTING)
            Morph_Compute(modelSpacePos, modelSpaceNorm, modelSpaceTan);
         #else
            Morph_Compute(modelSpacePos, modelSpaceNorm);
         #endif
    #endif

    #ifdef NUM_BONES
         #if defined(NORMALMAP) && !defined(VERTEX_LIGHTING)
            Skinning_Compute(modelSpacePos, modelSpaceNorm, modelSpaceTan);
         #else
            Skinning_Compute(modelSpacePos, modelSpaceNorm);
         #endif
    #endif

    gl_Position = TransformWorldViewProjection(modelSpacePos);
    texCoord = inTexCoord;
    #ifdef SEPARATE_TEXCOORD
       texCoord2 = inTexCoord2;
    #endif

    wPosition = TransformWorld(modelSpacePos).xyz;
    wNormal  = TransformWorldNormal(modelSpaceNorm);

    #if defined(NORMALMAP) || defined(PARALLAXMAP)
      wTangent = vec4(TransformWorldNormal(modelSpaceTan),inTangent.w);
    #endif

    Color = m_BaseColor;

    #ifdef VERTEX_COLOR
        Color *= inColor;
    #endif
}
2 Likes

So, I am going to revive this.
I cannot figure out why, but the baseColorMap texture is not being wrapped around the terrain. The correct texture is being selected for the vertex, but it is making everything one color. If I change the texture, the color changes. I am not sure if it is doing this for the other texture maps.

Remove the SOLVED tag?

Sorry can’t help with the code, shader code makes me sleepy.

1 Like

We can’t debug code we can’t see, so my first presumption would be that you haven’t set wrapmode on the texture array…?

Edit. Actually. It depends on what you’re doing. IsoSurfaces use 3D texture coordinates. Effectively they’re world coords. Again - no code to look at but it appears to be texture-coordinate related.

I am trying to build a test case, I am using a heavily modified version of your iso-surface terrain, the issue is that it is coupled into my project now. I am adapting a test case based on your repo, but it will take me a bit.

The default PBR shader uses texture coords. Just tell the shader to use the vertex coords instead.

OK, here is my test case: GitHub - tlf30/iso-terrain-pbr: Modified version of https://github.com/jayfella/iso-terrain for PBR testing.

I also see I have another issue, which is probably related, but it does not look like the vid is getting the correct value in the shader…

Files modified are:
MarchingCubesMeshGenerator2
Main
MaterialManager
AnimaliaWorld

I also added a PbrLighting appstate.

PS: Your main iso-surface repo does not compile, and the Main does not run correctly. This test repo has several other fixes not related to PBR in it…