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>
|
#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[] = {
|
const UInt8 r_viewerDataModule[] = {
|
||||||
#include <Nazara/Graphics/Resources/Shaders/Modules/Engine/ViewerData.nzslb.h>
|
#include <Nazara/Graphics/Resources/Shaders/Modules/Engine/ViewerData.nzslb.h>
|
||||||
};
|
};
|
||||||
|
|
@ -321,6 +329,8 @@ namespace Nz
|
||||||
RegisterEmbedShaderModule(r_mathCookTorrancePBRModule);
|
RegisterEmbedShaderModule(r_mathCookTorrancePBRModule);
|
||||||
RegisterEmbedShaderModule(r_phongMaterialShader);
|
RegisterEmbedShaderModule(r_phongMaterialShader);
|
||||||
RegisterEmbedShaderModule(r_physicallyBasedMaterialShader);
|
RegisterEmbedShaderModule(r_physicallyBasedMaterialShader);
|
||||||
|
RegisterEmbedShaderModule(r_skinningDataModule);
|
||||||
|
RegisterEmbedShaderModule(r_skinningLinearModule);
|
||||||
RegisterEmbedShaderModule(r_skeletalDataModule);
|
RegisterEmbedShaderModule(r_skeletalDataModule);
|
||||||
RegisterEmbedShaderModule(r_textureBlitShader);
|
RegisterEmbedShaderModule(r_textureBlitShader);
|
||||||
RegisterEmbedShaderModule(r_viewerDataModule);
|
RegisterEmbedShaderModule(r_viewerDataModule);
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ module BasicMaterial;
|
||||||
import InstanceData from Engine.InstanceData;
|
import InstanceData from Engine.InstanceData;
|
||||||
import SkeletalData from Engine.SkeletalData;
|
import SkeletalData from Engine.SkeletalData;
|
||||||
import ViewerData from Engine.ViewerData;
|
import ViewerData from Engine.ViewerData;
|
||||||
|
import SkinLinearPosition from Engine.SkinningLinear;
|
||||||
|
|
||||||
// Pass-specific options
|
// Pass-specific options
|
||||||
option DepthPass: bool = false;
|
option DepthPass: bool = false;
|
||||||
|
|
@ -175,23 +176,24 @@ fn billboardMain(input: VertIn) -> VertOut
|
||||||
fn main(input: VertIn) -> VertOut
|
fn main(input: VertIn) -> VertOut
|
||||||
{
|
{
|
||||||
let pos: vec3[f32];
|
let pos: vec3[f32];
|
||||||
|
|
||||||
const if (HasSkinning)
|
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]
|
let skinningOutput = SkinLinearPosition(jointMatrices, input.jointWeights, input.pos);
|
||||||
for i in 0 -> 4
|
pos = skinningOutput.position;
|
||||||
{
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
pos = input.pos;
|
pos = input.pos;
|
||||||
|
|
||||||
|
let worldPosition = instanceData.worldMatrix * vec4[f32](pos, 1.0);
|
||||||
|
|
||||||
let output: VertOut;
|
let output: VertOut;
|
||||||
output.position = viewerData.viewProjMatrix * instanceData.worldMatrix * vec4[f32](pos, 1.0);
|
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)]
|
[layout(std140)]
|
||||||
struct SkeletalData
|
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 SkeletalData from Engine.SkeletalData;
|
||||||
import ViewerData from Engine.ViewerData;
|
import ViewerData from Engine.ViewerData;
|
||||||
|
|
||||||
|
import SkinLinearPosition, SkinLinearPositionNormal from Engine.SkinningLinear;
|
||||||
|
|
||||||
// Pass-specific options
|
// Pass-specific options
|
||||||
option DepthPass: bool = false;
|
option DepthPass: bool = false;
|
||||||
|
|
||||||
|
|
@ -33,13 +35,16 @@ option VertexPositionLoc: i32;
|
||||||
option VertexTangentLoc: i32 = -1;
|
option VertexTangentLoc: i32 = -1;
|
||||||
option VertexUvLoc: i32 = -1;
|
option VertexUvLoc: i32 = -1;
|
||||||
|
|
||||||
|
option VertexJointIndicesLoc: i32 = -1;
|
||||||
|
option VertexJointWeightsLoc: i32 = -1;
|
||||||
|
|
||||||
const HasNormal = (VertexNormalLoc >= 0);
|
const HasNormal = (VertexNormalLoc >= 0);
|
||||||
const HasVertexColor = (VertexColorLoc >= 0);
|
const HasVertexColor = (VertexColorLoc >= 0);
|
||||||
const HasColor = (HasVertexColor || Billboard);
|
const HasColor = (HasVertexColor || Billboard);
|
||||||
const HasTangent = (VertexTangentLoc >= 0);
|
const HasTangent = (VertexTangentLoc >= 0);
|
||||||
const HasUV = (VertexUvLoc >= 0);
|
const HasUV = (VertexUvLoc >= 0);
|
||||||
const HasNormalMapping = HasNormalTexture && HasNormal && HasTangent && !DepthPass;
|
const HasNormalMapping = HasNormalTexture && HasNormal && HasTangent && !DepthPass;
|
||||||
|
const HasSkinning = (VertexJointIndicesLoc >= 0 && VertexJointWeightsLoc >= 0);
|
||||||
|
|
||||||
[layout(std140)]
|
[layout(std140)]
|
||||||
struct MaterialSettings
|
struct MaterialSettings
|
||||||
|
|
@ -272,6 +277,12 @@ struct VertIn
|
||||||
[cond(HasTangent), location(VertexTangentLoc)]
|
[cond(HasTangent), location(VertexTangentLoc)]
|
||||||
tangent: vec3[f32],
|
tangent: vec3[f32],
|
||||||
|
|
||||||
|
[cond(HasSkinning), location(VertexJointIndicesLoc)]
|
||||||
|
jointIndices: vec4[i32],
|
||||||
|
|
||||||
|
[cond(HasSkinning), location(VertexJointWeightsLoc)]
|
||||||
|
jointWeights: vec4[f32],
|
||||||
|
|
||||||
[cond(Billboard), location(BillboardCenterLocation)]
|
[cond(Billboard), location(BillboardCenterLocation)]
|
||||||
billboardCenter: vec3[f32],
|
billboardCenter: vec3[f32],
|
||||||
|
|
||||||
|
|
@ -316,7 +327,38 @@ fn billboardMain(input: VertIn) -> VertToFrag
|
||||||
[entry(vert), cond(!Billboard)]
|
[entry(vert), cond(!Billboard)]
|
||||||
fn main(input: VertIn) -> VertToFrag
|
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;
|
let output: VertToFrag;
|
||||||
output.worldPos = worldPosition.xyz;
|
output.worldPos = worldPosition.xyz;
|
||||||
|
|
@ -328,7 +370,7 @@ fn main(input: VertIn) -> VertToFrag
|
||||||
output.color = input.color;
|
output.color = input.color;
|
||||||
|
|
||||||
const if (HasNormal)
|
const if (HasNormal)
|
||||||
output.normal = rotationMatrix * input.normal;
|
output.normal = rotationMatrix * normal;
|
||||||
|
|
||||||
const if (HasUV)
|
const if (HasUV)
|
||||||
output.uv = input.uv;
|
output.uv = input.uv;
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,8 @@ import LightData from Engine.LightData;
|
||||||
import SkeletalData from Engine.SkeletalData;
|
import SkeletalData from Engine.SkeletalData;
|
||||||
import ViewerData from Engine.ViewerData;
|
import ViewerData from Engine.ViewerData;
|
||||||
|
|
||||||
|
import SkinLinearPosition, SkinLinearPositionNormal from Engine.SkinningLinear;
|
||||||
|
|
||||||
// Pass-specific options
|
// Pass-specific options
|
||||||
option DepthPass: bool = false;
|
option DepthPass: bool = false;
|
||||||
|
|
||||||
|
|
@ -35,12 +37,16 @@ option VertexPositionLoc: i32;
|
||||||
option VertexTangentLoc: i32 = -1;
|
option VertexTangentLoc: i32 = -1;
|
||||||
option VertexUvLoc: i32 = -1;
|
option VertexUvLoc: i32 = -1;
|
||||||
|
|
||||||
|
option VertexJointIndicesLoc: i32 = -1;
|
||||||
|
option VertexJointWeightsLoc: i32 = -1;
|
||||||
|
|
||||||
const HasNormal = (VertexNormalLoc >= 0);
|
const HasNormal = (VertexNormalLoc >= 0);
|
||||||
const HasVertexColor = (VertexColorLoc >= 0);
|
const HasVertexColor = (VertexColorLoc >= 0);
|
||||||
const HasColor = (HasVertexColor || Billboard);
|
const HasColor = (HasVertexColor || Billboard);
|
||||||
const HasTangent = (VertexTangentLoc >= 0);
|
const HasTangent = (VertexTangentLoc >= 0);
|
||||||
const HasUV = (VertexUvLoc >= 0);
|
const HasUV = (VertexUvLoc >= 0);
|
||||||
const HasNormalMapping = HasNormalTexture && HasNormal && HasTangent && !DepthPass;
|
const HasNormalMapping = HasNormalTexture && HasNormal && HasTangent && !DepthPass;
|
||||||
|
const HasSkinning = (VertexJointIndicesLoc >= 0 && VertexJointWeightsLoc >= 0);
|
||||||
|
|
||||||
[layout(std140)]
|
[layout(std140)]
|
||||||
struct MaterialSettings
|
struct MaterialSettings
|
||||||
|
|
@ -260,6 +266,12 @@ struct VertIn
|
||||||
[cond(HasTangent), location(VertexTangentLoc)]
|
[cond(HasTangent), location(VertexTangentLoc)]
|
||||||
tangent: vec3[f32],
|
tangent: vec3[f32],
|
||||||
|
|
||||||
|
[cond(HasSkinning), location(VertexJointIndicesLoc)]
|
||||||
|
jointIndices: vec4[i32],
|
||||||
|
|
||||||
|
[cond(HasSkinning), location(VertexJointWeightsLoc)]
|
||||||
|
jointWeights: vec4[f32],
|
||||||
|
|
||||||
[cond(Billboard), location(BillboardCenterLocation)]
|
[cond(Billboard), location(BillboardCenterLocation)]
|
||||||
billboardCenter: vec3[f32],
|
billboardCenter: vec3[f32],
|
||||||
|
|
||||||
|
|
@ -304,7 +316,38 @@ fn billboardMain(input: VertIn) -> VertToFrag
|
||||||
[entry(vert), cond(!Billboard)]
|
[entry(vert), cond(!Billboard)]
|
||||||
fn main(input: VertIn) -> VertToFrag
|
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;
|
let output: VertToFrag;
|
||||||
output.worldPos = worldPosition.xyz;
|
output.worldPos = worldPosition.xyz;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue