Announcement

Collapse
No announcement yet.

Runtime Mesh Component

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • replied
    Originally posted by Koderz View Post
    Which version are you using?
    I'm using UE 4.13.1 with the built in RMC 1.2.

    I would like to try out the GitHub version, but I'm not sure how. I'm assuming I need to download the code, compile it and then add it to the engine as a plugin? I just have no idea how to do that.

    On a side note, shadows now appear to be working with RMC. For a long time they didn't work, then today I noticed there was something different about my scene but couldn't put my finger on it until I realised there were shadows where there never used to be shadows. The only thing I've changed recently is upgrading from UE 4.12.5 to UE 4.13.1 about a week ago.

    However the issue with RMC not affecting the nav mesh still exists. I was hoping maybe that had fixed itself too after upgrading, but no. Have you had any luck with that bug as my game is completely broken because of it? My AI just walks through everything I place in the world like its not there. LOL.
    Last edited by wilberolive; 10-18-2016, 09:06 PM.

    Leave a comment:


  • replied
    Originally posted by wilberolive View Post
    [MENTION=141752]Koderz[/MENTION] Have run into another very strange issue with RMC. I'm trying to use a translucent material with my generated mesh. However, the first time I generate the mesh (at runtime), it is invisible. I've stepped through the code and it appears to be generating a mesh and adding it as a mesh section, but it just doesn't render on screen at all. However, if I clear that mesh section and then generate it again (while in runtime, not in the editor), it renders fine.

    So the issue seems to be that the first time you create a mesh section at runtime with a translucent material it doesn't render. You have to clear it once, then create it again for it to render.

    As a test, I just swapped the code over to use PMC instead and it works fine. The mesh renders first time every time with a translucent material. So it appears to be an issue with RMC.

    Well that's new...

    Which version are you using? Wondering since github master is a bit unstable atm, but I might be about to push a rather large update, so will look into it with this round.

    Leave a comment:


  • replied
    [MENTION=141752]Koderz[/MENTION] Have run into another very strange issue with RMC. I'm trying to use a translucent material with my generated mesh. However, the first time I generate the mesh (at runtime), it is invisible. I've stepped through the code and it appears to be generating a mesh and adding it as a mesh section, but it just doesn't render on screen at all. However, if I clear that mesh section and then generate it again (while in runtime, not in the editor), it renders fine.

    So the issue seems to be that the first time you create a mesh section at runtime with a translucent material it doesn't render. You have to clear it once, then create it again for it to render.

    As a test, I just swapped the code over to use PMC instead and it works fine. The mesh renders first time every time with a translucent material. So it appears to be an issue with RMC.

    Leave a comment:


  • replied
    Originally posted by rizzlewizzle View Post
    Ahh ok, thanks Koderz! I will look into it some more and see if I can come up with a new method of achieving what I am looking for.
    You're welcome! Good luck! My only suggestion would be to take world position in Z and localize it to a starting/ending height you want to blend between and then lerp between the two colors. There's probably a better way but that's a quick way to do it.




    Originally posted by ambershee View Post
    I've started playing with RMC today, have been backporting an example into C++, and I'm having some trouble actually generating something visible. As far as I can tell, everything I'm passing into CreateMeshSection is valid, and it isn't dropping out early, but I never see anything in the engine.

    Here's a snippet - am I missing something obvious / vital?
    Looking at it, the only thing that stands out as potentially a problem is registration. You're not giving it a parent object or registering it.



    Code:
    		
    		URuntimeMeshComponent* NewTile = NewObject<URuntimeMeshComponent>(this);
                    NewTile->RegisterComponent();
    		NewTile->SetupAttachment(RootComponent);
    but if you're in the constructor then the easier way is just
    Code:
    		
    		URuntimeMeshComponent* NewTile = CreateDefaultSubobject<URuntimeMeshComponent>(TEXT("TerrainTile"));
                    RootComponent = NewTile;

    (All of the above is done by memory, as I'm not at my desk atm, but I think it's right)

    Leave a comment:


  • replied
    I've started playing with RMC today, have been backporting an example into C++, and I'm having some trouble actually generating something visible. As far as I can tell, everything I'm passing into CreateMeshSection is valid, and it isn't dropping out early, but I never see anything in the engine.

    Here's a snippet - am I missing something obvious / vital?
    Code:
    		//URuntimeMeshComponent* NewTile = CreateDefaultSubobject<URuntimeMeshComponent>(TEXT("TerrainTile"));
    		URuntimeMeshComponent* NewTile = NewObject<URuntimeMeshComponent>();
    		NewTile->SetupAttachment(RootComponent);
    
    		//NewTile->bUseComplexAsSimpleCollision = true;
    		//NewTile->bShouldSerializeMeshData = true;
    
    		NewTile->SetRelativeLocation(RelativeTileLocations[TilesToSpawn - 1]);
    
    		TArray<FVector> Vertices;
    
    		for (int i = 0; i < TilesPerAxis; i++)
    			for (int j = 0; j < TilesPerAxis; j++)
    			{
    				FVector NewVert = FVector(0, 0, 0);
    
    				NewVert.X = j * (TileSize / TilesPerAxis);
    				NewVert.Y = i * (TileSize / TilesPerAxis);
    
    				Vertices.Add(NewVert);
    			}
    
    		int32 NumRowsColumns = FMath::TruncToInt(FMath::Sqrt(Vertices.Num()));
    
    		TArray<FVector2D> UVs;
    
    		//££ Todo: Duplicate UVs into Lightmap UVs.
    		TArray<FVector2D> LightmapUVs;
    
    		//Calculate UVs
    		for(int i = 0; i < NumRowsColumns; i++)
    			for (int j = 0; j < NumRowsColumns; j++)
    			{
    				FVector2D Coords = FVector2D(j * TileSize, i * TileSize);
    				UVs.Add(Coords);
    			}
    
    		//Generate Tris
    		TArray<int32> Triangles;
    
    		UKismetProceduralMeshLibrary::CreateGridMeshTriangles(NumRowsColumns, NumRowsColumns, true, Triangles);
    
    		//Calc Tangents
    		TArray<FVector> Normals;
    		TArray<FProcMeshTangent> KPTangents;
    
    		UKismetProceduralMeshLibrary::CalculateTangentsForMesh(Vertices, Triangles, UVs, Normals, KPTangents);
    
    		TArray<FRuntimeMeshTangent> Tangents;
    
    		for (FProcMeshTangent Tangent : KPTangents)
    		{
    			FRuntimeMeshTangent NewTangent = FRuntimeMeshTangent(Tangent.TangentX, false);
    
    			Tangents.Add(NewTangent);
    		}
    
    		//££ build black/white colour array.
    		TArray<FLinearColor> VertexColours;
    
    
    		//void URuntimeMeshComponent::CreateMeshSection_Blueprint(int32, const TArray<FVector, FDefaultAllocator> &, const TArray<ElementType, FDefaultAllocator> &, const TArray<FVector, FDefaultAllocator> &, const TArray<FRuntimeMeshTangent, FDefaultAllocator> &, const TArray<FVector2D, FDefaultAllocator> &, const TArray<FVector2D, FDefaultAllocator> &, const TArray<FLinearColor, FDefaultAllocator> &, bool, EUpdateFrequency)': cannot convert argument 7 from 'int' to 'const TArray<FVector2D, FDefaultAllocator> &'
    		NewTile->CreateMeshSection_Blueprint(0, Vertices, Triangles, Normals, Tangents, UVs, LightmapUVs, VertexColours, true, EUpdateFrequency::Frequent);
    
    		NewTile->SetMaterial(0, Material);
    Last edited by ambershee; 10-18-2016, 01:15 PM.

    Leave a comment:


  • replied
    Ahh ok, thanks Koderz! I will look into it some more and see if I can come up with a new method of achieving what I am looking for.

    Leave a comment:


  • replied
    Originally posted by rizzlewizzle View Post
    Hi,

    I don't know if this is possible but I have been trying to set the animated mesh to use a custom material that varies in colour with world position (varying from blue to red in the z-direction). The material works with other meshes but not the RMC. Is there any way to get this to work with the RMC? I'm pretty new to UE4 so don't fully understand how the RMC works. Images attached.
    If I'm not mistaken, the WorldAlignedBlend works by blending on the normal of the mesh, not the z position of the vertex like what it sounds like you're wanting. The RMC will work fine with either case, but that plane doesn't have its normals computed as there's 600k vertices IIRC and the usual normal/tangent calculator is entirely too slow to calculate that in real-time. With something like the cubes in that scene it should work correctly.

    Leave a comment:


  • replied
    Originally posted by wilberolive View Post
    @Koderz I'm not sure if I've found a bug or if this is just the way it is supposed to work.

    For some reason CreateMeshSection() was failing to create a mesh, even though all the inputs were valid (I stepped though my C++ and inspected them). After calling it, the RMC was still showing as having no mesh sections internally. After hours of scratching my head and fiddling I eventually figured out that it has to do with the way you create the FBox bounding box. It turns out my FBox was not valid.

    Here is the code I was using.

    Code:
    FBox Bounds;
    Bounds.Min.Set(Start.X, Start.Y, 0.0f);
    Bounds.Max.Set(End.X, End.Y, Z);
    Looks perfectly fine. However, the problem is that the internal FBox IsValid flag is not being set since I'm setting the Min/Max directly rather than going through the FBox constructor. So I changed the code to this.

    Code:
    FBox Bounds = FBox(FVector(Start.X, Start.Y, 0.0f), FVector(End.X, End.Y, Z));
    Now the IsValid flag is being set and CreateMeshSection() produces a mesh section. Great!

    So my question... Is this intended? Seems odd that the mesh section isn't created just because the IsValid flag was not set. It means you have to always create the FBox using one of its constructors. You can't manually create an FBox.

    This is indeed intended behavior. If the box is not valid, it can't be used for culling and such so it will bail when it sees an invalid box. In editor it should log an error message, in a packaged game it will outright crash you. Those are picked up by the validation logic which can be found at the top of RuntimeMeshComponent.h

    As for creating the box, there's a couple ways to do it. First is like you just showed...

    Code:
    FBox Bounds = FBox(FVector(Start.X, Start.Y, 0.0f), FVector(End.X, End.Y, Z));
    The next would be like you did originally with 1 addition.

    Code:
    FBox Bounds;
    Bounds.Min.Set(Start.X, Start.Y, 0.0f);
    Bounds.Max.Set(End.X, End.Y, Z);
    Bounds.IsValid = true;
    The third way is useful when you just need to sum up the points and don't know directly which is to do something along the lines of...

    Code:
    FBox Bounds(0);
    Bounds += Point;
    where 'Point' is a FVector point that the box needs to adjust to fit.

    I hope that helped!

    Leave a comment:


  • replied
    Hi,

    I don't know if this is possible but I have been trying to set the animated mesh to use a custom material that varies in colour with world position (varying from blue to red in the z-direction). The material works with other meshes but not the RMC. Is there any way to get this to work with the RMC? I'm pretty new to UE4 so don't fully understand how the RMC works. Images attached.

    Thanks in advance!

    RMC(with edited height variable):
    Click image for larger version

Name:	RMCwithMaterial - Copy.PNG
Views:	1
Size:	478.0 KB
ID:	1116670
    Custom material:
    Click image for larger version

Name:	customMaterial.PNG
Views:	1
Size:	347.1 KB
ID:	1116671
    Attached Files

    Leave a comment:


  • replied
    [MENTION=141752]Koderz[/MENTION] I'm not sure if I've found a bug or if this is just the way it is supposed to work.

    For some reason CreateMeshSection() was failing to create a mesh, even though all the inputs were valid (I stepped though my C++ and inspected them). After calling it, the RMC was still showing as having no mesh sections internally. After hours of scratching my head and fiddling I eventually figured out that it has to do with the way you create the FBox bounding box. It turns out my FBox was not valid.

    Here is the code I was using.

    Code:
    FBox Bounds;
    Bounds.Min.Set(Start.X, Start.Y, 0.0f);
    Bounds.Max.Set(End.X, End.Y, Z);
    Looks perfectly fine. However, the problem is that the internal FBox IsValid flag is not being set since I'm setting the Min/Max directly rather than going through the FBox constructor. So I changed the code to this.

    Code:
    FBox Bounds = FBox(FVector(Start.X, Start.Y, 0.0f), FVector(End.X, End.Y, Z));
    Now the IsValid flag is being set and CreateMeshSection() produces a mesh section. Great!

    So my question... Is this intended? Seems odd that the mesh section isn't created just because the IsValid flag was not set. It means you have to always create the FBox using one of its constructors. You can't manually create an FBox.

    Leave a comment:


  • replied
    Hi

    I tried to compile this plugin for PS4 and Linux and it seems like your code has some issues with clang. We implemented some workarounds but you might want to look into it

    Leave a comment:


  • replied
    Originally posted by Koderz View Post
    I'll let you know when the normal/tangent work is done and pushed to github! (It's the next thing being pushed once I find one last bug) The smc->rmc conversions are done on github.
    Thanks for the update. Super excited about the work you are doing. I've only been using the v1.2 plugin at the moment as I'm not really familiar with the process of compiling and installing a plugin from GitHub.

    Leave a comment:


  • replied
    First off. Sorry for the delay everyone, I am still working on v2 very slowly, just haven't had much time due to other things going on. I hope to get everything but collision fully finalized this week, not sure about collision as it requires me having more time to work in one consecutive shot then I've had recently.

    [MENTION=28104]wilberolive[/MENTION] I'll let you know when the normal/tangent work is done and pushed to github! (It's the next thing being pushed once I find one last bug) The smc->rmc conversions are done on github.
    [MENTION=19211]Thumper[/MENTION]...

    Wilber is on the right track, so I'll break down the major areas that affect what it sounds like you're trying to do...

    First up the difference between BeginMeshSectionUpdate/EndMeshSectionUpdate and UpdateMeshSection is that the first allows you to access and edit the RMC's stored version which removes one potentially costly copy operation and also allows you to skip storing it yourself as well.
    The problem is for both of these paths the next part is identical. When you commit an update either view EndMeshSectionUpdate or implicitly in UpdateMeshSection it copies the entire section and passes is to the render thread, which then locks a GPU buffer and copies that data to the GPU. This means that there's 2 types of impact you'll get from this. first is the obvious time to copy those 2 times, and the second is the time required to lock the GPU buffer. So many tiny buffers updating frequently can be slow dominated by lock time, and giant buffers are slow due to copy time.

    The other thing that's probably the far bigger factor is collision, and I'd be interested to see what the performance difference is for you with collision off. Unfortunately the PMC and RMC (Currently) have a rather brute force setup for collision. For PhysX (The underlying physics engine) to work with things like static meshes it must first 'cook' them which does a list of things to improve detection performance. The problem is this is slow (like 20+ms slow in some cases) and will very quickly destroy your fps. This is the big thing I'm working on for v2, and hope to have a testable version here pretty quick.
    The quick breakdown on the collision issue with the PMC/RMC is when you update any 1 section, it will cause that entire PMC/RMC to batch all the sections back together into one giant mesh and send it to the PhysX cooker on the game thread thereby halting your execuation while it cooks.

    What you can do for now is like wilber said, divide up the mesh, and if you're using collision separate them between multiple RMC's to reduce the collision impact. This will increase draw calls, but it should reduce update times substantially.

    Leave a comment:


  • replied
    Originally posted by Thumper View Post
    When I move those polygons I see my frame rate dip down (below 90 FPS because I'm in VR).
    Now I could be off base with this as I'm no expert on the subject. However, I believe that the entire list of vertices needs to be pushed to VRAM regardless of how many you actually change. So it makes sense that a list of ~700k vertices will take more time to send across than a ~200k list. At least my own testing verified this for me, so that's the assumption I'm rolling with for now until corrected.

    So what I did to get around the problem was to break my world up into multiple RMC's. I used a quad-tree approach to break the world up into even square chunks. Vertices are then assigned to a chunk based on their initial world location. So instead of one RMC with ~700k vertices, you end up with say 16 RMC's with ~40k vertices each. Then when you update a triangle, you are only updating that one chunk. I can now update multiple chunks every frame with no noticeable hit on frame time.

    Bare in mind that this approach results in 16 draw calls as opposed to 1 draw call. That was an acceptable trade-off for me as I update the chunks frequently. You would need to decide what is acceptable to you based on how often you update.

    Oh and one more thing... don't try any of this in BP. Stick to C++ for this kind of stuff. Not just for the performance of it, but because BP would get out of control with the math and what not going on.
    Last edited by wilberolive; 09-18-2016, 09:56 PM.

    Leave a comment:


  • replied
    When you update faces in place does it really matter how large the container is (within reason)? For instance I have a container that has 737,280 triangle faces in it. Now I want to move 13 polygons to a new location. My polygons have collision on them. When I move those polygons I see my frame rate dip down (below 90 FPS because I'm in VR). However if I do the same thing on the next subdivision level lower (184,320 triangles), my framerate is fine. It's still only modifying 13 triangles, and the matter in which those triangles are discovered is identical. There's a visible stutter in the CV1 when I use the higher subdivision container. Any ideas how I can improve this?

    Leave a comment:

Working...
X