Parallax Occlusion Mapping for jme

j3md:

// NOTE: Doesn't support OpenGL1
MaterialDef PBR Terrain {

    MaterialParameters {
        Float NormalType : -1.0
        Vector4 ProbeColor

        // Use alpha channel of normal texture for parallax mapping;
        Boolean parallaxMapping

        Float ParallaxLODDistance : 20 

        // The emissive color of the object
        Color Emissive        
        // the emissive power
        Float EmissivePower : 3.5      
        // the emissive intensity
        Float EmissiveIntensity : 2.3

        // Specular/gloss map
        Texture2D MetallicMap -LINEAR

        // Set to Use Lightmap
        Texture2D LightMap

        Float Roughness_0 : 0.0
        Float Roughness_1 : 0.0
        Float Roughness_2 : 0.0
        Float Roughness_3 : 0.0
        Float Roughness_4 : 0.0
        Float Roughness_5 : 0.0
        Float Roughness_6 : 0.0
        Float Roughness_7 : 0.0
        Float Roughness_8 : 0.0
        Float Roughness_9 : 0.0
        Float Roughness_10 : 0.0
        Float Roughness_11 : 0.0

        Float Metallic_0 : 0.0
        Float Metallic_1 : 0.0
        Float Metallic_2 : 0.0
        Float Metallic_3 : 0.0
        Float Metallic_4 : 0.0
        Float Metallic_5 : 0.0
        Float Metallic_6 : 0.0
        Float Metallic_7 : 0.0
        Float Metallic_8 : 0.0
        Float Metallic_9 : 0.0
        Float Metallic_10 : 0.0
        Float Metallic_11 : 0.0

        // use tri-planar mapping
        Boolean useTriPlanarMapping

        // Use ward specular instead of phong
        Boolean WardIso

        // Albedo color
        Color Albedo

        TextureArray PhongTextures
        TextureArray NormalmapTextures -LINEAR
        TextureArray ParallaxmapTextures -LINEAR

        // Texture map #0
        Float Slot_0_scale
        Float ParallaxHeight_0
        Boolean UseSlot_0
        Boolean UseNormalMap_0
        Boolean UseParallaxMap_0

        // Texture map #1
        Float Slot_1_scale
        Float ParallaxHeight_1
        Boolean UseSlot_1
        Boolean UseNormalMap_1
        Boolean UseParallaxMap_1

        // Texture map #2
        Float Slot_2_scale
        Float ParallaxHeight_2
        Boolean UseSlot_2
        Boolean UseNormalMap_2
        Boolean UseParallaxMap_2

        // Texture map #3
        Float Slot_3_scale
        Float ParallaxHeight_3
        Boolean UseSlot_3
        Boolean UseNormalMap_3
        Boolean UseParallaxMap_3

        // Texture map #4
        Float Slot_4_scale
        Float ParallaxHeight_4
        Boolean UseSlot_4
        Boolean UseNormalMap_4
        Boolean UseParallaxMap_4

        // Texture map #5
        Float Slot_5_scale
        Float ParallaxHeight_5
        Boolean UseSlot_5
        Boolean UseNormalMap_5
        Boolean UseParallaxMap_5

        // Texture map #6
        Float Slot_6_scale
        Float ParallaxHeight_6
        Boolean UseSlot_6
        Boolean UseNormalMap_6
        Boolean UseParallaxMap_6

        // Texture map #7
        Float Slot_7_scale
        Float ParallaxHeight_7
        Boolean UseSlot_7
        Boolean UseNormalMap_7
        Boolean UseParallaxMap_7

        // Texture map #8
        Float Slot_8_scale
        Float ParallaxHeight_8
        Boolean UseSlot_8
        Boolean UseNormalMap_8
        Boolean UseParallaxMap_8

        // Texture map #9
        Float Slot_9_scale
        Float ParallaxHeight_9
        Boolean UseSlot_9
        Boolean UseNormalMap_9
        Boolean UseParallaxMap_9

        // Texture map #10
        Float Slot_10_scale
        Float ParallaxHeight_10
        Boolean UseSlot_10
        Boolean UseNormalMap_10
        Boolean UseParallaxMap_10

        // Texture map #11
        Float Slot_11_scale
        Float ParallaxHeight_11
        Boolean UseSlot_11
        Boolean UseNormalMap_11
        Boolean UseParallaxMap_11

        // Texture that specifies alpha values
        Texture2D AlphaMap -LINEAR
        Texture2D AlphaMap_1 -LINEAR
        Texture2D AlphaMap_2 -LINEAR

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

        Vector4 ProbeData

        // Prefiltered Env Map for indirect specular lighting
        TextureCubeMap PrefEnvMap -LINEAR
        
        // Irradiance map for indirect diffuse lighting
        TextureCubeMap IrradianceMap -LINEAR

        //integrate BRDF map for indirect Lighting
        Texture2D IntegrateBRDF -LINEAR

        // Parallax/height map
        Texture2D ParallaxMap -LINEAR

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

        // Set to Use Lightmap
        Texture2D 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 instancing
        Boolean UseInstancing

        //For Vertex Color
        Boolean UseVertexColor

        Boolean BackfaceShadows : false
    }

    Technique {

        LightMode SinglePassAndImageBased

        VertexShader GLSL150:   MatDefs/PBRTerrainV2/terrainPBRShaderV2.vert
        FragmentShader GLSL150: MatDefs/PBRTerrainV2/terrainPBRShaderV2.frag

        WorldParameters {
            WorldViewProjectionMatrix
            CameraPosition
            WorldMatrix
            WorldNormalMatrix
            ViewProjectionMatrix
            ViewMatrix
            Time
        }

        Defines {
            PARALLAX_LOD_DISTANCE : ParallaxLODDistance
            PARALLAXMAPPING : parallaxMapping
            EMISSIVEMAP : EmissiveMap
            SPECGLOSSPIPELINE : SpecularMap
            PROBE_COLOR : ProbeColor
            NORMAL_TYPE: NormalType
            TRI_PLANAR_MAPPING : useTriPlanarMapping
            SLOT_0 : UseSlot_0
            SLOT_1 : UseSlot_1
            SLOT_2 : UseSlot_2
            SLOT_3 : UseSlot_3
            SLOT_4 : UseSlot_4
            SLOT_5 : UseSlot_5
            SLOT_6 : UseSlot_6
            SLOT_7 : UseSlot_7
            SLOT_8 : UseSlot_8
            SLOT_9 : UseSlot_9
            SLOT_10 : UseSlot_10
            SLOT_11 : UseSlot_11
            NORMALMAP_0 : UseNormalMap_0
            NORMALMAP_1 : UseNormalMap_1
            NORMALMAP_2 : UseNormalMap_2
            NORMALMAP_3 : UseNormalMap_3
            NORMALMAP_4 : UseNormalMap_4
            NORMALMAP_5 : UseNormalMap_5
            NORMALMAP_6 : UseNormalMap_6
            NORMALMAP_7 : UseNormalMap_7
            NORMALMAP_8 : UseNormalMap_8
            NORMALMAP_9 : UseNormalMap_9
            NORMALMAP_10 : UseNormalMap_10
            NORMALMAP_11 : UseNormalMap_11
            SPECULARMAP : SpecularMap
            ALPHAMAP : AlphaMap
            ALPHAMAP_1 : AlphaMap_1
            ALPHAMAP_2 : AlphaMap_2
            PARALLAXMAP_0 : UseParallaxMap_0
            PARALLAXMAP_1 : UseParallaxMap_1
            PARALLAXMAP_2 : UseParallaxMap_2
            PARALLAXMAP_3 : UseParallaxMap_3
            PARALLAXMAP_4 : UseParallaxMap_4
            PARALLAXMAP_5 : UseParallaxMap_5
            PARALLAXMAP_6 : UseParallaxMap_6
            PARALLAXMAP_7 : UseParallaxMap_7
            PARALLAXMAP_8 : UseParallaxMap_8
            PARALLAXMAP_9 : UseParallaxMap_9
            PARALLAXMAP_10 : UseParallaxMap_10
            PARALLAXMAP_11 : UseParallaxMap_11
        }
    }
    
}

