#define ATTENUATION\r
//#define HQ_ATTENUATION\r
\r
+uniform vec4 g_LightDirection;\r
varying vec2 texCoord;\r
#ifdef SEPARATE_TEXCOORD\r
varying vec2 texCoord2;\r
#endif\r
uniform float m_AlphaDiscardThreshold;\r
\r
-varying vec4 lightVec;\r
-varying vec4 spotVec;\r
+varying vec3 lightVec;\r
\r
#ifndef VERTEX_LIGHTING\r
uniform float m_Shininess;\r
\r
#ifndef VERTEX_LIGHTING\r
float spotFallOff = 1.0;\r
- if(spotVec.w != 0.0){\r
+ if(g_LightDirection.w != 0.0){\r
vec3 L = normalize(lightVec.xyz);\r
- vec3 spotdir = normalize(spotVec.xyz);\r
+ vec3 spotdir = normalize(g_LightDirection.xyz);\r
float curAngleCos = dot(-L, spotdir); \r
- float innerAngleCos = spotVec.w;\r
- float outerAngleCos = lightVec.w;\r
+ float innerAngleCos = floor(g_LightDirection.w) * 0.001;\r
+ float outerAngleCos = fract(g_LightDirection.w);\r
float innerMinusOuter = innerAngleCos - outerAngleCos;\r
spotFallOff = clamp((curAngleCos - outerAngleCos) / innerMinusOuter, 0.0, 1.0);\r
if(spotFallOff <= 0.0){\r
\r
uniform vec4 g_LightColor;\r
uniform vec4 g_LightPosition;\r
-uniform vec4 g_LightDirection;\r
+//uniform vec4 g_LightDirection;\r
uniform vec4 g_AmbientLightColor;\r
\r
varying vec2 texCoord;\r
attribute vec2 inTexCoord;\r
attribute vec3 inNormal;\r
\r
-varying vec4 lightVec;\r
-varying vec4 spotVec;\r
+varying vec3 lightVec;\r
+//varying vec4 spotVec;\r
\r
#ifdef VERTEX_COLOR\r
attribute vec4 inColor;\r
void lightComputeDir(in vec3 worldPos, in vec4 color, in vec4 position, out vec4 lightDir){\r
float posLight = step(0.5, color.w);\r
vec3 tempVec = position.xyz * sign(posLight - 0.5) - (worldPos * posLight);\r
- lightVec.xyz = tempVec; \r
+ lightVec = tempVec; \r
#ifdef ATTENUATION\r
float dist = length(tempVec);\r
lightDir.w = clamp(1.0 - position.w * dist * posLight, 0.0, 1.0);\r
#endif\r
\r
//computing spot direction in view space and unpacking spotlight cos\r
- spotVec = (g_ViewMatrix * vec4(g_LightDirection.xyz, 0.0) );\r
- spotVec.w = floor(g_LightDirection.w) * 0.001;\r
- lightVec.w = fract(g_LightDirection.w);\r
+// spotVec = (g_ViewMatrix * vec4(g_LightDirection.xyz, 0.0) );\r
+// spotVec.w = floor(g_LightDirection.w) * 0.001;\r
+// lightVec.w = fract(g_LightDirection.w);\r
\r
lightColor.w = 1.0;\r
#ifdef MATERIAL_COLORS\r
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;
additiveLight.setBlendMode(RenderState.BlendMode.AlphaAdditive);
additiveLight.setDepthWrite(false);
}
-
private AssetKey key;
private MaterialDef def;
private ListMap<String, MatParam> paramValues = new ListMap<String, MatParam>();
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.
*
}
}
- 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");
Quaternion tmpLightDirection = vars.quat1;
Quaternion tmpLightPosition = vars.quat2;
ColorRGBA tmpLightColor = vars.color;
+ Vector4f tmpVec = vars.vect4f;
ColorRGBA color = l.getColor();
tmpLightColor.set(color);
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:
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:
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;
autoSelectTechnique(rm);
Renderer r = rm.getRenderer();
+
TechniqueDef techDef = technique.getDef();
if (techDef.getLightMode() == LightMode.MultiPass
case MultiPass:
// NOTE: Special case!
resetUniformsNotSetByCurrent(shader);
- renderMultipassLighting(shader, geom, r);
+ renderMultipassLighting(shader, geom, rm);
// very important, notice the return statement!
return;
}
import com.jme3.math.Triangle;\r
import com.jme3.math.Vector2f;\r
import com.jme3.math.Vector3f;\r
+import com.jme3.math.Vector4f;\r
import com.jme3.scene.Spatial;\r
import java.nio.FloatBuffer;\r
import java.nio.IntBuffer;\r
* This returns an available instance of the TempVar class ensuring this \r
* particular instance is never used elsewhere in the mean time.\r
*/\r
-public class TempVars { \r
+public class TempVars {\r
\r
/**\r
* Allow X instances of TempVars in a single thread.\r
*/\r
private static final int STACK_SIZE = 5;\r
- \r
+\r
/**\r
* <code>TempVarsStack</code> contains a stack of TempVars.\r
* Every time TempVars.get() is called, a new entry is added to the stack,\r
* the current instance and then the index is decremented.\r
*/\r
private static class TempVarsStack {\r
+\r
int index = 0;\r
TempVars[] tempVars = new TempVars[STACK_SIZE];\r
}\r
- \r
/**\r
* ThreadLocal to store a TempVarsStack for each thread.\r
* This ensures each thread has a single TempVarsStack that is\r
* used only in method calls in that thread.\r
*/\r
private static final ThreadLocal<TempVarsStack> varsLocal = new ThreadLocal<TempVarsStack>() {\r
+\r
@Override\r
public TempVarsStack initialValue() {\r
return new TempVarsStack();\r
}\r
};\r
- \r
/**\r
* This instance of TempVars has been retrieved but not released yet.\r
*/\r
private boolean isUsed = false;\r
- \r
+\r
private TempVars() {\r
}\r
- \r
+\r
/**\r
* Acquire an instance of the TempVar class.\r
* You have to release the instance after use by calling the \r
*/\r
public static TempVars get() {\r
TempVarsStack stack = varsLocal.get();\r
- \r
+\r
TempVars instance = stack.tempVars[stack.index];\r
- \r
- if (instance == null){\r
+\r
+ if (instance == null) {\r
// Create new\r
instance = new TempVars();\r
- \r
+\r
// Put it in there\r
stack.tempVars[stack.index] = instance;\r
}\r
- \r
+\r
stack.index++;\r
- \r
+\r
instance.isUsed = true;\r
- \r
+\r
return instance;\r
}\r
\r
* first otherwise an exception will be thrown.\r
*/\r
public void release() {\r
- if (!isUsed){\r
+ if (!isUsed) {\r
throw new IllegalStateException("This instance of TempVars was already released!");\r
}\r
- \r
+\r
isUsed = false;\r
- \r
+\r
TempVarsStack stack = varsLocal.get();\r
- \r
+\r
// Return it to the stack\r
stack.index--;\r
- \r
+\r
// Check if it is actually there\r
- if (stack.tempVars[stack.index] != this){\r
+ if (stack.tempVars[stack.index] != this) {\r
throw new IllegalStateException("An instance of TempVars has not been released in a called method!");\r
}\r
}\r
- \r
/**\r
* For interfacing with OpenGL in Renderer.\r
*/\r
* Fetching triangle from mesh\r
*/\r
public final Triangle triangle = new Triangle();\r
- \r
/**\r
* Color\r
*/\r
public final Vector3f vect8 = new Vector3f();\r
public final Vector3f vect9 = new Vector3f();\r
public final Vector3f vect10 = new Vector3f();\r
+ public final Vector4f vect4f = new Vector4f();\r
public final Vector3f[] tri = {new Vector3f(),\r
new Vector3f(),\r
new Vector3f()};\r