Skip to content
This repository was archived by the owner on Dec 22, 2023. It is now read-only.

Error in techniques for VC model #8

Closed
javagl opened this issue Nov 20, 2016 · 3 comments
Closed

Error in techniques for VC model #8

javagl opened this issue Nov 20, 2016 · 3 comments

Comments

@javagl
Copy link
Contributor

javagl commented Nov 20, 2016

This may be a very specific issue, and awfully hard to debug (that's why I'm writing this at 3:30am).

There are other techniques that involve transparency (for example, for the windows of the aircrafts), and they contain the proper technique states with GL_BLEND, as well as the technique.states.functions. I also have an old copy of the VC model (from ~6 months ago, where it was still called vc, with lowercase names), and there, the technique that is used for this transparent texture image seems to be right.

I tried to go though the Git history, but it's hard to track this down, because there are some renamings and cases where all models have been re-generated. Someone with advanced Git-foo might have more luck here.


Possibly unrelated, but the context in which I noticed this:

I tried to get rid of the infamous "boxes" that have been reported in KhronosGroup/glTF#576 and that also still appeared in JglTF. Comparing the renderers from https://github.com/cx20/gltf-test (nice project, btw) showed that the boxes

  • do not appear in Three.js, Babylon.js and Cesium.js
  • do appear in xeogl and GLBoost (and in JglTF - I'm working on that)

It has something to do with transparency, blending, rendering order etc. I noticed that when changing the blend functions from 1 and 771 (GL_ONE and GL_ONE_MINUS_SRC_ALPHA) in the technique state functions...

                "blendFuncSeparate": [
                    1,
                    771,
                    1,
                    771
                ],

...to 770 (GL_SRC_ALPHA) and 771

                "blendFuncSeparate": [
                    770,
                    771,
                    770,
                    771
                ],

it seems to render properly. But this was just found out with trial-and-error. I thought that KhronosGroup/glTF#747 (and the linked pulls/issues) might be related, but the order of the parameters seems right. I read more about all this in the OpenGL docs, started looking at the .DAE input files and reading the COLLADA spec, and the section about "Determining Transparency (Opacity)" contains lots of information about the different cases, talking about A_ONE and A_ZERO opacity modes, where "transparency" sometimes means "transparency", and sometimes "transparency" means "opacity" (!!!). (Frankly: This is a mess...)

However, I'll probably try to create another "minimal example", consisting of two triangles, one opaque and one semi-transparent (and maybe something with a semi-transparent PNG). These examples could allow to quickly and easily check whether a renderer shows the intended behavior in regards to transparency handling. Right now, it's hard to say what the "intended behavior" is.

(BTW: Note that, in the renderer comparison mentioned above, Cesium.js also renders the heli propeller texture as a completely opaque one, although it should be transparent - but this is likely only caused by the error in the input file)

Edit:

Since I'm not sure whether this is an issue of glTF and the spec, the sample models (where VC unfortunately is the only one that uses technique.states.functions!), or the renderer implementation, I opened another issue detailing all this (and including a "simple test case") at javagl/JglTF#6

And another edit:

For a test, I uploaded the model from javagl/JglTF#6 to http://cesiumjs.org/convertmodel.html and it looks nice and correct. However, it also looks nice and correct when using

"blendFuncSeparate": [ 0, 0, 0, 0],

so I guess that this property is not taken into account at all. And at the moment, I think if it was taken into account, the settings

"blendFuncSeparate": [ 1, 771, 1, 771],

(that are currently used in the VC model) would cause the output to look like the first screenshot in the JglTF issue. But I might be utterly and embarassingly wrong here.

And a last edit - sorry about that:

The nice, correct rendering in Cesium is achieved by the order independent transparency. When disabling OIT, it looks like expected: With FUNC_ADD, and a completely transparent blue source (multiplied with GL_ONE (!)), and an opaque red destination (multiplied with GL_ONE_MINUS_SRC_ALPHA), the result is magenta. I don't think that this is the "right" way of blending, and think that the source factor should be GL_SRC_ALPHA (because that's what the alpha is for), but I think it is reasonable to say that, without OIT, there is no "right" way of blending anyhow...

@pjcozzi
Copy link
Member

pjcozzi commented Nov 23, 2016

@javagl thanks for all the research. Is this now duplicate with KhronosGroup/glTF#576? Should we consolidate these issues?

@javagl
Copy link
Contributor Author

javagl commented Nov 23, 2016

They are related, at least.

This issue only refers to the fact that a technique that eventually refers to a semi-opaque PNG does not contain the GL_BLEND state - but I think that it has to contain this, in order to be rendered properly (and in a previous version, it did contain it).

If it contained the GL_BLEND state, it would require additional techniques.states.functions - and this is the relationship to the other issue:

The issue 576 asked about these boxes. They appear in "non-sopisiticated" renderers (that do not use OIT or other fancy stuff). The reason of why the boxes appear is what I currently consider as an error in the glTF file: I think that that blendFuncSeparate parameters are wrong for transparent materials. At least, using GL_SRC_ALPHA for the source seems to be intuitively reasonable, and at corresponds to the "typical" setting that is also mentioned in https://www.opengl.org/archives/resources/faq/technical/transparency.htm#blen0020

I wondered about where to report this: Here in glTF-Sample-Models, or in COLLADA2GLTF, or the gltf-pipeline? You added the collada2gltf label at the other issue, and that's certainly a reasonable point to start investigating both issues (although one could first check whether the technique is already wrong or ambiguous in the .DAE input file, and only start digging deeper if not)

EDIT: From a quick glance, at least the technique.states.functions part seems to be based on the premultipledAlpha setting ( https://github.com/KhronosGroup/COLLADA2GLTF/blob/master/shaders/commonProfileShaders.cpp#L385 ). I'll have to read more about this. Sorry for bothering you.

@javagl
Copy link
Contributor Author

javagl commented Nov 24, 2016

So I'll have read more about premultiplied alpha (which is ENabled in WebGL by default, but DISabled in OpenGL usually), find the answer to the question of whether the fragment shader should be

gl_FragColor = color;
gl_FragColor = color * u_transparency;
gl_FragColor = vec4(color.rgb * diffuse.a, diffuse.a * u_transparency);
gl_FragColor = vec4(color.rgb * diffuse.a * u_transparency, diffuse.a * u_transparency);

(or whatever) in conjunction with the premultiplied alpha setting, and figure out how to render two assets at the same time, one with premultiplied alpha and one without. But all this is probably only an issue of the renderer implementation, and not of the sample models. Sorry again for the noise caused by my lack of knowledge here.

The texture is still rendered in "opaque black" in cesium, but maybe this is not an issue.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants