RM: add ability to force mat param
This commit is contained in:
parent
d0035b0bc6
commit
83259061d3
@ -774,31 +774,42 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable {
|
|||||||
sortingId = -1;
|
sortingId = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateShaderMaterialParameters(Renderer renderer, Shader shader, List<MatParamOverride> overrides) {
|
private int applyOverrides(Renderer renderer, Shader shader, List<MatParamOverride> overrides, int unit) {
|
||||||
int unit = 0;
|
for (MatParamOverride override : overrides) {
|
||||||
|
VarType type = override.getVarType();
|
||||||
|
|
||||||
if (overrides != null) {
|
MatParam paramDef = def.getMaterialParam(override.getName());
|
||||||
for (MatParamOverride override : overrides) {
|
|
||||||
VarType type = override.getVarType();
|
|
||||||
|
|
||||||
MatParam paramDef = def.getMaterialParam(override.getName());
|
if (paramDef == null || paramDef.getVarType() != type || !override.isEnabled()) {
|
||||||
if (paramDef == null || paramDef.getVarType() != type || !override.isEnabled()) {
|
continue;
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
Uniform uniform = shader.getUniform(override.getPrefixedName());
|
|
||||||
if (override.getValue() != null) {
|
|
||||||
if (type.isTextureType()) {
|
|
||||||
renderer.setTexture(unit, (Texture) override.getValue());
|
|
||||||
uniform.setValue(VarType.Int, unit);
|
|
||||||
unit++;
|
|
||||||
} else {
|
|
||||||
uniform.setValue(type, override.getValue());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
uniform.clearValue();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Uniform uniform = shader.getUniform(override.getPrefixedName());
|
||||||
|
|
||||||
|
if (override.getValue() != null) {
|
||||||
|
if (type.isTextureType()) {
|
||||||
|
renderer.setTexture(unit, (Texture) override.getValue());
|
||||||
|
uniform.setValue(VarType.Int, unit);
|
||||||
|
unit++;
|
||||||
|
} else {
|
||||||
|
uniform.setValue(type, override.getValue());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
uniform.clearValue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return unit;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateShaderMaterialParameters(Renderer renderer, Shader shader,
|
||||||
|
List<MatParamOverride> worldOverrides, List<MatParamOverride> forcedOverrides) {
|
||||||
|
|
||||||
|
int unit = 0;
|
||||||
|
if (worldOverrides != null) {
|
||||||
|
unit = applyOverrides(renderer, shader, worldOverrides, unit);
|
||||||
|
}
|
||||||
|
if (forcedOverrides != null) {
|
||||||
|
unit = applyOverrides(renderer, shader, forcedOverrides, unit);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < paramValues.size(); i++) {
|
for (int i = 0; i < paramValues.size(); i++) {
|
||||||
@ -854,8 +865,8 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Shader shader = technique.makeCurrent(renderManager, null, null, rendererCaps);
|
Shader shader = technique.makeCurrent(renderManager, null, null, null, rendererCaps);
|
||||||
updateShaderMaterialParameters(renderer, shader, null);
|
updateShaderMaterialParameters(renderer, shader, null, null);
|
||||||
renderManager.getRenderer().setShader(shader);
|
renderManager.getRenderer().setShader(shader);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -962,7 +973,7 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable {
|
|||||||
List<MatParamOverride> overrides = geometry.getWorldMatParamOverrides();
|
List<MatParamOverride> overrides = geometry.getWorldMatParamOverrides();
|
||||||
|
|
||||||
// Select shader to use
|
// Select shader to use
|
||||||
Shader shader = technique.makeCurrent(renderManager, overrides, lights, rendererCaps);
|
Shader shader = technique.makeCurrent(renderManager, overrides, renderManager.getForcedMatParams(), lights, rendererCaps);
|
||||||
|
|
||||||
// Begin tracking which uniforms were changed by material.
|
// Begin tracking which uniforms were changed by material.
|
||||||
clearUniformsSetByCurrent(shader);
|
clearUniformsSetByCurrent(shader);
|
||||||
@ -971,7 +982,7 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable {
|
|||||||
renderManager.updateUniformBindings(shader);
|
renderManager.updateUniformBindings(shader);
|
||||||
|
|
||||||
// Set material parameters
|
// Set material parameters
|
||||||
updateShaderMaterialParameters(renderer, shader, geometry.getWorldMatParamOverrides());
|
updateShaderMaterialParameters(renderer, shader, overrides, renderManager.getForcedMatParams());
|
||||||
|
|
||||||
// Clear any uniforms not changed by material.
|
// Clear any uniforms not changed by material.
|
||||||
resetUniformsNotSetByCurrent(shader);
|
resetUniformsNotSetByCurrent(shader);
|
||||||
|
@ -110,6 +110,20 @@ public final class Technique {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void applyOverrides(DefineList defineList, List<MatParamOverride> overrides) {
|
||||||
|
for (MatParamOverride override : overrides) {
|
||||||
|
if (!override.isEnabled()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Integer defineId = def.getShaderParamDefineId(override.name);
|
||||||
|
if (defineId != null) {
|
||||||
|
if (def.getDefineIdType(defineId) == override.type) {
|
||||||
|
defineList.set(defineId, override.type, override.value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called by the material to determine which shader to use for rendering.
|
* Called by the material to determine which shader to use for rendering.
|
||||||
*
|
*
|
||||||
@ -120,7 +134,8 @@ public final class Technique {
|
|||||||
* @param rendererCaps The renderer capabilities which the shader should support.
|
* @param rendererCaps The renderer capabilities which the shader should support.
|
||||||
* @return A compatible shader.
|
* @return A compatible shader.
|
||||||
*/
|
*/
|
||||||
Shader makeCurrent(RenderManager renderManager, List<MatParamOverride> overrides,
|
Shader makeCurrent(RenderManager renderManager, List<MatParamOverride> worldOverrides,
|
||||||
|
List<MatParamOverride> forcedOverrides,
|
||||||
LightList lights, EnumSet<Caps> rendererCaps) {
|
LightList lights, EnumSet<Caps> rendererCaps) {
|
||||||
TechniqueDefLogic logic = def.getLogic();
|
TechniqueDefLogic logic = def.getLogic();
|
||||||
AssetManager assetManager = owner.getMaterialDef().getAssetManager();
|
AssetManager assetManager = owner.getMaterialDef().getAssetManager();
|
||||||
@ -128,18 +143,11 @@ public final class Technique {
|
|||||||
dynamicDefines.clear();
|
dynamicDefines.clear();
|
||||||
dynamicDefines.setAll(paramDefines);
|
dynamicDefines.setAll(paramDefines);
|
||||||
|
|
||||||
if (overrides != null) {
|
if (worldOverrides != null) {
|
||||||
for (MatParamOverride override : overrides) {
|
applyOverrides(dynamicDefines, worldOverrides);
|
||||||
if (!override.isEnabled()) {
|
}
|
||||||
continue;
|
if (forcedOverrides != null) {
|
||||||
}
|
applyOverrides(dynamicDefines, forcedOverrides);
|
||||||
Integer defineId = def.getShaderParamDefineId(override.name);
|
|
||||||
if (defineId != null) {
|
|
||||||
if (def.getDefineIdType(defineId) == override.type) {
|
|
||||||
dynamicDefines.set(defineId, override.type, override.value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return logic.makeCurrent(assetManager, renderManager, rendererCaps, lights, dynamicDefines);
|
return logic.makeCurrent(assetManager, renderManager, rendererCaps, lights, dynamicDefines);
|
||||||
|
@ -34,6 +34,7 @@ package com.jme3.renderer;
|
|||||||
import com.jme3.light.DefaultLightFilter;
|
import com.jme3.light.DefaultLightFilter;
|
||||||
import com.jme3.light.LightFilter;
|
import com.jme3.light.LightFilter;
|
||||||
import com.jme3.light.LightList;
|
import com.jme3.light.LightList;
|
||||||
|
import com.jme3.material.MatParamOverride;
|
||||||
import com.jme3.material.Material;
|
import com.jme3.material.Material;
|
||||||
import com.jme3.material.MaterialDef;
|
import com.jme3.material.MaterialDef;
|
||||||
import com.jme3.material.RenderState;
|
import com.jme3.material.RenderState;
|
||||||
@ -82,6 +83,7 @@ public class RenderManager {
|
|||||||
private Material forcedMaterial = null;
|
private Material forcedMaterial = null;
|
||||||
private String forcedTechnique = null;
|
private String forcedTechnique = null;
|
||||||
private RenderState forcedRenderState = null;
|
private RenderState forcedRenderState = null;
|
||||||
|
private final List<MatParamOverride> forcedOverrides = new ArrayList<>();
|
||||||
private int viewX, viewY, viewWidth, viewHeight;
|
private int viewX, viewY, viewWidth, viewHeight;
|
||||||
private Matrix4f orthoMatrix = new Matrix4f();
|
private Matrix4f orthoMatrix = new Matrix4f();
|
||||||
private LightList filteredLightList = new LightList(null);
|
private LightList filteredLightList = new LightList(null);
|
||||||
@ -92,6 +94,7 @@ public class RenderManager {
|
|||||||
private TechniqueDef.LightMode preferredLightMode = TechniqueDef.LightMode.MultiPass;
|
private TechniqueDef.LightMode preferredLightMode = TechniqueDef.LightMode.MultiPass;
|
||||||
private int singlePassLightBatchSize = 1;
|
private int singlePassLightBatchSize = 1;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a high-level rendering interface over the
|
* Create a high-level rendering interface over the
|
||||||
* low-level rendering interface.
|
* low-level rendering interface.
|
||||||
@ -426,6 +429,44 @@ public class RenderManager {
|
|||||||
this.forcedTechnique = forcedTechnique;
|
this.forcedTechnique = forcedTechnique;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a forced material parameter to use when rendering geometries.
|
||||||
|
* <p>
|
||||||
|
* The provided parameter takes precedence over parameters set on the
|
||||||
|
* material or any overrides that exist in the scene graph that have the
|
||||||
|
* same name.
|
||||||
|
*
|
||||||
|
* @param override The override to add
|
||||||
|
* @see MatParamOverride
|
||||||
|
* @see #removeForcedMatParam(com.jme3.material.MatParamOverride)
|
||||||
|
*/
|
||||||
|
public void addForcedMatParam(MatParamOverride override) {
|
||||||
|
forcedOverrides.add(override);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove a forced material parameter previously added.
|
||||||
|
*
|
||||||
|
* @param override The override to remove.
|
||||||
|
* @see #addForcedMatParam(com.jme3.material.MatParamOverride)
|
||||||
|
*/
|
||||||
|
public void removeForcedMatParam(MatParamOverride override) {
|
||||||
|
forcedOverrides.remove(override);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the forced material parameters applied to rendered geometries.
|
||||||
|
* <p>
|
||||||
|
* Forced parameters can be added via
|
||||||
|
* {@link #addForcedMatParam(com.jme3.material.MatParamOverride)} or removed
|
||||||
|
* via {@link #removeForcedMatParam(com.jme3.material.MatParamOverride)}.
|
||||||
|
*
|
||||||
|
* @return The forced material parameters.
|
||||||
|
*/
|
||||||
|
public List<MatParamOverride> getForcedMatParams() {
|
||||||
|
return forcedOverrides;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enable or disable alpha-to-coverage.
|
* Enable or disable alpha-to-coverage.
|
||||||
* <p>
|
* <p>
|
||||||
|
@ -53,6 +53,7 @@ import com.jme3.system.TestUtil;
|
|||||||
import com.jme3.texture.Image.Format;
|
import com.jme3.texture.Image.Format;
|
||||||
import com.jme3.texture.Texture;
|
import com.jme3.texture.Texture;
|
||||||
import com.jme3.texture.Texture2D;
|
import com.jme3.texture.Texture2D;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
@ -126,6 +127,22 @@ public class MaterialMatParamOverrideTest {
|
|||||||
outUniforms(uniform("AlphaDiscardThreshold", VarType.Float, 2.79f));
|
outUniforms(uniform("AlphaDiscardThreshold", VarType.Float, 2.79f));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testForcedOverride() {
|
||||||
|
material("Common/MatDefs/Light/Lighting.j3md");
|
||||||
|
inputMp(mpoFloat("AlphaDiscardThreshold", 3.12f));
|
||||||
|
inputMpo(mpoFloat("AlphaDiscardThreshold", 2.79f));
|
||||||
|
inputFpo(mpoFloat("AlphaDiscardThreshold", 1.23f));
|
||||||
|
outDefines(def("DISCARD_ALPHA", VarType.Float, 1.23f));
|
||||||
|
outUniforms(uniform("AlphaDiscardThreshold", VarType.Float, 1.23f));
|
||||||
|
|
||||||
|
reset();
|
||||||
|
root.clearMatParamOverrides();
|
||||||
|
root.updateGeometricState();
|
||||||
|
outDefines(def("DISCARD_ALPHA", VarType.Float, 2.79f));
|
||||||
|
outUniforms(uniform("AlphaDiscardThreshold", VarType.Float, 2.79f));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testChildOverridesParent() {
|
public void testChildOverridesParent() {
|
||||||
material("Common/MatDefs/Light/Lighting.j3md");
|
material("Common/MatDefs/Light/Lighting.j3md");
|
||||||
@ -439,10 +456,22 @@ public class MaterialMatParamOverrideTest {
|
|||||||
root.updateGeometricState();
|
root.updateGeometricState();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void inputFpo(MatParamOverride... overrides) {
|
||||||
|
if (evaluated) {
|
||||||
|
throw new IllegalStateException();
|
||||||
|
}
|
||||||
|
for (MatParamOverride override : overrides) {
|
||||||
|
renderManager.addForcedMatParam(override);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void reset() {
|
private void reset() {
|
||||||
evaluated = false;
|
evaluated = false;
|
||||||
usedShader = null;
|
usedShader = null;
|
||||||
Arrays.fill(usedTextures, null);
|
Arrays.fill(usedTextures, null);
|
||||||
|
for (MatParamOverride override : new ArrayList<>(renderManager.getForcedMatParams())) {
|
||||||
|
renderManager.removeForcedMatParam(override);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Define def(String name, VarType type, Object value) {
|
private Define def(String name, VarType type, Object value) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user