GiM-GamesInMotion / gFurPro

Shell based fur plugin for Unreal Engine 5
https://gim.studio/animalia/animalia/
Other
89 stars 34 forks source link

The Fur Location error in UE5 #1

Closed StephenMhYt closed 1 year ago

StephenMhYt commented 1 year ago

image The Position should not transform to world position.

GiM-GamesInMotion commented 1 year ago

Yeah, that doesn't look good. Unfortunately right now we don't have a programmer and I'm definitely not one.

StephenMhYt commented 1 year ago

float3 SkinPosition( FVertexFactoryInput Input, FVertexFactoryIntermediates Intermediates ) {

if GPUSKIN_MORPH_BLEND

float4 Position = float4(MorphPosition(Input, Intermediates),1);

else

float4 Position = float4(Intermediates.UnpackedPosition,1);

endif

// Note the use of mul(Matrix,Vector), bone matrices are stored transposed
// for tighter packing.
return mul( Intermediates.BlendMatrix, Position );

}

/* transform position by weighted sum of skinning matrices / float3 SkinPreviousPosition( FVertexFactoryInput Input, FVertexFactoryIntermediates Intermediates ) {

if GPUSKIN_MORPH_BLEND

float3 Position = MorphPosition(Input, Intermediates);

else

float3 Position = Intermediates.UnpackedPosition;

endif

FBoneMatrix BlendMatrix = CalcPreviousBoneMatrix( Input );
Position = mul( BlendMatrix, float4(Position, 1) );

if NUM_MATERIAL_TEXCOORDS_VERTEX >= 2

float3 FurOffset = Input.FurOffset;
FurOffset = mul(BlendMatrix, float4(FurOffset.xyz, 0));

if GFUR_PHYSICS

float3 WorldPosition = LWCToFloat(TransformLocalToWorld(Input.Position, Intermediates.LocalToWorld));
float FurLength = length(FurOffset);

float3 PhysicsOffset = Input.BlendWeights.x * CalcPrevBoneFurPhysicsOffset(Input.BlendIndices.x, WorldPosition);
PhysicsOffset += Input.BlendWeights.y * CalcPrevBoneFurPhysicsOffset(Input.BlendIndices.y, WorldPosition);
PhysicsOffset += Input.BlendWeights.z * CalcPrevBoneFurPhysicsOffset(Input.BlendIndices.z, WorldPosition);
PhysicsOffset += Input.BlendWeights.w * CalcPrevBoneFurPhysicsOffset(Input.BlendIndices.w, WorldPosition);

if GPUSKIN_USE_EXTRA_INFLUENCES

PhysicsOffset += Input.BlendWeightsExtra.x * CalcPrevBoneFurPhysicsOffset(Input.BlendIndicesExtra.x, WorldPosition);
PhysicsOffset += Input.BlendWeightsExtra.y * CalcPrevBoneFurPhysicsOffset(Input.BlendIndicesExtra.y, WorldPosition);
PhysicsOffset += Input.BlendWeightsExtra.z * CalcPrevBoneFurPhysicsOffset(Input.BlendIndicesExtra.z, WorldPosition);
PhysicsOffset += Input.BlendWeightsExtra.w * CalcPrevBoneFurPhysicsOffset(Input.BlendIndicesExtra.w, WorldPosition);

endif // GPUSKIN_USE_EXTRA_INFLUENCES

float3 NormalVec = Intermediates.TangentToLocal[2];
PhysicsOffset -= dot(PhysicsOffset, NormalVec) * NormalVec;
PhysicsOffset *= pow(Input.TexCoords[1].x, FurOffsetPower);

float PhysicOffsetLength = length(PhysicsOffset);
float MaxPhysicsOffset = MaxPhysicsOffsetLength * FurLength;
if (PhysicOffsetLength > MaxPhysicsOffset)
    PhysicsOffset *= MaxPhysicsOffset / PhysicOffsetLength;

PhysicsOffset = LWCMultiplyVector(PhysicsOffset, Intermediates.WorldToLocal);
Position += normalize(FurOffset + PhysicsOffset) * FurLength;

else // GFUR_PHYSICS

Position += FurOffset;

endif // GFUR_PHYSICS

endif

return Position;// + ResolvedView.PrevPreViewTranslation;

}

float4 CalcWorldPosition(FVertexFactoryInput Input, FVertexFactoryIntermediates Intermediates) { float3 Position = SkinPosition(Input, Intermediates);

if GPUSKIN_APEX_CLOTH

if( IsSimulatedVertex(Input) )
{
    // skinned positions
    float4 SkinnedPosition = float4(Position, 1);

    // Intermediates.SimulatedPosition is a clothing position in world coord
    float3 BlendedPos = lerp(SkinnedPosition.xyz, Intermediates.SimulatedPosition, ClothBlendWeight);
    Position = BlendedPos;
}

endif

if NUM_MATERIAL_TEXCOORDS_VERTEX >= 2

float3 FurOffset = Input.FurOffset;
FurOffset = mul(Intermediates.BlendMatrix, float4(FurOffset.xyz, 0));

if GFUR_PHYSICS

float3 WorldPosition = LWCToFloat(TransformLocalToWorld(Input.Position, Intermediates.LocalToWorld));
float FurLength = length(FurOffset);

float3 PhysicsOffset = Input.BlendWeights.x * CalcBoneFurPhysicsOffset(Input.BlendIndices.x, WorldPosition);
PhysicsOffset += Input.BlendWeights.y * CalcBoneFurPhysicsOffset(Input.BlendIndices.y, WorldPosition);
PhysicsOffset += Input.BlendWeights.z * CalcBoneFurPhysicsOffset(Input.BlendIndices.z, WorldPosition);
PhysicsOffset += Input.BlendWeights.w * CalcBoneFurPhysicsOffset(Input.BlendIndices.w, WorldPosition);

if GPUSKIN_USE_EXTRA_INFLUENCES

PhysicsOffset += Input.BlendWeightsExtra.x * CalcBoneFurPhysicsOffset(Input.BlendIndicesExtra.x, WorldPosition);
PhysicsOffset += Input.BlendWeightsExtra.y * CalcBoneFurPhysicsOffset(Input.BlendIndicesExtra.y, WorldPosition);
PhysicsOffset += Input.BlendWeightsExtra.z * CalcBoneFurPhysicsOffset(Input.BlendIndicesExtra.z, WorldPosition);
PhysicsOffset += Input.BlendWeightsExtra.w * CalcBoneFurPhysicsOffset(Input.BlendIndicesExtra.w, WorldPosition);

endif // GPUSKIN_USE_EXTRA_INFLUENCES

float3 NormalVec = Intermediates.TangentToLocal[2];
PhysicsOffset -= dot(PhysicsOffset, NormalVec) * NormalVec;
PhysicsOffset *= pow(Input.TexCoords[1].x, FurOffsetPower);

float PhysicOffsetLength = length(PhysicsOffset);
float MaxPhysicsOffset = MaxPhysicsOffsetLength * FurLength;
if (PhysicOffsetLength > MaxPhysicsOffset)
    PhysicsOffset *= MaxPhysicsOffset / PhysicOffsetLength;

PhysicsOffset = LWCMultiplyVector(PhysicsOffset, Intermediates.WorldToLocal);
Position += normalize(FurOffset + PhysicsOffset) * FurLength;

else // GFUR_PHYSICS

Position += FurOffset;

endif // GFUR_PHYSICS

endif

return TransformLocalToTranslatedWorld(Position.xyz, Intermediates.LocalToWorld);

}

float4 VertexFactoryGetPreviousWorldPosition(FVertexFactoryInput Input, FVertexFactoryIntermediates Intermediates) { float3 PrevSkinnedPosition = SkinPreviousPosition(Input, Intermediates);

if GPUSKIN_APEX_CLOTH

if GPUSKIN_APEX_CLOTH_PREVIOUS

if (IsSimulatedVertex(Intermediates.ClothVertexInfluences[0]))
{
    // Transform simulated position from cloth space into local space and blend with skinned position
    float4 PrevTransformedSimulatedPos = mul(float4(Intermediates.PreviousSimulatedPosition.xyz, 1), PreviousClothToLocal);
    PrevSkinnedPosition = lerp(PrevSkinnedPosition, PrevTransformedSimulatedPos.xyz, ClothBlendWeight * Intermediates.PreviousSimulatedPosition.w);
}

endif // GPUSKIN_APEX_CLOTH_PREVIOUS

endif // GPUSKIN_APEX_CLOTH

return TransformPreviousLocalPositionToTranslatedWorld(PrevSkinnedPosition, Intermediates.PrevLocalToWorld);

}

float4 VertexFactoryGetWorldPosition(FVertexFactoryInput Input, FVertexFactoryIntermediates Intermediates) { return CalcWorldPosition(Input, Intermediates); }

StephenMhYt commented 1 year ago

I modified the file about GFurFactory.ush, and works well.

image

GiM-GamesInMotion commented 1 year ago

Hello, any chance you could commit those changes?

StephenMhYt commented 1 year ago

Can you give me a role as Contributor? otherwise, I need to create a pull request.

StephenMhYt commented 1 year ago

I can also give the changes to support ue5.1, but you must create a 5.1 branch based on 5.0.

StephenMhYt commented 1 year ago

I create a pull request, and you can check it. image

GiM-GamesInMotion commented 1 year ago

Hello, done. I made 5.1 the master branch. Grateful for your contribution.