ShaderNodes : UnshadedNodes now supports hardware skinning, and discard threshold

git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@10807 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
experimental
rem..om 12 years ago
parent 915638a370
commit f0aff05d41
  1. 50
      engine/src/core-data/Common/MatDefs/Misc/UnshadedNodes.j3md
  2. 18
      engine/src/core-data/Common/MatDefs/ShaderNodes/Basic/AlphaDiscard.j3sn
  3. 3
      engine/src/core-data/Common/MatDefs/ShaderNodes/Basic/alphaDiscard.frag
  4. 61
      engine/src/core-data/Common/MatDefs/ShaderNodes/HardwareSkinning/HardwareSkinning.j3sn
  5. 8
      engine/src/core-data/Common/MatDefs/ShaderNodes/HardwareSkinning/basicGpuSkinning.vert
  6. 12
      engine/src/core-data/Common/MatDefs/ShaderNodes/HardwareSkinning/fullGpuSkinning.vert
  7. 7
      engine/src/core-plugins/com/jme3/material/plugins/ShaderNodeLoaderDelegate.java
  8. 9
      engine/src/core/com/jme3/shader/ShaderNodeDefinition.java

@ -7,10 +7,13 @@ MaterialDef UnshadedNodes {
Boolean VertexColor (UseVertexColor) Boolean VertexColor (UseVertexColor)
Boolean SeparateTexCoord Boolean SeparateTexCoord
//FOG parameters // Alpha threshold for fragment discarding
Boolean UseFog Float AlphaDiscardThreshold (AlphaTestFallOff)
Float FogDensity :1
Color FogColor : 1 1 1 1 // For hardware skinning
Int NumberOfBones
Matrix4Array BoneMatrices
} }
Technique { Technique {
@ -22,13 +25,17 @@ MaterialDef UnshadedNodes {
} }
VertexShaderNodes{ VertexShaderNodes{
ShaderNode FogFactor{ ShaderNode GpuSkinning{
Definition: FogFactor : Common/MatDefs/ShaderNodes/Fog/Fog.j3sn Definition: BasicGPUSkinning : Common/MatDefs/ShaderNodes/HardwareSkinning/HardwareSkinning.j3sn
Condition: UseFog Condition : NumberOfBones
InputMapping{ InputMapping{
modelViewMatrix = WorldParam.WorldViewMatrix modelPosition = Global.position;
modelPosition = Global.position boneMatrices = MatParam.BoneMatrices
fogDensity = MatParam.FogDensity boneWeight = Attr.inHWBoneWeight
boneIndex = Attr.inHWBoneIndex
}
OutputMapping{
Global.position = modModelPosition
} }
} }
ShaderNode UnshadedVert{ ShaderNode UnshadedVert{
@ -44,8 +51,6 @@ MaterialDef UnshadedNodes {
Global.position = projPosition Global.position = projPosition
} }
} }
} }
FragmentShaderNodes{ FragmentShaderNodes{
ShaderNode UnshadedFrag{ ShaderNode UnshadedFrag{
@ -61,6 +66,15 @@ MaterialDef UnshadedNodes {
Global.outColor = color Global.outColor = color
} }
} }
ShaderNode AlphaDiscardThreshold{
Definition: AlphaDiscard : Common/MatDefs/ShaderNodes/Basic/AlphaDiscard.j3sn
Condition : AlphaDiscardThreshold
InputMapping{
alpha = Global.outColor.a
threshold = MatParam.AlphaDiscardThreshold
}
}
ShaderNode LightMap{ ShaderNode LightMap{
Definition: LightMapping : Common/MatDefs/ShaderNodes/LightMapping/LightMapping.j3sn Definition: LightMapping : Common/MatDefs/ShaderNodes/LightMapping/LightMapping.j3sn
Condition: LightMap Condition: LightMap
@ -75,18 +89,6 @@ MaterialDef UnshadedNodes {
} }
} }
ShaderNode FogOutput{
Definition: FogOutput : Common/MatDefs/ShaderNodes/Fog/Fog.j3sn
Condition: UseFog
InputMapping{
fogFactor = FogFactor.fogFactor
color = Global.outColor
fogColor = MatParam.FogColor
}
OutputMapping{
Global.outColor = color
}
}
} }
} }

@ -0,0 +1,18 @@
ShaderNodeDefinitions{
ShaderNodeDefinition AlphaDiscard {
Type: Fragment
Shader GLSL100: Common/MatDefs/ShaderNodes/Basic/alphaDiscard.frag
Documentation{
Discards the current pixel if its alpha channel value is below the given threshold
@input alpha the alpha value
@input threshold the discard threshold
}
Input {
float alpha
float threshold
}
Output {
None
}
}
}

@ -0,0 +1,3 @@
void main(){
if( alpha <= threshold )discard;
}

