Jump to content
JackT

Firemonkey 3D vertex and fragment shading

Recommended Posts

I wish to use some thing like a TMesh component and be able to assign a color value dynamically to each vertex for the purpose of producing a color map for data cluster visualisation.

 

Is there an easy way to do this in firemonkey ?

 

Thanks for any help in advance.

 

 

Jack T

Share this post


Link to post

Hi !

Short answer  : No, afaik.

But it is very possible.


In fact, there are 3 things to do : 

1 - Build a TMesh descendant, with "Color0[index]"  affected (near vertices). (You certainly do it for your project ?) 

 

2 - You cannot use "standart" TMesh, because they are build with this VertexBuffer : 

  FVertexBuffer := TVertexBuffer.Create([TVertexFormat.Vertex, TVertexFormat.Normal, TVertexFormat.TexCoord0, TVertexFormat.BiNormal, TVertexFormat.Tangent], 0);
  FIndexBuffer := TIndexBuffer.Create(0, TIndexFormat.UInt32);

As you can(not) see there is a lack of TVertexFormat.Color0 in the stuff.

So, when you build your new mesh, make a meshData.ChangeFormat to include it.

 

3 - Here is the "hard" part.

As we change the vertexBuffer format, the materialSource will not be compatible anymore. It's not an issue, because all of them do not process Color's vertices indexed buffer (because they are directly linked to the TVertexBuffer's format).

-> You have to do your own MaterialSource, which take care of that data.

If your have an exemple of a mesh, I can see if I can adapt an old MaterialSource that I commited years ago 🙂

Vincent
 

Edited by Vincent Gsell

Share this post


Link to post

Retrieve my code, dig in paleo stuff of last decade 🙂

Is that do you need ? 

image.thumb.png.5bce070810e9af942ddc6cf4bbe38e50.png

 

Edited by Vincent Gsell

Share this post


Link to post

Thanks for the reply. That code looks like the kind of think I need to do.  So as you said there don't seem to be any built in materials or shaders in firemonkey that are set up to do this.

I found an article that goes through the steps you need to create custom TMaterial and shaders so you are right it looks like I can have a go at coding it myself.

 

https://blog.grijjy.com/2021/01/14/shader-programming/

 

I will give it a go and report back. 

Share this post


Link to post
12 hours ago, JackT said:

there don't seem to be any built in materials or shaders in firemonkey

As far as I know, yes. In fact, the only mention of "color0" buffer pipe part is used in FMX.Canvas.GPU. None of TMesh declaration use it. So, I'm pretty sure that vertice's indexed color is not implemented shader side.

In fact, it is a little bit weird, but it is undestandable because of memory bandwitch needed in this type of colored mesh.

 

12 hours ago, JackT said:

Yeah, it is certainly one of the best source actually ! (it is in GitHub too) - At the time I did this, it was mainly based upon the Embarcadero demo "lowlevel3d", wich is a bit more complex/less documented 🙂

12 hours ago, JackT said:

so you are right it looks like I can have a go at coding it myself.

Personnaly, it make me happy to retrieve this code, I will certainly convert it on grijjy methodology, clean it up, remove old support lib, and perhaps put it on my git. 

 

Share this post


Link to post

Yes, it is an option, but it not the same thing !

 

In this demo, a texture is used as a color Palette : This work well in 2 situations

- huge number of vertices

- small change of color value between same face's (i.e. triangles) vertices 

In this demo, it is masterized, and work well.

 

In fact, this technique could be used, but is usually used to fix the very same color at an entire "face", else, you got color distortion effect.

 

The "Color0" buffer, is not same things : Color is not indexed in a texture, but directly assigned "in/near" the vertex data (please see the code in the capture). The hardware will then set a linear color distribution between vertices.

This work well in the situation of  "great" space between vertices (zoome situation, typically)

 

In fact, technicaly, it is not the same memory bandwitch : Color0 can take more memory than a texture, it depends.

 

It is linked too on the use case and final render that we need. In map, scientific image or chart, the color index is usually used.

 

 

@JackT : If used a texture could match, you do not have to rewrite a shader, but it depends what do you need : In the description of your use case, I interpret it as the need of linear color rendering.

 

Edited by Vincent Gsell

Share this post


Link to post

I have a grid of 64 sensors that are measuring magnetic fields in the range 0 to 150 Hz. The grid is non rectelinear. The idea was to build a mesh in  the shape of the grid and then use a shader to set positive values red and negative values blue in real time.

 

So all I really need to do is to pass a float in along with each vertex. I have started learning high level shader language to try to accomplish this. 

 

Best Regards,

 

 

Jack T

 

Share this post


Link to post

Update

I have managed to make my own TMaterial(s) and TMaterialSource(s) for direct X11 and write my own rudimentary shaders in hlsl.

 

The only problem I have found is with the example code is where TCustomDX9Context / TCustomDx11Context etc is defined so I have had to comment some checks out in order to get the materials to work.

I don't know where these classes have been moved to in Rad Studio 12.

I am working purely on the windows platform so this isn't a big issue.

 

Thanks for your help

 

Best Regards

 

Jack T

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×