vert:

#import "MatDefs/ShaderLib/GLSLCompat.glsllib"
#import "MatDefs/ShaderLib/Instancing.glsllib"

attribute vec3 inPosition;
attribute vec3 inNormal;
attribute vec2 inTexCoord;
uniform vec3 g_CameraPosition;

uniform vec4 g_AmbientLightColor; //passed to .frag for scaling light probe brightness in 3.3 compatible version of this shader.

varying vec2 texCoord;
varying vec3 wPosition;
varying vec3 wNormal;

#ifdef TRI_PLANAR_MAPPING
  varying vec4 wVertex;
#endif


#if defined(NORMALMAP_0) || defined(NORMALMAP_1) || defined(NORMALMAP_2) || defined(NORMALMAP_3) || defined(NORMALMAP_4) || defined(PLAGUEDNORMALMAP)
    attribute vec4 inTangent;
    varying vec4 wTangent;
#endif

varying float camDist;   

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

    gl_Position = TransformWorldViewProjection(modelSpacePos);

    texCoord = inTexCoord;

    wPosition = TransformWorld(modelSpacePos).xyz;
    wNormal  = normalize(TransformWorldNormal(inNormal));
   #if  defined(NORMALMAP_0) || defined(NORMALMAP_1) || defined(NORMALMAP_2) || defined(NORMALMAP_3) || defined(NORMALMAP_4) || defined(NORMALMAP_5) || defined(NORMALMAP_6) || defined(NORMALMAP_7)  || defined(PLAGUEDNORMALMAP)
        wTangent = vec4(TransformWorldNormal(inTangent.xyz),inTangent.w);
    #endif

    #ifdef TRI_PLANAR_MAPPING
       wVertex = vec4(inPosition,0.0);
       wNormal = inNormal;
    #endif

    camDist = distance(g_CameraPosition.xyz, wPosition.xyz);
}