@ -0,0 +1,61 @@
ShaderNodesDefinitions {
ShaderNodeDefinition BasicGPUSkinning{
Type: Vertex
Shader GLSL100: Common/MatDefs/ShaderNodes/HardwareSkinning/basicGpuSkinning.vert
Documentation {
This Node is responsible for computing vertex positions transformation
of the vertex due to skinning in model space
Note that the input position and the output are both in model Space so the output
of this node will need to be translated to projection space.
This shader node doesn't take Normals and Tangent into account for full support use FullGPUSkinning
IMPORTANT NOTE : for this node to work properly, you must declare a Int NumberOfBones material parameter to which the number of bones will be passed.
@input modelPosition the vertex position in model space (usually assigned with Attr.inPosition or Global.position)
@input boneMatrices an array of matrice holding the transforms of the bones assigned to this vertex. Its size is defined by the NumberOfBones material parameter
@input boneWeight a vec4 holding the bone weights applied to this vertex (4 weights max).
@input boneIndex a vec4 holding the bone indices assignes to this vertex (4 bones max).
@output modModelPosition transformed position of the vertex in model space.
}
Input{
vec4 modelPosition
mat4 boneMatrices[NumberOfBones]
vec4 boneWeight
vec4 boneIndex
}
Output{
vec4 modModelPosition
}
}
ShaderNodeDefinition FullGPUSkinning{
Type: Vertex
Shader GLSL100: Common/MatDefs/ShaderNodes/HardwareSkinning/fullGpuSkinning.vert
Documentation {
This Node is responsible for computing vertex positions, normals and tangents transformation
of the vertex due to skinning in model space
Note that the input position and the output are both in model Space so the output
of this node will need to be translated to projection space.
IMPORTANT NOTE : for this node to work properly, you must declare a Int NumberOfBones material parameter to which the number of bones will be passed.
@input modelPosition the vertex position in model space (usually assigned with Attr.inPosition or Global.position)
@input modelNormal the vertex normal in model space (usually assigned with Attr.inNormal)
@input modelTangent the vertex tangent in model space (usually assigned with Attr.inTangent)
@input boneMatrices an array of matrice holding the transforms of the bones assigned to this vertex. Its size is defined by the NumberOfBones material parameter
@input boneWeight a vec4 holding the bone weights applied to this vertex (4 weights max).
@input boneIndex a vec4 holding the bone indices assignes to this vertex (4 bones max).
@output modModelPosition transformed position of the vertex in model space.
@output modModelNormal transformed normal of the vertex in model space.
@output modModelTangent transformed tangent of the vertex in model space.
}
Input{
vec4 modelPosition
vec3 modelNormal
vec3 modelTangent
mat4 boneMatrices[NumberOfBones]
vec4 boneWeight
vec4 boneIndex
}
Output{
vec4 modModelPosition
vec3 modModelNormal
vec3 modModelTangent
}
}
}

@ -0,0 +1,8 @@
void main(){
modModelPosition = (mat4(0.0) +
boneMatrices[int(boneIndex.x)] * boneWeight.x +
boneMatrices[int(boneIndex.y)] * boneWeight.y +
boneMatrices[int(boneIndex.z)] * boneWeight.z +
boneMatrices[int(boneIndex.w)] * boneWeight.w) * vec4(modelPosition.xyz,1.0);
}

@ -0,0 +1,12 @@
void main(){
modModelPosition = (mat4(0.0) +
boneMatrices[int(boneIndex.x)] * boneWeight.x +
boneMatrices[int(boneIndex.y)] * boneWeight.y +
boneMatrices[int(boneIndex.z)] * boneWeight.z +
boneMatrices[int(boneIndex.w)] * boneWeight.w) * modelPosition;
mat3 rotMat = mat3(mat[0].xyz, mat[1].xyz, mat[2].xyz);
modModelTangent = rotMat * modelTangent;
modModelNormal = rotMat * modelNormal;
}

@ -256,8 +256,12 @@ public class ShaderNodeLoaderDelegate {
} else if (line.startsWith("Output")) { } else if (line.startsWith("Output")) {
varNames = ""; varNames = "";
for (Statement statement1 : statement.getContents()) { for (Statement statement1 : statement.getContents()) {
if(statement1.getLine().trim().equals("None")){
shaderNodeDefinition.setNoOutput(true);
}else{
shaderNodeDefinition.getOutputs().add(readVariable(statement1)); shaderNodeDefinition.getOutputs().add(readVariable(statement1));
} }
}
} else { } else {
throw new MatParseException("one of Type, Shader, Documentation, Input, Output", split[0], statement); throw new MatParseException("one of Type, Shader, Documentation, Input, Output", split[0], statement);
} }
@ -315,6 +319,9 @@ public class ShaderNodeLoaderDelegate {
if (line.startsWith("Definition")) { if (line.startsWith("Definition")) {
ShaderNodeDefinition def = findDefinition(statement); ShaderNodeDefinition def = findDefinition(statement);
shaderNode.setDefinition(def); shaderNode.setDefinition(def);
if(def.isNoOutput()){
techniqueDef.getShaderGenerationInfo().getUnusedNodes().remove(shaderNode.getName());
}
} else if (line.startsWith("Condition")) { } else if (line.startsWith("Condition")) {
String condition = line.substring(line.lastIndexOf(":") + 1).trim(); String condition = line.substring(line.lastIndexOf(":") + 1).trim();
extractCondition(condition, statement); extractCondition(condition, statement);

@ -58,6 +58,7 @@ public class ShaderNodeDefinition implements Savable {
private List<ShaderNodeVariable> inputs = new ArrayList<ShaderNodeVariable>(); private List<ShaderNodeVariable> inputs = new ArrayList<ShaderNodeVariable>();
private List<ShaderNodeVariable> outputs = new ArrayList<ShaderNodeVariable>(); private List<ShaderNodeVariable> outputs = new ArrayList<ShaderNodeVariable>();
private String path = null; private String path = null;
private boolean noOutput = false;
/** /**
* creates a ShaderNodeDefinition * creates a ShaderNodeDefinition
@ -210,6 +211,14 @@ public class ShaderNodeDefinition implements Savable {
return shadersPath; return shadersPath;
} }
public boolean isNoOutput() {
return noOutput;
}
public void setNoOutput(boolean noOutput) {
this.noOutput = noOutput;
}
/** /**

Loading…
Cancel
Save