diff --git a/engine/src/core-data/Common/MatDefs/Light/Lighting.frag b/engine/src/core-data/Common/MatDefs/Light/Lighting.frag index 1dfe0e0f9..0c50b072c 100644 --- a/engine/src/core-data/Common/MatDefs/Light/Lighting.frag +++ b/engine/src/core-data/Common/MatDefs/Light/Lighting.frag @@ -2,6 +2,7 @@ #define ATTENUATION //#define HQ_ATTENUATION +uniform vec4 g_LightDirection; varying vec2 texCoord; #ifdef SEPARATE_TEXCOORD varying vec2 texCoord2; @@ -50,8 +51,7 @@ varying vec3 SpecularSum; #endif uniform float m_AlphaDiscardThreshold; -varying vec4 lightVec; -varying vec4 spotVec; +varying vec3 lightVec; #ifndef VERTEX_LIGHTING uniform float m_Shininess; @@ -162,12 +162,12 @@ void main(){ #ifndef VERTEX_LIGHTING float spotFallOff = 1.0; - if(spotVec.w != 0.0){ + if(g_LightDirection.w != 0.0){ vec3 L = normalize(lightVec.xyz); - vec3 spotdir = normalize(spotVec.xyz); + vec3 spotdir = normalize(g_LightDirection.xyz); float curAngleCos = dot(-L, spotdir); - float innerAngleCos = spotVec.w; - float outerAngleCos = lightVec.w; + 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); if(spotFallOff <= 0.0){ diff --git a/engine/src/core-data/Common/MatDefs/Light/Lighting.vert b/engine/src/core-data/Common/MatDefs/Light/Lighting.vert index 7f880c10f..031633efe 100644 --- a/engine/src/core-data/Common/MatDefs/Light/Lighting.vert +++ b/engine/src/core-data/Common/MatDefs/Light/Lighting.vert @@ -13,7 +13,7 @@ uniform float m_Shininess; uniform vec4 g_LightColor; uniform vec4 g_LightPosition; -uniform vec4 g_LightDirection; +//uniform vec4 g_LightDirection; uniform vec4 g_AmbientLightColor; varying vec2 texCoord; @@ -30,8 +30,8 @@ attribute vec3 inPosition; attribute vec2 inTexCoord; attribute vec3 inNormal; -varying vec4 lightVec; -varying vec4 spotVec; +varying vec3 lightVec; +//varying vec4 spotVec; #ifdef VERTEX_COLOR attribute vec4 inColor; @@ -83,7 +83,7 @@ varying vec4 spotVec; 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; + lightVec = tempVec; #ifdef ATTENUATION float dist = length(tempVec); lightDir.w = clamp(1.0 - position.w * dist * posLight, 0.0, 1.0); @@ -176,9 +176,9 @@ void main(){ #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); +// 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 diff --git a/engine/src/core/com/jme3/material/Material.java b/engine/src/core/com/jme3/material/Material.java index 369b64681..fa14f0d12 100644 --- a/engine/src/core/com/jme3/material/Material.java +++ b/engine/src/core/com/jme3/material/Material.java @@ -47,7 +47,6 @@ import com.jme3.light.LightList; import com.jme3.light.PointLight; import com.jme3.light.SpotLight; import com.jme3.material.TechniqueDef.LightMode; -import com.jme3.math.FastMath; import com.jme3.math.Quaternion; import com.jme3.math.Vector3f; import com.jme3.math.Vector4f; @@ -98,7 +97,6 @@ public class Material implements Asset, Cloneable, Savable, Comparable additiveLight.setBlendMode(RenderState.BlendMode.AlphaAdditive); additiveLight.setDepthWrite(false); } - private AssetKey key; private MaterialDef def; private ListMap paramValues = new ListMap(); @@ -141,14 +139,14 @@ public class Material implements Asset, Cloneable, Savable, Comparable return key != null ? key.getName() : null; } - public void setKey(AssetKey key){ + public void setKey(AssetKey key) { this.key = key; } - - public AssetKey getKey(){ + + public AssetKey getKey() { return key; } - + /** * Returns the sorting ID or sorting index for this material. * @@ -698,7 +696,9 @@ public class Material implements Asset, Cloneable, Savable, Comparable } } - protected void renderMultipassLighting(Shader shader, Geometry g, Renderer r) { + protected void renderMultipassLighting(Shader shader, Geometry g, RenderManager rm) { + + Renderer r = rm.getRenderer(); LightList lightList = g.getWorldLightList(); Uniform lightDir = shader.getUniform("g_LightDirection"); Uniform lightColor = shader.getUniform("g_LightColor"); @@ -729,6 +729,7 @@ public class Material implements Asset, Cloneable, Savable, Comparable Quaternion tmpLightDirection = vars.quat1; Quaternion tmpLightPosition = vars.quat2; ColorRGBA tmpLightColor = vars.color; + Vector4f tmpVec = vars.vect4f; ColorRGBA color = l.getColor(); tmpLightColor.set(color); @@ -742,7 +743,7 @@ public class Material implements Asset, Cloneable, Savable, Comparable tmpLightPosition.set(dir.getX(), dir.getY(), dir.getZ(), -1); lightPos.setValue(VarType.Vector4, tmpLightPosition); - tmpLightDirection.set(0,0,0,0); + tmpLightDirection.set(0, 0, 0, 0); lightDir.setValue(VarType.Vector4, tmpLightDirection); break; case Point: @@ -752,7 +753,7 @@ public class Material implements Asset, Cloneable, Savable, Comparable tmpLightPosition.set(pos.getX(), pos.getY(), pos.getZ(), invRadius); lightPos.setValue(VarType.Vector4, tmpLightPosition); - tmpLightDirection.set(0,0,0,0); + tmpLightDirection.set(0, 0, 0, 0); lightDir.setValue(VarType.Vector4, tmpLightDirection); break; case Spot: @@ -765,7 +766,13 @@ public class Material implements Asset, Cloneable, Savable, Comparable tmpLightPosition.set(pos2.getX(), pos2.getY(), pos2.getZ(), invRange); lightPos.setValue(VarType.Vector4, tmpLightPosition); - tmpLightDirection.set(dir2.getX(), dir2.getY(), dir2.getZ(), spotAngleCos); + //We transform the spot directoin in view space here to save 5 varying later in the lighting shader + //one vec4 less and a vec4 that becomes a vec3 + //the downside is that spotAngleCos decoding happen now in the frag shader. + tmpVec.set(dir2.getX(), dir2.getY(), dir2.getZ(),0); + rm.getCurrentCamera().getViewMatrix().mult(tmpVec, tmpVec); + tmpLightDirection.set(tmpVec.getX(), tmpVec.getY(), tmpVec.getZ(), spotAngleCos); + lightDir.setValue(VarType.Vector4, tmpLightDirection); break; @@ -951,6 +958,7 @@ public class Material implements Asset, Cloneable, Savable, Comparable autoSelectTechnique(rm); Renderer r = rm.getRenderer(); + TechniqueDef techDef = technique.getDef(); if (techDef.getLightMode() == LightMode.MultiPass @@ -999,7 +1007,7 @@ public class Material implements Asset, Cloneable, Savable, Comparable case MultiPass: // NOTE: Special case! resetUniformsNotSetByCurrent(shader); - renderMultipassLighting(shader, geom, r); + renderMultipassLighting(shader, geom, rm); // very important, notice the return statement! return; } diff --git a/engine/src/core/com/jme3/util/TempVars.java b/engine/src/core/com/jme3/util/TempVars.java index f51ab8313..5b361e952 100644 --- a/engine/src/core/com/jme3/util/TempVars.java +++ b/engine/src/core/com/jme3/util/TempVars.java @@ -41,6 +41,7 @@ import com.jme3.math.Quaternion; import com.jme3.math.Triangle; import com.jme3.math.Vector2f; import com.jme3.math.Vector3f; +import com.jme3.math.Vector4f; import com.jme3.scene.Spatial; import java.nio.FloatBuffer; import java.nio.IntBuffer; @@ -53,13 +54,13 @@ import java.util.ArrayList; * This returns an available instance of the TempVar class ensuring this * particular instance is never used elsewhere in the mean time. */ -public class TempVars { +public class TempVars { /** * Allow X instances of TempVars in a single thread. */ private static final int STACK_SIZE = 5; - + /** * TempVarsStack contains a stack of TempVars. * Every time TempVars.get() is called, a new entry is added to the stack, @@ -68,30 +69,30 @@ public class TempVars { * the current instance and then the index is decremented. */ private static class TempVarsStack { + int index = 0; TempVars[] tempVars = new TempVars[STACK_SIZE]; } - /** * ThreadLocal to store a TempVarsStack for each thread. * This ensures each thread has a single TempVarsStack that is * used only in method calls in that thread. */ private static final ThreadLocal varsLocal = new ThreadLocal() { + @Override public TempVarsStack initialValue() { return new TempVarsStack(); } }; - /** * This instance of TempVars has been retrieved but not released yet. */ private boolean isUsed = false; - + private TempVars() { } - + /** * Acquire an instance of the TempVar class. * You have to release the instance after use by calling the @@ -103,21 +104,21 @@ public class TempVars { */ public static TempVars get() { TempVarsStack stack = varsLocal.get(); - + TempVars instance = stack.tempVars[stack.index]; - - if (instance == null){ + + if (instance == null) { // Create new instance = new TempVars(); - + // Put it in there stack.tempVars[stack.index] = instance; } - + stack.index++; - + instance.isUsed = true; - + return instance; } @@ -129,23 +130,22 @@ public class TempVars { * first otherwise an exception will be thrown. */ public void release() { - if (!isUsed){ + if (!isUsed) { throw new IllegalStateException("This instance of TempVars was already released!"); } - + isUsed = false; - + TempVarsStack stack = varsLocal.get(); - + // Return it to the stack stack.index--; - + // Check if it is actually there - if (stack.tempVars[stack.index] != this){ + if (stack.tempVars[stack.index] != this) { throw new IllegalStateException("An instance of TempVars has not been released in a called method!"); } } - /** * For interfacing with OpenGL in Renderer. */ @@ -161,7 +161,6 @@ public class TempVars { * Fetching triangle from mesh */ public final Triangle triangle = new Triangle(); - /** * Color */ @@ -180,6 +179,7 @@ public class TempVars { public final Vector3f vect8 = new Vector3f(); public final Vector3f vect9 = new Vector3f(); public final Vector3f vect10 = new Vector3f(); + public final Vector4f vect4f = new Vector4f(); public final Vector3f[] tri = {new Vector3f(), new Vector3f(), new Vector3f()};