Nvg gradient functions do not work correctly for transparent colors

Version: 1.6.34.0

Frequency: Consistently

Severity: Low
Low - quality of life, workflow optimization, rare enough to not impact production, etc…

Context: any wasm gauge using nanovg

Similar MSFS 2020 issue: same issue in 2020

Bug description:

Gradient functions from nanoVG library like nvgLinearGradient work fine for solid colors, but don’t work for colors with alpha less than 1.0f. With alpha, they sometimes create gradient paint using only the start color, or gradient transition, but output colors are wrong.

Hard to make the fancy drop shadows in modern avionics without that working correctly.

Repro steps:

This is easily visible when you compare the nvg demo as it shows in wasm gauge sample aircraft from SDK to how it looks rendered outside the simulator using different nvg implementation. Note the box shadow under windows or color picker elements is just a uniform rectangle in MSFS

Attachments:

After further testing, the alpha is doing “something”, but not what’s expected. It also generates different result depending on whether the gradient goes from opaque to transparent, or from transparent to opaque. It looks like the underlying renderer is not interpreting correctly the alpha channel calculated by the nvg gradient function. Maybe a problem with premultiplied alpha.

Here’s a code drawing a red→transparent and transparent→red gradient over blue background:

nvgFillColor(g, nvgRGBA(0, 0, 255, 255));
nvgBeginPath(g);
nvgRect(g, 0, 0, 640, 480);
nvgFill(g);

//gradient red to transparent
auto paint = nvgLinearGradient(g, 0, 0, 320, 0, nvgRGBA(255, 0, 0, 255), nvgRGBA(255, 0, 0, 0));
nvgFillPaint(g, paint);
nvgBeginPath(g);
nvgRect(g, 0, 0, 320, 480);
nvgFill(g);

//gradient transparent to red
paint= nvgLinearGradient(g, 320, 0, 640, 0, nvgRGBA(255, 0, 0, 0), nvgRGBA(255, 0, 0, 255));
nvgFillPaint(g, paint);
nvgBeginPath(g);
nvgRect(g, 320, 0, 320, 480);
nvgFill(g);

Here’s the expected result:

Here’s what MSFS produces: