Introduced a LightSpace attribute in the TechniqueDef to define in what space LightData should be sent to the shader. Used it for the multipass lighting

define_list_fix
Nehon 10 years ago
parent b7c2050487
commit 01ed6db77c
  1. 25
      jme3-core/src/main/java/com/jme3/material/Material.java
  2. 36
      jme3-core/src/main/java/com/jme3/material/TechniqueDef.java

@ -874,7 +874,7 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable {
TempVars vars = TempVars.get(); TempVars vars = TempVars.get();
Quaternion tmpLightDirection = vars.quat1; Quaternion tmpLightDirection = vars.quat1;
Quaternion tmpLightPosition = vars.quat2; Vector4f tmpLightPosition = vars.vect4f2;
ColorRGBA tmpLightColor = vars.color; ColorRGBA tmpLightColor = vars.color;
Vector4f tmpVec = vars.vect4f1; Vector4f tmpVec = vars.vect4f1;
@ -893,6 +893,7 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable {
//LightPosition uniform. The lighting shader needs to be //LightPosition uniform. The lighting shader needs to be
//reworked though in order to fix this. //reworked though in order to fix this.
tmpLightPosition.set(dir.getX(), dir.getY(), dir.getZ(), -1); tmpLightPosition.set(dir.getX(), dir.getY(), dir.getZ(), -1);
transposeLightDataToSpace(technique.getDef().getLightSpace(), rm, tmpLightPosition);
lightPos.setValue(VarType.Vector4, tmpLightPosition); lightPos.setValue(VarType.Vector4, tmpLightPosition);
tmpLightDirection.set(0, 0, 0, 0); tmpLightDirection.set(0, 0, 0, 0);
lightDir.setValue(VarType.Vector4, tmpLightDirection); lightDir.setValue(VarType.Vector4, tmpLightDirection);
@ -903,6 +904,7 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable {
float invRadius = pl.getInvRadius(); float invRadius = pl.getInvRadius();
tmpLightPosition.set(pos.getX(), pos.getY(), pos.getZ(), invRadius); tmpLightPosition.set(pos.getX(), pos.getY(), pos.getZ(), invRadius);
transposeLightDataToSpace(technique.getDef().getLightSpace(), rm, tmpLightPosition);
lightPos.setValue(VarType.Vector4, tmpLightPosition); lightPos.setValue(VarType.Vector4, tmpLightPosition);
tmpLightDirection.set(0, 0, 0, 0); tmpLightDirection.set(0, 0, 0, 0);
lightDir.setValue(VarType.Vector4, tmpLightDirection); lightDir.setValue(VarType.Vector4, tmpLightDirection);
@ -915,13 +917,19 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable {
float spotAngleCos = sl.getPackedAngleCos(); float spotAngleCos = sl.getPackedAngleCos();
tmpLightPosition.set(pos2.getX(), pos2.getY(), pos2.getZ(), invRange); tmpLightPosition.set(pos2.getX(), pos2.getY(), pos2.getZ(), invRange);
transposeLightDataToSpace(technique.getDef().getLightSpace(), rm, tmpLightPosition);
lightPos.setValue(VarType.Vector4, tmpLightPosition); lightPos.setValue(VarType.Vector4, tmpLightPosition);
tmpVec.set(dir2.getX(), dir2.getY(), dir2.getZ(), 0);
if (technique.getDef().getLightSpace() == TechniqueDef.LightSpace.Legacy) {
//Legacy kept for backward compatibility.
//We transform the spot direction in view space here to save 5 varying later in the lighting shader //We transform the spot direction in view space here to save 5 varying later in the lighting shader
//one vec4 less and a vec4 that becomes a vec3 //one vec4 less and a vec4 that becomes a vec3
//the downside is that spotAngleCos decoding happens now in the frag shader. //the downside is that spotAngleCos decoding happens now in the frag shader.
tmpVec.set(dir2.getX(), dir2.getY(), dir2.getZ(), 0); transposeLightDataToSpace(TechniqueDef.LightSpace.View, rm, tmpVec);
rm.getCurrentCamera().getViewMatrix().mult(tmpVec, tmpVec); } else {
transposeLightDataToSpace(technique.getDef().getLightSpace(), rm, tmpVec);
}
tmpLightDirection.set(tmpVec.getX(), tmpVec.getY(), tmpVec.getZ(), spotAngleCos); tmpLightDirection.set(tmpVec.getX(), tmpVec.getY(), tmpVec.getZ(), spotAngleCos);
lightDir.setValue(VarType.Vector4, tmpLightDirection); lightDir.setValue(VarType.Vector4, tmpLightDirection);
@ -946,6 +954,12 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable {
} }
} }
private void transposeLightDataToSpace(TechniqueDef.LightSpace space, RenderManager rm, Vector4f store){
if(space == TechniqueDef.LightSpace.View){
rm.getCurrentCamera().getViewMatrix().mult(store, store);
}
};
/** /**
* Select the technique to use for rendering this material. * Select the technique to use for rendering this material.
* <p> * <p>
@ -1179,15 +1193,17 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable {
Shader shader = technique.getShader(); Shader shader = technique.getShader();
// send lighting information, if needed // send lighting information, if needed
switch (techDef.getLightMode()) { switch (techDef.getLightMode()) {
case Disable: case Disable:
break; break;
case SinglePass: case SinglePass:
assert technique.getDef().getLightSpace()!= null;
int nbRenderedLights = 0; int nbRenderedLights = 0;
resetUniformsNotSetByCurrent(shader); resetUniformsNotSetByCurrent(shader);
if (lights.size() == 0) { if (lights.size() == 0) {
nbRenderedLights = updateLightListUniforms(shader, geom, lights, rm.getSinglePassLightBatchSize(), rm, 0); updateLightListUniforms(shader, geom, lights, rm.getSinglePassLightBatchSize(), rm, 0);
r.setShader(shader); r.setShader(shader);
renderMeshFromGeometry(r, geom); renderMeshFromGeometry(r, geom);
} else { } else {
@ -1201,6 +1217,7 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable {
case FixedPipeline: case FixedPipeline:
throw new IllegalArgumentException("OpenGL1 is not supported"); throw new IllegalArgumentException("OpenGL1 is not supported");
case MultiPass: case MultiPass:
assert technique.getDef().getLightSpace()!= null;
// NOTE: Special case! // NOTE: Special case!
resetUniformsNotSetByCurrent(shader); resetUniformsNotSetByCurrent(shader);
renderMultipassLighting(shader, geom, lights, rm); renderMultipassLighting(shader, geom, lights, rm);

@ -91,6 +91,15 @@ public class TechniqueDef implements Savable {
PostPass, PostPass,
} }
/**
* Define in what space the light data should be sent to the shader.
*/
public enum LightSpace {
World,
View,
Legacy
}
private EnumSet<Caps> requiredCaps = EnumSet.noneOf(Caps.class); private EnumSet<Caps> requiredCaps = EnumSet.noneOf(Caps.class);
private String name; private String name;
@ -111,6 +120,8 @@ public class TechniqueDef implements Savable {
private HashMap<String, String> defineParams; private HashMap<String, String> defineParams;
private ArrayList<UniformBinding> worldBinds; private ArrayList<UniformBinding> worldBinds;
//The space in which the light should be transposed before sending to the shader.
private LightSpace lightSpace;
/** /**
* Creates a new technique definition. * Creates a new technique definition.
@ -161,6 +172,14 @@ public class TechniqueDef implements Savable {
*/ */
public void setLightMode(LightMode lightMode) { public void setLightMode(LightMode lightMode) {
this.lightMode = lightMode; this.lightMode = lightMode;
//if light space is not specified we set it to Legacy
if(lightSpace == null){
if(lightMode== LightMode.MultiPass){
lightSpace = LightSpace.Legacy;
}else if(lightMode== LightMode.SinglePass){
lightSpace = LightSpace.View;
}
}
} }
/** /**
@ -531,4 +550,21 @@ public class TechniqueDef implements Savable {
public String toString() { public String toString() {
return "TechniqueDef{" + "requiredCaps=" + requiredCaps + ", name=" + name /*+ ", vertName=" + vertName + ", fragName=" + fragName + ", vertLanguage=" + vertLanguage + ", fragLanguage=" + fragLanguage */+ ", presetDefines=" + presetDefines + ", usesShaders=" + usesShaders + ", usesNodes=" + usesNodes + ", shaderNodes=" + shaderNodes + ", shaderGenerationInfo=" + shaderGenerationInfo + ", renderState=" + renderState + ", forcedRenderState=" + forcedRenderState + ", lightMode=" + lightMode + ", shadowMode=" + shadowMode + ", defineParams=" + defineParams + ", worldBinds=" + worldBinds + '}'; return "TechniqueDef{" + "requiredCaps=" + requiredCaps + ", name=" + name /*+ ", vertName=" + vertName + ", fragName=" + fragName + ", vertLanguage=" + vertLanguage + ", fragLanguage=" + fragLanguage */+ ", presetDefines=" + presetDefines + ", usesShaders=" + usesShaders + ", usesNodes=" + usesNodes + ", shaderNodes=" + shaderNodes + ", shaderGenerationInfo=" + shaderGenerationInfo + ", renderState=" + renderState + ", forcedRenderState=" + forcedRenderState + ", lightMode=" + lightMode + ", shadowMode=" + shadowMode + ", defineParams=" + defineParams + ", worldBinds=" + worldBinds + '}';
} }
/**
* Returns the space in which the light data should be passed to the shader.
* @return the light space
*/
public LightSpace getLightSpace() {
return lightSpace;
}
/**
* Sets the space in which the light data should be passed to the shader.
* @param lightSpace the light space
*/
public void setLightSpace(LightSpace lightSpace) {
this.lightSpace = lightSpace;
}
} }

Loading…
Cancel
Save