parent
9f9edee332
commit
b57ecf35ea
@ -0,0 +1,105 @@ |
||||
package com.jme3.shader.builder; |
||||
|
||||
import com.jme3.material.TechniqueDef; |
||||
import com.jme3.shader.*; |
||||
|
||||
import java.util.regex.Matcher; |
||||
import java.util.regex.Pattern; |
||||
|
||||
public class InlineShaderNodeBuilder extends ShaderNodeBuilder { |
||||
|
||||
|
||||
private TechniqueDef technique; |
||||
private Pattern varPattern = Pattern.compile("%(\\w+)"); |
||||
private String[] outputTypes; |
||||
|
||||
public InlineShaderNodeBuilder(String name, ShaderNodeDefinition def, String code, TechniqueDef technique) { |
||||
super(name, def); |
||||
this.technique = technique; |
||||
Matcher m = varPattern.matcher(code); |
||||
while (m.find()) { |
||||
// type will be inferred with mapping
|
||||
ShaderNodeVariable v = new ShaderNodeVariable(null, m.group(1)); |
||||
def.getParams().add(v); |
||||
def.getInputs().add(v); |
||||
} |
||||
def.setInlinedCode(code.replaceAll("%", "")); |
||||
def.getOutputs().add(new ShaderNodeVariable(def.getReturnType(), "result")); |
||||
} |
||||
|
||||
@Override |
||||
public InlineShaderNodeBuilder inputs(VariableMappingBuilder... inputs) { |
||||
ShaderNodeDefinition def = getNode().getDefinition(); |
||||
for (VariableMappingBuilder map : inputs) { |
||||
ShaderNodeVariable v = findVariable(map.getName(), def.getInputs()); |
||||
|
||||
def.getInputs().add(v); |
||||
ShaderNodeVariable right = map.getVariable(); |
||||
if (right.getDefaultValue() != null) { |
||||
throw new IllegalArgumentException("Inlined expression for input " + v.getName() |
||||
+ " is not supported with inline node " + getNode().getName() |
||||
+ ". Please inline the expression in the node code."); |
||||
} |
||||
// infer type
|
||||
int idx = right.getType().indexOf("|"); |
||||
if (idx > 0) { |
||||
// texture type, taking the first available type
|
||||
String type = right.getType().substring(0, right.getType().indexOf("|")); |
||||
right.setType(type); |
||||
} |
||||
|
||||
v.setType(right.getType()); |
||||
|
||||
} |
||||
super.inputs(inputs); |
||||
return this; |
||||
} |
||||
|
||||
@Override |
||||
public InlineShaderNodeBuilder outputs(VariableMappingBuilder... outputs) { |
||||
if (outputs.length > 1 || !outputs[0].getName().equals("result")) { |
||||
throw new IllegalArgumentException("Only the 'result' output can be mapped for an inlined node"); |
||||
} |
||||
super.outputs(outputs); |
||||
return this; |
||||
} |
||||
|
||||
@Override |
||||
public void build() { |
||||
ShaderNodeDefinition def = getNode().getDefinition(); |
||||
//generate the code
|
||||
StringBuilder sb = new StringBuilder(); |
||||
sb.append(def.getReturnType()).append(" ").append(def.getName()).append("("); |
||||
boolean isFirst = true; |
||||
int outTypeIndex = 0; |
||||
for (ShaderNodeVariable v : def.getParams()) { |
||||
if (!isFirst) { |
||||
sb.append(", "); |
||||
} |
||||
sb.append("const in "); |
||||
if (def.getInputs().contains(v)) { |
||||
|
||||
} else { |
||||
sb.append("out "); |
||||
if (!def.getOutputs().contains(v)) { |
||||
// the variable is not in the output list
|
||||
def.getOutputs().add(v); |
||||
} |
||||
if (v.getType() == null && outTypeIndex < outputTypes.length) { |
||||
v.setType(outputTypes[outTypeIndex]); |
||||
} else { |
||||
throw new IllegalArgumentException("Output variable " + v.getName() + " has no type in node " + getNode().getName() + ". Make sure you properly declare it"); |
||||
} |
||||
} |
||||
if (v.getType() == null) { |
||||
throw new IllegalArgumentException("Unable to infer type for input variable " + v.getName() + " in node " + getNode().getName()); |
||||
} |
||||
sb.append(v.getType()).append(" "); |
||||
sb.append(v.getName()); |
||||
isFirst = false; |
||||
} |
||||
sb.append("){\n\treturn ").append(def.getInlinedCode()).append(";\n}"); |
||||
def.setInlinedCode(sb.toString()); |
||||
super.build(); |
||||
} |
||||
} |
@ -0,0 +1,146 @@ |
||||
package com.jme3.shader.builder; |
||||
|
||||
import com.jme3.asset.AssetManager; |
||||
import com.jme3.material.*; |
||||
import com.jme3.scene.VertexBuffer; |
||||
import com.jme3.shader.*; |
||||
import com.jme3.texture.image.ColorSpace; |
||||
|
||||
import java.util.*; |
||||
|
||||
public class MaterialBuilder { |
||||
|
||||
private MaterialDef matDef; |
||||
private Map<String, TechniqueBuilder> techBuilders = new HashMap<>(); |
||||
private AssetManager assetManager; |
||||
private TechniqueBuilder currentTechnique; |
||||
|
||||
public MaterialBuilder(AssetManager assetManager) { |
||||
matDef = new MaterialDef(assetManager, "MatDef"); |
||||
this.assetManager = assetManager; |
||||
} |
||||
|
||||
public MaterialBuilder(AssetManager assetManager, MaterialDef matDef) { |
||||
this.matDef = matDef; |
||||
this.assetManager = assetManager; |
||||
} |
||||
|
||||
public MaterialBuilder(AssetManager assetManager, String matDefName) { |
||||
this.matDef = (MaterialDef) assetManager.loadAsset(matDefName); |
||||
this.assetManager = assetManager; |
||||
} |
||||
|
||||
public TechniqueBuilder technique(String name) { |
||||
TechniqueBuilder tb = techBuilders.get(name); |
||||
if (tb == null) { |
||||
List<TechniqueDef> defs = matDef.getTechniqueDefs(name); |
||||
if (defs == null || defs.isEmpty()) { |
||||
String techniqueUniqueName = matDef.getAssetName() + "@" + name; |
||||
tb = new TechniqueBuilder(assetManager, name, techniqueUniqueName.hashCode()); |
||||
matDef.addTechniqueDef(tb.getTechniqueDef()); |
||||
|
||||
} else { |
||||
tb = new TechniqueBuilder(assetManager, defs.get(0)); |
||||
} |
||||
techBuilders.put(name, tb); |
||||
} |
||||
currentTechnique = tb; |
||||
return tb; |
||||
} |
||||
|
||||
public TechniqueBuilder technique() { |
||||
return this.technique("Default"); |
||||
} |
||||
|
||||
public Material build() { |
||||
|
||||
for (Map.Entry<String, TechniqueBuilder> entry : techBuilders.entrySet()) { |
||||
TechniqueBuilder tb = entry.getValue(); |
||||
tb.build(); |
||||
ShaderUtils.computeShaderNodeGenerationInfo(tb.getTechniqueDef(), matDef); |
||||
} |
||||
return new Material(matDef); |
||||
} |
||||
|
||||
public ShaderNodeVariable var(String expression) { |
||||
String[] names = expression.split("\\."); |
||||
if (names.length != 2) { |
||||
// we might have an inlined expression
|
||||
ShaderNodeVariable tmp = new ShaderNodeVariable(null, null); |
||||
tmp.setDefaultValue(expression); |
||||
return tmp; |
||||
} |
||||
if (names[0].equals("MatParam")) { |
||||
MatParam param = matDef.getMaterialParam(names[1]); |
||||
if (param == null) { |
||||
throw new IllegalArgumentException("Couldn't find material parameter named " + names[1]); |
||||
} |
||||
return new ShaderNodeVariable(param.getVarType().getGlslType(), names[0], names[1], null, "m_"); |
||||
} |
||||
if (names[0].equals("WorldParam")) { |
||||
UniformBinding worldParam = UniformBinding.valueOf(names[1]); |
||||
currentTechnique.addWorldParam(worldParam.name()); |
||||
return new ShaderNodeVariable(worldParam.getGlslType(), "WorldParam", worldParam.name(), null, "g_"); |
||||
} |
||||
if (names[0].equals("Attr")) { |
||||
String n = names[1].substring(2); |
||||
VertexBuffer.Type attribute = VertexBuffer.Type.valueOf(n); |
||||
return new ShaderNodeVariable(ShaderUtils.getDefaultAttributeType(attribute), names[0], names[1]); |
||||
} |
||||
|
||||
if (names[0].equals("Global")) { |
||||
if(!names[1].equals("position") && !names[1].startsWith("color")){ |
||||
throw new IllegalArgumentException("Global output must be outPosition or outColor, got " + names[1]); |
||||
} |
||||
|
||||
return new ShaderNodeVariable("vec4", names[0], names[1]); |
||||
} |
||||
|
||||
ShaderNodeBuilder nb = currentTechnique.node(names[0]); |
||||
if (nb == null) { |
||||
throw new IllegalArgumentException("Couldn't find node named " + names[0]); |
||||
} |
||||
|
||||
ShaderNodeVariable v = nb.variable(names[1]); |
||||
if (v == null) { |
||||
throw new IllegalArgumentException("Couldn't find variable named " + names[1] + " in node " + names[0]); |
||||
} |
||||
|
||||
return v; |
||||
} |
||||
|
||||
public VariableMappingBuilder map(String param, String expression) { |
||||
return new VariableMappingBuilder(param, var(expression)); |
||||
} |
||||
|
||||
public VariableMappingBuilder map(String param, ShaderNodeVariable variable) { |
||||
return new VariableMappingBuilder(param, variable); |
||||
} |
||||
|
||||
public VariableMappingBuilder map(String param, VertexBuffer.Type attribute) { |
||||
ShaderNodeVariable variable = new ShaderNodeVariable(ShaderUtils.getDefaultAttributeType(attribute), "Attr", "in" + attribute.name()); |
||||
return new VariableMappingBuilder(param, variable); |
||||
} |
||||
|
||||
public VariableMappingBuilder map(String param, UniformBinding worldParam) { |
||||
ShaderNodeVariable variable = new ShaderNodeVariable(worldParam.getGlslType(), "WorldParam", worldParam.name(), null, "g_"); |
||||
currentTechnique.addWorldParam(worldParam.name()); |
||||
return new VariableMappingBuilder(param, variable); |
||||
} |
||||
|
||||
public void addMatParam(VarType type, String name){ |
||||
if(type.isTextureType()){ |
||||
matDef.addMaterialParamTexture(type, name, ColorSpace.sRGB); |
||||
} else { |
||||
matDef.addMaterialParam(type, name, null); |
||||
} |
||||
} |
||||
|
||||
public void addMatParamTexture(VarType type, String name, ColorSpace colorSpace){ |
||||
if(!type.isTextureType()){ |
||||
throw new IllegalArgumentException(type + "is not a texture type "); |
||||
} |
||||
matDef.addMaterialParamTexture(type, name, colorSpace); |
||||
} |
||||
|
||||
} |
@ -0,0 +1,113 @@ |
||||
package com.jme3.shader.builder; |
||||
|
||||
import com.jme3.shader.*; |
||||
|
||||
import java.util.List; |
||||
|
||||
public class ShaderNodeBuilder { |
||||
|
||||
private ShaderNode node; |
||||
|
||||
protected ShaderNodeBuilder(String name, ShaderNodeDefinition def) { |
||||
node = new ShaderNode(name, def, null); |
||||
} |
||||
|
||||
protected ShaderNodeBuilder(ShaderNode node) { |
||||
this.node = node; |
||||
} |
||||
|
||||
protected ShaderNode getNode() { |
||||
return node; |
||||
} |
||||
|
||||
protected ShaderNodeVariable variable(String name){ |
||||
ShaderNodeDefinition def = node.getDefinition(); |
||||
for (ShaderNodeVariable variable : def.getParams()) { |
||||
if(variable.getName().equals(name)){ |
||||
ShaderNodeVariable var = variable.clone(); |
||||
var.setNameSpace(node.getName()); |
||||
return var; |
||||
} |
||||
} |
||||
|
||||
for (ShaderNodeVariable variable : def.getOutputs()) { |
||||
if(variable.getName().equals(name)){ |
||||
ShaderNodeVariable var = variable.clone(); |
||||
var.setNameSpace(node.getName()); |
||||
return var; |
||||
} |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
public ShaderNodeBuilder inputs(VariableMappingBuilder... inputs){ |
||||
List<VariableMapping> mappings = node.getInputMapping(); |
||||
mappings.clear(); |
||||
for (VariableMappingBuilder mb : inputs) { |
||||
ShaderNodeVariable left = findVariable(mb.getName(), node.getDefinition().getInputs() ); |
||||
if(left == null){ |
||||
throw new IllegalArgumentException("Couldn't find input " + mb.getName() + " in node definition " + node.getDefinition().getName()); |
||||
} |
||||
left = left.clone(); |
||||
left.setNameSpace(node.getName()); |
||||
ShaderNodeVariable right = mb.getVariable(); |
||||
VariableMapping m = map(left, right); |
||||
mappings.add(m); |
||||
} |
||||
return this; |
||||
} |
||||
|
||||
|
||||
public ShaderNodeBuilder outputs(VariableMappingBuilder... outputs){ |
||||
List<VariableMapping> mappings = node.getOutputMapping(); |
||||
mappings.clear(); |
||||
for (VariableMappingBuilder mb : outputs) { |
||||
ShaderNodeVariable right = findVariable(mb.getName(), node.getDefinition().getOutputs() ); |
||||
if(right == null){ |
||||
throw new IllegalArgumentException("Couldn't find input " + mb.getName() + " in node definition " + node.getDefinition().getName()); |
||||
} |
||||
right = right.clone(); |
||||
right.setNameSpace(node.getName()); |
||||
ShaderNodeVariable left = mb.getVariable(); |
||||
VariableMapping m = map(left, right); |
||||
mappings.add(m); |
||||
} |
||||
return this; |
||||
} |
||||
|
||||
|
||||
private VariableMapping map(ShaderNodeVariable left, ShaderNodeVariable right) { |
||||
if(right.getType() == null){ |
||||
// tmp variable, with default value
|
||||
VariableMapping m = new VariableMapping(); |
||||
m.setLeftVariable(left); |
||||
m.setRightExpression(right.getDefaultValue()); |
||||
return m; |
||||
} |
||||
int leftCard = ShaderUtils.getCardinality(left.getType(), ""); |
||||
int rightCard = ShaderUtils.getCardinality(right.getType(), ""); |
||||
String swizzle = "xyzw"; |
||||
String rightVarSwizzle = ""; |
||||
String leftVarSwizzle =""; |
||||
if (rightCard > leftCard) { |
||||
rightVarSwizzle = swizzle.substring(0, leftCard); |
||||
} else if (rightCard > rightCard) { |
||||
leftVarSwizzle = swizzle.substring(0, rightCard); |
||||
} |
||||
|
||||
return new VariableMapping(left, leftVarSwizzle, right, rightVarSwizzle, null); |
||||
} |
||||
|
||||
protected ShaderNodeVariable findVariable(String name, List<ShaderNodeVariable> list){ |
||||
for (ShaderNodeVariable variable : list) { |
||||
if(variable.getName().equals(name)){ |
||||
return variable; |
||||
} |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
public void build(){ |
||||
|
||||
} |
||||
} |
@ -0,0 +1,145 @@ |
||||
package com.jme3.shader.builder; |
||||
|
||||
import com.jme3.asset.AssetManager; |
||||
import com.jme3.asset.ShaderNodeDefinitionKey; |
||||
import com.jme3.material.ShaderGenerationInfo; |
||||
import com.jme3.material.TechniqueDef; |
||||
import com.jme3.material.logic.*; |
||||
import com.jme3.shader.*; |
||||
|
||||
import java.text.ParseException; |
||||
import java.util.*; |
||||
|
||||
public class TechniqueBuilder { |
||||
|
||||
private TechniqueDef techniqueDef; |
||||
private AssetManager assetManager; |
||||
private Map<String, ShaderNodeBuilder> nodeBuilders = new HashMap<>(); |
||||
|
||||
protected TechniqueBuilder(AssetManager assetManager, String name, int sortId) { |
||||
techniqueDef = new TechniqueDef(name, sortId); |
||||
this.assetManager = assetManager; |
||||
} |
||||
|
||||
protected TechniqueBuilder(AssetManager assetManager, TechniqueDef techniqueDef) { |
||||
this.techniqueDef = techniqueDef; |
||||
this.assetManager = assetManager; |
||||
} |
||||
|
||||
protected TechniqueDef getTechniqueDef() { |
||||
return techniqueDef; |
||||
} |
||||
|
||||
public ShaderNodeBuilder node(String name) { |
||||
ShaderNodeBuilder b = nodeBuilders.get(name); |
||||
if (b == null){ |
||||
ShaderNode n = findShaderNode(name); |
||||
if(n == null){ |
||||
throw new IllegalArgumentException("Can't find node with name " + name + " in technique definition " + techniqueDef.getName()); |
||||
} |
||||
b = new ShaderNodeBuilder(n); |
||||
nodeBuilders.put(name, b); |
||||
} |
||||
return b; |
||||
} |
||||
|
||||
public ShaderNodeBuilder addNode(String name, String defName, String shaderNodeDefPath) { |
||||
List<ShaderNodeDefinition> defs; |
||||
if(shaderNodeDefPath.endsWith(".j3sn")){ |
||||
defs = assetManager.loadAsset(new ShaderNodeDefinitionKey(shaderNodeDefPath)); |
||||
} else { |
||||
try { |
||||
defs = ShaderUtils.loadSahderNodeDefinition(assetManager, shaderNodeDefPath); |
||||
} catch (ParseException e) { |
||||
throw new IllegalArgumentException("Couldn't parse definition " + shaderNodeDefPath, e); |
||||
} |
||||
} |
||||
ShaderNodeDefinition definition = findDefinition(defName, defs); |
||||
if(definition == null){ |
||||
throw new IllegalArgumentException("Couldn't find definition " + defName + " in " + shaderNodeDefPath); |
||||
} |
||||
|
||||
ShaderNodeBuilder b = new ShaderNodeBuilder(name,definition); |
||||
if(techniqueDef.getShaderNodes() == null){ |
||||
techniqueDef.setShaderNodes(new ArrayList<ShaderNode>()); |
||||
} |
||||
techniqueDef.setShaderFile(techniqueDef.hashCode() + "", techniqueDef.hashCode() + "", "GLSL100", "GLSL100"); |
||||
techniqueDef.getShaderNodes().add(b.getNode()); |
||||
techniqueDef.setShaderGenerationInfo(new ShaderGenerationInfo()); |
||||
techniqueDef.setLogic(new DefaultTechniqueDefLogic(techniqueDef)); |
||||
techniqueDef.setShaderPrologue(""); |
||||
nodeBuilders.put(name, b); |
||||
return b; |
||||
} |
||||
|
||||
|
||||
public InlineShaderNodeBuilder inlineVertexNode(String type, String name, String code){ |
||||
return inlineNode(type, name, code, Shader.ShaderType.Vertex); |
||||
} |
||||
|
||||
public InlineShaderNodeBuilder inlineFragmentNode(String type, String name, String code){ |
||||
return inlineNode(type, name, code, Shader.ShaderType.Fragment); |
||||
} |
||||
|
||||
public InlineShaderNodeBuilder inlineNode(String returnType, String name, String code, Shader.ShaderType type){ |
||||
ShaderNodeDefinition def = new ShaderNodeDefinition(); |
||||
def.setName(name); |
||||
def.setType(type); |
||||
def.setReturnType(returnType); |
||||
InlineShaderNodeBuilder sb = new InlineShaderNodeBuilder(name, def, code, techniqueDef); |
||||
nodeBuilders.put(name, sb); |
||||
techniqueDef.getShaderNodes().add(sb.getNode()); |
||||
return sb; |
||||
} |
||||
|
||||
public boolean addWorldParam(String name){ |
||||
return techniqueDef.addWorldParam(name); |
||||
} |
||||
|
||||
private void setLightMode(TechniqueDef.LightMode mode){ |
||||
switch (techniqueDef.getLightMode()) { |
||||
case Disable: |
||||
techniqueDef.setLogic(new DefaultTechniqueDefLogic(techniqueDef)); |
||||
break; |
||||
case MultiPass: |
||||
techniqueDef.setLogic(new MultiPassLightingLogic(techniqueDef)); |
||||
break; |
||||
case SinglePass: |
||||
techniqueDef.setLogic(new SinglePassLightingLogic(techniqueDef)); |
||||
break; |
||||
case StaticPass: |
||||
techniqueDef.setLogic(new StaticPassLightingLogic(techniqueDef)); |
||||
break; |
||||
case SinglePassAndImageBased: |
||||
techniqueDef.setLogic(new SinglePassAndImageBasedLightingLogic(techniqueDef)); |
||||
break; |
||||
default: |
||||
throw new UnsupportedOperationException(); |
||||
} |
||||
} |
||||
|
||||
private ShaderNodeDefinition findDefinition(String defName, List<ShaderNodeDefinition> defs) { |
||||
for (ShaderNodeDefinition def : defs) { |
||||
if(def.getName().equals(defName)){ |
||||
return def; |
||||
} |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
private ShaderNode findShaderNode(String name){ |
||||
for (ShaderNode shaderNode : techniqueDef.getShaderNodes()) { |
||||
if(shaderNode.getName().equals(name)){ |
||||
return shaderNode; |
||||
} |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
protected void build(){ |
||||
for (Map.Entry<String, ShaderNodeBuilder> entry : nodeBuilders.entrySet()) { |
||||
ShaderNodeBuilder nb = entry.getValue(); |
||||
nb.build(); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,23 @@ |
||||
package com.jme3.shader.builder; |
||||
|
||||
import com.jme3.shader.ShaderNodeVariable; |
||||
|
||||
public class VariableMappingBuilder { |
||||
|
||||
private String name; |
||||
private ShaderNodeVariable variable; |
||||
|
||||
protected VariableMappingBuilder(String name, ShaderNodeVariable variable) { |
||||
this.name = name; |
||||
this.variable = variable; |
||||
} |
||||
|
||||
public String getName() { |
||||
return name; |
||||
} |
||||
|
||||
public ShaderNodeVariable getVariable() { |
||||
return variable; |
||||
} |
||||
|
||||
} |
@ -0,0 +1,86 @@ |
||||
package jme3test.material; |
||||
|
||||
import com.jme3.app.SimpleApplication; |
||||
import com.jme3.material.Material; |
||||
import com.jme3.material.Technique; |
||||
import com.jme3.material.TechniqueDef; |
||||
import com.jme3.math.*; |
||||
import com.jme3.scene.Geometry; |
||||
import com.jme3.scene.VertexBuffer; |
||||
import com.jme3.scene.shape.Box; |
||||
import com.jme3.shader.*; |
||||
import com.jme3.shader.builder.MaterialBuilder; |
||||
import com.jme3.texture.Texture; |
||||
|
||||
import java.util.logging.Level; |
||||
import java.util.logging.Logger; |
||||
|
||||
public class TestShaderNodesApi extends SimpleApplication { |
||||
|
||||
public static void main(String[] args) { |
||||
TestShaderNodesApi app = new TestShaderNodesApi(); |
||||
app.start(); |
||||
} |
||||
|
||||
@Override |
||||
public void simpleInitApp() { |
||||
flyCam.setMoveSpeed(20); |
||||
Logger.getLogger("com.jme3").setLevel(Level.WARNING); |
||||
Box boxshape1 = new Box(1f, 1f, 1f); |
||||
Geometry cube = new Geometry("A Box", boxshape1); |
||||
Texture tex = assetManager.loadTexture("Interface/Logo/Monkey.jpg"); |
||||
|
||||
MaterialBuilder mb = new MaterialBuilder(assetManager); |
||||
mb.addMatParam(VarType.Vector4, "Color"); |
||||
mb.addMatParam(VarType.Texture2D, "Texture"); |
||||
|
||||
mb.technique().addNode("CommonVert", "CommonVert", "jme3test/matdefs/CommonVert.vert") |
||||
.inputs( |
||||
mb.map("worldViewProjectionMatrix", UniformBinding.WorldViewProjectionMatrix), |
||||
mb.map("modelPosition", VertexBuffer.Type.Position)) |
||||
.outputs( |
||||
mb.map("result", "Global.position") |
||||
); |
||||
|
||||
mb.technique().inlineVertexNode("vec2","TexCoord", "%texIn") |
||||
.inputs( |
||||
mb.map("texIn", VertexBuffer.Type.TexCoord) |
||||
); |
||||
|
||||
mb.technique().addNode("ColorMult", "ColorMult", "jme3test/matdefs/ColorMult.frag") |
||||
.inputs( |
||||
mb.map("color1", "vec4(0.1, 0.1, 0.1, 1.0)"), |
||||
mb.map("color2", "MatParam.Color")) |
||||
.outputs( |
||||
mb.map("result", "Global.color") |
||||
); |
||||
|
||||
mb.technique().inlineFragmentNode("vec4","InlineNode","%color1 * texture2D(%tex, %texCoord)") |
||||
.inputs( |
||||
mb.map("color1", "ColorMult.result"), |
||||
mb.map("tex", "MatParam.Texture"), |
||||
mb.map("texCoord", "TexCoord.result") |
||||
).outputs( |
||||
mb.map("result", "Global.color") |
||||
); |
||||
|
||||
Material mat = mb.build(); |
||||
|
||||
//Material mat = new Material(assetManager, "jme3test/matdefs/test2.j3md");
|
||||
|
||||
mat.selectTechnique(TechniqueDef.DEFAULT_TECHNIQUE_NAME, renderManager); |
||||
Technique t = mat.getActiveTechnique(); |
||||
|
||||
for (Shader.ShaderSource shaderSource : t.getDef().getShader(assetManager, renderer.getCaps(), t.getDynamicDefines()).getSources()) { |
||||
System.out.println(shaderSource.getSource()); |
||||
} |
||||
|
||||
mat.setColor("Color", ColorRGBA.Yellow); |
||||
mat.setTexture("Texture", tex); |
||||
cube.setMaterial(mat); |
||||
cube.move(0, 0, 0); |
||||
rootNode.attachChild(cube); |
||||
|
||||
|
||||
} |
||||
} |
Loading…
Reference in new issue