Skip to content

Commit

Permalink
Merge pull request #2 from Live2D/develop
Browse files Browse the repository at this point in the history
Update to Cubism 5 SDK for Unreal Engine R1 alpha3
  • Loading branch information
itoh-at-live2d-com authored Oct 31, 2024
2 parents 19d42e6 + 4f85a27 commit 9d40484
Show file tree
Hide file tree
Showing 13 changed files with 692 additions and 199 deletions.
32 changes: 32 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# This setting refers to https://github.com/EpicGames/UnrealEngine/blob/release/.editorconfig .

# top-most EditorConfig file
root = true

# Baseline
[*]
charset = utf-8
indent_style = tab
indent_size = 4
tab_width = 4
trim_trailing_whitespace = false
max_line_length = 150

# ReSharper properties
resharper_cpp_keep_user_linebreaks = false
resharper_cpp_wrap_lines = false
resharper_cpp_wrap_before_colon = true
resharper_cpp_line_break_before_comma_in_member_initializer_lists = true

# MSBuild
[*.{csproj,proj,projitems,shproj,fsproj,target,props}]
indent_style = space
indent_size = 2

# XML config files
[*.{config,nuspec,resx,natvis}]
indent_style = space
indent_size = 2

[*.md]
trim_trailing_whitespace = false
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,14 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).


## [5-r.1-alpha.3] - 2024-10-31

### Changed

* Optimize mask texture rendering.
* Optimize model mesh rendering.


## [5-r.1-alpha.2] - 2024-09-26

### Added
Expand All @@ -28,4 +36,5 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
* New released!


[5-r.1-alpha.3]: https://github.com/Live2D/CubismUnrealEngineComponents/compare/5-r.1-alpha.2...5-r.1-alpha.3
[5-r.1-alpha.2]: https://github.com/Live2D/CubismUnrealEngineComponents/compare/5-r.1-alpha.1...5-r.1-alpha.2
2 changes: 1 addition & 1 deletion Live2DCubismSDK.uplugin
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"FileVersion": 3,
"Version": 1,
"VersionName": "5-r.1-alpha.2",
"VersionName": "5-r.1-alpha.3",
"FriendlyName": "Live2DCubismSDK",
"Description": "Live2D Cubism SDK for Unreal Engine Components",
"Category": "Other",
Expand Down
2 changes: 1 addition & 1 deletion README.ja.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ Cubismファイルをuassetファイルに変換する機能は `./Source/Live2D

| ライブラリ / ツール | バージョン |
| --- | --- |
| Visual Studio 2022 | 17.11.4 |
| Visual Studio 2022 | 17.11.5 |
| Windows SDK | 10.0.22621.0 |

## テスト済みの環境
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ Resources like shaders and other assets are located in `./Content/Materials`.

| Library / Tool | Version |
| --- | --- |
| Visual Studio 2022 | 17.11.4 |
| Visual Studio 2022 | 17.11.5 |
| Windows SDK | 10.0.22621.0 |

## Tested environment
Expand Down
4 changes: 2 additions & 2 deletions Shaders/Private/CubismMeshMask.usf
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@
float4 Offset;

void MainVS(
in float4 InPosition : ATTRIBUTE0, in float2 InUV : ATTRIBUTE2,
in float2 InPosition : ATTRIBUTE0, in float2 InUV : ATTRIBUTE1,
out float4 OutPosition : SV_POSITION, out float2 OutUV : TEXCOORD0
)
{
OutPosition = InPosition;
OutPosition = float4(InPosition.xy, 0.0, 1.0);

OutPosition.xy += Offset.xy;
OutPosition.xy *= Offset.z;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -264,27 +264,24 @@ void UCubismDrawableComponent::SendRenderDynamicData_Concurrent()
FCubismDrawableDynamicMeshData NewDynamicData;

NewDynamicData.Index = Index;
NewDynamicData.Indices.Append(VertexIndices);

for (const FVector2D& LocalPosition : GetVertexPositions())
{
NewDynamicData.Positions.Add(FVector3f(ToGlobalPosition(LocalPosition)));
}

for (const FVector2D& Uv : GetVertexUvs())
for (const FVector2D& UV : GetVertexUvs())
{
NewDynamicData.UVs.Add(FVector2f(Uv));
NewDynamicData.UVs.Add(FVector2f(UV));
}

NewDynamicData.Color = BaseColor.ToRGBE();
NewDynamicData.Color.A *= Opacity;

NewDynamicData.Indices.Append(VertexIndices);
NewDynamicData.bTwoSided = bTwoSided;

ENQUEUE_RENDER_COMMAND(DrawableUpdateDynamicData)(
[DrawableProxy, NewDynamicData](FRHICommandListImmediate& RHICommandList)
{
DrawableProxy->DynamicData = NewDynamicData;
DrawableProxy->UpdateDynamicData(NewDynamicData);
}
);
}
Expand Down Expand Up @@ -357,6 +354,23 @@ FBoxSphereBounds UCubismDrawableComponent::CalcBounds(const FTransform& LocalToW
//~ Begin UPrimitiveComponent Interface
FPrimitiveSceneProxy* UCubismDrawableComponent::CreateSceneProxy()
{
return new FCubismDrawableSceneProxy(this);
FCubismDrawableDynamicMeshData DynamicData;

DynamicData.Index = Index;

for (const FVector2D& LocalPosition : GetVertexPositions())
{
DynamicData.Positions.Add(FVector3f(ToGlobalPosition(LocalPosition)));
}

for (const FVector2D& UV : GetVertexUvs())
{
DynamicData.UVs.Add(FVector2f(UV));
}

DynamicData.Indices.Append(VertexIndices);
DynamicData.bTwoSided = bTwoSided;

return new FCubismDrawableSceneProxy(this, DynamicData);
}
//~ End UPrimitiveComponent Interface
Original file line number Diff line number Diff line change
Expand Up @@ -8,40 +8,77 @@

#pragma once

#include "PrimitiveSceneProxy.h"
#include "DynamicMeshBuilder.h"
#include "Materials/Material.h"
#if ENGINE_MAJOR_VERSION == 5 && ENGINE_MINOR_VERSION >= 2
#include "Materials/MaterialRenderProxy.h"
#endif

/**
* Dynamic mesh data for a drawable.
*/
struct FCubismDrawableDynamicMeshData
{
int32 Index;
TArray<uint32> Indices;
FColor Color;
TArray<FVector3f> Positions;
TArray<FVector2f> UVs;
bool bTwoSided;
};
#include "CubismRenderingResource.h"

/**
* A representation of a UCubismDrawableComponent on the rendering thread.
*/
class FCubismDrawableSceneProxy : public FPrimitiveSceneProxy
{
public:
FCubismDrawableSceneProxy(const TObjectPtr<UCubismDrawableComponent>& Drawable)
FCubismDrawableSceneProxy(const TObjectPtr<UCubismDrawableComponent>& Drawable, FCubismDrawableDynamicMeshData InDynamicData)
: FPrimitiveSceneProxy(Drawable)
, DynamicData(InDynamicData)
, MaterialInstance(Drawable->GetMaterial(0))
, MaterialRelevance(Drawable->GetMaterialRelevance(GetScene().GetFeatureLevel()))
, VertexBuffer(nullptr)
, IndexBuffer(nullptr)
, VertexFactory(nullptr)
{
ENQUEUE_RENDER_COMMAND(InitCubismDrawableSceneProxy)(
[this](FRHICommandListImmediate& RHICmdList)
{
if (!VertexBuffer)
{
VertexBuffer = new FCubismDrawableVertexBuffer(DynamicData);
#if ENGINE_MAJOR_VERSION == 5 && ENGINE_MINOR_VERSION >= 3
VertexBuffer->InitResource(RHICmdList);
#else
VertexBuffer->InitResource();
#endif
}

if (!IndexBuffer)
{
IndexBuffer = new FCubismDrawableIndexBuffer(DynamicData);
#if ENGINE_MAJOR_VERSION == 5 && ENGINE_MINOR_VERSION >= 3
IndexBuffer->InitResource(RHICmdList);
#else
IndexBuffer->InitResource();
#endif
}

if (!VertexFactory)
{
VertexFactory = new FCubismDrawableVertexFactory(GetScene().GetFeatureLevel(), VertexBuffer);
#if ENGINE_MAJOR_VERSION == 5 && ENGINE_MINOR_VERSION >= 3
VertexFactory->InitResource(RHICmdList);
#else
VertexFactory->InitResource();
#endif
}
}
);
}

virtual ~FCubismDrawableSceneProxy() { }
virtual ~FCubismDrawableSceneProxy()
{
if (VertexFactory)
{
VertexFactory->ReleaseResource();
delete VertexFactory;
}
if (VertexBuffer)
{
VertexBuffer->ReleaseResource();
delete VertexBuffer;
}
if (IndexBuffer)
{
IndexBuffer->ReleaseResource();
delete IndexBuffer;
}
}

SIZE_T GetTypeHash() const override
{
Expand All @@ -56,9 +93,14 @@ class FCubismDrawableSceneProxy : public FPrimitiveSceneProxy
FMeshElementCollector& Collector
) const override
{
if (DynamicData.Positions.Num() == 0)
{
return;
}

const bool bWireframe = AllowDebugViewmodes() && ViewFamily.EngineShowFlags.Wireframe;

FMaterialRenderProxy* MaterialProxy = nullptr;
FMaterialRenderProxy* MaterialRenderProxy = nullptr;
if (bWireframe)
{
FColoredMaterialRenderProxy* WireframeMaterialInstance = new FColoredMaterialRenderProxy(
Expand All @@ -67,24 +109,11 @@ class FCubismDrawableSceneProxy : public FPrimitiveSceneProxy
);

Collector.RegisterOneFrameMaterialProxy(WireframeMaterialInstance);
MaterialProxy = WireframeMaterialInstance;
MaterialRenderProxy = WireframeMaterialInstance;
}
else
{
MaterialProxy = MaterialInstance->GetRenderProxy();
}

TArray<FDynamicMeshVertex> Vertices;
for (int32 i = 0; i < DynamicData.Positions.Num(); i++)
{
FDynamicMeshVertex Vertex;

Vertex.SetTangents(FVector3f(1.0f,0.0f,0.0f), FVector3f(0.0f,1.0f,0.0f), FVector3f(0.0f,0.0f,1.0f));
Vertex.Color = DynamicData.Color;
Vertex.Position = DynamicData.Positions[i];
Vertex.TextureCoordinate[0] = DynamicData.UVs[i];

Vertices.Add(Vertex);
MaterialRenderProxy = MaterialInstance->GetRenderProxy();
}

for (int32 ViewIndex = 0; ViewIndex < Views.Num(); ViewIndex++)
Expand All @@ -93,18 +122,32 @@ class FCubismDrawableSceneProxy : public FPrimitiveSceneProxy
{
const FSceneView* View = Views[ViewIndex];

FDynamicMeshBuilder Builder(View->GetFeatureLevel());
Builder.AddVertices(Vertices);
Builder.AddTriangles(DynamicData.Indices);
Builder.GetMesh(
GetLocalToWorld(),
MaterialProxy,
SDPG_World,
DynamicData.bTwoSided,
false,
ViewIndex,
Collector
);
FMeshBatch& Mesh = Collector.AllocateMesh();
Mesh.ReverseCulling = IsLocalToWorldDeterminantNegative();
Mesh.bDisableBackfaceCulling = DynamicData.bTwoSided;
Mesh.Type = PT_TriangleList;

Mesh.VertexFactory = VertexFactory;
Mesh.MaterialRenderProxy = MaterialRenderProxy;

FMeshBatchElement& BatchElement = Mesh.Elements[0];

FDynamicPrimitiveUniformBuffer& DynamicPrimitiveUniformBuffer = Collector.AllocateOneFrameResource<FDynamicPrimitiveUniformBuffer>();
#if ENGINE_MAJOR_VERSION == 5 && ENGINE_MINOR_VERSION >= 4
DynamicPrimitiveUniformBuffer.Set(Collector.GetRHICommandList(), GetLocalToWorld(), GetLocalToWorld(), GetBounds(), GetLocalBounds(), false, false, AlwaysHasVelocity());
#else
DynamicPrimitiveUniformBuffer.Set(GetLocalToWorld(), GetLocalToWorld(), GetBounds(), GetLocalBounds(), false, false, AlwaysHasVelocity());
#endif
BatchElement.PrimitiveUniformBufferResource = &DynamicPrimitiveUniformBuffer.UniformBuffer;

BatchElement.IndexBuffer = IndexBuffer;

BatchElement.FirstIndex = 0;
BatchElement.NumPrimitives = IndexBuffer->Indices.Num() / 3;
BatchElement.MinVertexIndex = 0;
BatchElement.MaxVertexIndex = VertexBuffer->Positions.Num() - 1;

Collector.AddMesh(ViewIndex, Mesh);
}
}
}
Expand All @@ -126,6 +169,19 @@ class FCubismDrawableSceneProxy : public FPrimitiveSceneProxy

virtual uint32 GetMemoryFootprint(void) const override { return(sizeof(*this) + GetAllocatedSize()); }

void UpdateDynamicData(const FCubismDrawableDynamicMeshData& NewDynamicData)
{
DynamicData = NewDynamicData;
if (VertexBuffer)
{
VertexBuffer->UpdateBuffer(DynamicData.Positions, DynamicData.UVs);
}
if (IndexBuffer)
{
IndexBuffer->UpdateBuffer(DynamicData.Indices);
}
}

public:
/** Dynamic mesh data for the drawable. */
FCubismDrawableDynamicMeshData DynamicData;
Expand All @@ -136,4 +192,9 @@ class FCubismDrawableSceneProxy : public FPrimitiveSceneProxy

/** The material relevance for the drawable. */
FMaterialRelevance MaterialRelevance;

/** Dynamic rendering resources */
mutable FCubismDrawableVertexBuffer* VertexBuffer;
mutable FCubismDrawableIndexBuffer* IndexBuffer;
mutable FCubismDrawableVertexFactory* VertexFactory;
};
Loading

0 comments on commit 9d40484

Please sign in to comment.