edit:
oh and i forgot:

riccardo OcclusionParallax.glsllib was updated too, i forgot to send.

here it is:

/**
*   Occlusion Parallax Mapping
*   The implementation is based on this: https://learnopengl.com/Advanced-Lighting/Parallax-Mapping
*
*       - Riccardo Balbo
*/

#ifndef _OCCLUSION_PARALLAX_
    #define _OCCLUSION_PARALLAX_
     
    #ifndef Texture_sample
        #define Texture_sample texture
    #endif

    // #define HEIGHT_MAP R_COMPONENT
    // #define DEPTH_MAP R_COMPONENT
    
    #define R_COMPONENT 0
    #define G_COMPONENT 1
    #define B_COMPONENT 2    
    #define A_COMPONENT 3

    #if !defined(HEIGHT_MAP) && !defined(DEPTH_MAP)
        #define HEIGHT_MAP R_COMPONENT
    #endif
    
    #ifdef DEPTH_MAP
        #define HEIGHT_MAP DEPTH_MAP
    #endif

     struct _ParallaxData{
        vec2 deltaTexCoords;
        float layerDepth;
    } ParallaxData;

    
    void Parallax_initFor(in vec3 viewDir,in float heightScale){
        const float minLayers = 8.;
        const float maxLayers = 64.;

        float numLayers = mix(maxLayers, minLayers, abs(dot(vec3(0.0, 0.0, 1.0), viewDir))); 

        vec2 P = viewDir.xy / viewDir.z * heightScale;

        ParallaxData.layerDepth = 1.0 / numLayers;
        ParallaxData.deltaTexCoords = P / numLayers;
    }

    float _Parallax_selectDepth(in vec4 d){
        float depth;
        
        #if HEIGHT_MAP==R_COMPONENT
            depth=d.r;
        #elif HEIGHT_MAP==G_COMPONENT
            depth=d.g;
        #elif HEIGHT_MAP==B_COMPONENT
            depth=d.b;
        #else 
            depth=d.a;            
        #endif

        #ifndef DEPTH_MAP
            depth=1.-depth;
        #endif

        return depth;
    }

    float _Parallax_sampleDepth(in sampler2D depthMap,in vec2 uv){
        vec4 d=Texture_sample(depthMap,uv);
        return _Parallax_selectDepth(d);
    }

    void Parallax_displaceCoords(inout vec2 texCoords,in sampler2D depthMap){
        vec2 currentTexCoords = texCoords;
        float currentDepthMapValue = (_Parallax_sampleDepth(depthMap, currentTexCoords));
        float currentLayerDepth = 0.0;

        while(currentLayerDepth < currentDepthMapValue){
            currentTexCoords -= ParallaxData.deltaTexCoords;
            currentDepthMapValue = (_Parallax_sampleDepth(depthMap, currentTexCoords));
            currentLayerDepth += ParallaxData.layerDepth;
        }

        vec2 prevTexCoords = currentTexCoords + ParallaxData.deltaTexCoords;
        float afterDepth = currentDepthMapValue - currentLayerDepth;
        float beforeDepth = (_Parallax_sampleDepth(depthMap, prevTexCoords)) - currentLayerDepth + ParallaxData.layerDepth;

        float weight = afterDepth / (afterDepth - beforeDepth);
        texCoords = prevTexCoords * weight + currentTexCoords * (1.0 - weight);
    }

    float _Parallax_TextureArray_sampleDepth(in sampler2DArray depthMap,in vec2 uv,in int index){
        vec4 d= texture2DArray(depthMap, vec3(uv, index) );
        return _Parallax_selectDepth(d);
    }

    void Parallax_TextureArray_displaceCoords(inout vec2 texCoords,in sampler2DArray depthMap,in int index){
        vec2 currentTexCoords = texCoords;
        float currentDepthMapValue = (_Parallax_TextureArray_sampleDepth(depthMap, currentTexCoords, index));
        float currentLayerDepth = 0.0;

        while(currentLayerDepth < currentDepthMapValue){
            currentTexCoords -= ParallaxData.deltaTexCoords;
            currentDepthMapValue = (_Parallax_TextureArray_sampleDepth(depthMap, currentTexCoords, index));
            currentLayerDepth += ParallaxData.layerDepth;
        }

        vec2 prevTexCoords = currentTexCoords + ParallaxData.deltaTexCoords;
        float afterDepth = currentDepthMapValue - currentLayerDepth;
        float beforeDepth = (_Parallax_TextureArray_sampleDepth(depthMap, prevTexCoords, index)) - currentLayerDepth + ParallaxData.layerDepth;

        float weight = afterDepth / (afterDepth - beforeDepth);
        texCoords = prevTexCoords * weight + currentTexCoords * (1.0 - weight);
    }
#endif
2 Likes