From f0aff05d415c23e0de08d6160fe18473d917bed4 Mon Sep 17 00:00:00 2001 From: "rem..om" Date: Sun, 29 Sep 2013 12:36:37 +0000 Subject: [PATCH] ShaderNodes : UnshadedNodes now supports hardware skinning, and discard threshold git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@10807 75d07b2b-3a1a-0410-a2c5-0572b91ccdca --- .../Common/MatDefs/Misc/UnshadedNodes.j3md | 62 ++++++++++--------- .../ShaderNodes/Basic/AlphaDiscard.j3sn | 18 ++++++ .../ShaderNodes/Basic/alphaDiscard.frag | 3 + .../HardwareSkinning/HardwareSkinning.j3sn | 61 ++++++++++++++++++ .../HardwareSkinning/basicGpuSkinning.vert | 8 +++ .../HardwareSkinning/fullGpuSkinning.vert | 12 ++++ .../plugins/ShaderNodeLoaderDelegate.java | 15 +++-- .../com/jme3/shader/ShaderNodeDefinition.java | 9 +++ 8 files changed, 154 insertions(+), 34 deletions(-) create mode 100644 engine/src/core-data/Common/MatDefs/ShaderNodes/Basic/AlphaDiscard.j3sn create mode 100644 engine/src/core-data/Common/MatDefs/ShaderNodes/Basic/alphaDiscard.frag create mode 100644 engine/src/core-data/Common/MatDefs/ShaderNodes/HardwareSkinning/HardwareSkinning.j3sn create mode 100644 engine/src/core-data/Common/MatDefs/ShaderNodes/HardwareSkinning/basicGpuSkinning.vert create mode 100644 engine/src/core-data/Common/MatDefs/ShaderNodes/HardwareSkinning/fullGpuSkinning.vert diff --git a/engine/src/core-data/Common/MatDefs/Misc/UnshadedNodes.j3md b/engine/src/core-data/Common/MatDefs/Misc/UnshadedNodes.j3md index 8785ed968..f9fb05288 100644 --- a/engine/src/core-data/Common/MatDefs/Misc/UnshadedNodes.j3md +++ b/engine/src/core-data/Common/MatDefs/Misc/UnshadedNodes.j3md @@ -6,11 +6,14 @@ MaterialDef UnshadedNodes { Color Color (Color) Boolean VertexColor (UseVertexColor) Boolean SeparateTexCoord - - //FOG parameters - Boolean UseFog - Float FogDensity :1 - Color FogColor : 1 1 1 1 + + // Alpha threshold for fragment discarding + Float AlphaDiscardThreshold (AlphaTestFallOff) + + // For hardware skinning + Int NumberOfBones + Matrix4Array BoneMatrices + } Technique { @@ -21,16 +24,20 @@ MaterialDef UnshadedNodes { WorldViewMatrix } - VertexShaderNodes{ - ShaderNode FogFactor{ - Definition: FogFactor : Common/MatDefs/ShaderNodes/Fog/Fog.j3sn - Condition: UseFog - InputMapping{ - modelViewMatrix = WorldParam.WorldViewMatrix - modelPosition = Global.position - fogDensity = MatParam.FogDensity - } - } + VertexShaderNodes{ + ShaderNode GpuSkinning{ + Definition: BasicGPUSkinning : Common/MatDefs/ShaderNodes/HardwareSkinning/HardwareSkinning.j3sn + Condition : NumberOfBones + InputMapping{ + modelPosition = Global.position; + boneMatrices = MatParam.BoneMatrices + boneWeight = Attr.inHWBoneWeight + boneIndex = Attr.inHWBoneIndex + } + OutputMapping{ + Global.position = modModelPosition + } + } ShaderNode UnshadedVert{ Definition: CommonVert : Common/MatDefs/ShaderNodes/Common/CommonVert.j3sn InputMapping{ @@ -44,8 +51,6 @@ MaterialDef UnshadedNodes { Global.position = projPosition } } - - } FragmentShaderNodes{ ShaderNode UnshadedFrag{ @@ -61,6 +66,15 @@ MaterialDef UnshadedNodes { 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{ Definition: LightMapping : Common/MatDefs/ShaderNodes/LightMapping/LightMapping.j3sn Condition: LightMap @@ -74,19 +88,7 @@ MaterialDef UnshadedNodes { Global.outColor = color } } - - 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 - } - } + } } diff --git a/engine/src/core-data/Common/MatDefs/ShaderNodes/Basic/AlphaDiscard.j3sn b/engine/src/core-data/Common/MatDefs/ShaderNodes/Basic/AlphaDiscard.j3sn new file mode 100644 index 000000000..00b30aa92 --- /dev/null +++ b/engine/src/core-data/Common/MatDefs/ShaderNodes/Basic/AlphaDiscard.j3sn @@ -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 + } + } +} \ No newline at end of file diff --git a/engine/src/core-data/Common/MatDefs/ShaderNodes/Basic/alphaDiscard.frag b/engine/src/core-data/Common/MatDefs/ShaderNodes/Basic/alphaDiscard.frag new file mode 100644 index 000000000..7a1c8c701 --- /dev/null +++ b/engine/src/core-data/Common/MatDefs/ShaderNodes/Basic/alphaDiscard.frag @@ -0,0 +1,3 @@ +void main(){ + if( alpha <= threshold )discard; +} \ No newline at end of file diff --git a/engine/src/core-data/Common/MatDefs/ShaderNodes/HardwareSkinning/HardwareSkinning.j3sn b/engine/src/core-data/Common/MatDefs/ShaderNodes/HardwareSkinning/HardwareSkinning.j3sn new file mode 100644 index 000000000..2b734b5c8 --- /dev/null +++ b/engine/src/core-data/Common/MatDefs/ShaderNodes/HardwareSkinning/HardwareSkinning.j3sn @@ -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 + } + } +} \ No newline at end of file diff --git a/engine/src/core-data/Common/MatDefs/ShaderNodes/HardwareSkinning/basicGpuSkinning.vert b/engine/src/core-data/Common/MatDefs/ShaderNodes/HardwareSkinning/basicGpuSkinning.vert new file mode 100644 index 000000000..4c153e27f --- /dev/null +++ b/engine/src/core-data/Common/MatDefs/ShaderNodes/HardwareSkinning/basicGpuSkinning.vert @@ -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); +} \ No newline at end of file diff --git a/engine/src/core-data/Common/MatDefs/ShaderNodes/HardwareSkinning/fullGpuSkinning.vert b/engine/src/core-data/Common/MatDefs/ShaderNodes/HardwareSkinning/fullGpuSkinning.vert new file mode 100644 index 000000000..49f8a659e --- /dev/null +++ b/engine/src/core-data/Common/MatDefs/ShaderNodes/HardwareSkinning/fullGpuSkinning.vert @@ -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; +} \ No newline at end of file diff --git a/engine/src/core-plugins/com/jme3/material/plugins/ShaderNodeLoaderDelegate.java b/engine/src/core-plugins/com/jme3/material/plugins/ShaderNodeLoaderDelegate.java index 81f579bd6..d738b39db 100644 --- a/engine/src/core-plugins/com/jme3/material/plugins/ShaderNodeLoaderDelegate.java +++ b/engine/src/core-plugins/com/jme3/material/plugins/ShaderNodeLoaderDelegate.java @@ -256,7 +256,11 @@ public class ShaderNodeLoaderDelegate { } else if (line.startsWith("Output")) { varNames = ""; for (Statement statement1 : statement.getContents()) { - shaderNodeDefinition.getOutputs().add(readVariable(statement1)); + if(statement1.getLine().trim().equals("None")){ + shaderNodeDefinition.setNoOutput(true); + }else{ + shaderNodeDefinition.getOutputs().add(readVariable(statement1)); + } } } else { throw new MatParseException("one of Type, Shader, Documentation, Input, Output", split[0], statement); @@ -314,7 +318,10 @@ public class ShaderNodeLoaderDelegate { String[] split = statement.getLine().split("[ \\{]"); if (line.startsWith("Definition")) { ShaderNodeDefinition def = findDefinition(statement); - shaderNode.setDefinition(def); + shaderNode.setDefinition(def); + if(def.isNoOutput()){ + techniqueDef.getShaderGenerationInfo().getUnusedNodes().remove(shaderNode.getName()); + } } else if (line.startsWith("Condition")) { String condition = line.substring(line.lastIndexOf(":") + 1).trim(); extractCondition(condition, statement); @@ -325,12 +332,12 @@ public class ShaderNodeLoaderDelegate { techniqueDef.getShaderGenerationInfo().getUnusedNodes().remove(mapping.getRightVariable().getNameSpace()); shaderNode.getInputMapping().add(mapping); } - } else if (line.startsWith("OutputMapping")) { + } else if (line.startsWith("OutputMapping")) { for (Statement statement1 : statement.getContents()) { VariableMapping mapping = readOutputMapping(statement1); techniqueDef.getShaderGenerationInfo().getUnusedNodes().remove(shaderNode.getName()); shaderNode.getOutputMapping().add(mapping); - } + } } else { throw new MatParseException("ShaderNodeDefinition", split[0], statement); } diff --git a/engine/src/core/com/jme3/shader/ShaderNodeDefinition.java b/engine/src/core/com/jme3/shader/ShaderNodeDefinition.java index 46b5eeb71..c8c7089ad 100644 --- a/engine/src/core/com/jme3/shader/ShaderNodeDefinition.java +++ b/engine/src/core/com/jme3/shader/ShaderNodeDefinition.java @@ -58,6 +58,7 @@ public class ShaderNodeDefinition implements Savable { private List inputs = new ArrayList(); private List outputs = new ArrayList(); private String path = null; + private boolean noOutput = false; /** * creates a ShaderNodeDefinition @@ -210,6 +211,14 @@ public class ShaderNodeDefinition implements Savable { return shadersPath; } + public boolean isNoOutput() { + return noOutput; + } + + public void setNoOutput(boolean noOutput) { + this.noOutput = noOutput; + } + /**