Hi everyone,
Is there an example of a modified terrain material that uses texture arrays to bypass the texture count limit (which is limited to 12 textures)?
Thanks in advance
Hi everyone,
Is there an example of a modified terrain material that uses texture arrays to bypass the texture count limit (which is limited to 12 textures)?
Thanks in advance
didnt @yaRnMcDonuts had one here?
Im using Texture Array for terrain textures like:
frag:
uniform sampler2DArray m_PhongTextures;
uniform sampler2DArray m_NormalmapTextures;
uniform sampler2DArray m_ParallaxmapTextures;
uniform sampler2DArray m_RoughnessmapTextures;
if you want read:
tempAlbedo.rgb = texture2DArray(m_PhongTextures, vec3(coord##index, texIndex) ).rgb;\
j3md:
TextureArray PhongTextures
TextureArray NormalmapTextures -LINEAR
TextureArray ParallaxmapTextures -LINEAR
TextureArray RoughnessmapTextures -LINEAR
java:
import com.jme3.texture.TextureArray;
using:
List<Image> phongTextureList = new ArrayList<>();
// some code to fill, remember about below(tho im not sure if needed here):
phong.setWrap(Texture.WrapMode.Repeat);
TextureArray phongTextures = new TextureArray(phongTextureList);
phongTextures.setWrap(Texture.WrapMode.Repeat);
phongTextures.setMinFilter(Texture.MinFilter.Trilinear);
// some material init code / etc
mat.setTexture("PhongTextures", phongTextures);
Thank you so much, @oxplay2
Donât know. I think he is using PBR material. In my case, I am using Phong material.
Do you pass alpha map textures also in the texture arrays?
Edit:
If possible, I would appreciate it if you can post the whole frag shader and j3md file (for the Phong material), please?
I am a shader nooob!
oh, it would be too much now to just pull phong only, i will just show you all .frag file and .j3md file
#extension GL_EXT_texture_array : enable
#import "MatDefs/ShaderLib/GLSLCompat.glsllib"
#import "MatDefs/ShaderLib/PBR.glsllib"
#import "MatDefs/ShaderLib/Parallax.glsllib"
#import "MatDefs/ShaderLib/Lighting.glsllib"
uniform vec4 g_LightData[NB_LIGHTS];
uniform vec4 g_AmbientLightColor;
varying vec3 wPosition;
uniform float g_Time;
// Configure height channel
#ifdef NORMALMAP_PARALLAX
#define HEIGHT_MAP A_COMPONENT
#else
#define HEIGHT_MAP R_COMPONENT
#endif
#import "MatDefs/ShaderLib/OcclusionParallax.glsllib"
#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 EMISSIVE
uniform vec4 m_Emissive;
#endif
#ifdef EMISSIVEMAP
uniform sampler2D m_EmissiveMap;
#endif
#if defined(EMISSIVE) || defined(EMISSIVEMAP)
uniform float m_EmissivePower;
uniform float m_EmissiveIntensity;
#endif
#ifdef SPECGLOSSPIPELINE
uniform sampler2D m_SpecularMap;
uniform sampler2D m_GlossMap;
#endif
#ifdef LIGHTMAP
uniform sampler2D m_LightMap;
#endif
varying vec3 vNormal;
#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)
varying vec4 wTangent;
#endif
varying vec2 texCoord;
uniform vec3 inPosition;
uniform mat4 g_WorldViewMatrix;
uniform vec3 g_CameraPosition;
varying vec3 vPosition;
varying vec3 vnPosition;
varying vec3 vViewDir;
varying vec4 vLightDir;
varying vec4 vnLightDir;
varying vec3 lightVec;
uniform float m_Roughness_0;
uniform float m_Roughness_1;
uniform float m_Roughness_2;
uniform float m_Roughness_3;
uniform float m_Metallic_0;
uniform float m_Metallic_1;
uniform float m_Metallic_2;
uniform float m_Metallic_3;
uniform float m_Parallax_0;
uniform float m_Parallax_1;
uniform float m_Parallax_2;
uniform float m_Parallax_3;
uniform sampler2DArray m_PhongTextures;
uniform sampler2DArray m_NormalmapTextures;
uniform sampler2DArray m_ParallaxmapTextures;
uniform sampler2DArray m_RoughnessmapTextures;
#ifdef SLOT_0
uniform float m_Slot_0_scale;
#endif
#ifdef SLOT_1
uniform float m_Slot_1_scale;
#endif
#ifdef SLOT_2
uniform float m_Slot_2_scale;
#endif
#ifdef SLOT_3
uniform float m_Slot_3_scale;
#endif
#ifdef ALPHAMAP
uniform sampler2D m_AlphaMap;
#endif
#ifdef PARALLAXMAP_0
uniform float m_ParallaxHeight_0;
uniform float m_ParallaxHeightFix_0;
uniform float m_ParallaxAOColorFactor_0;
#endif
#ifdef PARALLAXMAP_1
uniform float m_ParallaxHeight_1;
uniform float m_ParallaxHeightFix_1;
uniform float m_ParallaxAOColorFactor_1;
#endif
#ifdef PARALLAXMAP_2
uniform float m_ParallaxHeight_2;
uniform float m_ParallaxHeightFix_2;
uniform float m_ParallaxAOColorFactor_2;
#endif
#ifdef PARALLAXMAP_3
uniform float m_ParallaxHeight_3;
uniform float m_ParallaxHeightFix_3;
uniform float m_ParallaxAOColorFactor_3;
#endif
uniform sampler2D m_NoiseMap_1;
uniform sampler2D m_NoiseMap_2;
vec4 emissive;
varying vec3 wNormal;
//ifdef TRI_PLANAR_MAPPING
varying vec4 wVertex;
//#endif
varying float camDist;
varying float height;
vec2 coord;
vec4 albedo = vec4(0.0,0.0,0.0,1.0);
vec4 tempAlbedo = vec4(0.0,0.0,0.0,1.0);
vec4 tempNormal;
vec4 tempRoughness;
vec3 normal = vec3(0.0,1.0,0.0);
vec3 newNormal;
vec3 parallax;
vec2 newTexCoord;
vec3 viewDir;
mat3 tbnMat;
vec3 norm;
float Metallic = 0.0;
float Roughness = 0.5;
float currentBlendValue = 0.01;
float blendPercent = 1.0;
float parallaxAverageDepth = 0.0;
float parallaxAverageAOColorFactor = 0.0;
float clampedMoistureDepth = 0.0;
float moistureRoughness = 0.0;
vec4 alphaBlend;
float normalBasedMoisureIntensity = 0.0;
float noise = 0.0;
float noise2 = 0.0;
float noise3 = 0.0;
float noise4 = 0.0;
/////////////////////////////////////////
//TANGENTS
///////////////////////////////////////
/*
vec3 Texture_sampleTSpaceNormal(in sampler2D itx,in vec2 uv){
vec4 normalHeight = Texture_sample(itx, uv);
#ifdef OPENGL_NORMALMAP
vec3 normal = normalize((normalHeight.xyz * vec3(2.,-2.,2.) - vec3(1.,-1.,1.)));
#else
vec3 normal = normalize((normalHeight.xyz * vec3(2.,2.,2.) - vec3(1.,1.,1.)));
#endif
normal.z = sqrt(1-clamp(dot(normal.xy, normal.xy),0.,1.)); // Reconstruct Z
return normal;
}
vec3 Triplanar_sampleWorldNormal(in sampler2D tx,in sampler2D txTop,in float scale){
vec3 normalX=Texture_sampleTSpaceNormal(tx,(TriplanarData.worldPos.zy+TriplanarData.zyOffset)*scale);
vec3 normalY=Texture_sampleTSpaceNormal(txTop,(TriplanarData.worldPos.xz+TriplanarData.xzOffset)*scale); //tx?
vec3 normalZ=Texture_sampleTSpaceNormal(tx,(TriplanarData.worldPos.xy+TriplanarData.xyOffset)*scale);
vec3 s=sign(TriplanarData.surfaceWorldNormal);
vec3 T=vec3(0,0,1);
vec3 N=vec3(1,0,0)*s;
vec3 B=cross(T,N);
mat3 tbnMat= mat3(T,B,N );
normalX=tbnMat*normalX;
T=vec3(0,0,1);
N=vec3(0,1,0)*s;
B=cross(T,N);
tbnMat=mat3(T,B,N );
normalY=tbnMat*normalY;
T=vec3(0,1,0);
N=vec3(0,0,1)*s;
B=cross(T,N);
tbnMat= mat3(T,B,N );
normalZ=tbnMat*normalZ;
vec3 blending=abs(TriplanarData.surfaceNormal);
blending=normalize(max(blending, 0.00001));
float b=(blending.x+blending.y+blending.z);
blending/=vec3(b);
return (normalX * (blending.x)) + (normalY *(blending.y)) + (normalZ * (blending.z));
}
*/
///////////////////////////////////////////
//TANGENTS CALCULATING
mat3 cotangent_frame(vec3 N, vec3 p, vec2 uv){
// get edge vectors of the pixel triangle
vec3 dp1 = dFdx( p );
vec3 dp2 = dFdy( p );
vec2 duv1 = dFdx( uv );
vec2 duv2 = dFdy( uv );
// solve the linear system
vec3 dp2perp = cross( dp2, N );
vec3 dp1perp = cross( N, dp1 );
vec3 T = dp2perp * duv1.x + dp1perp * duv2.x;
vec3 B = dp2perp * duv1.y + dp1perp * duv2.y;
// construct a scale-invariant frame
float invmax = 1.0/sqrt( max( dot(T,T), dot(B,B) ) );
return mat3( T * invmax, B * invmax, N );
}
mat3 calcTBN(vec3 N, vec3 V, vec2 texcoord ){
mat3 TBN = cotangent_frame( N, -V, texcoord );
return TBN;
}
////////////////////////////////////
#define DEFINE_COORD(index) vec2 coord##index = newTexCoord * m_Slot##index##_scale;
#define CALCULATE_BLEND_PERCENT(ab)\
currentBlendValue += ab;\
blendPercent = (0.0000001+ab)/(currentBlendValue+0.0000001);
#define BLEND(index, ab, texIndex)\
tempAlbedo.rgb = texture2DArray(m_PhongTextures, vec3(coord##index, texIndex) ).rgb;\
tempRoughness.rgb = texture2DArray(m_RoughnessmapTextures, vec3(coord##index, texIndex) ).rgb;\
albedo.rgb = mix( albedo.rgb, tempAlbedo.rgb, blendPercent);\
normal.rgb = mix(normal.xyz, wNormal.xyz, blendPercent);\
clampedMoistureDepth = PARALLAX_MOISTURE_DEPTH_INTENSITY##index * lastParallaxDepth + PARALLAX_MOISTURE_DEPTH_FIX##index;\
moistureRoughness = mix(moistureRoughness, clampedMoistureDepth, blendPercent);\
Metallic = mix(Metallic, m_Metallic##index, blendPercent);\
Roughness = mix(Roughness, m_Roughness##index * tempRoughness.r, blendPercent);
#define BLEND_NORMAL(index, ab, texIndex)\
newNormal = texture2DArray(m_NormalmapTextures, vec3(coord##index, texIndex) ).rgb;\
normal = mix(normal, newNormal, blendPercent);\
#define PARALLAX_BLEND(index, ab, texIndex)\
calculateParallax(coord##index, m_ParallaxHeightFix##index, m_ParallaxHeight##index, m_ParallaxAOColorFactor##index, ab, texIndex);
void calculateParallax(inout vec2 parallaxTexCoord, in float initialParallaxHeight, in float parallaxHeight, in float parallaxAOColorFactor, in float intensity, in int texIndex) {
#ifdef PARALLAX_LOD_DISTANCE
if(camDist < PARALLAX_LOD_DISTANCE && blendPercent > 0.2){
#else
if(blendPercent > 0.2){
#endif
mat3 invTBN=transpose(tbnMat);
vec3 TanPos = invTBN*wPosition;
vec3 TanCamPos = invTBN*g_CameraPosition;
vec3 TanViewDir=normalize(TanCamPos-TanPos);
Parallax_initFor(TanViewDir,parallaxHeight);
Parallax_TextureArray_displaceCoords(parallaxTexCoord, m_ParallaxmapTextures, initialParallaxHeight, texIndex);
}
parallaxAverageDepth += lastParallaxDepth * blendPercent;
parallaxAverageDepth = clamp(parallaxAverageDepth, 0.0, 1.0);
parallaxAverageAOColorFactor += clamp(parallaxAOColorFactor, 0.0, 1.0) * blendPercent;
}
vec4 calculateAlbedoBlend(in vec2 newTexCoord) {
//vec4 alphaBlend = texture2D( m_AlphaMap, newTexCoord.xy );
vec4 albedo = vec4(0.1);
Roughness = 0.95;
Metallic = 0.0;
parallaxAverageDepth = 0;
vec3 blending = abs( wNormal );
blending = (blending -0.2) * 0.7;
blending = normalize(max(blending, 0.000001)); // Force weights to sum to 1.0 (very important!)
float b = (blending.x + blending.y + blending.z);
blending /= vec3(b, b, b);
normalBasedMoisureIntensity = normalize(wNormal).y;
normalBasedMoisureIntensity = clamp(pow(normalBasedMoisureIntensity, 8), 0.0, 1.0);
vec3 wvPosition=(vec4(inPosition,1)*g_WorldViewMatrix).xyz;
#ifdef SLOT_0
DEFINE_COORD(_0)
CALCULATE_BLEND_PERCENT(alphaBlend.r)
#if defined(PARALLAXMAPPING) && defined (PARALLAXMAP_0)
PARALLAX_BLEND(_0, alphaBlend.r, 0)
#endif
BLEND(_0, alphaBlend.r, 0)
#ifdef NORMALMAP_0
BLEND_NORMAL(_0, alphaBlend.r, 0)
#endif
#endif
#ifdef SLOT_1
DEFINE_COORD(_1)
CALCULATE_BLEND_PERCENT(alphaBlend.g)
#if defined(PARALLAXMAPPING) && defined (PARALLAXMAP_1)
PARALLAX_BLEND(_1, alphaBlend.g, 1)
#endif
BLEND(_1, alphaBlend.g, 1)
#ifdef NORMALMAP_1
BLEND_NORMAL(_1, alphaBlend.g, 1)
#endif
#endif
#ifdef SLOT_2
DEFINE_COORD(_2)
CALCULATE_BLEND_PERCENT(alphaBlend.b)
#if defined(PARALLAXMAPPING) && defined (PARALLAXMAP_2)
PARALLAX_BLEND(_2, alphaBlend.b, 2)
#endif
BLEND(_2, alphaBlend.b, 2)
#ifdef NORMALMAP_2
BLEND_NORMAL(_2, alphaBlend.b, 2)
#endif
#endif
#ifdef SLOT_3
DEFINE_COORD(_3)
CALCULATE_BLEND_PERCENT(alphaBlend.a)
#if defined(PARALLAXMAPPING) && defined (PARALLAXMAP_3)
PARALLAX_BLEND(_3, alphaBlend.a, 3)
#endif
BLEND(_3, alphaBlend.a, 3)
#ifdef NORMALMAP_3
BLEND_NORMAL(_3, alphaBlend.a, 3)
#endif
#endif
#if defined(PARALLAXMAPPING)
moistureRoughness *= clamp(0.5 + noise, 0.0, 1.0);
moistureRoughness *= normalBasedMoisureIntensity;
float moisureIntensity = POST_RAIN_MOISTURE;
Roughness -= moistureRoughness * clamp(moisureIntensity, 0.0, 1.0);
Metallic += moistureRoughness * clamp(moisureIntensity, 0.0, 1.0);
if(Roughness < 0.5){
Roughness -= (0.5 - Roughness) * 1;
Metallic += (0.5 - Roughness) * 1;
}
#endif
return albedo;
}
#ifdef PROBE_COLOR
uniform vec4 m_ProbeColor;
#endif
void main(){
noise = texture2D(m_NoiseMap_1, texCoord*20).r;
noise2 = texture2D(m_NoiseMap_2, texCoord*20).r;
noise3 = texture2D(m_NoiseMap_1, texCoord*30).r;
noise4 = texture2D(m_NoiseMap_2, texCoord*30).r;
viewDir = normalize(g_CameraPosition - wPosition);
vec3 norm = normalize(wNormal);
normal = norm;
/////////////////////////////////////////
//TANGENTS
///////////////////////////////////////
tbnMat = calcTBN(normal, viewDir, texCoord);
/////////////////////////////////////////
//fix for geforce card (wireframe mode)
if(isnan(tbnMat[0].x)){
// domyslny tangent
vec3 T=vec3(0,0,1);
vec3 N=vec3(0,1,0);
vec3 B=cross(T,N);
tbnMat=mat3(T,B,N);
}
/////////////////////////////////////////
newTexCoord=texCoord;
alphaBlend = texture2D( m_AlphaMap, newTexCoord.xy );
//always calculated since the
vec3 blending;
#ifdef SLOT_0
#ifdef ALPHAMAP
albedo = calculateAlbedoBlend(newTexCoord);
#else
DEFINE_COORD(_0)
albedo = texture2DArray(m_PhongTextures, vec3(coord##index, 0) );
#endif
#endif
Metallic = clamp(Metallic, 0.0, 1.0);
Roughness = clamp(Roughness, 0.0, 1.0);
//roughnessing vars
Roughness *= 0.9 + noise3 * 0.1;
Metallic *= 0.8 + noise4 * 0.2;
// for high roughness, make normal up direction so it will be flat
normal = mix(vec3(0.0,1.0,0.0), normal, clamp(Roughness, 0.0, 1.0));
normal = normalize(normal);
#ifdef SPECGLOSSPIPELINE
#ifdef USE_PACKED_SG
vec4 specularColor = texture2D(m_SpecularGlossinessMap, newTexCoord);
float glossiness = specularColor.a * m_Glossiness;
specularColor *= m_Specular;
#else
#ifdef SPECULARMAP
vec4 specularColor = texture2D(m_SpecularMap, newTexCoord);
#else
vec4 specularColor = vec4(1.0);
#endif
#ifdef GLOSSINESSMAP
float glossiness = texture2D(m_GlossinessMap, 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);
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;
}
//////////////////////////////////////////////////
//normal.y *= 20;
//normal = normalize(normal);
//////////////////////////////////////////////////
vec3 metalnessNormal = normal;
metalnessNormal.y *= 2;
metalnessNormal = normalize(metalnessNormal);
#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, metalnessNormal, metalnessNormal, Roughness, diffuseColor, specularColor, ndotv, ao, g_LightProbeData, g_ShCoeffs, g_PrefEnvMap, color1);
#if NB_PROBES >= 2
float ndf2 = renderProbe(viewDir, wPosition, metalnessNormal, metalnessNormal, Roughness, diffuseColor, specularColor, ndotv, ao, g_LightProbeData2, g_ShCoeffs2, g_PrefEnvMap2, color2);
#endif
#if NB_PROBES == 3
float ndf3 = renderProbe(viewDir, wPosition, metalnessNormal, metalnessNormal, 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
emissive = texture2D(m_EmissiveMap, newTexCoord);
#else
emissive = m_Emissive;
#endif
gl_FragColor += emissive * pow(emissive.a, m_EmissivePower) * m_EmissiveIntensity;
#endif
//noise = texture2D(m_NoiseMap_2, texCoord).r;
//parallaxAverageAOColorFactor *= noise;
//gl_FragColor.rbg = mix(gl_FragColor.rbg,vec3(0,0,0),parallaxAverageDepth/2);
gl_FragColor.rbg = mix(gl_FragColor.rbg*parallaxAverageAOColorFactor,gl_FragColor.rbg,clamp((1.-parallaxAverageDepth)*1.2,0.0,1.0));
gl_FragColor.a = 1.0;
//ponizej robi ze tam gdzie niema alphy - tekstury, tam jest czarne
//gl_FragColor.rbg = mix(vec3(0.0,0.0,0.0), gl_FragColor.rbg,clamp(1000.0*(alphaBlend.r + alphaBlend.g + alphaBlend.b + alphaBlend.a),0.0,1.0));
//gl_FragColor.rgb = vec3(parallaxAverageDepth, parallaxAverageDepth, parallaxAverageDepth);
//gl_FragColor.rgb = vec3(Metallic, Metallic, Metallic);
//gl_FragColor.rgb = vec3(Roughness, Roughness, Roughness);
//gl_FragColor.rgb = vec3(noise, noise, noise);
//gl_FragColor.a = 1.0;
//gl_FragColor.rgb = vec3(height/50,0,0);
//gl_FragColor.rgb = vec3(height/20,1 - height/20,0);
//gl_FragColor.r *= normalize(wNormal).y;
//gl_FragColor.b *= normalize(wNormal).y;
//gl_FragColor.rgb = vec3(normalBasedMoisureIntensity, 1.0 - normalBasedMoisureIntensity, 0.0);
//gl_FragColor.rgb *= normalize(normal);
//int texIndex = 0;
//vec4 baseColorMapValue = texture2DArray(m_PhongTextures, vec3(texCoord, texIndex) ).rgba;
//gl_FragColor = (baseColorMapValue * );
}
j3md:
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
Float PostRainMoisture : 0.5
// 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 Metallic_0 : 0.0
Float Metallic_1 : 0.0
Float Metallic_2 : 0.0
Float Metallic_3 : 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
TextureArray RoughnessmapTextures -LINEAR
Texture2D NoiseMap_1
Texture2D NoiseMap_2
// Texture map #0
Float Slot_0_scale
Float ParallaxHeight_0
Float ParallaxHeightFix_0
Float ParallaxAOColorFactor_0 : 0.3
Float ParallaxRainMoistureDepthFix_0 : 0
Float ParallaxRainMoistureDepthIntensity_0 : 1
Float ParallaxRainMoistureDepthWater_0 : 1
Boolean UseSlot_0
Boolean UseNormalMap_0
Boolean UseParallaxMap_0
// Texture map #1
Float Slot_1_scale
Float ParallaxHeight_1
Float ParallaxHeightFix_1
Float ParallaxAOColorFactor_1 : 0.3
Float ParallaxRainMoistureDepthFix_1 : 0
Float ParallaxRainMoistureDepthIntensity_1 : 1
Float ParallaxRainMoistureDepthWater_1 : 1
Boolean UseSlot_1
Boolean UseNormalMap_1
Boolean UseParallaxMap_1
// Texture map #2
Float Slot_2_scale
Float ParallaxHeight_2
Float ParallaxHeightFix_2
Float ParallaxAOColorFactor_2 : 0.3
Float ParallaxRainMoistureDepthFix_2 : 0
Float ParallaxRainMoistureDepthIntensity_2 : 1
Float ParallaxRainMoistureDepthWater_2 : 1
Boolean UseSlot_2
Boolean UseNormalMap_2
Boolean UseParallaxMap_2
// Texture map #3
Float Slot_3_scale
Float ParallaxHeight_3
Float ParallaxHeightFix_3
Float ParallaxAOColorFactor_3 : 0.3
Float ParallaxRainMoistureDepthFix_3 : 0
Float ParallaxRainMoistureDepthIntensity_3 : 1
Float ParallaxRainMoistureDepthWater_3 : 1
Boolean UseSlot_3
Boolean UseNormalMap_3
Boolean UseParallaxMap_3
// Texture map #11
Float Slot_11_scale
Float ParallaxHeight_11
Float ParallaxAOColorFactor_11 : 0.3
Boolean UseSlot_11
Boolean UseNormalMap_11
Boolean UseParallaxMap_11
// Texture that specifies alpha values
Texture2D AlphaMap -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 GLSL330: MatDefs/RTerrain/RTerrain.vert
FragmentShader GLSL330: MatDefs/RTerrain/RTerrain.frag
WorldParameters {
WorldViewProjectionMatrix
CameraPosition
WorldMatrix
WorldNormalMatrix
ViewProjectionMatrix
ViewMatrix
Time
}
Defines {
POST_RAIN_MOISTURE : PostRainMoisture;
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
NORMALMAP_0 : UseNormalMap_0
NORMALMAP_1 : UseNormalMap_1
NORMALMAP_2 : UseNormalMap_2
NORMALMAP_3 : UseNormalMap_3
SPECULARMAP : SpecularMap
ALPHAMAP : AlphaMap
PARALLAXMAP_0 : UseParallaxMap_0
PARALLAXMAP_1 : UseParallaxMap_1
PARALLAXMAP_2 : UseParallaxMap_2
PARALLAXMAP_3 : UseParallaxMap_3
PARALLAX_MOISTURE_DEPTH_FIX_0 : ParallaxRainMoistureDepthFix_0
PARALLAX_MOISTURE_DEPTH_FIX_1 : ParallaxRainMoistureDepthFix_1
PARALLAX_MOISTURE_DEPTH_FIX_2 : ParallaxRainMoistureDepthFix_2
PARALLAX_MOISTURE_DEPTH_FIX_3 : ParallaxRainMoistureDepthFix_3
PARALLAX_MOISTURE_DEPTH_INTENSITY_0 : ParallaxRainMoistureDepthIntensity_0
PARALLAX_MOISTURE_DEPTH_INTENSITY_1 : ParallaxRainMoistureDepthIntensity_1
PARALLAX_MOISTURE_DEPTH_INTENSITY_2 : ParallaxRainMoistureDepthIntensity_2
PARALLAX_MOISTURE_DEPTH_INTENSITY_3 : ParallaxRainMoistureDepthIntensity_3
PARALLAX_MOISTURE_DEPTH_WATER_0 : ParallaxRainMoistureDepthWater_0
PARALLAX_MOISTURE_DEPTH_WATER_1 : ParallaxRainMoistureDepthWater_1
PARALLAX_MOISTURE_DEPTH_WATER_2 : ParallaxRainMoistureDepthWater_2
PARALLAX_MOISTURE_DEPTH_WATER_3 : ParallaxRainMoistureDepthWater_3
NOISEMAP_1 : NoiseMap_1
NOISEMAP_2 : NoiseMap_2
}
}
}
.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;
varying float height;
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);
height = wPosition.y;
}
remove not needed code or ust from default terrain shader to replace my crazy code there
note, my terrain material do not support triplannar as i remember.
Alphamap i probably had still just sampler, but you can use sampler2DArray to have multiple alphamaps, tho it will require much more blending there. (so i probably due to optimize/fps issues just have one)
Thanks
FYI, Ryanâs PBR terrain shaders have been integrated in the Engine. The advanced version uses texture arrays:
Looking at those codes and the code provided by @oxplay2, I got a grasp of how to use texture array.
Thanks, everyone for the help.
You may also be interested in considering using this new loop functionality thatâs been added to the master branch. ( I have not used these new for loops yet myself, but I do plan to refractor my terrain shaders with these for loops in the future )
When I wrote my shader using texture arrays, this PR didnât exist, so thatâs why every JME terrain shader has redundant code for texture slots 1-12 instead of using recursion. But now I think for loops should be possible in jme shaders, so thatâs something to consider if youâre feeling more adventurous and are using master branch.
good one, i forgot about it!
Thanks, will take a look at it.
Does a single instance of texture array still limited to 16 textures (on GPU) or there is no such limit?
You can put every texture into one massive array if you want I think, but I just split them up into more than one texture array for organizational purpose.
So if there is a limit to the number of textures you can have in each texture array, I expect it is quite high, or at least high enough I havenât hit it.
So you are still limited to 16 texture params, but one or more of these params can be a texture array param which can contain as many textures as you want in each array.
im not sure about limit, but thing is that each texture need to be same size (i mean in TextureArray)
Yeah the âmust be same size and formatâ error can be finicky to troubleshoot (especially if your textures come from different sources) because it not only is talking about the size and .jpg and .png format, but also the bit depth and color space of the texture.