Vertex color ignored for FCanvasTriangleItem with material

I’m drawing a triangle onto an FCanvas and the VertexColor node is coming through as white in my material. Looking through the code to try to track down why, I see that in FCanvasTriangleItem::Draw, if the material is non-null, the code path ends up calling FTriangleRenderer::DrawTriangle with a default argument for InVertexColor. The vertex colors specified on the FCanvasUVTri are not used at all. If there is no material, everything works as expected.

Is this a bug? If it’s intended, is there some other process I should be using instead of this? I’m attempting to draw some primitives from an ICustomSlateElement and need to pass through vertex color to the material for each triangle.

Hey -

Could you post the code you’re using to make your draw calls? I would like to try reproducing this on my machine however I’m not sure I can follow your steps from the description. Looking at the code directly will help me setup a test case for myself.

Cheers

Hi .
There’s no need to recreate the custom slate context in which I’m doing this, this behaviour can be observed anywhere you try to draw a triangle onto a canvas with a material. In fact I’ve just experimented and found it’s super easy to reproduce.

Create a HUD blueprint and override the drawing as below.

The material you hook up should just be an unlit material which plugs a VertexColor node directly into the emissive. Enable your HUD class in your game mode and run. No matter what color you set in the DrawMaterialTriangle node, the triangle will be white.

The cause is:

  1. FCanvasTriangleItem::Draw, when MaterialRenderProxy is not null, calls FCanvasTriangleRendererItem::AddTriangle (with the correct triangle vertex colors).

  2. FCanvasTriangleRendererItem::Render_RenderThread delegates to FTriangleRenderer::DrawTriangle.

  3. FTriangleRenderer::DrawTriangle takes in the FCanvasUVTri (which contains the vertex color data), but also takes in a parameter InVertexColor, which defaults to white. It then uses this to set the colors of all three vertices and ignores the colors in the FCanvasUVTri.

Hey -

UI only relates to screen space rather than 3D space. The Draw Material triangle node is passing a 2D vector to the material, however the Vertex Color node is expecting a 3D vector so it doesn’t know what to do with what is being passed in. Since there is no depth component the value passed in is ignored. With the default VertexColor node plugged into the emissive of your material it will appear white. Using a vector 3 node to set the emissive color in the material will change the color of the triangle in game.

Cheers

Sorry I don’t follow. The VertexColor node exposes the color value interpolated between colors attached to each vertex. This interpolation is valid regardless of whether the primitive was specified in 3D or screen space. It works just the same was as the UV interpolation, which is working correctly.

The DrawMaterialTriangle node has a color pin for each vertex, the only reason to have these pins is to pass them through to the material via the VertexColor node. Currently they are ignored in the code I referenced, and as such are serving no purpose.

Just to be sure, I just made the obvious fix to the code in my local github clone and it now produces the expected behaviour. I could submit it as a pull request but it seems unnecessary since the change takes 1 minute to make.

Hi -

I have placed a bug report in as UE-18707 and will keep you informed as we investigate a solution. If you feel that you have already implemented a successful solution I do recommend submitting a pull request and reference the UE number listed above.

Thank You

Eric Ketchum

Okay, pull request submitted.
Cheers.