From c55717141e5de9a0939dc6171784bf642c0638dd Mon Sep 17 00:00:00 2001
From: Nehon
diff --git a/jme3-core/src/main/resources/Common/MatDefs/Light/Lighting.frag b/jme3-core/src/main/resources/Common/MatDefs/Light/Lighting.frag
index e4773c8cf..370c62bc9 100644
--- a/jme3-core/src/main/resources/Common/MatDefs/Light/Lighting.frag
+++ b/jme3-core/src/main/resources/Common/MatDefs/Light/Lighting.frag
@@ -1,7 +1,9 @@
#import "Common/ShaderLib/Parallax.glsllib"
#import "Common/ShaderLib/Optics.glsllib"
-#define ATTENUATION
-//#define HQ_ATTENUATION
+#ifndef VERTEX_LIGHTING
+ #import "Common/ShaderLib/PhongLighting.glsllib"
+ #import "Common/ShaderLib/Lighting.glsllib"
+#endif
varying vec2 texCoord;
#ifdef SEPARATE_TEXCOORD
@@ -58,82 +60,14 @@ varying vec3 SpecularSum;
uniform float m_AlphaDiscardThreshold;
#ifndef VERTEX_LIGHTING
-uniform float m_Shininess;
-
-#ifdef HQ_ATTENUATION
-uniform vec4 g_LightPosition;
-#endif
-
-#ifdef USE_REFLECTION
- uniform float m_ReflectionPower;
- uniform float m_ReflectionIntensity;
- varying vec4 refVec;
-
- uniform ENVMAP m_EnvMap;
-#endif
-
-float tangDot(in vec3 v1, in vec3 v2){
- float d = dot(v1,v2);
- #ifdef V_TANGENT
- d = 1.0 - d*d;
- return step(0.0, d) * sqrt(d);
- #else
- return d;
- #endif
-}
-
-float lightComputeDiffuse(in vec3 norm, in vec3 lightdir, in vec3 viewdir){
- #ifdef MINNAERT
- float NdotL = max(0.0, dot(norm, lightdir));
- float NdotV = max(0.0, dot(norm, viewdir));
- return NdotL * pow(max(NdotL * NdotV, 0.1), -1.0) * 0.5;
- #else
- return max(0.0, dot(norm, lightdir));
- #endif
-}
+ uniform float m_Shininess;
+ #ifdef USE_REFLECTION
+ uniform float m_ReflectionPower;
+ uniform float m_ReflectionIntensity;
+ varying vec4 refVec;
-float lightComputeSpecular(in vec3 norm, in vec3 viewdir, in vec3 lightdir, in float shiny){
- // NOTE: check for shiny <= 1 removed since shininess is now
- // 1.0 by default (uses matdefs default vals)
- #ifdef LOW_QUALITY
- // Blinn-Phong
- // Note: preferably, H should be computed in the vertex shader
- vec3 H = (viewdir + lightdir) * vec3(0.5);
- return pow(max(tangDot(H, norm), 0.0), shiny);
- #elif defined(WARDISO)
- // Isotropic Ward
- vec3 halfVec = normalize(viewdir + lightdir);
- float NdotH = max(0.001, tangDot(norm, halfVec));
- float NdotV = max(0.001, tangDot(norm, viewdir));
- float NdotL = max(0.001, tangDot(norm, lightdir));
- float a = tan(acos(NdotH));
- float p = max(shiny/128.0, 0.001);
- return NdotL * (1.0 / (4.0*3.14159265*p*p)) * (exp(-(a*a)/(p*p)) / (sqrt(NdotV * NdotL)));
- #else
- // Standard Phong
- vec3 R = reflect(-lightdir, norm);
- return pow(max(tangDot(R, viewdir), 0.0), shiny);
+ uniform ENVMAP m_EnvMap;
#endif
-}
-
-vec2 computeLighting(in vec3 wvNorm, in vec3 wvViewDir, in vec3 wvLightDir){
- float diffuseFactor = lightComputeDiffuse(wvNorm, wvLightDir, wvViewDir);
- float specularFactor = lightComputeSpecular(wvNorm, wvViewDir, wvLightDir, m_Shininess);
-
- #ifdef HQ_ATTENUATION
- float att = clamp(1.0 - g_LightPosition.w * length(lightVec), 0.0, 1.0);
- #else
- float att = vLightDir.w;
- #endif
-
- if (m_Shininess <= 1.0) {
- specularFactor = 0.0; // should be one instruction on most cards ..
- }
-
- specularFactor *= diffuseFactor;
-
- return vec2(diffuseFactor, specularFactor) * vec2(att);
-}
#endif
void main(){
@@ -176,36 +110,7 @@ void main(){
discard;
}
- #ifndef VERTEX_LIGHTING
- float spotFallOff = 1.0;
-
- #if __VERSION__ >= 110
- // allow use of control flow
- if(g_LightDirection.w != 0.0){
- #endif
-
- vec3 L = normalize(lightVec.xyz);
- vec3 spotdir = normalize(g_LightDirection.xyz);
- float curAngleCos = dot(-L, spotdir);
- float innerAngleCos = floor(g_LightDirection.w) * 0.001;
- float outerAngleCos = fract(g_LightDirection.w);
- float innerMinusOuter = innerAngleCos - outerAngleCos;
- spotFallOff = (curAngleCos - outerAngleCos) / innerMinusOuter;
- #if __VERSION__ >= 110
- if(spotFallOff <= 0.0){
- gl_FragColor.rgb = AmbientSum * diffuseColor.rgb;
- gl_FragColor.a = alpha;
- return;
- }else{
- spotFallOff = clamp(spotFallOff, 0.0, 1.0);
- }
- }
- #else
- spotFallOff = clamp(spotFallOff, step(g_LightDirection.w, 0.001), 1.0);
- #endif
- #endif
-
// ***********************
// Read from textures
// ***********************
@@ -257,8 +162,23 @@ void main(){
vec4 lightDir = vLightDir;
lightDir.xyz = normalize(lightDir.xyz);
vec3 viewDir = normalize(vViewDir);
+ float spotFallOff = 1.0;
+
+ #if __VERSION__ >= 110
+ // allow use of control flow
+ if(g_LightDirection.w != 0.0){
+ #endif
+ spotFallOff = computeSpotFalloff(g_LightDirection, lightVec);
+ #if __VERSION__ >= 110
+ if(spotFallOff <= 0.0){
+ gl_FragColor.rgb = AmbientSum * diffuseColor.rgb;
+ gl_FragColor.a = alpha;
+ return;
+ }
+ }
+ #endif
- vec2 light = computeLighting(normal, viewDir, lightDir.xyz) * spotFallOff;
+ vec2 light = computeLighting(normal, viewDir, lightDir.xyz, lightDir.w * spotFallOff, m_Shininess) ;
#ifdef COLORRAMP
diffuseColor.rgb *= texture2D(m_ColorRamp, vec2(light.x, 0.0)).rgb;
specularColor.rgb *= texture2D(m_ColorRamp, vec2(light.y, 0.0)).rgb;
diff --git a/jme3-core/src/main/resources/Common/MatDefs/Light/Lighting.j3md b/jme3-core/src/main/resources/Common/MatDefs/Light/Lighting.j3md
index 779242445..e5613f040 100644
--- a/jme3-core/src/main/resources/Common/MatDefs/Light/Lighting.j3md
+++ b/jme3-core/src/main/resources/Common/MatDefs/Light/Lighting.j3md
@@ -6,34 +6,12 @@ MaterialDef Phong Lighting {
// For better performance
Boolean VertexLighting
- // Use more efficent algorithms to improve performance
- Boolean LowQuality
-
- // Improve quality at the cost of performance
- Boolean HighQuality
-
- // Output alpha from the diffuse map
- Boolean UseAlpha
-
// Alpha threshold for fragment discarding
Float AlphaDiscardThreshold (AlphaTestFallOff)
- // Normal map is in BC5/ATI2n/LATC/3Dc compression format
- Boolean LATC
-
// Use the provided ambient, diffuse, and specular colors
Boolean UseMaterialColors
- // Activate shading along the tangent, instead of the normal
- // Requires tangent data to be available on the model.
- Boolean VTangent
-
- // Use minnaert diffuse instead of lambert
- Boolean Minnaert
-
- // Use ward specular instead of phong
- Boolean WardIso
-
// Use vertex color as an additional diffuse color.
Boolean UseVertexColor
@@ -133,9 +111,48 @@ MaterialDef Phong Lighting {
Int NumberOfBones
Matrix4Array BoneMatrices
+ //For instancing
Boolean UseInstancing
}
+ Technique {
+ LightMode SinglePass
+
+ VertexShader GLSL100: Common/MatDefs/Light/SPLighting.vert
+ FragmentShader GLSL100: Common/MatDefs/Light/SPLighting.frag
+
+ WorldParameters {
+ WorldViewProjectionMatrix
+ NormalMatrix
+ WorldViewMatrix
+ ViewMatrix
+ CameraPosition
+ WorldMatrix
+ ViewProjectionMatrix
+ }
+
+ Defines {
+ VERTEX_COLOR : UseVertexColor
+ VERTEX_LIGHTING : VertexLighting
+ MATERIAL_COLORS : UseMaterialColors
+ DIFFUSEMAP : DiffuseMap
+ NORMALMAP : NormalMap
+ SPECULARMAP : SpecularMap
+ PARALLAXMAP : ParallaxMap
+ NORMALMAP_PARALLAX : PackedNormalParallax
+ STEEP_PARALLAX : SteepParallax
+ ALPHAMAP : AlphaMap
+ COLORRAMP : ColorRamp
+ LIGHTMAP : LightMap
+ SEPARATE_TEXCOORD : SeparateTexCoord
+ DISCARD_ALPHA : AlphaDiscardThreshold
+ USE_REFLECTION : EnvMap
+ SPHERE_MAP : SphereMap
+ NUM_BONES : NumberOfBones
+ INSTANCING : UseInstancing
+ }
+ }
+
Technique {
LightMode MultiPass
@@ -154,17 +171,9 @@ MaterialDef Phong Lighting {
}
Defines {
- LATC : LATC
VERTEX_COLOR : UseVertexColor
- VERTEX_LIGHTING : VertexLighting
- ATTENUATION : Attenuation
+ VERTEX_LIGHTING : VertexLighting
MATERIAL_COLORS : UseMaterialColors
- V_TANGENT : VTangent
- MINNAERT : Minnaert
- WARDISO : WardIso
- LOW_QUALITY : LowQuality
- HQ_ATTENUATION : HighQuality
-
DIFFUSEMAP : DiffuseMap
NORMALMAP : NormalMap
SPECULARMAP : SpecularMap
@@ -175,16 +184,16 @@ MaterialDef Phong Lighting {
COLORRAMP : ColorRamp
LIGHTMAP : LightMap
SEPARATE_TEXCOORD : SeparateTexCoord
-
+ DISCARD_ALPHA : AlphaDiscardThreshold
USE_REFLECTION : EnvMap
SPHERE_MAP : SphereMap
-
- NUM_BONES : NumberOfBones
-
+ NUM_BONES : NumberOfBones
INSTANCING : UseInstancing
}
}
+
+
Technique PreShadow {
VertexShader GLSL100 : Common/MatDefs/Shadow/PreShadow.vert
@@ -373,4 +382,4 @@ MaterialDef Phong Lighting {
}
}
-}
\ No newline at end of file
+}
diff --git a/jme3-core/src/main/resources/Common/MatDefs/Light/Lighting.vert b/jme3-core/src/main/resources/Common/MatDefs/Light/Lighting.vert
index 737786fb4..1901ebc67 100644
--- a/jme3-core/src/main/resources/Common/MatDefs/Light/Lighting.vert
+++ b/jme3-core/src/main/resources/Common/MatDefs/Light/Lighting.vert
@@ -1,8 +1,10 @@
#import "Common/ShaderLib/Instancing.glsllib"
-#define ATTENUATION
-//#define HQ_ATTENUATION
-
#import "Common/ShaderLib/Skinning.glsllib"
+#import "Common/ShaderLib/Lighting.glsllib"
+#ifdef VERTEX_LIGHTING
+ #import "Common/ShaderLib/PhongLighting.glsllib"
+#endif
+
uniform vec4 m_Ambient;
uniform vec4 m_Diffuse;
@@ -28,7 +30,6 @@ attribute vec2 inTexCoord;
attribute vec3 inNormal;
varying vec3 lightVec;
-//varying vec4 spotVec;
#ifdef VERTEX_COLOR
attribute vec4 inColor;
@@ -39,8 +40,7 @@ varying vec3 lightVec;
#ifndef NORMALMAP
varying vec3 vNormal;
- #endif
- //varying vec3 vPosition;
+ #endif
varying vec3 vViewDir;
varying vec4 vLightDir;
#else
@@ -77,57 +77,6 @@ varying vec3 lightVec;
}
#endif
-// JME3 lights in world space
-void lightComputeDir(in vec3 worldPos, in vec4 color, in vec4 position, out vec4 lightDir){
- float posLight = step(0.5, color.w);
- vec3 tempVec = position.xyz * sign(posLight - 0.5) - (worldPos * posLight);
- lightVec = tempVec;
- #ifdef ATTENUATION
- float dist = length(tempVec);
- lightDir.w = clamp(1.0 - position.w * dist * posLight, 0.0, 1.0);
- lightDir.xyz = tempVec / vec3(dist);
- #else
- lightDir = vec4(normalize(tempVec), 1.0);
- #endif
-}
-
-#ifdef VERTEX_LIGHTING
- float lightComputeDiffuse(in vec3 norm, in vec3 lightdir){
- return max(0.0, dot(norm, lightdir));
- }
-
- float lightComputeSpecular(in vec3 norm, in vec3 viewdir, in vec3 lightdir, in float shiny){
- if (shiny <= 1.0){
- return 0.0;
- }
- #ifndef LOW_QUALITY
- vec3 H = (viewdir + lightdir) * vec3(0.5);
- return pow(max(dot(H, norm), 0.0), shiny);
- #else
- return 0.0;
- #endif
- }
-
-vec2 computeLighting(in vec3 wvPos, in vec3 wvNorm, in vec3 wvViewDir, in vec4 wvLightPos){
- vec4 lightDir;
- lightComputeDir(wvPos, g_LightColor, wvLightPos, lightDir);
- float spotFallOff = 1.0;
- if(g_LightDirection.w != 0.0){
- vec3 L=normalize(lightVec.xyz);
- vec3 spotdir = normalize(g_LightDirection.xyz);
- float curAngleCos = dot(-L, spotdir);
- float innerAngleCos = floor(g_LightDirection.w) * 0.001;
- float outerAngleCos = fract(g_LightDirection.w);
- float innerMinusOuter = innerAngleCos - outerAngleCos;
- spotFallOff = clamp((curAngleCos - outerAngleCos) / innerMinusOuter, 0.0, 1.0);
- }
- float diffuseFactor = lightComputeDiffuse(wvNorm, lightDir.xyz);
- float specularFactor = lightComputeSpecular(wvNorm, wvViewDir, lightDir.xyz, m_Shininess);
- //specularFactor *= step(0.01, diffuseFactor);
- return vec2(diffuseFactor, specularFactor) * vec2(lightDir.w)*spotFallOff;
- }
-#endif
-
void main(){
vec4 modelSpacePos = vec4(inPosition, 1.0);
vec3 modelSpaceNorm = inNormal;
@@ -154,11 +103,6 @@ void main(){
vec3 wvNormal = normalize(TransformNormal(modelSpaceNorm));//normalize(g_NormalMatrix * modelSpaceNorm);
vec3 viewDir = normalize(-wvPosition);
- //vec4 lightColor = g_LightColor[gl_InstanceID];
- //vec4 lightPos = g_LightPosition[gl_InstanceID];
- //vec4 wvLightPos = (g_ViewMatrix * vec4(lightPos.xyz, lightColor.w));
- //wvLightPos.w = lightPos.w;
-
vec4 wvLightPos = (g_ViewMatrix * vec4(g_LightPosition.xyz,clamp(g_LightColor.w,0.0,1.0)));
wvLightPos.w = g_LightPosition.w;
vec4 lightColor = g_LightColor;
@@ -166,41 +110,24 @@ void main(){
#if defined(NORMALMAP) && !defined(VERTEX_LIGHTING)
vec3 wvTangent = normalize(TransformNormal(modelSpaceTan));
vec3 wvBinormal = cross(wvNormal, wvTangent);
-
mat3 tbnMat = mat3(wvTangent, wvBinormal * inTangent.w,wvNormal);
-
- //vPosition = wvPosition * tbnMat;
- //vViewDir = viewDir * tbnMat;
+
vViewDir = -wvPosition * tbnMat;
- lightComputeDir(wvPosition, lightColor, wvLightPos, vLightDir);
+ lightComputeDir(wvPosition, lightColor.w, wvLightPos, vLightDir, lightVec);
vLightDir.xyz = (vLightDir.xyz * tbnMat).xyz;
#elif !defined(VERTEX_LIGHTING)
vNormal = wvNormal;
-
- //vPosition = wvPosition;
vViewDir = viewDir;
-
- lightComputeDir(wvPosition, lightColor, wvLightPos, vLightDir);
-
- #ifdef V_TANGENT
- vNormal = normalize(TransformNormal(inTangent.xyz));
- vNormal = -cross(cross(vLightDir.xyz, vNormal), vNormal);
- #endif
+ lightComputeDir(wvPosition, lightColor.w, wvLightPos, vLightDir, lightVec);
#endif
- //computing spot direction in view space and unpacking spotlight cos
-// spotVec = (g_ViewMatrix * vec4(g_LightDirection.xyz, 0.0) );
-// spotVec.w = floor(g_LightDirection.w) * 0.001;
-// lightVec.w = fract(g_LightDirection.w);
-
- lightColor.w = 1.0;
#ifdef MATERIAL_COLORS
AmbientSum = (m_Ambient * g_AmbientLightColor).rgb;
- DiffuseSum = m_Diffuse * lightColor;
+ DiffuseSum = m_Diffuse * vec4(lightColor.rgb, 1.0);
SpecularSum = (m_Specular * lightColor).rgb;
#else
- AmbientSum = vec3(0.2, 0.2, 0.2) * g_AmbientLightColor.rgb; // Default: ambient color is dark gray
- DiffuseSum = lightColor;
+ AmbientSum = g_AmbientLightColor.rgb; // Default: ambient color is dark gray
+ DiffuseSum = vec4(lightColor.rgb, 1.0);
SpecularSum = vec3(0.0);
#endif
@@ -210,10 +137,22 @@ void main(){
#endif
#ifdef VERTEX_LIGHTING
- vertexLightValues = computeLighting(wvPosition, wvNormal, viewDir, wvLightPos);
+ float spotFallOff = 1.0;
+ vec4 vLightDir;
+ lightComputeDir(wvPosition, lightColor.w, wvLightPos, vLightDir, lightVec);
+ #if __VERSION__ >= 110
+ // allow use of control flow
+ if(lightColor.w > 1.0){
+ #endif
+ spotFallOff = computeSpotFalloff(g_LightDirection, lightVec);
+ #if __VERSION__ >= 110
+ }
+ #endif
+
+ vertexLightValues = computeLighting(wvNormal, viewDir, vLightDir.xyz, vLightDir.w * spotFallOff, m_Shininess);
#endif
- #ifdef USE_REFLECTION
+ #ifdef USE_REFLECTION
computeRef(modelSpacePos);
#endif
}
\ No newline at end of file
diff --git a/jme3-core/src/main/resources/Common/MatDefs/Light/SPLighting.frag b/jme3-core/src/main/resources/Common/MatDefs/Light/SPLighting.frag
new file mode 100644
index 000000000..09478c6e8
--- /dev/null
+++ b/jme3-core/src/main/resources/Common/MatDefs/Light/SPLighting.frag
@@ -0,0 +1,218 @@
+#import "Common/ShaderLib/Parallax.glsllib"
+#import "Common/ShaderLib/Optics.glsllib"
+#ifndef VERTEX_LIGHTING
+ #import "Common/ShaderLib/PhongLighting.glsllib"
+ #import "Common/ShaderLib/Lighting.glsllib"
+#endif
+
+varying vec2 texCoord;
+#ifdef SEPARATE_TEXCOORD
+ varying vec2 texCoord2;
+#endif
+
+varying vec3 AmbientSum;
+varying vec4 DiffuseSum;
+varying vec3 SpecularSum;
+
+#ifndef VERTEX_LIGHTING
+ uniform mat4 g_ViewMatrix;
+ uniform vec4 g_LightData[NB_LIGHTS];
+ varying vec3 vPos;
+#else
+ varying vec3 specularAccum;
+ varying vec4 diffuseAccum;
+#endif
+
+#ifdef DIFFUSEMAP
+ uniform sampler2D m_DiffuseMap;
+#endif
+
+#ifdef SPECULARMAP
+ uniform sampler2D m_SpecularMap;
+#endif
+
+#ifdef PARALLAXMAP
+ uniform sampler2D m_ParallaxMap;
+#endif
+#if (defined(PARALLAXMAP) || (defined(NORMALMAP_PARALLAX) && defined(NORMALMAP))) && !defined(VERTEX_LIGHTING)
+ uniform float m_ParallaxHeight;
+#endif
+
+#ifdef LIGHTMAP
+ uniform sampler2D m_LightMap;
+#endif
+
+#ifdef NORMALMAP
+ uniform sampler2D m_NormalMap;
+ varying vec3 vTangent;
+ varying vec3 vBinormal;
+#endif
+varying vec3 vNormal;
+
+#ifdef ALPHAMAP
+ uniform sampler2D m_AlphaMap;
+#endif
+
+#ifdef COLORRAMP
+ uniform sampler2D m_ColorRamp;
+#endif
+
+uniform float m_AlphaDiscardThreshold;
+
+#ifndef VERTEX_LIGHTING
+uniform float m_Shininess;
+
+ #ifdef USE_REFLECTION
+ uniform float m_ReflectionPower;
+ uniform float m_ReflectionIntensity;
+ varying vec4 refVec;
+
+ uniform ENVMAP m_EnvMap;
+ #endif
+#endif
+
+void main(){
+ vec2 newTexCoord;
+
+ #if (defined(PARALLAXMAP) || (defined(NORMALMAP_PARALLAX) && defined(NORMALMAP))) && !defined(VERTEX_LIGHTING)
+
+ #ifdef STEEP_PARALLAX
+ #ifdef NORMALMAP_PARALLAX
+ //parallax map is stored in the alpha channel of the normal map
+ newTexCoord = steepParallaxOffset(m_NormalMap, vViewDir, texCoord, m_ParallaxHeight);
+ #else
+ //parallax map is a texture
+ newTexCoord = steepParallaxOffset(m_ParallaxMap, vViewDir, texCoord, m_ParallaxHeight);
+ #endif
+ #else
+ #ifdef NORMALMAP_PARALLAX
+ //parallax map is stored in the alpha channel of the normal map
+ newTexCoord = classicParallaxOffset(m_NormalMap, vViewDir, texCoord, m_ParallaxHeight);
+ #else
+ //parallax map is a texture
+ newTexCoord = classicParallaxOffset(m_ParallaxMap, vViewDir, texCoord, m_ParallaxHeight);
+ #endif
+ #endif
+ #else
+ newTexCoord = texCoord;
+ #endif
+
+ #ifdef DIFFUSEMAP
+ vec4 diffuseColor = texture2D(m_DiffuseMap, newTexCoord);
+ #else
+ vec4 diffuseColor = vec4(1.0);
+ #endif
+
+ float alpha = DiffuseSum.a * diffuseColor.a;
+
+ #ifdef ALPHAMAP
+ alpha = alpha * texture2D(m_AlphaMap, newTexCoord).r;
+ #endif
+
+ #ifdef DISCARD_ALPHA
+ if(alpha < m_AlphaDiscardThreshold){
+ discard;
+ }
+ #endif
+
+ // ***********************
+ // Read from textures
+ // ***********************
+ #if defined(NORMALMAP) && !defined(VERTEX_LIGHTING)
+ vec4 normalHeight = texture2D(m_NormalMap, 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,-2.0,2.0) - vec3(1.0,-1.0,1.0)));
+ #elif !defined(VERTEX_LIGHTING)
+ vec3 normal = normalize(vNormal);
+ #endif
+
+ #ifdef SPECULARMAP
+ vec4 specularColor = texture2D(m_SpecularMap, newTexCoord);
+ #else
+ vec4 specularColor = vec4(1.0);
+ #endif
+
+ #ifdef LIGHTMAP
+ vec3 lightMapColor;
+ #ifdef SEPARATE_TEXCOORD
+ lightMapColor = texture2D(m_LightMap, texCoord2).rgb;
+ #else
+ lightMapColor = texture2D(m_LightMap, texCoord).rgb;
+ #endif
+ specularColor.rgb *= lightMapColor;
+ diffuseColor.rgb *= lightMapColor;
+ #endif
+
+ #ifdef VERTEX_LIGHTING
+ gl_FragColor.rgb = AmbientSum * diffuseColor.rgb
+ +diffuseAccum.rgb *diffuseColor.rgb
+ +specularAccum.rgb * specularColor.rgb;
+ gl_FragColor.a=1.0;
+ #else
+
+ int i = 0;
+ gl_FragColor.rgb = AmbientSum * diffuseColor.rgb;
+
+ #ifdef USE_REFLECTION
+ vec4 refColor = Optics_GetEnvColor(m_EnvMap, refVec.xyz);
+ #endif
+
+ #ifdef NORMALMAP
+ mat3 tbnMat = mat3(normalize(vTangent.xyz) , normalize(vBinormal.xyz) , normalize(vNormal.xyz));
+ #endif
+
+ 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(vPos, lightColor.w, lightData1, lightDir,lightVec);
+
+ float spotFallOff = 1.0;
+ #if __VERSION__ >= 110
+ // allow use of control flow
+ if(lightColor.w > 1.0){
+ #endif
+ spotFallOff = computeSpotFalloff(g_LightData[i+2], lightVec);
+ #if __VERSION__ >= 110
+ }
+ #endif
+
+ #ifdef NORMALMAP
+ //Normal map -> lighting is computed in tangent space
+ lightDir.xyz = normalize(lightDir.xyz * tbnMat);
+ vec3 viewDir = normalize(-vPos.xyz * tbnMat);
+ #else
+ //no Normal map -> lighting is computed in view space
+ lightDir.xyz = normalize(lightDir.xyz);
+ vec3 viewDir = normalize(-vPos.xyz);
+ #endif
+
+ vec2 light = computeLighting(normal, viewDir, lightDir.xyz, lightDir.w * spotFallOff , m_Shininess);
+
+ #ifdef COLORRAMP
+ diffuseColor.rgb *= texture2D(m_ColorRamp, vec2(light.x, 0.0)).rgb;
+ specularColor.rgb *= texture2D(m_ColorRamp, vec2(light.y, 0.0)).rgb;
+ #endif
+
+ // Workaround, since it is not possible to modify varying variables
+ vec4 SpecularSum2 = vec4(SpecularSum, 1.0);
+ #ifdef USE_REFLECTION
+ // Interpolate light specularity toward reflection color
+ // Multiply result by specular map
+ specularColor = mix(SpecularSum2 * light.y, refColor, refVec.w) * specularColor;
+
+ SpecularSum2 = vec4(1.0);
+ light.y = 1.0;
+ #endif
+
+ gl_FragColor.rgb += DiffuseSum.rgb * lightColor.rgb * diffuseColor.rgb * vec3(light.x) +
+ SpecularSum2.rgb * specularColor.rgb * vec3(light.y);
+ }
+
+ #endif
+ gl_FragColor.a = alpha;
+}
diff --git a/jme3-core/src/main/resources/Common/MatDefs/Light/SPLighting.vert b/jme3-core/src/main/resources/Common/MatDefs/Light/SPLighting.vert
new file mode 100644
index 000000000..81ea869b6
--- /dev/null
+++ b/jme3-core/src/main/resources/Common/MatDefs/Light/SPLighting.vert
@@ -0,0 +1,172 @@
+#import "Common/ShaderLib/Instancing.glsllib"
+#import "Common/ShaderLib/Skinning.glsllib"
+#import "Common/ShaderLib/Lighting.glsllib"
+#ifdef VERTEX_LIGHTING
+ #import "Common/ShaderLib/PhongLighting.glsllib"
+#endif
+
+
+uniform vec4 m_Ambient;
+uniform vec4 m_Diffuse;
+uniform vec4 m_Specular;
+uniform float m_Shininess;
+
+#if defined(VERTEX_LIGHTING)
+ uniform vec4 g_LightData[NB_LIGHTS];
+#endif
+uniform vec4 g_AmbientLightColor;
+varying vec2 texCoord;
+
+#ifdef SEPARATE_TEXCOORD
+ varying vec2 texCoord2;
+ attribute vec2 inTexCoord2;
+#endif
+
+varying vec3 AmbientSum;
+varying vec4 DiffuseSum;
+varying vec3 SpecularSum;
+
+attribute vec3 inPosition;
+attribute vec2 inTexCoord;
+attribute vec3 inNormal;
+
+#ifdef VERTEX_COLOR
+ attribute vec4 inColor;
+#endif
+
+#ifndef VERTEX_LIGHTING
+ varying vec3 vNormal;
+ varying vec3 vPos;
+ #ifdef NORMALMAP
+ attribute vec4 inTangent;
+ varying vec3 vTangent;
+ varying vec3 vBinormal;
+ #endif
+#else
+ varying vec3 specularAccum;
+ varying vec4 diffuseAccum;
+#endif
+
+#ifdef USE_REFLECTION
+ uniform vec3 g_CameraPosition;
+ uniform vec3 m_FresnelParams;
+ varying vec4 refVec;
+
+ /**
+ * Input:
+ * attribute inPosition
+ * attribute inNormal
+ * uniform g_WorldMatrix
+ * uniform g_CameraPosition
+ *
+ * Output:
+ * varying refVec
+ */
+ void computeRef(in vec4 modelSpacePos){
+ // vec3 worldPos = (g_WorldMatrix * modelSpacePos).xyz;
+ vec3 worldPos = TransformWorld(modelSpacePos).xyz;
+
+ vec3 I = normalize( g_CameraPosition - worldPos ).xyz;
+ // vec3 N = normalize( (g_WorldMatrix * vec4(inNormal, 0.0)).xyz );
+ vec3 N = normalize( TransformWorld(vec4(inNormal, 0.0)).xyz );
+
+ refVec.xyz = reflect(I, N);
+ refVec.w = m_FresnelParams.x + m_FresnelParams.y * pow(1.0 + dot(I, N), m_FresnelParams.z);
+ }
+#endif
+
+void main(){
+ vec4 modelSpacePos = vec4(inPosition, 1.0);
+ vec3 modelSpaceNorm = inNormal;
+
+ #if defined(NORMALMAP) && !defined(VERTEX_LIGHTING)
+ vec3 modelSpaceTan = inTangent.xyz;
+ #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
+
+ vec3 wvPosition = TransformWorldView(modelSpacePos).xyz;
+ vec3 wvNormal = normalize(TransformNormal(modelSpaceNorm));
+ vec3 viewDir = normalize(-wvPosition);
+
+
+ #if defined(NORMALMAP) && !defined(VERTEX_LIGHTING)
+ vTangent = TransformNormal(modelSpaceTan);
+ vBinormal = cross(wvNormal, vTangent)* inTangent.w;
+ vNormal = wvNormal;
+ vPos = wvPosition;
+ #elif !defined(VERTEX_LIGHTING)
+ vNormal = wvNormal;
+ vPos = wvPosition;
+ #endif
+
+ #ifdef MATERIAL_COLORS
+ AmbientSum = m_Ambient.rgb * g_AmbientLightColor.rgb;
+ SpecularSum = m_Specular.rgb;
+ DiffuseSum = m_Diffuse;
+ #else
+ AmbientSum = g_AmbientLightColor.rgb;
+ SpecularSum = vec3(0.0);
+ DiffuseSum = vec4(1.0);
+ #endif
+ #ifdef VERTEX_COLOR
+ AmbientSum *= inColor.rgb;
+ DiffuseSum *= inColor;
+ #endif
+ #ifdef VERTEX_LIGHTING
+ int i = 0;
+ diffuseAccum = vec4(0.0);
+ specularAccum = vec3(0.0);
+ vec4 diffuseColor;
+ vec3 specularColor;
+ for (int i =0;i < NB_LIGHTS; i+=3){
+ vec4 lightColor = g_LightData[i];
+ vec4 lightData1 = g_LightData[i+1];
+ DiffuseSum = vec4(1.0);
+ #ifdef MATERIAL_COLORS
+ diffuseColor = m_Diffuse * vec4(lightColor.rgb, 1.0);
+ specularColor = m_Specular.rgb * lightColor.rgb;
+ #else
+ diffuseColor = vec4(lightColor.rgb, 1.0);
+ specularColor = vec3(0.0);
+ #endif
+
+ vec4 lightDir;
+ vec3 lightVec;
+ lightComputeDir(wvPosition, lightColor.w, lightData1, lightDir, lightVec);
+ // lightDir = normalize(lightDir);
+ // lightVec = normalize(lightVec);
+
+ float spotFallOff = 1.0;
+ #if __VERSION__ >= 110
+ // allow use of control flow
+ if(lightColor.w > 1.0){
+ #endif
+ vec4 lightDirection = g_LightData[i+2];
+ spotFallOff = computeSpotFalloff(lightDirection, lightVec);
+ #if __VERSION__ >= 110
+ }
+ #endif
+ vec2 v = computeLighting(wvNormal, viewDir, lightDir.xyz, lightDir.w * spotFallOff, m_Shininess);
+ diffuseAccum +=v.x * diffuseColor;
+ specularAccum += v.y * specularColor;
+ }
+ #endif
+
+
+ #ifdef USE_REFLECTION
+ computeRef(modelSpacePos);
+ #endif
+}
\ No newline at end of file
diff --git a/jme3-core/src/main/resources/Common/ShaderLib/Lighting.glsllib b/jme3-core/src/main/resources/Common/ShaderLib/Lighting.glsllib
index 4d1b40436..3b8863b6c 100644
--- a/jme3-core/src/main/resources/Common/ShaderLib/Lighting.glsllib
+++ b/jme3-core/src/main/resources/Common/ShaderLib/Lighting.glsllib
@@ -1,48 +1,30 @@
-#ifndef NUM_LIGHTS
- #define NUM_LIGHTS 4
-#endif
+/*Common function for light calculations*/
-uniform mat4 g_ViewMatrix;
-uniform vec4 g_LightPosition[NUM_LIGHTS];
-uniform vec4 g_g_LightColor[NUM_LIGHTS];
-uniform float m_Shininess;
-float Lighting_Diffuse(vec3 norm, vec3 lightdir){
- return max(0.0, dot(norm, lightdir));
-}
-
-float Lighting_Specular(vec3 norm, vec3 viewdir, vec3 lightdir, float shiny){
- vec3 refdir = reflect(-lightdir, norm);
- return pow(max(dot(refdir, viewdir), 0.0), shiny);
-}
-
-void Lighting_Direction(vec3 worldPos, vec4 color, vec4 position, out vec4 lightDir){
- float posLight = step(0.5, color.w);
+/*
+* Computes light direction
+* lightType should be 0.0,1.0,2.0, repectively for Directional, point and spot lights.
+* Outputs the light direction and the light half vector.
+*/
+void lightComputeDir(in vec3 worldPos, in float ligthType, in vec4 position, out vec4 lightDir, out vec3 lightVec){
+ float posLight = step(0.5, ligthType);
vec3 tempVec = position.xyz * sign(posLight - 0.5) - (worldPos * posLight);
+ lightVec = tempVec;
float dist = length(tempVec);
-
lightDir.w = clamp(1.0 - position.w * dist * posLight, 0.0, 1.0);
- lightDir.xyz = tempVec / dist;
+ lightDir.xyz = tempVec / vec3(dist);
}
-void Lighting_ComputePS(vec3 tanNormal, mat3 tbnMat,
- int lightCount, out vec3 outDiffuse, out vec3 outSpecular){
- // find tangent view dir & vert pos
- vec3 tanViewDir = viewDir * tbnMat;
-
- for (int i = 0; i < lightCount; i++){
- // find light dir in tangent space, works for point & directional lights
- vec4 wvLightPos = (g_ViewMatrix * vec4(g_LightPosition[i].xyz, g_LightColor[i].w));
- wvLightPos.w = g_LightPosition[i].w;
-
- vec4 tanLightDir;
- Lighting_Direction(wvPosition, g_LightColor[i], wvLightPos, tanLightDir);
- tanLightDir.xyz = tanLightDir.xyz * tbnMat;
-
- vec3 lightScale = g_LightColor[i].rgb * tanLightDir.w;
- float specular = Lighting_Specular(tanNormal, tanViewDir, tanLightDir.xyz, m_Shininess);
- float diffuse = Lighting_Diffuse(tanNormal, tanLightDir.xyz);
- outSpecular += specular * lightScale * step(0.01, diffuse) * g_LightColor[i].rgb;
- outDiffuse += diffuse * lightScale * g_LightColor[i].rgb;
- }
+/*
+* Computes the spot falloff for a spotlight
+*/
+float computeSpotFalloff(in vec4 lightDirection, in vec3 lightVector){
+ vec3 L=normalize(lightVector);
+ vec3 spotdir = normalize(lightDirection.xyz);
+ float curAngleCos = dot(-L, spotdir);
+ float innerAngleCos = floor(lightDirection.w) * 0.001;
+ float outerAngleCos = fract(lightDirection.w);
+ float innerMinusOuter = innerAngleCos - outerAngleCos;
+ return clamp((curAngleCos - outerAngleCos) / innerMinusOuter, step(lightDirection.w, 0.001), 1.0);
}
+
diff --git a/jme3-core/src/main/resources/Common/ShaderLib/PhongLighting.glsllib b/jme3-core/src/main/resources/Common/ShaderLib/PhongLighting.glsllib
new file mode 100644
index 000000000..8ebeb9924
--- /dev/null
+++ b/jme3-core/src/main/resources/Common/ShaderLib/PhongLighting.glsllib
@@ -0,0 +1,29 @@
+/*Standard Phong ligting*/
+
+/*
+* Computes diffuse factor
+*/
+float lightComputeDiffuse(in vec3 norm, in vec3 lightdir){
+ return max(0.0, dot(norm, lightdir));
+}
+
+/*
+* Computes specular factor
+*/
+float lightComputeSpecular(in vec3 norm, in vec3 viewdir, in vec3 lightdir, in float shiny){
+ vec3 R = reflect(-lightdir, norm);
+ return pow(max(dot(R, viewdir), 0.0), shiny);
+}
+
+/*
+* Computes diffuse and specular factors and pack them in a vec2 (x=diffuse, y=specular)
+*/
+vec2 computeLighting(in vec3 norm, in vec3 viewDir, in vec3 lightDir, in float attenuation, in float shininess){
+ float diffuseFactor = lightComputeDiffuse(norm, lightDir);
+ float specularFactor = lightComputeSpecular(norm, viewDir, lightDir, shininess);
+ if (shininess <= 1.0) {
+ specularFactor = 0.0; // should be one instruction on most cards ..
+ }
+ specularFactor *= diffuseFactor;
+ return vec2(diffuseFactor, specularFactor) * vec2(attenuation);
+}
\ No newline at end of file
diff --git a/jme3-examples/src/main/java/jme3test/light/TestManyLightsSingle.java b/jme3-examples/src/main/java/jme3test/light/TestManyLightsSingle.java
new file mode 100644
index 000000000..acc0037b8
--- /dev/null
+++ b/jme3-examples/src/main/java/jme3test/light/TestManyLightsSingle.java
@@ -0,0 +1,255 @@
+/*
+ * Copyright (c) 2009-2012 jMonkeyEngine
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package jme3test.light;
+
+import com.jme3.app.BasicProfilerState;
+import com.jme3.app.SimpleApplication;
+import com.jme3.font.BitmapText;
+import com.jme3.input.KeyInput;
+import com.jme3.input.controls.ActionListener;
+import com.jme3.input.controls.KeyTrigger;
+import com.jme3.light.AmbientLight;
+import com.jme3.light.DirectionalLight;
+import com.jme3.light.Light;
+import com.jme3.light.LightList;
+import com.jme3.light.PointLight;
+import com.jme3.light.SpotLight;
+import com.jme3.material.Material;
+import com.jme3.material.TechniqueDef;
+import com.jme3.math.ColorRGBA;
+import com.jme3.math.FastMath;
+import com.jme3.math.Quaternion;
+import com.jme3.math.Vector3f;
+import com.jme3.renderer.RenderManager;
+import com.jme3.renderer.ViewPort;
+import com.jme3.scene.Geometry;
+import com.jme3.scene.LightNode;
+import com.jme3.scene.Node;
+import com.jme3.scene.Spatial;
+import com.jme3.scene.control.AbstractControl;
+import com.jme3.scene.shape.Box;
+
+public class TestManyLightsSingle extends SimpleApplication {
+
+ public static void main(String[] args) {
+ TestManyLightsSingle app = new TestManyLightsSingle();
+ app.start();
+ }
+ TechniqueDef.LightMode lm = TechniqueDef.LightMode.MultiPass;
+ int lightNum = 6 ;
+
+ @Override
+ public void simpleInitApp() {
+ renderManager.setPreferredLightMode(lm);
+ renderManager.setSinglePassLightBatchSize(lightNum);
+
+
+ flyCam.setMoveSpeed(10);
+
+ Node scene = (Node) assetManager.loadModel("Scenes/ManyLights/Main.scene");
+ rootNode.attachChild(scene);
+ Node n = (Node) rootNode.getChild(0);
+ LightList lightList = n.getWorldLightList();
+ Geometry g = (Geometry) n.getChild("Grid-geom-1");
+
+ g.getMaterial().setColor("Ambient", new ColorRGBA(0.2f, 0.2f, 0.2f, 1f));
+
+ /* A colored lit cube. Needs light source! */
+ Box boxMesh = new Box(1f, 1f, 1f);
+ Geometry boxGeo = new Geometry("Colored Box", boxMesh);
+ Material boxMat = g.getMaterial().clone();
+ boxMat.setBoolean("UseMaterialColors", true);
+ boxMat.setColor("Ambient", new ColorRGBA(0.2f, 0.2f, 0.2f, 1f));
+ boxMat.setColor("Diffuse", ColorRGBA.Blue);
+ boxGeo.setMaterial(boxMat);
+
+ int nb = 0;
+ for (Light light : lightList) {
+ nb++;
+ PointLight p = (PointLight) light;
+ if (nb >60) {
+ n.removeLight(light);
+ } else {
+
+ LightNode ln = new LightNode("l", light);
+ n.attachChild(ln);
+ ln.setLocalTranslation(p.getPosition());
+ int rand = FastMath.nextRandomInt(0, 3);
+ switch (rand) {
+ case 0:
+ light.setColor(ColorRGBA.Red);
+ // ln.addControl(new MoveControl(5f));
+ break;
+ case 1:
+ light.setColor(ColorRGBA.Yellow);
+ // ln.addControl(new MoveControl(5f));
+ break;
+ case 2:
+ light.setColor(ColorRGBA.Green);
+ //ln.addControl(new MoveControl(-5f));
+ break;
+ case 3:
+ light.setColor(ColorRGBA.Orange);
+ //ln.addControl(new MoveControl(-5f));
+ break;
+ }
+ }
+ Geometry b = boxGeo.clone();
+ n.attachChild(b);
+ b.setLocalTranslation(p.getPosition().x, 2, p.getPosition().z);
+
+ }
+
+
+// cam.setLocation(new Vector3f(3.1893547f, 17.977385f, 30.8378f));
+// cam.setRotation(new Quaternion(0.14317635f, 0.82302624f, -0.23777823f, 0.49557027f));
+
+ cam.setLocation(new Vector3f(-1.8901939f, 29.34097f, 73.07533f));
+ cam.setRotation(new Quaternion(0.0021000702f, 0.971012f, -0.23886925f, 0.008527749f));
+
+
+ BasicProfilerState profiler = new BasicProfilerState(true);
+ profiler.setGraphScale(1000f);
+
+ // getStateManager().attach(profiler);
+// guiNode.setCullHint(CullHint.Always);
+
+
+
+
+ flyCam.setDragToRotate(true);
+ flyCam.setMoveSpeed(50);
+
+
+ inputManager.addListener(new ActionListener() {
+ public void onAction(String name, boolean isPressed, float tpf) {
+ if (name.equals("toggle") && isPressed) {
+ if (lm == TechniqueDef.LightMode.SinglePass) {
+ lm = TechniqueDef.LightMode.MultiPass;
+ } else {
+ lm = TechniqueDef.LightMode.SinglePass;
+ }
+ renderManager.setPreferredLightMode(lm);
+ }
+ if (name.equals("lightsUp") && isPressed) {
+ lightNum++;
+ renderManager.setSinglePassLightBatchSize(lightNum);
+ helloText.setText("nb lights per batch : " + lightNum);
+ }
+ if (name.equals("lightsDown") && isPressed) {
+ lightNum--;
+ renderManager.setSinglePassLightBatchSize(lightNum);
+ helloText.setText("nb lights per batch : " + lightNum);
+ }
+ }
+ }, "toggle", "lightsUp", "lightsDown");
+
+ inputManager.addMapping("toggle", new KeyTrigger(KeyInput.KEY_SPACE));
+ inputManager.addMapping("lightsUp", new KeyTrigger(KeyInput.KEY_UP));
+ inputManager.addMapping("lightsDown", new KeyTrigger(KeyInput.KEY_DOWN));
+
+
+ SpotLight spot = new SpotLight();
+ spot.setDirection(new Vector3f(-1f, -1f, -1f).normalizeLocal());
+ spot.setColor(ColorRGBA.Blue.mult(5));
+ spot.setSpotOuterAngle(FastMath.DEG_TO_RAD * 20);
+ spot.setSpotInnerAngle(FastMath.DEG_TO_RAD * 5);
+ spot.setPosition(new Vector3f(10, 10, 20));
+ rootNode.addLight(spot);
+
+ DirectionalLight dl = new DirectionalLight();
+ dl.setDirection(new Vector3f(-1, -1, 1));
+ rootNode.addLight(dl);
+
+ AmbientLight al = new AmbientLight();
+ al.setColor(new ColorRGBA(0.2f, 0.2f, 0.2f, 1f));
+ rootNode.addLight(al);
+
+
+ /**
+ * Write text on the screen (HUD)
+ */
+ guiNode.detachAllChildren();
+ guiFont = assetManager.loadFont("Interface/Fonts/Default.fnt");
+ helloText = new BitmapText(guiFont, false);
+ helloText.setSize(guiFont.getCharSet().getRenderedSize());
+ helloText.setText("nb lights per batch : " + lightNum);
+ helloText.setLocalTranslation(300, helloText.getLineHeight(), 0);
+ guiNode.attachChild(helloText);
+
+
+ }
+ BitmapText helloText;
+ long time;
+ long nbFrames;
+ long startTime = 0;
+
+ @Override
+ public void simpleUpdate(float tpf) {
+// if (nbFrames == 4000) {
+// startTime = System.nanoTime();
+// }
+// if (nbFrames > 4000) {
+// time = System.nanoTime();
+// float average = ((float) time - (float) startTime) / ((float) nbFrames - 4000f);
+// helloText.setText("Average = " + average);
+// }
+// nbFrames++;
+ }
+
+ class MoveControl extends AbstractControl {
+
+ float direction;
+ Vector3f origPos = new Vector3f();
+
+ public MoveControl(float direction) {
+ this.direction = direction;
+ }
+
+ @Override
+ public void setSpatial(Spatial spatial) {
+ super.setSpatial(spatial); //To change body of generated methods, choose Tools | Templates.
+ origPos.set(spatial.getLocalTranslation());
+ }
+ float time = 0;
+
+ @Override
+ protected void controlUpdate(float tpf) {
+ time += tpf;
+ spatial.setLocalTranslation(origPos.x + FastMath.cos(time) * direction, origPos.y, origPos.z + FastMath.sin(time) * direction);
+ }
+
+ @Override
+ protected void controlRender(RenderManager rm, ViewPort vp) {
+ }
+ }
+}
\ No newline at end of file
diff --git a/jme3-terrain/src/main/resources/Common/MatDefs/Terrain/SPTerrainLighting.frag b/jme3-terrain/src/main/resources/Common/MatDefs/Terrain/SPTerrainLighting.frag
new file mode 100644
index 000000000..9556f256d
--- /dev/null
+++ b/jme3-terrain/src/main/resources/Common/MatDefs/Terrain/SPTerrainLighting.frag
@@ -0,0 +1,615 @@
+#import "Common/ShaderLib/PhongLighting.glsllib"
+#import "Common/ShaderLib/Lighting.glsllib"
+
+uniform float m_Shininess;
+
+varying vec4 AmbientSum;
+varying vec4 DiffuseSum;
+varying vec4 SpecularSum;
+
+uniform mat4 g_ViewMatrix;
+uniform vec4 g_LightData[NB_LIGHTS];
+varying vec3 vTangent;
+varying vec3 vBinormal;
+varying vec3 vPos;
+varying vec3 vNormal;
+varying vec2 texCoord;
+
+
+#ifdef DIFFUSEMAP
+ uniform sampler2D m_DiffuseMap;
+#endif
+#ifdef DIFFUSEMAP_1
+ uniform sampler2D m_DiffuseMap_1;
+#endif
+#ifdef DIFFUSEMAP_2
+ uniform sampler2D m_DiffuseMap_2;
+#endif
+#ifdef DIFFUSEMAP_3
+ uniform sampler2D m_DiffuseMap_3;
+#endif
+#ifdef DIFFUSEMAP_4
+ uniform sampler2D m_DiffuseMap_4;
+#endif
+#ifdef DIFFUSEMAP_5
+ uniform sampler2D m_DiffuseMap_5;
+#endif
+#ifdef DIFFUSEMAP_6
+ uniform sampler2D m_DiffuseMap_6;
+#endif
+#ifdef DIFFUSEMAP_7
+ uniform sampler2D m_DiffuseMap_7;
+#endif
+#ifdef DIFFUSEMAP_8
+ uniform sampler2D m_DiffuseMap_8;
+#endif
+#ifdef DIFFUSEMAP_9
+ uniform sampler2D m_DiffuseMap_9;
+#endif
+#ifdef DIFFUSEMAP_10
+ uniform sampler2D m_DiffuseMap_10;
+#endif
+#ifdef DIFFUSEMAP_11
+ uniform sampler2D m_DiffuseMap_11;
+#endif
+
+
+#ifdef DIFFUSEMAP_0_SCALE
+ uniform float m_DiffuseMap_0_scale;
+#endif
+#ifdef DIFFUSEMAP_1_SCALE
+ uniform float m_DiffuseMap_1_scale;
+#endif
+#ifdef DIFFUSEMAP_2_SCALE
+ uniform float m_DiffuseMap_2_scale;
+#endif
+#ifdef DIFFUSEMAP_3_SCALE
+ uniform float m_DiffuseMap_3_scale;
+#endif
+#ifdef DIFFUSEMAP_4_SCALE
+ uniform float m_DiffuseMap_4_scale;
+#endif
+#ifdef DIFFUSEMAP_5_SCALE
+ uniform float m_DiffuseMap_5_scale;
+#endif
+#ifdef DIFFUSEMAP_6_SCALE
+ uniform float m_DiffuseMap_6_scale;
+#endif
+#ifdef DIFFUSEMAP_7_SCALE
+ uniform float m_DiffuseMap_7_scale;
+#endif
+#ifdef DIFFUSEMAP_8_SCALE
+ uniform float m_DiffuseMap_8_scale;
+#endif
+#ifdef DIFFUSEMAP_9_SCALE
+ uniform float m_DiffuseMap_9_scale;
+#endif
+#ifdef DIFFUSEMAP_10_SCALE
+ uniform float m_DiffuseMap_10_scale;
+#endif
+#ifdef DIFFUSEMAP_11_SCALE
+ uniform float m_DiffuseMap_11_scale;
+#endif
+
+
+#ifdef ALPHAMAP
+ uniform sampler2D m_AlphaMap;
+#endif
+#ifdef ALPHAMAP_1
+ uniform sampler2D m_AlphaMap_1;
+#endif
+#ifdef ALPHAMAP_2
+ uniform sampler2D m_AlphaMap_2;
+#endif
+
+#ifdef NORMALMAP
+ uniform sampler2D m_NormalMap;
+#endif
+#ifdef NORMALMAP_1
+ uniform sampler2D m_NormalMap_1;
+#endif
+#ifdef NORMALMAP_2
+ uniform sampler2D m_NormalMap_2;
+#endif
+#ifdef NORMALMAP_3
+ uniform sampler2D m_NormalMap_3;
+#endif
+#ifdef NORMALMAP_4
+ uniform sampler2D m_NormalMap_4;
+#endif
+#ifdef NORMALMAP_5
+ uniform sampler2D m_NormalMap_5;
+#endif
+#ifdef NORMALMAP_6
+ uniform sampler2D m_NormalMap_6;
+#endif
+#ifdef NORMALMAP_7
+ uniform sampler2D m_NormalMap_7;
+#endif
+#ifdef NORMALMAP_8
+ uniform sampler2D m_NormalMap_8;
+#endif
+#ifdef NORMALMAP_9
+ uniform sampler2D m_NormalMap_9;
+#endif
+#ifdef NORMALMAP_10
+ uniform sampler2D m_NormalMap_10;
+#endif
+#ifdef NORMALMAP_11
+ uniform sampler2D m_NormalMap_11;
+#endif
+
+
+#ifdef TRI_PLANAR_MAPPING
+ varying vec4 wVertex;
+ varying vec3 wNormal;
+#endif
+
+
+#ifdef ALPHAMAP
+
+ vec4 calculateDiffuseBlend(in vec2 texCoord) {
+ vec4 alphaBlend = texture2D( m_AlphaMap, texCoord.xy );
+
+ #ifdef ALPHAMAP_1
+ vec4 alphaBlend1 = texture2D( m_AlphaMap_1, texCoord.xy );
+ #endif
+ #ifdef ALPHAMAP_2
+ vec4 alphaBlend2 = texture2D( m_AlphaMap_2, texCoord.xy );
+ #endif
+
+ vec4 diffuseColor = texture2D(m_DiffuseMap, texCoord * m_DiffuseMap_0_scale);
+ diffuseColor *= alphaBlend.r;
+ #ifdef DIFFUSEMAP_1
+ vec4 diffuseColor1 = texture2D(m_DiffuseMap_1, texCoord * m_DiffuseMap_1_scale);
+ diffuseColor = mix( diffuseColor, diffuseColor1, alphaBlend.g );
+ #endif
+ #ifdef DIFFUSEMAP_2
+ vec4 diffuseColor2 = texture2D(m_DiffuseMap_2, texCoord * m_DiffuseMap_2_scale);
+ diffuseColor = mix( diffuseColor, diffuseColor2, alphaBlend.b );
+ #endif
+ #ifdef DIFFUSEMAP_3
+ vec4 diffuseColor3 = texture2D(m_DiffuseMap_3, texCoord * m_DiffuseMap_3_scale);
+ diffuseColor = mix( diffuseColor, diffuseColor3, alphaBlend.a );
+ #endif
+
+ #ifdef ALPHAMAP_1
+ #ifdef DIFFUSEMAP_4
+ vec4 diffuseColor4 = texture2D(m_DiffuseMap_4, texCoord * m_DiffuseMap_4_scale);
+ diffuseColor = mix( diffuseColor, diffuseColor4, alphaBlend1.r );
+ #endif
+ #ifdef DIFFUSEMAP_5
+ vec4 diffuseColor5 = texture2D(m_DiffuseMap_5, texCoord * m_DiffuseMap_5_scale);
+ diffuseColor = mix( diffuseColor, diffuseColor5, alphaBlend1.g );
+ #endif
+ #ifdef DIFFUSEMAP_6
+ vec4 diffuseColor6 = texture2D(m_DiffuseMap_6, texCoord * m_DiffuseMap_6_scale);
+ diffuseColor = mix( diffuseColor, diffuseColor6, alphaBlend1.b );
+ #endif
+ #ifdef DIFFUSEMAP_7
+ vec4 diffuseColor7 = texture2D(m_DiffuseMap_7, texCoord * m_DiffuseMap_7_scale);
+ diffuseColor = mix( diffuseColor, diffuseColor7, alphaBlend1.a );
+ #endif
+ #endif
+
+ #ifdef ALPHAMAP_2
+ #ifdef DIFFUSEMAP_8
+ vec4 diffuseColor8 = texture2D(m_DiffuseMap_8, texCoord * m_DiffuseMap_8_scale);
+ diffuseColor = mix( diffuseColor, diffuseColor8, alphaBlend2.r );
+ #endif
+ #ifdef DIFFUSEMAP_9
+ vec4 diffuseColor9 = texture2D(m_DiffuseMap_9, texCoord * m_DiffuseMap_9_scale);
+ diffuseColor = mix( diffuseColor, diffuseColor9, alphaBlend2.g );
+ #endif
+ #ifdef DIFFUSEMAP_10
+ vec4 diffuseColor10 = texture2D(m_DiffuseMap_10, texCoord * m_DiffuseMap_10_scale);
+ diffuseColor = mix( diffuseColor, diffuseColor10, alphaBlend2.b );
+ #endif
+ #ifdef DIFFUSEMAP_11
+ vec4 diffuseColor11 = texture2D(m_DiffuseMap_11, texCoord * m_DiffuseMap_11_scale);
+ diffuseColor = mix( diffuseColor, diffuseColor11, alphaBlend2.a );
+ #endif
+ #endif
+
+ return diffuseColor;
+ }
+
+ vec3 calculateNormal(in vec2 texCoord) {
+ vec3 normal = vec3(0,0,1);
+ vec3 n = vec3(0,0,0);
+
+ vec4 alphaBlend = texture2D( m_AlphaMap, texCoord.xy );
+
+ #ifdef ALPHAMAP_1
+ vec4 alphaBlend1 = texture2D( m_AlphaMap_1, texCoord.xy );
+ #endif
+ #ifdef ALPHAMAP_2
+ vec4 alphaBlend2 = texture2D( m_AlphaMap_2, texCoord.xy );
+ #endif
+
+ #ifdef NORMALMAP
+ n = texture2D(m_NormalMap, texCoord * m_DiffuseMap_0_scale).xyz;
+ normal += n * alphaBlend.r;
+ #else
+ normal += vec3(0.5,0.5,1) * alphaBlend.r;
+ #endif
+
+ #ifdef NORMALMAP_1
+ n = texture2D(m_NormalMap_1, texCoord * m_DiffuseMap_1_scale).xyz;
+ normal += n * alphaBlend.g;
+ #else
+ normal += vec3(0.5,0.5,1) * alphaBlend.g;
+ #endif
+
+ #ifdef NORMALMAP_2
+ n = texture2D(m_NormalMap_2, texCoord * m_DiffuseMap_2_scale).xyz;
+ normal += n * alphaBlend.b;
+ #else
+ normal += vec3(0.5,0.5,1) * alphaBlend.b;
+ #endif
+
+ #ifdef NORMALMAP_3
+ n = texture2D(m_NormalMap_3, texCoord * m_DiffuseMap_3_scale).xyz;
+ normal += n * alphaBlend.a;
+ #else
+ normal += vec3(0.5,0.5,1) * alphaBlend.a;
+ #endif
+
+ #ifdef ALPHAMAP_1
+ #ifdef NORMALMAP_4
+ n = texture2D(m_NormalMap_4, texCoord * m_DiffuseMap_4_scale).xyz;
+ normal += n * alphaBlend1.r;
+ #endif
+
+ #ifdef NORMALMAP_5
+ n = texture2D(m_NormalMap_5, texCoord * m_DiffuseMap_5_scale).xyz;
+ normal += n * alphaBlend1.g;
+ #endif
+
+ #ifdef NORMALMAP_6
+ n = texture2D(m_NormalMap_6, texCoord * m_DiffuseMap_6_scale).xyz;
+ normal += n * alphaBlend1.b;
+ #endif
+
+ #ifdef NORMALMAP_7
+ n = texture2D(m_NormalMap_7, texCoord * m_DiffuseMap_7_scale).xyz;
+ normal += n * alphaBlend1.a;
+ #endif
+ #endif
+
+ #ifdef ALPHAMAP_2
+ #ifdef NORMALMAP_8
+ n = texture2D(m_NormalMap_8, texCoord * m_DiffuseMap_8_scale).xyz;
+ normal += n * alphaBlend2.r;
+ #endif
+
+ #ifdef NORMALMAP_9
+ n = texture2D(m_NormalMap_9, texCoord * m_DiffuseMap_9_scale);
+ normal += n * alphaBlend2.g;
+ #endif
+
+ #ifdef NORMALMAP_10
+ n = texture2D(m_NormalMap_10, texCoord * m_DiffuseMap_10_scale);
+ normal += n * alphaBlend2.b;
+ #endif
+
+ #ifdef NORMALMAP_11
+ n = texture2D(m_NormalMap_11, texCoord * m_DiffuseMap_11_scale);
+ normal += n * alphaBlend2.a;
+ #endif
+ #endif
+
+ normal = (normal.xyz * vec3(2.0) - vec3(1.0));
+ return normalize(normal);
+ }
+
+ #ifdef TRI_PLANAR_MAPPING
+
+ vec4 getTriPlanarBlend(in vec4 coords, in vec3 blending, in sampler2D map, in float scale) {
+ vec4 col1 = texture2D( map, coords.yz * scale);
+ vec4 col2 = texture2D( map, coords.xz * scale);
+ vec4 col3 = texture2D( map, coords.xy * scale);
+ // blend the results of the 3 planar projections.
+ vec4 tex = col1 * blending.x + col2 * blending.y + col3 * blending.z;
+ return tex;
+ }
+
+ vec4 calculateTriPlanarDiffuseBlend(in vec3 wNorm, in vec4 wVert, in vec2 texCoord) {
+ // tri-planar texture bending factor for this fragment's normal
+ vec3 blending = abs( wNorm );
+ blending = (blending -0.2) * 0.7;
+ blending = normalize(max(blending, 0.00001)); // Force weights to sum to 1.0 (very important!)
+ float b = (blending.x + blending.y + blending.z);
+ blending /= vec3(b, b, b);
+
+ // texture coords
+ vec4 coords = wVert;
+
+ // blend the results of the 3 planar projections.
+ vec4 tex0 = getTriPlanarBlend(coords, blending, m_DiffuseMap, m_DiffuseMap_0_scale);
+
+ #ifdef DIFFUSEMAP_1
+ // blend the results of the 3 planar projections.
+ vec4 tex1 = getTriPlanarBlend(coords, blending, m_DiffuseMap_1, m_DiffuseMap_1_scale);
+ #endif
+ #ifdef DIFFUSEMAP_2
+ // blend the results of the 3 planar projections.
+ vec4 tex2 = getTriPlanarBlend(coords, blending, m_DiffuseMap_2, m_DiffuseMap_2_scale);
+ #endif
+ #ifdef DIFFUSEMAP_3
+ // blend the results of the 3 planar projections.
+ vec4 tex3 = getTriPlanarBlend(coords, blending, m_DiffuseMap_3, m_DiffuseMap_3_scale);
+ #endif
+ #ifdef DIFFUSEMAP_4
+ // blend the results of the 3 planar projections.
+ vec4 tex4 = getTriPlanarBlend(coords, blending, m_DiffuseMap_4, m_DiffuseMap_4_scale);
+ #endif
+ #ifdef DIFFUSEMAP_5
+ // blend the results of the 3 planar projections.
+ vec4 tex5 = getTriPlanarBlend(coords, blending, m_DiffuseMap_5, m_DiffuseMap_5_scale);
+ #endif
+ #ifdef DIFFUSEMAP_6
+ // blend the results of the 3 planar projections.
+ vec4 tex6 = getTriPlanarBlend(coords, blending, m_DiffuseMap_6, m_DiffuseMap_6_scale);
+ #endif
+ #ifdef DIFFUSEMAP_7
+ // blend the results of the 3 planar projections.
+ vec4 tex7 = getTriPlanarBlend(coords, blending, m_DiffuseMap_7, m_DiffuseMap_7_scale);
+ #endif
+ #ifdef DIFFUSEMAP_8
+ // blend the results of the 3 planar projections.
+ vec4 tex8 = getTriPlanarBlend(coords, blending, m_DiffuseMap_8, m_DiffuseMap_8_scale);
+ #endif
+ #ifdef DIFFUSEMAP_9
+ // blend the results of the 3 planar projections.
+ vec4 tex9 = getTriPlanarBlend(coords, blending, m_DiffuseMap_9, m_DiffuseMap_9_scale);
+ #endif
+ #ifdef DIFFUSEMAP_10
+ // blend the results of the 3 planar projections.
+ vec4 tex10 = getTriPlanarBlend(coords, blending, m_DiffuseMap_10, m_DiffuseMap_10_scale);
+ #endif
+ #ifdef DIFFUSEMAP_11
+ // blend the results of the 3 planar projections.
+ vec4 tex11 = getTriPlanarBlend(coords, blending, m_DiffuseMap_11, m_DiffuseMap_11_scale);
+ #endif
+
+ vec4 alphaBlend = texture2D( m_AlphaMap, texCoord.xy );
+
+ #ifdef ALPHAMAP_1
+ vec4 alphaBlend1 = texture2D( m_AlphaMap_1, texCoord.xy );
+ #endif
+ #ifdef ALPHAMAP_2
+ vec4 alphaBlend2 = texture2D( m_AlphaMap_2, texCoord.xy );
+ #endif
+
+ vec4 diffuseColor = tex0 * alphaBlend.r;
+ #ifdef DIFFUSEMAP_1
+ diffuseColor = mix( diffuseColor, tex1, alphaBlend.g );
+ #endif
+ #ifdef DIFFUSEMAP_2
+ diffuseColor = mix( diffuseColor, tex2, alphaBlend.b );
+ #endif
+ #ifdef DIFFUSEMAP_3
+ diffuseColor = mix( diffuseColor, tex3, alphaBlend.a );
+ #endif
+ #ifdef ALPHAMAP_1
+ #ifdef DIFFUSEMAP_4
+ diffuseColor = mix( diffuseColor, tex4, alphaBlend1.r );
+ #endif
+ #ifdef DIFFUSEMAP_5
+ diffuseColor = mix( diffuseColor, tex5, alphaBlend1.g );
+ #endif
+ #ifdef DIFFUSEMAP_6
+ diffuseColor = mix( diffuseColor, tex6, alphaBlend1.b );
+ #endif
+ #ifdef DIFFUSEMAP_7
+ diffuseColor = mix( diffuseColor, tex7, alphaBlend1.a );
+ #endif
+ #endif
+ #ifdef ALPHAMAP_2
+ #ifdef DIFFUSEMAP_8
+ diffuseColor = mix( diffuseColor, tex8, alphaBlend2.r );
+ #endif
+ #ifdef DIFFUSEMAP_9
+ diffuseColor = mix( diffuseColor, tex9, alphaBlend2.g );
+ #endif
+ #ifdef DIFFUSEMAP_10
+ diffuseColor = mix( diffuseColor, tex10, alphaBlend2.b );
+ #endif
+ #ifdef DIFFUSEMAP_11
+ diffuseColor = mix( diffuseColor, tex11, alphaBlend2.a );
+ #endif
+ #endif
+
+ return diffuseColor;
+ }
+
+ vec3 calculateNormalTriPlanar(in vec3 wNorm, in vec4 wVert,in vec2 texCoord) {
+ // tri-planar texture bending factor for this fragment's world-space normal
+ vec3 blending = abs( wNorm );
+ blending = (blending -0.2) * 0.7;
+ blending = normalize(max(blending, 0.00001)); // Force weights to sum to 1.0 (very important!)
+ float b = (blending.x + blending.y + blending.z);
+ blending /= vec3(b, b, b);
+
+ // texture coords
+ vec4 coords = wVert;
+ vec4 alphaBlend = texture2D( m_AlphaMap, texCoord.xy );
+
+ #ifdef ALPHAMAP_1
+ vec4 alphaBlend1 = texture2D( m_AlphaMap_1, texCoord.xy );
+ #endif
+ #ifdef ALPHAMAP_2
+ vec4 alphaBlend2 = texture2D( m_AlphaMap_2, texCoord.xy );
+ #endif
+
+ vec3 normal = vec3(0,0,1);
+ vec3 n = vec3(0,0,0);
+
+ #ifdef NORMALMAP
+ n = getTriPlanarBlend(coords, blending, m_NormalMap, m_DiffuseMap_0_scale).xyz;
+ normal += n * alphaBlend.r;
+ #else
+ normal += vec3(0.5,0.5,1) * alphaBlend.r;
+ #endif
+
+ #ifdef NORMALMAP_1
+ n = getTriPlanarBlend(coords, blending, m_NormalMap_1, m_DiffuseMap_1_scale).xyz;
+ normal += n * alphaBlend.g;
+ #else
+ normal += vec3(0.5,0.5,1) * alphaBlend.g;
+ #endif
+
+ #ifdef NORMALMAP_2
+ n = getTriPlanarBlend(coords, blending, m_NormalMap_2, m_DiffuseMap_2_scale).xyz;
+ normal += n * alphaBlend.b;
+ #else
+ normal += vec3(0.5,0.5,1) * alphaBlend.b;
+ #endif
+
+ #ifdef NORMALMAP_3
+ n = getTriPlanarBlend(coords, blending, m_NormalMap_3, m_DiffuseMap_3_scale).xyz;
+ normal += n * alphaBlend.a;
+ #else
+ normal += vec3(0.5,0.5,1) * alphaBlend.a;
+ #endif
+
+ #ifdef ALPHAMAP_1
+ #ifdef NORMALMAP_4
+ n = getTriPlanarBlend(coords, blending, m_NormalMap_4, m_DiffuseMap_4_scale).xyz;
+ normal += n * alphaBlend1.r;
+ #else
+ normal += vec3(0.5,0.5,1) * alphaBlend.r;
+ #endif
+
+ #ifdef NORMALMAP_5
+ n = getTriPlanarBlend(coords, blending, m_NormalMap_5, m_DiffuseMap_5_scale).xyz;
+ normal += n * alphaBlend1.g;
+ #else
+ normal += vec3(0.5,0.5,1) * alphaBlend.g;
+ #endif
+
+ #ifdef NORMALMAP_6
+ n = getTriPlanarBlend(coords, blending, m_NormalMap_6, m_DiffuseMap_6_scale).xyz;
+ normal += n * alphaBlend1.b;
+ #else
+ normal += vec3(0.5,0.5,1) * alphaBlend.b;
+ #endif
+
+ #ifdef NORMALMAP_7
+ n = getTriPlanarBlend(coords, blending, m_NormalMap_7, m_DiffuseMap_7_scale).xyz;
+ normal += n * alphaBlend1.a;
+ #else
+ normal += vec3(0.5,0.5,1) * alphaBlend.a;
+ #endif
+ #endif
+
+ #ifdef ALPHAMAP_2
+ #ifdef NORMALMAP_8
+ n = getTriPlanarBlend(coords, blending, m_NormalMap_8, m_DiffuseMap_8_scale).xyz;
+ normal += n * alphaBlend2.r;
+ #else
+ normal += vec3(0.5,0.5,1) * alphaBlend.r;
+ #endif
+
+ #ifdef NORMALMAP_9
+ n = getTriPlanarBlend(coords, blending, m_NormalMap_9, m_DiffuseMap_9_scale).xyz;
+ normal += n * alphaBlend2.g;
+ #else
+ normal += vec3(0.5,0.5,1) * alphaBlend.g;
+ #endif
+
+ #ifdef NORMALMAP_10
+ n = getTriPlanarBlend(coords, blending, m_NormalMap_10, m_DiffuseMap_10_scale).xyz;
+ normal += n * alphaBlend2.b;
+ #else
+ normal += vec3(0.5,0.5,1) * alphaBlend.b;
+ #endif
+
+ #ifdef NORMALMAP_11
+ n = getTriPlanarBlend(coords, blending, m_NormalMap_11, m_DiffuseMap_11_scale).xyz;
+ normal += n * alphaBlend2.a;
+ #else
+ normal += vec3(0.5,0.5,1) * alphaBlend.a;
+ #endif
+ #endif
+
+ normal = (normal.xyz * vec3(2.0) - vec3(1.0));
+ return normalize(normal);
+ }
+ #endif
+
+#endif
+
+void main(){
+
+ //----------------------
+ // diffuse calculations
+ //----------------------
+ #ifdef DIFFUSEMAP
+ #ifdef ALPHAMAP
+ #ifdef TRI_PLANAR_MAPPING
+ vec4 diffuseColor = calculateTriPlanarDiffuseBlend(wNormal, wVertex, texCoord);
+ #else
+ vec4 diffuseColor = calculateDiffuseBlend(texCoord);
+ #endif
+ #else
+ vec4 diffuseColor = texture2D(m_DiffuseMap, texCoord);
+ #endif
+ #else
+ vec4 diffuseColor = vec4(1.0);
+ #endif
+
+
+ //---------------------
+ // normal calculations
+ //---------------------
+ #if defined(NORMALMAP) || defined(NORMALMAP_1) || defined(NORMALMAP_2) || defined(NORMALMAP_3) || defined(NORMALMAP_4) || defined(NORMALMAP_5) || defined(NORMALMAP_6) || defined(NORMALMAP_7) || defined(NORMALMAP_8) || defined(NORMALMAP_9) || defined(NORMALMAP_10) || defined(NORMALMAP_11)
+ #ifdef TRI_PLANAR_MAPPING
+ vec3 normal = calculateNormalTriPlanar(wNormal, wVertex, texCoord);
+ #else
+ vec3 normal = calculateNormal(texCoord);
+ #endif
+ mat3 tbnMat = mat3(normalize(vTangent.xyz) , normalize(vBinormal.xyz) , normalize(vNormal.xyz));
+ #else
+ vec3 normal = vNormal;
+ #endif
+
+
+ //-----------------------
+ // lighting calculations
+ //-----------------------
+ gl_FragColor = AmbientSum * diffuseColor;
+ 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(vPos, lightColor.w, lightData1, lightDir, lightVec);
+
+ float spotFallOff = 1.0;
+ #if __VERSION__ >= 110
+ // allow use of control flow
+ if(lightColor.w > 1.0){
+ #endif
+ spotFallOff = computeSpotFalloff(g_LightData[i+2], lightVec);
+ #if __VERSION__ >= 110
+ }
+ #endif
+
+ #ifdef NORMALMAP
+ //Normal map -> lighting is computed in tangent space
+ lightDir.xyz = normalize(lightDir.xyz * tbnMat);
+ vec3 viewDir = normalize(-vPos.xyz * tbnMat);
+ #else
+ //no Normal map -> lighting is computed in view space
+ lightDir.xyz = normalize(lightDir.xyz);
+ vec3 viewDir = normalize(-vPos.xyz);
+ #endif
+
+ vec2 light = computeLighting(normal, viewDir, lightDir.xyz, lightDir.w * spotFallOff, m_Shininess);
+ gl_FragColor.rgb += DiffuseSum.rgb * lightColor.rgb * diffuseColor.rgb * vec3(light.x) +
+ SpecularSum.rgb * vec3(light.y);
+ }
+
+}
\ No newline at end of file
diff --git a/jme3-terrain/src/main/resources/Common/MatDefs/Terrain/SPTerrainLighting.vert b/jme3-terrain/src/main/resources/Common/MatDefs/Terrain/SPTerrainLighting.vert
new file mode 100644
index 000000000..78036c93c
--- /dev/null
+++ b/jme3-terrain/src/main/resources/Common/MatDefs/Terrain/SPTerrainLighting.vert
@@ -0,0 +1,66 @@
+uniform mat4 g_WorldViewProjectionMatrix;
+uniform mat4 g_WorldViewMatrix;
+uniform mat3 g_NormalMatrix;
+uniform mat4 g_ViewMatrix;
+
+uniform vec4 g_AmbientLightColor;
+
+attribute vec3 inPosition;
+attribute vec3 inNormal;
+attribute vec2 inTexCoord;
+attribute vec4 inTangent;
+
+varying vec3 vNormal;
+varying vec2 texCoord;
+varying vec3 vPos;
+varying vec3 vTangent;
+varying vec3 vBinormal;
+
+varying vec4 AmbientSum;
+varying vec4 DiffuseSum;
+varying vec4 SpecularSum;
+
+#ifdef TRI_PLANAR_MAPPING
+ varying vec4 wVertex;
+ varying vec3 wNormal;
+#endif
+
+
+
+void main(){
+ vec4 pos = vec4(inPosition, 1.0);
+ gl_Position = g_WorldViewProjectionMatrix * pos;
+ #ifdef TERRAIN_GRID
+ texCoord = inTexCoord * 2.0;
+ #else
+ texCoord = inTexCoord;
+ #endif
+
+ vec3 wvPosition = (g_WorldViewMatrix * pos).xyz;
+ vec3 wvNormal = normalize(g_NormalMatrix * inNormal);
+
+ //--------------------------
+ // specific to normal maps:
+ //--------------------------
+ #if defined(NORMALMAP) || defined(NORMALMAP_1) || defined(NORMALMAP_2) || defined(NORMALMAP_3) || defined(NORMALMAP_4) || defined(NORMALMAP_5) || defined(NORMALMAP_6) || defined(NORMALMAP_7) || defined(NORMALMAP_8) || defined(NORMALMAP_9) || defined(NORMALMAP_10) || defined(NORMALMAP_11)
+ vTangent = g_NormalMatrix * inTangent.xyz;
+ vBinormal = cross(wvNormal, vTangent)* inTangent.w;
+ #endif
+
+ //-------------------------
+ // general to all lighting
+ //-------------------------
+ vNormal = wvNormal;
+ vPos = wvPosition;
+
+ AmbientSum = g_AmbientLightColor;
+ DiffuseSum = vec4(1.0);
+ SpecularSum = vec4(0.0);
+
+
+#ifdef TRI_PLANAR_MAPPING
+ wVertex = vec4(inPosition,0.0);
+ wNormal = inNormal;
+#endif
+
+}
\ No newline at end of file
diff --git a/jme3-terrain/src/main/resources/Common/MatDefs/Terrain/TerrainLighting.frag b/jme3-terrain/src/main/resources/Common/MatDefs/Terrain/TerrainLighting.frag
index 68bd2d236..8ab9b993b 100644
--- a/jme3-terrain/src/main/resources/Common/MatDefs/Terrain/TerrainLighting.frag
+++ b/jme3-terrain/src/main/resources/Common/MatDefs/Terrain/TerrainLighting.frag
@@ -1,3 +1,5 @@
+#import "Common/ShaderLib/PhongLighting.glsllib"
+#import "Common/ShaderLib/Lighting.glsllib"
uniform float m_Shininess;
uniform vec4 g_LightDirection;
@@ -145,54 +147,6 @@ varying vec3 lightVec;
varying vec3 wNormal;
#endif
-
-
-float tangDot(in vec3 v1, in vec3 v2){
- float d = dot(v1,v2);
- #ifdef V_TANGENT
- d = 1.0 - d*d;
- return step(0.0, d) * sqrt(d);
- #else
- return d;
- #endif
-}
-
-
-float lightComputeDiffuse(in vec3 norm, in vec3 lightdir, in vec3 viewdir){
- return max(0.0, dot(norm, lightdir));
-}
-
-float lightComputeSpecular(in vec3 norm, in vec3 viewdir, in vec3 lightdir, in float shiny){
- #ifdef WARDISO
- // Isotropic Ward
- vec3 halfVec = normalize(viewdir + lightdir);
- float NdotH = max(0.001, tangDot(norm, halfVec));
- float NdotV = max(0.001, tangDot(norm, viewdir));
- float NdotL = max(0.001, tangDot(norm, lightdir));
- float a = tan(acos(NdotH));
- float p = max(shiny/128.0, 0.001);
- return NdotL * (1.0 / (4.0*3.14159265*p*p)) * (exp(-(a*a)/(p*p)) / (sqrt(NdotV * NdotL)));
- #else
- // Standard Phong
- vec3 R = reflect(-lightdir, norm);
- return pow(max(tangDot(R, viewdir), 0.0), shiny);
- #endif
-}
-
-vec2 computeLighting(in vec3 wvPos, in vec3 wvNorm, in vec3 wvViewDir, in vec3 wvLightDir){
- float diffuseFactor = lightComputeDiffuse(wvNorm, wvLightDir, wvViewDir);
- float specularFactor = lightComputeSpecular(wvNorm, wvViewDir, wvLightDir, m_Shininess);
-
- if (m_Shininess <= 1.0) {
- specularFactor = 0.0; // should be one instruction on most cards ..
- }
-
- float att = vLightDir.w;
-
- return vec2(diffuseFactor, specularFactor) * vec2(att);
-}
-
-
#ifdef ALPHAMAP
vec4 calculateDiffuseBlend(in vec2 texCoord) {
@@ -355,7 +309,7 @@ vec2 computeLighting(in vec3 wvPos, in vec3 wvNorm, in vec3 wvViewDir, in vec3 w
vec4 getTriPlanarBlend(in vec4 coords, in vec3 blending, in sampler2D map, in float scale) {
vec4 col1 = texture2D( map, coords.yz * scale);
vec4 col2 = texture2D( map, coords.xz * scale);
- vec4 col3 = texture2D( map, coords.xy * scale);
+ vec4 col3 = texture2D( map, coords.xy * scale);
// blend the results of the 3 planar projections.
vec4 tex = col1 * blending.x + col2 * blending.y + col3 * blending.z;
return tex;
@@ -627,7 +581,7 @@ void main(){
spotFallOff = clamp(spotFallOff, 0.0, 1.0);
}
}
-
+
//---------------------
// normal calculations
//---------------------
@@ -648,7 +602,7 @@ void main(){
vec4 lightDir = vLightDir;
lightDir.xyz = normalize(lightDir.xyz);
- vec2 light = computeLighting(vPosition, normal, vViewDir.xyz, lightDir.xyz)*spotFallOff;
+ vec2 light = computeLighting(normal, vViewDir.xyz, lightDir.xyz,lightDir.w*spotFallOff,m_Shininess);
vec4 specularColor = vec4(1.0);
diff --git a/jme3-terrain/src/main/resources/Common/MatDefs/Terrain/TerrainLighting.j3md b/jme3-terrain/src/main/resources/Common/MatDefs/Terrain/TerrainLighting.j3md
index 04470ca26..48c404da4 100644
--- a/jme3-terrain/src/main/resources/Common/MatDefs/Terrain/TerrainLighting.j3md
+++ b/jme3-terrain/src/main/resources/Common/MatDefs/Terrain/TerrainLighting.j3md
@@ -163,6 +163,70 @@ MaterialDef Terrain Lighting {
}
}
+
+ Technique {
+
+ LightMode SinglePass
+
+ VertexShader GLSL100: Common/MatDefs/Terrain/SPTerrainLighting.vert
+ FragmentShader GLSL100: Common/MatDefs/Terrain/SPTerrainLighting.frag
+
+ WorldParameters {
+ WorldViewProjectionMatrix
+ NormalMatrix
+ WorldViewMatrix
+ ViewMatrix
+ }
+
+ Defines {
+ TRI_PLANAR_MAPPING : useTriPlanarMapping
+ TERRAIN_GRID : isTerrainGrid
+ WARDISO : WardIso
+
+ DIFFUSEMAP : DiffuseMap
+ DIFFUSEMAP_1 : DiffuseMap_1
+ DIFFUSEMAP_2 : DiffuseMap_2
+ DIFFUSEMAP_3 : DiffuseMap_3
+ DIFFUSEMAP_4 : DiffuseMap_4
+ DIFFUSEMAP_5 : DiffuseMap_5
+ DIFFUSEMAP_6 : DiffuseMap_6
+ DIFFUSEMAP_7 : DiffuseMap_7
+ DIFFUSEMAP_8 : DiffuseMap_8
+ DIFFUSEMAP_9 : DiffuseMap_9
+ DIFFUSEMAP_10 : DiffuseMap_10
+ DIFFUSEMAP_11 : DiffuseMap_11
+ NORMALMAP : NormalMap
+ NORMALMAP_1 : NormalMap_1
+ NORMALMAP_2 : NormalMap_2
+ NORMALMAP_3 : NormalMap_3
+ NORMALMAP_4 : NormalMap_4
+ NORMALMAP_5 : NormalMap_5
+ NORMALMAP_6 : NormalMap_6
+ NORMALMAP_7 : NormalMap_7
+ NORMALMAP_8 : NormalMap_8
+ NORMALMAP_9 : NormalMap_9
+ NORMALMAP_10 : NormalMap_10
+ NORMALMAP_11 : NormalMap_11
+ SPECULARMAP : SpecularMap
+ ALPHAMAP : AlphaMap
+ ALPHAMAP_1 : AlphaMap_1
+ ALPHAMAP_2 : AlphaMap_2
+ DIFFUSEMAP_0_SCALE : DiffuseMap_0_scale
+ DIFFUSEMAP_1_SCALE : DiffuseMap_1_scale
+ DIFFUSEMAP_2_SCALE : DiffuseMap_2_scale
+ DIFFUSEMAP_3_SCALE : DiffuseMap_3_scale
+ DIFFUSEMAP_4_SCALE : DiffuseMap_4_scale
+ DIFFUSEMAP_5_SCALE : DiffuseMap_5_scale
+ DIFFUSEMAP_6_SCALE : DiffuseMap_6_scale
+ DIFFUSEMAP_7_SCALE : DiffuseMap_7_scale
+ DIFFUSEMAP_8_SCALE : DiffuseMap_8_scale
+ DIFFUSEMAP_9_SCALE : DiffuseMap_9_scale
+ DIFFUSEMAP_10_SCALE : DiffuseMap_10_scale
+ DIFFUSEMAP_11_SCALE : DiffuseMap_11_scale
+ }
+ }
+
+
Technique PreShadow {
VertexShader GLSL100 : Common/MatDefs/Shadow/PreShadow.vert
diff --git a/jme3-terrain/src/main/resources/Common/MatDefs/Terrain/TerrainLighting.vert b/jme3-terrain/src/main/resources/Common/MatDefs/Terrain/TerrainLighting.vert
index a3a1cc24e..e03f03f7f 100644
--- a/jme3-terrain/src/main/resources/Common/MatDefs/Terrain/TerrainLighting.vert
+++ b/jme3-terrain/src/main/resources/Common/MatDefs/Terrain/TerrainLighting.vert
@@ -1,3 +1,5 @@
+#import "Common/ShaderLib/Lighting.glsllib"
+
uniform mat4 g_WorldViewProjectionMatrix;
uniform mat4 g_WorldViewMatrix;
uniform mat3 g_NormalMatrix;
@@ -34,16 +36,6 @@ varying vec4 SpecularSum;
varying vec3 wNormal;
#endif
-// JME3 lights in world space
-void lightComputeDir(in vec3 worldPos, in vec4 color, in vec4 position, out vec4 lightDir){
- float posLight = step(0.5, color.w);
- vec3 tempVec = position.xyz * sign(posLight - 0.5) - (worldPos * posLight);
- lightVec.xyz = tempVec;
- float dist = length(tempVec);
- lightDir.w = clamp(1.0 - position.w * dist * posLight, 0.0, 1.0);
- lightDir.xyz = tempVec / vec3(dist);
-}
-
void main(){
vec4 pos = vec4(inPosition, 1.0);
@@ -66,35 +58,30 @@ void main(){
// specific to normal maps:
//--------------------------
#if defined(NORMALMAP) || defined(NORMALMAP_1) || defined(NORMALMAP_2) || defined(NORMALMAP_3) || defined(NORMALMAP_4) || defined(NORMALMAP_5) || defined(NORMALMAP_6) || defined(NORMALMAP_7) || defined(NORMALMAP_8) || defined(NORMALMAP_9) || defined(NORMALMAP_10) || defined(NORMALMAP_11)
- vec3 wvTangent = normalize(g_NormalMatrix * inTangent.xyz);
- vec3 wvBinormal = cross(wvNormal, wvTangent);
+ vec3 wvTangent = normalize(g_NormalMatrix * inTangent.xyz);
+ vec3 wvBinormal = cross(wvNormal, wvTangent);
- mat3 tbnMat = mat3(wvTangent, wvBinormal * -inTangent.w,wvNormal);
+ mat3 tbnMat = mat3(wvTangent, wvBinormal * inTangent.w,wvNormal);
- vPosition = wvPosition * tbnMat;
- vViewDir = viewDir * tbnMat;
- lightComputeDir(wvPosition, lightColor, wvLightPos, vLightDir);
- vLightDir.xyz = (vLightDir.xyz * tbnMat).xyz;
- #else
+ vPosition = wvPosition * tbnMat;
+ vViewDir = viewDir * tbnMat;
- //-------------------------
- // general to all lighting
- //-------------------------
- vNormal = wvNormal;
+ lightComputeDir(wvPosition, lightColor.w, wvLightPos, vLightDir, lightVec);
+ vLightDir.xyz = (vLightDir.xyz * tbnMat).xyz;
+ #else
+ //-------------------------
+ // general to all lighting
+ //-------------------------
+ vNormal = wvNormal;
- vPosition = wvPosition;
- vViewDir = viewDir;
+ vPosition = wvPosition;
+ vViewDir = viewDir;
- lightComputeDir(wvPosition, lightColor, wvLightPos, vLightDir);
+ lightComputeDir(wvPosition, lightColor.w, wvLightPos, vLightDir, lightVec);
#endif
- //computing spot direction in view space and unpacking spotlight cos
- // spotVec=(g_ViewMatrix *vec4(g_LightDirection.xyz,0.0) );
- // spotVec.w=floor(g_LightDirection.w)*0.001;
- // lightVec.w = fract(g_LightDirection.w);
-
- AmbientSum = vec4(0.2, 0.2, 0.2, 1.0) * g_AmbientLightColor; // Default: ambient color is dark gray
+ AmbientSum = g_AmbientLightColor; // Default: ambient color is dark gray
DiffuseSum = lightColor;
SpecularSum = lightColor;
From e225e6ff89de79da03741c4e6914ac65f6f41ed2 Mon Sep 17 00:00:00 2001
From: shadowislord +AY^v5@~-& GHqtY;OD1Hn+4HkHE6Hf^Fup>$ZJ0G>fxFo+HFS1^u9AxJ4KLR(@y4^
z|64nqA?*~(^V_Ko?WEfyi{~NF^SVyMIXhoqZc3QG@}&)L>1x~Hb;Xy?_xtxfOY;s#
zHhgUO1L$M7Za8N+l3zW1rAg;c8;)$K9$x74X~QV*3z0Xg`|CcL*Z ?^Gdbzyv;^`VaZ!_77y@NHAqpZizu
z>y>p)!F@aI^&AUs`%`W?*8QvYLYH@WuvZ6rM{m!2J`dykevDfqeWNyi>)}-eTi=}F
z9ey4DoJQSUit*jU8tG|_4SC4BUT2xI#|v}Yt>$#^k|f6W;F;cBI}e#T2>VS-2VnDZ
ztZ{A%<#)|RU)Tb@wiCTm?(rtC>coD=OPJr &-}V>)hJ=0e7m^g#w^Gtr5?v=4LQ
zGS{=egm2AhPP~U}!~SWif7>bUd;Td@?_OtcZP;T?@4Mnb?D6Xx>XgmU|Ad(P?eU&H
zN$hwLXTu(C&buNfUc|qRs)jh&WtzCN;8?t6gx-4l#I1iXY=
zXD&WT><@5WMtAm)i+%eOy@mF
5irGAIvn?EM@
>I%NsIa&2Z{H8+nsJ_^B;py3F^^K!G#_`B7IJO7!TWTnm&-?8z3`1wj>q
z`3PI@GbiWe+$z?p{u+s0|1SN~-bbHA=#yspBSv0!kN0kW^w|$?{CdNk>{W>DRjlkC
zWW8uDI&b?5@j+x*A-2d*p=mC3mrN^RuIy*fU3&_VD{)Gh8Q!FPwRyzctJdrNs9K|b
zv9I%L!Kt$P2Ufi92PW=k-!SEgs1MG#n>jrf-cO;s>VJwl6{ilLV|}oU_^sxaa)aT5
zLG