From 6be0d5cb30d8f8e81aa931edda5fa314ef7996fc Mon Sep 17 00:00:00 2001 From: dexy Date: Sun, 3 Nov 2019 22:43:39 +1100 Subject: [PATCH] Skin mesh now using correct bone transforms --- .../GameFiles/Resources/Drawable.cs | 56 +++++--- Rendering/Renderable.cs | 68 +++++----- Rendering/Renderer.cs | 52 ++++--- Rendering/Shaders/BasicShader.cs | 31 ++++- Rendering/Shaders/ShadowShader.cs | 81 +++++++++-- Shaders/CodeWalkerShaders.vcxproj | 10 ++ Shaders/CodeWalkerShaders.vcxproj.filters | 1 + Shaders/ShadowVS_Skin.cso | Bin 0 -> 3580 bytes Shaders/ShadowVS_Skin.hlsl | 127 ++++++++++++++++++ 9 files changed, 342 insertions(+), 84 deletions(-) create mode 100644 Shaders/ShadowVS_Skin.cso create mode 100644 Shaders/ShadowVS_Skin.hlsl diff --git a/CodeWalker.Core/GameFiles/Resources/Drawable.cs b/CodeWalker.Core/GameFiles/Resources/Drawable.cs index 11ebd0e..a3dca40 100644 --- a/CodeWalker.Core/GameFiles/Resources/Drawable.cs +++ b/CodeWalker.Core/GameFiles/Resources/Drawable.cs @@ -622,6 +622,11 @@ namespace CodeWalker.GameFiles { var bone = Bones[i]; BonesMap[bone.Id] = bone; + + bone.BindTransformInv = (i < TransformationsInverted?.Length) ? TransformationsInverted[i] : Matrix.Invert(bone.AnimTransform); + bone.BindTransformInv.M44 = 1.0f; + + bone.UpdateAnimTransform(); } } @@ -776,9 +781,7 @@ namespace CodeWalker.GameFiles public Quaternion Rotation { get; set; } public Vector3 Translation { get; set; } public uint Unknown_1Ch { get; set; } // 0x00000000 RHW? - public float ScaleX { get; set; } // 1.0 - public float ScaleY { get; set; } // 1.0 - public float ScaleZ { get; set; } // 1.0 + public Vector3 Scale { get; set; } public float Unknown_2Ch { get; set; } // 1.0 RHW? public ushort NextSiblingIndex { get; set; } //limb end index? IK chain? public short ParentIndex { get; set; } @@ -800,10 +803,12 @@ namespace CodeWalker.GameFiles //used by CW for animating skeletons. - public Quaternion AnimRotation; - public Vector3 AnimTranslation; - public Matrix AnimTransform; - + public Quaternion AnimRotation;//relative to parent + public Vector3 AnimTranslation;//relative to parent + public Vector3 AnimScale; + public Matrix AnimTransform;//absolute world transform, animated + public Matrix BindTransformInv;//inverse of bind pose transform + public Matrix SkinTransform;//transform to use for skin meshes /// /// Reads the data-block from a stream. @@ -811,19 +816,10 @@ namespace CodeWalker.GameFiles public override void Read(ResourceDataReader reader, params object[] parameters) { // read structure data - //this.RotationX = reader.ReadSingle(); - //this.RotationY = reader.ReadSingle(); - //this.RotationZ = reader.ReadSingle(); - //this.RotationW = reader.ReadSingle(); this.Rotation = new Quaternion(reader.ReadVector4()); this.Translation = reader.ReadVector3(); - //this.TranslationX = reader.ReadSingle(); - //this.TranslationY = reader.ReadSingle(); - //this.TranslationZ = reader.ReadSingle(); this.Unknown_1Ch = reader.ReadUInt32(); - this.ScaleX = reader.ReadSingle(); - this.ScaleY = reader.ReadSingle(); - this.ScaleZ = reader.ReadSingle(); + this.Scale = reader.ReadVector3(); this.Unknown_2Ch = reader.ReadSingle(); this.NextSiblingIndex = reader.ReadUInt16(); this.ParentIndex = reader.ReadInt16(); @@ -844,7 +840,7 @@ namespace CodeWalker.GameFiles AnimRotation = Rotation; AnimTranslation = Translation; - AnimTransform = Matrix.AffineTransformation(1.0f, AnimRotation, AnimTranslation); + AnimScale = Scale; } /// @@ -859,9 +855,7 @@ namespace CodeWalker.GameFiles writer.Write(this.Rotation.ToVector4()); writer.Write(this.Translation); writer.Write(this.Unknown_1Ch); - writer.Write(this.ScaleX); - writer.Write(this.ScaleY); - writer.Write(this.ScaleZ); + writer.Write(this.Scale); writer.Write(this.Unknown_2Ch); writer.Write(this.NextSiblingIndex); writer.Write(this.ParentIndex); @@ -893,6 +887,26 @@ namespace CodeWalker.GameFiles { return Id.ToString() + ": " + Name; } + + + public void UpdateAnimTransform() + { + //AnimTransform = Matrix.AffineTransformation(1.0f, AnimRotation, AnimTranslation);//(local transform) + var pos = AnimTranslation; + var ori = AnimRotation; + var sca = AnimScale; + var pbone = Parent; + while (pbone != null) + { + pos = pbone.AnimRotation.Multiply(pos) + pbone.AnimTranslation; + ori = pbone.AnimRotation * ori; + pbone = pbone.Parent; + } + AnimTransform = Matrix.AffineTransformation(1.0f, ori, pos);//(global transform) + AnimTransform.ScaleVector *= sca; + SkinTransform = BindTransformInv * AnimTransform; + //SkinTransform = Matrix.Identity;//(for testing) + } } [TypeConverter(typeof(ExpandableObjectConverter))] public class Joints : ResourceSystemBlock diff --git a/Rendering/Renderable.cs b/Rendering/Renderable.cs index 6952040..ef49ce8 100644 --- a/Rendering/Renderable.cs +++ b/Rendering/Renderable.cs @@ -78,7 +78,7 @@ namespace CodeWalker.Rendering public Dictionary ModelBoneLinks; public Matrix3_s[] BoneTransforms; - + public List Bones; public override void Init(DrawableBase drawable) { @@ -238,6 +238,7 @@ namespace CodeWalker.Rendering HasSkeleton = hasskeleton; HasTransforms = hastransforms; + Bones = skeleton?.Bones?.Data; //calculate transforms for the models if there are any. (TODO: move this to a method for re-use...) @@ -249,7 +250,7 @@ namespace CodeWalker.Rendering if (hastransforms) { - int boneidx = (int)((model.SkeletonBinding >> 24) & 0xFF); + int boneidx = model.BoneIndex; Matrix trans = (boneidx < modeltransforms.Length) ? modeltransforms[boneidx] : Matrix.Identity; Bone bone = (hasbones && (boneidx < bones.Count)) ? bones[boneidx] : null; @@ -289,7 +290,7 @@ namespace CodeWalker.Rendering } } - if (((model.SkeletonBinding >> 8) & 0xFF) > 0) //skin mesh? + if (model.IsSkinMesh) { model.Transform = Matrix.Identity; } @@ -304,22 +305,7 @@ namespace CodeWalker.Rendering - //populate the bonetransforms array - Matrix[] bonetrans = (fragtransforms != null) ? fragtransforms : (modeltransforms != null) ? modeltransforms : null; - if (bonetrans != null) - { - BoneTransforms = new Matrix3_s[bonetrans.Length]; - for (int i = 0; i < bonetrans.Length; i++) - { - Matrix b = bonetrans[i]; - Matrix3_s bt = new Matrix3_s(); - bt.Row1 = b.Row1; - bt.Row2 = b.Row2; - bt.Row3 = b.Row3; - BoneTransforms[i] = bt; - } - } - + UpdateBoneTransforms(); } @@ -373,6 +359,27 @@ namespace CodeWalker.Rendering + private void UpdateBoneTransforms() + { + if (Bones == null) return; + if ((BoneTransforms == null) || (BoneTransforms.Length != Bones.Count)) + { + BoneTransforms = new Matrix3_s[Bones.Count]; + } + for (int i = 0; i < Bones.Count; i++) + { + var bone = Bones[i]; + Matrix b = bone.SkinTransform; + Matrix3_s bt = new Matrix3_s(); + bt.Row1 = b.Column1; + bt.Row2 = b.Column2; + bt.Row3 = b.Column3; + BoneTransforms[i] = bt; + } + } + + + public void UpdateAnims(double realTime) { if (CurrentAnimTime == realTime) return;//already updated this! @@ -469,25 +476,17 @@ namespace CodeWalker.Rendering for (int i = 0; i < bones.Count; i++) { var bone = bones[i]; - var pos = bone.AnimTranslation; - var ori = bone.AnimRotation; - var pbone = bone.Parent; - while (pbone != null) - { - pos = pbone.AnimRotation.Multiply(pos) + pbone.AnimTranslation; - ori = pbone.AnimRotation * ori; - pbone = pbone.Parent; - } - bone.AnimTransform = Matrix.AffineTransformation(1.0f, ori, pos); + bone.UpdateAnimTransform(); //update model's transform from animated bone RenderableModel bmodel = null; ModelBoneLinks?.TryGetValue(bone.Id, out bmodel); + + if (bmodel == null) { continue; } - - if (((bmodel.SkeletonBinding >> 8) & 0xFF) > 0) //skin mesh? //TODO: see eg. p_oil_pjack_03_s + if (bmodel.IsSkinMesh) //don't transform model for skin mesh { continue; } bmodel.Transform = bone.AnimTransform; @@ -495,6 +494,8 @@ namespace CodeWalker.Rendering } + UpdateBoneTransforms(); + } private void UpdateAnimUV(ClipMapEntry cme, RenderableGeometry rgeom = null) { @@ -591,11 +592,16 @@ namespace CodeWalker.Rendering public bool UseTransform; public Matrix Transform; + public int BoneIndex = 0; + public bool IsSkinMesh = false; + public void Init(DrawableModel dmodel) { SkeletonBinding = dmodel.SkeletonBinding;//4th byte is bone index, 2nd byte for skin meshes RenderMaskFlags = dmodel.RenderMaskFlags; //only the first byte seems be related to this + IsSkinMesh = ((SkeletonBinding >> 8) & 0xFF) > 0; + BoneIndex = (int)((SkeletonBinding >> 24) & 0xFF); DrawableModel = dmodel; long geomcount = dmodel.Geometries.data_items.Length; diff --git a/Rendering/Renderer.cs b/Rendering/Renderer.cs index 0346a80..4747864 100644 --- a/Rendering/Renderer.cs +++ b/Rendering/Renderer.cs @@ -1102,12 +1102,15 @@ namespace CodeWalker.Rendering skeletonLineVerts.Clear(); + const uint cred = 4278190335;// (uint)new Color4(1.0f, 0.0f, 0.0f, 1.0f).ToRgba(); const uint cgrn = 4278255360;// (uint)new Color4(0.0f, 1.0f, 0.0f, 1.0f).ToRgba(); const uint cblu = 4294901760;// (uint)new Color4(0.0f, 0.0f, 1.0f, 1.0f).ToRgba(); - VertexTypePC v1 = new VertexTypePC(); - VertexTypePC v2 = new VertexTypePC(); - v1.Colour = cgrn; - v2.Colour = cblu; + VertexTypePC vr = new VertexTypePC(); + VertexTypePC vg = new VertexTypePC(); + VertexTypePC vb = new VertexTypePC(); + vr.Colour = cred; + vg.Colour = cgrn; + vb.Colour = cblu; foreach (var item in renderskeletonlist) { @@ -1127,7 +1130,6 @@ namespace CodeWalker.Rendering var pind = pinds[i]; var bone = bones[i]; var pbone = bone.Parent; - if (pbone == null) continue; //nothing to draw for the root bone if (xforms != null)//how to use xforms? bind pose? { @@ -1142,24 +1144,44 @@ namespace CodeWalker.Rendering //draw line from bone's position to parent position... Vector3 lbeg = Vector3.Zero; Vector3 lend = bone.AnimTranslation;// bone.Rotation.Multiply(); - while (pbone != null) - { - lbeg = pbone.AnimRotation.Multiply(lbeg) + pbone.AnimTranslation; - lend = pbone.AnimRotation.Multiply(lend) + pbone.AnimTranslation; - pbone = pbone.Parent; - } + float starsize = (bone.AnimTransform.TranslationVector-camera.Position).Length() * 0.011f; + Vector3[] starverts0 = { Vector3.UnitX * starsize, Vector3.UnitY * starsize, Vector3.UnitZ * starsize }; + Vector3[] starverts1 = { Vector3.UnitX * -starsize, Vector3.UnitY * -starsize, Vector3.UnitZ * -starsize }; + for (int j = 0; j < 3; j++) starverts0[j] = bone.AnimTransform.MultiplyW(starverts0[j]); + for (int j = 0; j < 3; j++) starverts1[j] = bone.AnimTransform.MultiplyW(starverts1[j]); + + if (pbone != null) + { + lbeg = pbone.AnimTransform.MultiplyW(lbeg); + lend = pbone.AnimTransform.MultiplyW(lend); + } + if (entity != null) { lbeg = entity.Position + entity.Orientation.Multiply(lbeg * entity.Scale); lend = entity.Position + entity.Orientation.Multiply(lend * entity.Scale); + + for (int j = 0; j < 3; j++) starverts0[j] = entity.Position + entity.Orientation.Multiply(starverts0[j] * entity.Scale); + for (int j = 0; j < 3; j++) starverts1[j] = entity.Position + entity.Orientation.Multiply(starverts1[j] * entity.Scale); } - v1.Position = lbeg; - v2.Position = lend; - skeletonLineVerts.Add(v1); - skeletonLineVerts.Add(v2); + vr.Position = starverts0[0]; skeletonLineVerts.Add(vr); + vr.Position = starverts1[0]; skeletonLineVerts.Add(vr); + vg.Position = starverts0[1]; skeletonLineVerts.Add(vg); + vg.Position = starverts1[1]; skeletonLineVerts.Add(vg); + vb.Position = starverts0[2]; skeletonLineVerts.Add(vb); + vb.Position = starverts1[2]; skeletonLineVerts.Add(vb); + + + if (pbone != null) //don't draw the origin to root bone line + { + vg.Position = lbeg; + vb.Position = lend; + skeletonLineVerts.Add(vg); + skeletonLineVerts.Add(vb); + } } diff --git a/Rendering/Shaders/BasicShader.cs b/Rendering/Shaders/BasicShader.cs index 9e9bbc4..9aafcd6 100644 --- a/Rendering/Shaders/BasicShader.cs +++ b/Rendering/Shaders/BasicShader.cs @@ -173,7 +173,8 @@ namespace CodeWalker.Rendering public ShaderParamNames RenderTextureSampler = ShaderParamNames.DiffuseSampler; public bool SpecularEnable = true; - + Matrix3_s[] defaultBoneMatrices; + bool defaultBoneMatricesBound = false; private Dictionary layouts = new Dictionary(); @@ -276,11 +277,13 @@ namespace CodeWalker.Rendering layouts.Add(VertexType.PBBNCTT, new InputLayout(device, vspbbncttbytes, VertexTypePBBNCTT.GetLayout())); layouts.Add(VertexType.PBBNCTTT, new InputLayout(device, vspbbnctttbytes, VertexTypePBBNCTTT.GetLayout())); layouts.Add(VertexType.PBBNCCT, new InputLayout(device, vspbbncctbytes, VertexTypePBBNCCT.GetLayout())); + layouts.Add(VertexType.PBBNCCTT, new InputLayout(device, vspbbncctbytes, VertexTypePBBNCCTT.GetLayout()));//TODO layouts.Add(VertexType.PBBNCCTX, new InputLayout(device, vspbbncctxbytes, VertexTypePBBNCCTX.GetLayout())); layouts.Add(VertexType.PBBNCTTX, new InputLayout(device, vspbbncttxbytes, VertexTypePBBNCTTX.GetLayout())); layouts.Add(VertexType.PBBNCTTTX, new InputLayout(device, vspbbncttxbytes, VertexTypePBBNCTTTX.GetLayout()));//TODO layouts.Add(VertexType.PBBNCCTTX, new InputLayout(device, vspbbncctxbytes, VertexTypePBBNCCTTX.GetLayout()));//TODO - + //PBBCCT todo + //PBBNC todo @@ -343,6 +346,14 @@ namespace CodeWalker.Rendering sphere = new UnitSphere(device, vsspherebytes, 4); capsule = new UnitCapsule(device, vscapsulebytes, 4); cylinder = new UnitCylinder(device, vscylinderbytes, 8); + + defaultBoneMatrices = new Matrix3_s[255]; + for (int i = 0; i < 255; i++) + { + defaultBoneMatrices[i].Row1 = Vector4.UnitX; + defaultBoneMatrices[i].Row2 = Vector4.UnitY; + defaultBoneMatrices[i].Row3 = Vector4.UnitZ; + } } private void InitInstGlobalVars() @@ -446,6 +457,9 @@ namespace CodeWalker.Rendering case VertexType.PBBNCCT: vs = basicvspbbncct; break; + case VertexType.PBBNCCTT://todo + vs = basicvspbbncct; + break; case VertexType.PBBNCTX: vs = basicvspbbnctx; break; @@ -557,12 +571,15 @@ namespace CodeWalker.Rendering public override void SetModelVars(DeviceContext context, RenderableModel model) { - if (((model.SkeletonBinding >> 8) & 0xFF) > 0) + if (model.Owner.BoneTransforms != null) { - if (model.Owner.BoneTransforms != null) - { - SetBoneMatrices(context, model.Owner.BoneTransforms); - } + SetBoneMatrices(context, model.Owner.BoneTransforms); + defaultBoneMatricesBound = false; + } + else if (!defaultBoneMatricesBound) + { + SetBoneMatrices(context, defaultBoneMatrices); + defaultBoneMatricesBound = true; } if (!model.UseTransform) return; diff --git a/Rendering/Shaders/ShadowShader.cs b/Rendering/Shaders/ShadowShader.cs index e7cc64f..29d9256 100644 --- a/Rendering/Shaders/ShadowShader.cs +++ b/Rendering/Shaders/ShadowShader.cs @@ -57,12 +57,14 @@ namespace CodeWalker.Rendering bool disposed = false; VertexShader shadowvs; + VertexShader shadowvs_skin; PixelShader shadowps; GpuVarsBuffer VSSceneVars; GpuVarsBuffer VSEntityVars; GpuVarsBuffer VSModelVars; GpuVarsBuffer GeomVars; + GpuABuffer BoneMatrices; SamplerState texsampler; SamplerState texsamplerc; @@ -70,15 +72,20 @@ namespace CodeWalker.Rendering public Vector4 WindVector { get; set; } + Matrix3_s[] defaultBoneMatrices; + bool defaultBoneMatricesBound = false; + private Dictionary layouts = new Dictionary(); public ShadowShader(Device device) { byte[] vsbytes = File.ReadAllBytes("Shaders\\ShadowVS.cso"); + byte[] vssbytes = File.ReadAllBytes("Shaders\\ShadowVS_Skin.cso"); byte[] psbytes = File.ReadAllBytes("Shaders\\ShadowPS.cso"); shadowvs = new VertexShader(device, vsbytes); + shadowvs_skin = new VertexShader(device, vssbytes); shadowps = new PixelShader(device, psbytes); @@ -86,6 +93,7 @@ namespace CodeWalker.Rendering VSEntityVars = new GpuVarsBuffer(device); VSModelVars = new GpuVarsBuffer(device); GeomVars = new GpuVarsBuffer(device); + BoneMatrices = new GpuABuffer(device, 255); //supported layouts - requires Position, Normal, Colour, Texcoord @@ -93,8 +101,6 @@ namespace CodeWalker.Rendering layouts.Add(VertexType.DefaultEx, new InputLayout(device, vsbytes, VertexTypeDefaultEx.GetLayout())); layouts.Add(VertexType.PNCCT, new InputLayout(device, vsbytes, VertexTypePNCCT.GetLayout())); layouts.Add(VertexType.PNCCTTTT, new InputLayout(device, vsbytes, VertexTypePNCCTTTT.GetLayout())); - layouts.Add(VertexType.PBBNCCTTX, new InputLayout(device, vsbytes, VertexTypePBBNCCTTX.GetLayout())); - layouts.Add(VertexType.PBBNCCT, new InputLayout(device, vsbytes, VertexTypePBBNCCT.GetLayout())); layouts.Add(VertexType.PNCTTTX, new InputLayout(device, vsbytes, VertexTypePNCTTTX.GetLayout())); layouts.Add(VertexType.PNCTTTX_2, new InputLayout(device, vsbytes, VertexTypePNCTTTX_2.GetLayout())); layouts.Add(VertexType.PNCTTTX_3, new InputLayout(device, vsbytes, VertexTypePNCTTTX_3.GetLayout())); @@ -103,19 +109,25 @@ namespace CodeWalker.Rendering layouts.Add(VertexType.PNCCTTX, new InputLayout(device, vsbytes, VertexTypePNCCTTX.GetLayout())); layouts.Add(VertexType.PNCCTTX_2, new InputLayout(device, vsbytes, VertexTypePNCCTTX_2.GetLayout())); layouts.Add(VertexType.PNCCTTTX, new InputLayout(device, vsbytes, VertexTypePNCCTTTX.GetLayout())); - layouts.Add(VertexType.PBBNCCTX, new InputLayout(device, vsbytes, VertexTypePBBNCCTX.GetLayout())); - layouts.Add(VertexType.PBBNCTX, new InputLayout(device, vsbytes, VertexTypePBBNCTX.GetLayout())); - layouts.Add(VertexType.PBBNCT, new InputLayout(device, vsbytes, VertexTypePBBNCT.GetLayout())); layouts.Add(VertexType.PNCCTT, new InputLayout(device, vsbytes, VertexTypePNCCTT.GetLayout())); layouts.Add(VertexType.PNCCTX, new InputLayout(device, vsbytes, VertexTypePNCCTX.GetLayout())); layouts.Add(VertexType.PNCH2, new InputLayout(device, vsbytes, VertexTypePNCH2.GetLayout())); layouts.Add(VertexType.PCCH2H4, new InputLayout(device, vsbytes, VertexTypePCCH2H4.GetLayout())); - layouts.Add(VertexType.PBBNCTT, new InputLayout(device, vsbytes, VertexTypePBBNCTT.GetLayout())); - layouts.Add(VertexType.PBBNCTTX, new InputLayout(device, vsbytes, VertexTypePBBNCTTX.GetLayout())); - layouts.Add(VertexType.PBBNCTTT, new InputLayout(device, vsbytes, VertexTypePBBNCTTT.GetLayout())); layouts.Add(VertexType.PNCTT, new InputLayout(device, vsbytes, VertexTypePNCTT.GetLayout())); layouts.Add(VertexType.PNCTTT, new InputLayout(device, vsbytes, VertexTypePNCTTT.GetLayout())); - layouts.Add(VertexType.PBBNCTTTX, new InputLayout(device, vsbytes, VertexTypePBBNCTTTX.GetLayout())); + + layouts.Add(VertexType.PBBNCT, new InputLayout(device, vssbytes, VertexTypePBBNCT.GetLayout())); + layouts.Add(VertexType.PBBNCTX, new InputLayout(device, vssbytes, VertexTypePBBNCTX.GetLayout())); + layouts.Add(VertexType.PBBNCTT, new InputLayout(device, vssbytes, VertexTypePBBNCTT.GetLayout())); + layouts.Add(VertexType.PBBNCTTT, new InputLayout(device, vssbytes, VertexTypePBBNCTTT.GetLayout())); + layouts.Add(VertexType.PBBNCCT, new InputLayout(device, vssbytes, VertexTypePBBNCCT.GetLayout())); + layouts.Add(VertexType.PBBNCCTT, new InputLayout(device, vssbytes, VertexTypePBBNCCTT.GetLayout()));//TODO + layouts.Add(VertexType.PBBNCCTX, new InputLayout(device, vssbytes, VertexTypePBBNCCTX.GetLayout())); + layouts.Add(VertexType.PBBNCTTX, new InputLayout(device, vssbytes, VertexTypePBBNCTTX.GetLayout())); + layouts.Add(VertexType.PBBNCTTTX, new InputLayout(device, vssbytes, VertexTypePBBNCTTTX.GetLayout()));//TODO + layouts.Add(VertexType.PBBNCCTTX, new InputLayout(device, vssbytes, VertexTypePBBNCCTTX.GetLayout()));//TODO + //PBBCCT todo + //PBBNC todo @@ -146,13 +158,22 @@ namespace CodeWalker.Rendering MipLodBias = 0, }); + + + defaultBoneMatrices = new Matrix3_s[255]; + for (int i = 0; i < 255; i++) + { + defaultBoneMatrices[i].Row1 = Vector4.UnitX; + defaultBoneMatrices[i].Row2 = Vector4.UnitY; + defaultBoneMatrices[i].Row3 = Vector4.UnitZ; + } + } public override void SetShader(DeviceContext context) { - context.VertexShader.Set(shadowvs); context.PixelShader.Set(shadowps); } @@ -161,6 +182,26 @@ namespace CodeWalker.Rendering InputLayout l; if (layouts.TryGetValue(type, out l)) { + VertexShader vs = shadowvs; + switch (type) + { + case VertexType.PBBNCT: + case VertexType.PBBNCTX: + case VertexType.PBBNCTT: + case VertexType.PBBNCTTT: + case VertexType.PBBNCCT: + case VertexType.PBBNCCTT: + case VertexType.PBBNCCTX: + case VertexType.PBBNCTTX: + case VertexType.PBBNCTTTX: + case VertexType.PBBNCCTTX: + vs = shadowvs_skin; + break; + } + + context.VertexShader.Set(vs); + + context.InputAssembler.InputLayout = l; return true; } @@ -192,6 +233,17 @@ namespace CodeWalker.Rendering public override void SetModelVars(DeviceContext context, RenderableModel model) { + if (model.Owner.BoneTransforms != null) + { + SetBoneMatrices(context, model.Owner.BoneTransforms); + defaultBoneMatricesBound = false; + } + else if (!defaultBoneMatricesBound) + { + SetBoneMatrices(context, defaultBoneMatrices); + defaultBoneMatricesBound = true; + } + if (!model.UseTransform) return; VSModelVars.Vars.Transform = Matrix.Transpose(model.Transform); VSModelVars.Update(context); @@ -306,6 +358,13 @@ namespace CodeWalker.Rendering } } + public void SetBoneMatrices(DeviceContext context, Matrix3_s[] matrices) + { + BoneMatrices.Update(context, matrices); + BoneMatrices.SetVSCBuffer(context, 7); + } + + public override void UnbindResources(DeviceContext context) { context.VertexShader.SetConstantBuffer(0, null); @@ -341,10 +400,12 @@ namespace CodeWalker.Rendering VSEntityVars.Dispose(); VSModelVars.Dispose(); GeomVars.Dispose(); + BoneMatrices.Dispose(); shadowps.Dispose(); shadowvs.Dispose(); + shadowvs_skin.Dispose(); disposed = true; } diff --git a/Shaders/CodeWalkerShaders.vcxproj b/Shaders/CodeWalkerShaders.vcxproj index 33c135b..0bb754e 100644 --- a/Shaders/CodeWalkerShaders.vcxproj +++ b/Shaders/CodeWalkerShaders.vcxproj @@ -486,6 +486,16 @@ Vertex Vertex + + Vertex + 4.0 + Vertex + 4.0 + Vertex + 4.0 + Vertex + 4.0 + Pixel Pixel diff --git a/Shaders/CodeWalkerShaders.vcxproj.filters b/Shaders/CodeWalkerShaders.vcxproj.filters index 290c326..e871bd8 100644 --- a/Shaders/CodeWalkerShaders.vcxproj.filters +++ b/Shaders/CodeWalkerShaders.vcxproj.filters @@ -74,6 +74,7 @@ + diff --git a/Shaders/ShadowVS_Skin.cso b/Shaders/ShadowVS_Skin.cso new file mode 100644 index 0000000000000000000000000000000000000000..0266dc316942051b7bb22894e067a05cea95c176 GIT binary patch literal 3580 zcmb7HPiP!f9DYf*+f9rnMnnij2PvTyiD_D5Eux$3pJXA)E<4M%JxCd|ugz+*TV_Wa zPi}$;QmMDnn|cYtig=QOJ*cM?5qhX1Uc^&HL?lWOQRDZ`yx(TBPEz{|Z{B;~@9+0} zZ)QpQ%v9>v?_an)^VRmpmmYcZ&-LH#40kD|{<>eO1DH=>yd6_&5u492n!t`v_rdj*WeE)PEhJ?*=CRKSbzzLi(Q~^an%wvTZNunl3wT zLzV4J&8vE^nay0iqL=*jw5~7vi>Z1|&pDo3UC<5HA~)7@5yccjdB`b&@h$LV2qzcT z-H!spI61I)W56xUBCMVEKLWq?l%PtzM-Y<4VEzxy{sv}Zg9hI)c)6-C72Ntus?}=s zs2&x=pUCNIty0ztUfor#F6g>Kx@!y$>5TU-aAKW!3%CVbqF*=u8<-CpoRHw(U~?qG z{toabBk-Srj{)z;V4UCifW*+BXF2=3o%ktdxu};^-mU7I=Xlk6P0ctB`(?ePJ*-yLqbgov>E2`jBjwyQq5E>cu3W<$CInMqbHc%2c z%agNd2ZqrH#-_90Pk*dZ5pF#=Y`c7}oxU9%aqXFO@j7ZtBGNAib{5wnd&Tl2ux{Bi5BbTSbuhl{xh8ft z5%{w|e*-uNGk1`;Dp+q~%~-^_rVrQSSTnxZGxr6g+_VB;`e@o=&-EhG(Z)hMhWuNr z)Ns@Cb&T1S40?k;^=(2=pX{SSzHaE6>h)B3;P>Z1+wOtDenhGJ)Gehtar%>Qcpy(N z?U=j#u*rADim?yFCjU6%i4A(}>-vl?Zu*i%ZpMhReZttT51aV=*q$=BTaWFwod8c4 zI@X>Y3VKUy&0y>sy7T;lxZ*>=Sc}xenSRn!o>z!#oLt%G5Z`|Cr5*UT^--K@1J055 zQM~uFkK#^ya(X<($*=2waAFVk<3#E1|C)}Te*ic8g`iAAli2afj=?GLBO{uXzu}=2UYh?yj{OY)%HbcyE2q z%p>)T^qRU1cd6O$x8X7J)=q4`@6wYnXZDPOKKc3RFR={HNo~EeD^|b6lKyrlX{Gp- z!I*xJ7*F^P4-Ph0VZ?7M@62}tH>pO4vR?{(JxA{Hd4shHLh~d=C>t zmN^T&UljSB>|IcDiDf|u} R#b8_t^WTdw4t?+D_b;tEW48bR literal 0 HcmV?d00001 diff --git a/Shaders/ShadowVS_Skin.hlsl b/Shaders/ShadowVS_Skin.hlsl new file mode 100644 index 0000000..48ee841 --- /dev/null +++ b/Shaders/ShadowVS_Skin.hlsl @@ -0,0 +1,127 @@ +#include "Common.hlsli" +#include "Quaternion.hlsli" + + +cbuffer VSSceneVars : register(b0) +{ + float4x4 ViewProj; + float4 WindVector; +} +cbuffer VSEntityVars : register(b1) +{ + float4 CamRel; + float4 Orientation; + uint HasSkeleton; + uint HasTransforms; + uint TintPaletteIndex; + uint Pad1; + float3 Scale; + uint Pad2; +} +cbuffer VSModelVars : register(b2) +{ + float4x4 Transform; +} +cbuffer GeomVars : register(b3) +{ + uint EnableTexture; + uint EnableTint; + uint IsDecal; + uint EnableWind; + float4 WindOverrideParams; +} +cbuffer BoneMatrices : register(b7) //rage_bonemtx +{ + row_major float3x4 gBoneMtx[255]; // Offset: 0 Size: 12240 +} + +struct VS_INPUT +{ + float4 Position : POSITION; + float4 BlendWeights : BLENDWEIGHTS; + float4 BlendIndices : BLENDINDICES; + float3 Normal : NORMAL; + float2 Texcoord : TEXCOORD0; + float4 Colour : COLOR0; +}; + +struct VS_OUTPUT +{ + float4 Position : SV_POSITION; + //float3 Normal : NORMAL; + float2 Texcoord : TEXCOORD0; + //float4 Colour : COLOR0; + //float4 Tint : COLOR1; +}; + +//Texture2D TintPalette : register(t0); +//SamplerState TextureSS : register(s0); + + + +float3x4 BoneMatrix(float4 weights, float4 indices) +{ + uint4 binds = (uint4) (indices * 255.001953); + float3x4 b0 = gBoneMtx[binds.x]; + float3x4 b1 = gBoneMtx[binds.y]; + float3x4 b2 = gBoneMtx[binds.z]; + float3x4 b3 = gBoneMtx[binds.w]; + float4 t0 = b0[0] * weights.x + b1[0] * weights.y + b2[0] * weights.z + b3[0] * weights.w; + float4 t1 = b0[1] * weights.x + b1[1] * weights.y + b2[1] * weights.z + b3[1] * weights.w; + float4 t2 = b0[2] * weights.x + b1[2] * weights.y + b2[2] * weights.z + b3[2] * weights.w; + return float3x4(t0, t1, t2); +} +float3 BoneTransform(float3 ipos, float3x4 m) +{ + float3 r; + float4 p = float4(ipos, 1); + r.x = dot(m[0], p); + r.y = dot(m[1], p); + r.z = dot(m[2], p); + return r; +} + + + + + +VS_OUTPUT main(VS_INPUT input) +{ + VS_OUTPUT output; + float3x4 bone = BoneMatrix(input.BlendWeights, input.BlendIndices); + float3 ipos = BoneTransform(input.Position.xyz, bone); + float3 tpos = (HasTransforms == 1) ? mul(float4(ipos, 1), Transform).xyz : ipos; + float3 spos = tpos * Scale; + float3 bpos = mulvq(spos, Orientation); + if (EnableWind) + { + bpos = GeomWindMotion(bpos, input.Colour.xyz, WindVector, WindOverrideParams); + } + float3 opos = CamRel.xyz + bpos; + float4 pos = float4(opos, 1); + float4 cpos = mul(pos, ViewProj); + //if (IsDecal == 1) + //{ + // //cpos.z -= 0.003; //todo: correct decal z-bias + //} + //cpos.z = saturate(cpos.z); //might need work + + //cpos.z = DepthFunc(cpos.zw); + + //float3 inorm = input.Normal; + //float3 tnorm = (HasTransforms == 1) ? mul(inorm, (float3x3)Transform) : inorm; + //float3 bnorm = normalize(mulvq(tnorm, Orientation)); + + //float4 tnt = 0; + //if (EnableTint == 1) + //{ + // tnt = TintPalette.SampleLevel(TextureSS, float2(input.Colour.b, TintYVal), 0); + //} + + output.Position = cpos; + //output.Normal = bnorm; + output.Texcoord = input.Texcoord; + //output.Colour = input.Colour; + //output.Tint = tnt; + return output; +} \ No newline at end of file