Graphics: Move skinning to a separate module
This commit is contained in:
parent
1205155466
commit
5502e51d71
|
|
@ -53,6 +53,14 @@ namespace Nz
|
|||
#include <Nazara/Graphics/Resources/Shaders/Modules/Engine/SkeletalData.nzslb.h>
|
||||
};
|
||||
|
||||
const UInt8 r_skinningDataModule[] = {
|
||||
#include <Nazara/Graphics/Resources/Shaders/Modules/Engine/SkinningData.nzslb.h>
|
||||
};
|
||||
|
||||
const UInt8 r_skinningLinearModule[] = {
|
||||
#include <Nazara/Graphics/Resources/Shaders/Modules/Engine/SkinningLinear.nzslb.h>
|
||||
};
|
||||
|
||||
const UInt8 r_viewerDataModule[] = {
|
||||
#include <Nazara/Graphics/Resources/Shaders/Modules/Engine/ViewerData.nzslb.h>
|
||||
};
|
||||
|
|
@ -321,6 +329,8 @@ namespace Nz
|
|||
RegisterEmbedShaderModule(r_mathCookTorrancePBRModule);
|
||||
RegisterEmbedShaderModule(r_phongMaterialShader);
|
||||
RegisterEmbedShaderModule(r_physicallyBasedMaterialShader);
|
||||
RegisterEmbedShaderModule(r_skinningDataModule);
|
||||
RegisterEmbedShaderModule(r_skinningLinearModule);
|
||||
RegisterEmbedShaderModule(r_skeletalDataModule);
|
||||
RegisterEmbedShaderModule(r_textureBlitShader);
|
||||
RegisterEmbedShaderModule(r_viewerDataModule);
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ module BasicMaterial;
|
|||
import InstanceData from Engine.InstanceData;
|
||||
import SkeletalData from Engine.SkeletalData;
|
||||
import ViewerData from Engine.ViewerData;
|
||||
import SkinLinearPosition from Engine.SkinningLinear;
|
||||
|
||||
// Pass-specific options
|
||||
option DepthPass: bool = false;
|
||||
|
|
@ -175,23 +176,24 @@ fn billboardMain(input: VertIn) -> VertOut
|
|||
fn main(input: VertIn) -> VertOut
|
||||
{
|
||||
let pos: vec3[f32];
|
||||
|
||||
const if (HasSkinning)
|
||||
{
|
||||
pos = vec3[f32](0.0, 0.0, 0.0);
|
||||
let jointMatrices = array[mat4[f32]](
|
||||
skeletalData.jointMatrices[input.jointIndices[0]],
|
||||
skeletalData.jointMatrices[input.jointIndices[1]],
|
||||
skeletalData.jointMatrices[input.jointIndices[2]],
|
||||
skeletalData.jointMatrices[input.jointIndices[3]]
|
||||
);
|
||||
|
||||
[unroll]
|
||||
for i in 0 -> 4
|
||||
{
|
||||
let jointIndex = input.jointIndices[i];
|
||||
let jointWeight = input.jointWeights[i];
|
||||
|
||||
let jointMatrix = skeletalData.JointMatrices[jointIndex];
|
||||
pos += (jointMatrix * vec4[f32](input.pos, 1.0)).xyz * jointWeight;
|
||||
}
|
||||
let skinningOutput = SkinLinearPosition(jointMatrices, input.jointWeights, input.pos);
|
||||
pos = skinningOutput.position;
|
||||
}
|
||||
else
|
||||
pos = input.pos;
|
||||
|
||||
let worldPosition = instanceData.worldMatrix * vec4[f32](pos, 1.0);
|
||||
|
||||
let output: VertOut;
|
||||
output.position = viewerData.viewProjMatrix * instanceData.worldMatrix * vec4[f32](pos, 1.0);
|
||||
|
||||
|
|
|
|||
|
|
@ -9,5 +9,5 @@ const MaxJointCount: u32 = u32(256); //< FIXME: Fix integral value types
|
|||
[layout(std140)]
|
||||
struct SkeletalData
|
||||
{
|
||||
JointMatrices: array[mat4[f32], MaxJointCount]
|
||||
jointMatrices: array[mat4[f32], MaxJointCount]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,23 @@
|
|||
[nzsl_version("1.0")]
|
||||
module Engine.SkinningData;
|
||||
|
||||
[export]
|
||||
struct SkinPositionOutput
|
||||
{
|
||||
position: vec3[f32]
|
||||
}
|
||||
|
||||
[export]
|
||||
struct SkinPositionNormalOutput
|
||||
{
|
||||
position: vec3[f32],
|
||||
normal: vec3[f32]
|
||||
}
|
||||
|
||||
[export]
|
||||
struct SkinPositionNormalTangentOutput
|
||||
{
|
||||
position: vec3[f32],
|
||||
normal: vec3[f32],
|
||||
tangent: vec3[f32]
|
||||
}
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
[nzsl_version("1.0")]
|
||||
module Engine.SkinningLinear;
|
||||
|
||||
import * from Engine.SkinningData;
|
||||
|
||||
[export]
|
||||
fn SkinLinearPosition(jointMatrices: array[mat4[f32], 4], jointWeights: vec4[f32], position: vec3[f32]) -> SkinPositionOutput
|
||||
{
|
||||
let skinMatrix = mat4[f32](0.0);
|
||||
|
||||
[unroll]
|
||||
for i in 0 -> 4
|
||||
skinMatrix += jointMatrices[i] * jointWeights[i];
|
||||
|
||||
let output: SkinPositionOutput;
|
||||
output.position = (skinMatrix * vec4[f32](position, 1.0)).xyz;
|
||||
return output;
|
||||
}
|
||||
|
||||
[export]
|
||||
fn SkinLinearPositionNormal(jointMatrices: array[mat4[f32], 4], jointWeights: vec4[f32], position: vec3[f32], normal: vec3[f32]) -> SkinPositionNormalOutput
|
||||
{
|
||||
let skinMatrix = mat4[f32](0.0);
|
||||
|
||||
[unroll]
|
||||
for i in 0 -> 4
|
||||
skinMatrix += jointMatrices[i] * jointWeights[i];
|
||||
|
||||
let inverseTransposeSkinMatrix = transpose(inverse(mat3[f32](skinMatrix)));
|
||||
|
||||
let output: SkinPositionNormalOutput;
|
||||
output.position = (skinMatrix * vec4[f32](position, 1.0)).xyz;
|
||||
output.normal = inverseTransposeSkinMatrix * normal;
|
||||
return output;
|
||||
}
|
||||
|
|
@ -6,6 +6,8 @@ import LightData from Engine.LightData;
|
|||
import SkeletalData from Engine.SkeletalData;
|
||||
import ViewerData from Engine.ViewerData;
|
||||
|
||||
import SkinLinearPosition, SkinLinearPositionNormal from Engine.SkinningLinear;
|
||||
|
||||
// Pass-specific options
|
||||
option DepthPass: bool = false;
|
||||
|
||||
|
|
@ -33,13 +35,16 @@ option VertexPositionLoc: i32;
|
|||
option VertexTangentLoc: i32 = -1;
|
||||
option VertexUvLoc: i32 = -1;
|
||||
|
||||
option VertexJointIndicesLoc: i32 = -1;
|
||||
option VertexJointWeightsLoc: i32 = -1;
|
||||
|
||||
const HasNormal = (VertexNormalLoc >= 0);
|
||||
const HasVertexColor = (VertexColorLoc >= 0);
|
||||
const HasColor = (HasVertexColor || Billboard);
|
||||
const HasTangent = (VertexTangentLoc >= 0);
|
||||
const HasUV = (VertexUvLoc >= 0);
|
||||
const HasNormalMapping = HasNormalTexture && HasNormal && HasTangent && !DepthPass;
|
||||
|
||||
const HasSkinning = (VertexJointIndicesLoc >= 0 && VertexJointWeightsLoc >= 0);
|
||||
|
||||
[layout(std140)]
|
||||
struct MaterialSettings
|
||||
|
|
@ -272,6 +277,12 @@ struct VertIn
|
|||
[cond(HasTangent), location(VertexTangentLoc)]
|
||||
tangent: vec3[f32],
|
||||
|
||||
[cond(HasSkinning), location(VertexJointIndicesLoc)]
|
||||
jointIndices: vec4[i32],
|
||||
|
||||
[cond(HasSkinning), location(VertexJointWeightsLoc)]
|
||||
jointWeights: vec4[f32],
|
||||
|
||||
[cond(Billboard), location(BillboardCenterLocation)]
|
||||
billboardCenter: vec3[f32],
|
||||
|
||||
|
|
@ -316,7 +327,38 @@ fn billboardMain(input: VertIn) -> VertToFrag
|
|||
[entry(vert), cond(!Billboard)]
|
||||
fn main(input: VertIn) -> VertToFrag
|
||||
{
|
||||
let worldPosition = instanceData.worldMatrix * vec4[f32](input.pos, 1.0);
|
||||
let pos: vec3[f32];
|
||||
const if (HasNormal) let normal: vec3[f32];
|
||||
|
||||
const if (HasSkinning)
|
||||
{
|
||||
let jointMatrices = array[mat4[f32]](
|
||||
skeletalData.jointMatrices[input.jointIndices[0]],
|
||||
skeletalData.jointMatrices[input.jointIndices[1]],
|
||||
skeletalData.jointMatrices[input.jointIndices[2]],
|
||||
skeletalData.jointMatrices[input.jointIndices[3]]
|
||||
);
|
||||
|
||||
const if (HasNormal)
|
||||
{
|
||||
let skinningOutput = SkinLinearPositionNormal(jointMatrices, input.jointWeights, input.pos, input.normal);
|
||||
pos = skinningOutput.position;
|
||||
normal = skinningOutput.normal;
|
||||
}
|
||||
else
|
||||
{
|
||||
let skinningOutput = SkinLinearPosition(jointMatrices, input.jointWeights, input.pos);
|
||||
pos = skinningOutput.position;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pos = input.pos;
|
||||
const if (HasNormal)
|
||||
normal = input.normal;
|
||||
}
|
||||
|
||||
let worldPosition = instanceData.worldMatrix * vec4[f32](pos, 1.0);
|
||||
|
||||
let output: VertToFrag;
|
||||
output.worldPos = worldPosition.xyz;
|
||||
|
|
@ -328,7 +370,7 @@ fn main(input: VertIn) -> VertToFrag
|
|||
output.color = input.color;
|
||||
|
||||
const if (HasNormal)
|
||||
output.normal = rotationMatrix * input.normal;
|
||||
output.normal = rotationMatrix * normal;
|
||||
|
||||
const if (HasUV)
|
||||
output.uv = input.uv;
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@ import LightData from Engine.LightData;
|
|||
import SkeletalData from Engine.SkeletalData;
|
||||
import ViewerData from Engine.ViewerData;
|
||||
|
||||
import SkinLinearPosition, SkinLinearPositionNormal from Engine.SkinningLinear;
|
||||
|
||||
// Pass-specific options
|
||||
option DepthPass: bool = false;
|
||||
|
||||
|
|
@ -35,12 +37,16 @@ option VertexPositionLoc: i32;
|
|||
option VertexTangentLoc: i32 = -1;
|
||||
option VertexUvLoc: i32 = -1;
|
||||
|
||||
option VertexJointIndicesLoc: i32 = -1;
|
||||
option VertexJointWeightsLoc: i32 = -1;
|
||||
|
||||
const HasNormal = (VertexNormalLoc >= 0);
|
||||
const HasVertexColor = (VertexColorLoc >= 0);
|
||||
const HasColor = (HasVertexColor || Billboard);
|
||||
const HasTangent = (VertexTangentLoc >= 0);
|
||||
const HasUV = (VertexUvLoc >= 0);
|
||||
const HasNormalMapping = HasNormalTexture && HasNormal && HasTangent && !DepthPass;
|
||||
const HasSkinning = (VertexJointIndicesLoc >= 0 && VertexJointWeightsLoc >= 0);
|
||||
|
||||
[layout(std140)]
|
||||
struct MaterialSettings
|
||||
|
|
@ -260,6 +266,12 @@ struct VertIn
|
|||
[cond(HasTangent), location(VertexTangentLoc)]
|
||||
tangent: vec3[f32],
|
||||
|
||||
[cond(HasSkinning), location(VertexJointIndicesLoc)]
|
||||
jointIndices: vec4[i32],
|
||||
|
||||
[cond(HasSkinning), location(VertexJointWeightsLoc)]
|
||||
jointWeights: vec4[f32],
|
||||
|
||||
[cond(Billboard), location(BillboardCenterLocation)]
|
||||
billboardCenter: vec3[f32],
|
||||
|
||||
|
|
@ -304,7 +316,38 @@ fn billboardMain(input: VertIn) -> VertToFrag
|
|||
[entry(vert), cond(!Billboard)]
|
||||
fn main(input: VertIn) -> VertToFrag
|
||||
{
|
||||
let worldPosition = instanceData.worldMatrix * vec4[f32](input.pos, 1.0);
|
||||
let pos: vec3[f32];
|
||||
const if (HasNormal) let normal: vec3[f32];
|
||||
|
||||
const if (HasSkinning)
|
||||
{
|
||||
let jointMatrices = array[mat4[f32]](
|
||||
skeletalData.jointMatrices[input.jointIndices[0]],
|
||||
skeletalData.jointMatrices[input.jointIndices[1]],
|
||||
skeletalData.jointMatrices[input.jointIndices[2]],
|
||||
skeletalData.jointMatrices[input.jointIndices[3]]
|
||||
);
|
||||
|
||||
const if (HasNormal)
|
||||
{
|
||||
let skinningOutput = SkinLinearPositionNormal(jointMatrices, input.jointWeights, input.pos, input.normal);
|
||||
pos = skinningOutput.position;
|
||||
normal = skinningOutput.normal;
|
||||
}
|
||||
else
|
||||
{
|
||||
let skinningOutput = SkinLinearPosition(jointMatrices, input.jointWeights, input.pos);
|
||||
pos = skinningOutput.position;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pos = input.pos;
|
||||
const if (HasNormal)
|
||||
normal = input.normal;
|
||||
}
|
||||
|
||||
let worldPosition = instanceData.worldMatrix * vec4[f32](pos, 1.0);
|
||||
|
||||
let output: VertToFrag;
|
||||
output.worldPos = worldPosition.xyz;
|
||||
|
|
|
|||
Loading…
Reference in New Issue