leozide / leocad

A CAD application for creating virtual LEGO models
https://www.leocad.org
2.47k stars 210 forks source link

Transparent colors need to be exported as transparent/alpha materials/shaders #797

Closed nathaneltitane closed 2 years ago

nathaneltitane commented 2 years ago

Describe the bug Currently, none of the export formats seem to translate/export the LDRaw transparent colors with alpha transparency (at the very least)

All parts with that are assigned a transparent part color turn out solid when loaded into a viewer (blender, webgl, threejs or others)

To Reproduce Steps to reproduce the behavior: open model select part assign transparent color from color palette File > export > collada/3ds/wavefront

Expected behavior colors with transparency/translucency should reflect at the very least with some alpha channel being enabled in the export file

Screenshots Screenshot_20220401_221225

Version (please complete the following information): continuous - all

leozide commented 2 years ago

translucent colors are exported correctly, make sure you're in material mode in blender

nathaneltitane commented 2 years ago

@leozide I used blender to quickly verify the validity. it seems that any viewer I use (threejs webgl, sketchfab) keeps all the values solid (no alpha)...

nathaneltitane commented 2 years ago

@leozide I used blender to quickly verify the validity. it seems that any viewer I use (threejs webgl, sketchfab) keeps all the values solid (no alpha)...

Genome36 commented 2 years ago

translucent colors are exported correctly, make sure you're in material mode in blender

Hello @leozide, I have exported 4 peices with different materials to experiment with. Screenshot from 2022-04-08 20-41-25

It seems you have a problem with your Collada exports. The RGBA value that you are assigning in the .dae file under the transparent tag is erroneous and should be applied to the transparency tag additionally/instead. code_error

On another hand, taking a look at your Wavefront exports shows that you have correctly assigned the transparency within the d value. Serving to reinforce that the current transparency value in Collada is a bug. code_correct_obj_trans

Lastly, importing the Wavefront to Blender shows the correct transparency of 0.94 (240 / 255 -> 0.941176471) blender_correct_obj_trans

P.S.: Manually changing the transparency tag within Collada yields the correct outcome within Blender too. blender_333_markup

nathaneltitane commented 2 years ago

furthermore: nothing seems to be wrong with the current viewer in terms of alpha transparency rendering: wavefront works just fine.

here is also a very interesting outcome - exported model from leocad to collada (renders opaque):

Screenshot_20220418_100534

import same collada into blender and re-export back to same file as collada (renders translucent):

Screenshot_20220418_100755

output file from blender is attached (added suffix for upload to github) vf-1s-super-fighter.dae.txt

leozide commented 2 years ago

It seems you have a problem with your Collada exports. The RGBA value that you are assigning in the .dae file under the transparent tag is erroneous and should be applied to the transparency tag additionally/instead. code_error

No, the transparent alpha gets multiplied by transparency so the export is correct. The spec is clear about this:

If either or exists then transparency rendering is activated, the renderer needs to turn on alpha blending mode, and the following equations define how to combine the two values. Use these equations to get the correct results based on the opaque setting of , where fb is the frame buffer (that is, the image behind what is being rendered) and mat is the material color before the transparency calculation. • In A_ONE opaque mode: result.r = fb.r (1.0f - transparent.a transparency) + mat.r (transparent.a transparency) result.g = fb.g (1.0f - transparent.a transparency) + mat.g (transparent.a transparency) result.b = fb.b (1.0f - transparent.a transparency) + mat.b (transparent.a transparency) result.a = fb.a (1.0f - transparent.a transparency) + mat.a (transparent.a transparency)

nathaneltitane commented 2 years ago

@Genome36 ^^

nathaneltitane commented 2 years ago

It seems you have a problem with your Collada exports. The RGBA value that you are assigning in the .dae file under the transparent tag is erroneous and should be applied to the transparency tag additionally/instead. code_error

No, the transparent alpha gets multiplied by transparency so the export is correct. The spec is clear about this:

If either or exists then transparency rendering is activated, the renderer needs to turn on alpha blending mode, and the following equations define how to combine the two values. Use these equations to get the correct results based on the opaque setting of , where fb is the frame buffer (that is, the image behind what is being rendered) and mat is the material color before the transparency calculation. • In A_ONE opaque mode: result.r = fb.r (1.0f - transparent.a transparency) + mat.r (transparent.a transparency) result.g = fb.g (1.0f - transparent.a transparency) + mat.g (transparent.a transparency) result.b = fb.b (1.0f - transparent.a transparency) + mat.b (transparent.a transparency) result.a = fb.a (1.0f - transparent.a transparency) + mat.a (transparent.a transparency)

Ref to spec please?

Genome36 commented 2 years ago

@leozide It appears you have not respected the Collada spec sheet properly. Collada 1.4.1 indeed specifies that the alpha should be calculated with the equation; yet it also says that if the Transparency tag is given then transparent and transparency are both honoured and taken into account for the calculation.

the Transparent tag is used for Alpha Blending Modes, all other types use the Transparency tag instead. The only problem is that not everyone wants to use alpha blending and you are also always specifying Transparency as float(1.0). If you are going to add the Transparency tag then at least honor the specification by giving it the same value as the Alpha component.

Screenshot_20220419-154835_Drive

nathaneltitane commented 1 year ago

Ref: https://github.com/f3d-app/f3d/issues/1000

nathaneltitane commented 1 year ago

@leozide

seems the collada exporter is the issue after all:

I managed to get three.js webgl rendered to render translucent parts by adding the opaque declaration to the tag

image

effects/materials declarations should be revised to include at least opaque="A_ONE" or some kind of option for export preferences to set the opaque type on export in the settings.

Before and after:

image

Spec discussion:

https://community.khronos.org/t/transparent-and-transparency-revisited/5962

nathaneltitane commented 1 year ago

also ref:

https://github.com/mrdoob/three.js/issues/2210

https://github.com/ros-visualization/rviz/issues/995

mwestphal commented 1 year ago

I did not read the whole issue but the "Loading data in F3D issue" is caused by this assimp issue: https://github.com/assimp/assimp/issues/5234

nathaneltitane commented 1 year ago

I did not read the whole issue but the "Loading data in F3D issue" is caused by this assimp issue: assimp/assimp#5234

@mwestphal as discussed over on discord, I managed to pinpoint the fact that the collada export as generated by leocad fails to explicit the opacity argument for the tag

one thing i would like to add is that it would also be more within known standards to actually have the transparency float be 0 and call opacity as A_ZERO to better reflect the 0-255 or 0-100 gradation of an opacity scale, translating the result into transparency (0 being fully transparent, 1 being fully opaque)