A little while ago I said I would revisit the handling of transparency in the Collada plugin. To that I end I started a thread on the Collada forum asking for help interpreting the spec in this area.

https://collada.org/public_forum/viewtopic.php?t=1210

Since tumbleweeds now appears to be blowing across that thread I, I thought I would try a different approach. I will attempt to set out a suggested mapping between a Collada FX Common profile effect containing a Blinn technique, and OpenGL fixed functionality, and then throw this open to comments/assistance in this forum.

The blinn element schema looks like this

<xs:element name="blinn">
<xs:complexType>
<xs:sequence>
<xs:element name="emission" type="fx_common_color_or_texture_type" minOccurs="0" />
<xs:element name="ambient" type="fx_common_color_or_texture_type" minOccurs="0" />
<xs:element name="diffuse" type="fx_common_color_or_texture_type" minOccurs="0" />
<xs:element name="specular" type="fx_common_color_or_texture_type" minOccurs="0" />
<xs:element name="shininess" type="fx_common_float_or_param_type" minOccurs="0" />
<xs:element name="reflective" type="fx_common_color_or_texture_type" minOccurs="0" />
<xs:element name="reflectivity" type="fx_common_float_or_param_type" minOccurs="0" />
<xs:element name="transparent" type="fx_common_transparent_type" minOccurs="0" />
<xs:element name="transparency" type="fx_common_float_or_param_type" minOccurs="0" />
<xs:element name="index_of_refraction" type="fx_common_float_or_param_type" minOccurs="0" />
</xs:sequence>
</xs:complexType>
</xs:element>

So Collada is giving us emission, ambient, diffuse, and specular elements which can be either a fixed colour or a variable colour acquired from a texture map. In the OpenGL pipeline the lighting calculations are done prior to the fragment shading. The only exception is the specular highlighting which we can optionally postponed until after the fragment shading phase. So I would suggest that the starting position is that any textures in the emission, ambient, and specular elements are ignored. If a texture exists in the diffuse element then a default value (probably white) can be applied as the fixed diffuse colour and the texture used to modulate (GL_MODULATE)  the incoming fragment colour in the fixed function fragment shader. The common profile does not allow multiple techniques to used in an effect, i.e. no multitexturing.

If the diffuse channel contains a texture and the shininess element is non zero then specular highlighting should be postponed.

I cannot think of a way of handling the index_of_refraction. Has anyone got any thoughts on this?

Reflective and reflectivity need further study. Anyone got any ideas?

That leaves the thorny issues surrounding the transparent and transparency elements. This is what the Collada spec has to say about then in general terms.

==========================================================

Determining Transparency (Opacity)

If either <transparent> or <transparency> 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
<transparent>, 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)

• In RGB_ZERO opaque mode:
result.r = fb.r * (transparent.r * transparency) + mat.r * (1.0f -transparent.r * transparency)
result.g = fb.g * (transparent.g * transparency) + mat.g * (1.0f -transparent.g * transparency)
result.b = fb.b * (transparent.b * transparency) + mat.b * (1.0f -transparent.b * transparency)
result.a = fb.a * (luminance(transparent.rgb) * transparency) + mat.a * (1.0f - luminance(transparent.rgb) * transparency)

• In A_ZERO opaque mode:
result.r = fb.r * (transparent.a * transparency) + mat.r * (1.0f - transparent.a * transparency)
result.g = fb.g * (transparent.a * transparency) + mat.g * (1.0f - transparent.a * transparency)
result.b = fb.b * (transparent.a * transparency) + mat.b * (1.0f - transparent.a * transparency)
result.a = fb.a * (transparent.a * transparency) + mat.a * (1.0f - transparent.a * transparency)

• In RGB_ONE opaque mode:
result.r = fb.r * (1.0f - transparent.r * transparency) + mat.r * (transparent.r * transparency)
result.g = fb.g * (1.0f - transparent.g * transparency) + mat.g * (transparent.g * transparency)
result.b = fb.b * (1.0f - transparent.b * transparency) + mat.b * (transparent.b * transparency)
result.a = fb.a * (1.0f - luminance(transparent.rgb) * transparency) + mat.a * (luminance(transparent.rgb) * transparency)

where luminance is the function, based on the ISO/CIE color standards (see ITU-R Recommendation BT.709-4), that averages the color channels into one value:
luminance = (color.r * 0.212671) + (color.g * 0.715160) + (color.b * 0.072169)

The interaction between <transparent> and <transparency> is as follows:
• If <transparent> does not exist then it has no effect on the equation’s result, and the opaque mode is the default opaque mode. This is equivalent to:
transparent = <color> 1.0 1.0 1.0 1.0 </color>
• If <transparency> does not exist then it has no effect on the equation’s result. This is equivalent to a factor that is 1.0:
transparency = <float> 1.0 <float>
• If both <transparent> and <transparency> exist then both are honored.
In the following example, the colors are used as specified but the RGB values are ignored for transparency calculations because A_ONE specifies that the transparency information comes from the alpha channel, not the RGB channels:
<transparent opaque=A_ONE><color>1 0 0.5 0</color></transparent>

==========================================================

Sorry about that big inclusion but I thought it was better to pull it in, it is page 249 of the Collada 1.5 spec. and is from the "Getting started with FX" section of the spec, which I have been repeatedly told is "for guidance only". Taking the alpha one opaque set of equations as a starting point.

• 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)

I believe (and have been told) that the mat term represents the result of the lighting equation which in Collada terms can include a diffuse texture. In OpenGL terms this would seem to be the output from, or potentially an intermediate phase in, the fragment shading process.

The question I asked in the Collada forums and failed to get answered clearly was "What does result represent?". Is it the final output of the alpha blending process as written back to the frame buffer or is it the input to a subsequent alpha blending process? The answer I seemed to get in the Collada forum was that result was the input to a subsequent alpha blending process. In many ways that makes sense of the equations as then the alpha value of the lit and textured fragment can then be used to blend the fragment in to the frame buffer. However I failed to get any answer to my subsequent observation that this answer would seem to contradict the use of frame buffer terms in the original equation.

What follows is my proposal for how we should deal with this. I use the "alpha one is opaque" mode as an example but the same principle can be mapped into the other modes.

I propose that if there is a texture present in the diffuse channel we turn turn the blender on if either the transparent or transparency elements are present. If there is no texture present the I propose that we turn the blender on if our transparency calculation would yield a non opaque value, see below.

If there is a texture present, then if transparency * transparent yields an opaque value (transparency.a * transparent == 1 in A_ONE mode) the we use source alpha as the blending constant. If transparent * transparency yields a transparent value then we put that value into the blenders constant colour alpha and use that as the bending constant.

If there is no texture present then if transparency * transparent * mat.a yields an opaque value we do not turn the blender on. Otherwise we should put transparency * transparent * mat.a into the blenders constant colour alpha and use that as the bending constant.

This effectively modifies the equations as follows (I think!)
factor = transparent.a * transparency * mat.a
fb.r = fb.r * (1.0f - factor ) + mat.r * factor
fb.g = fb.g * (1.0f - factor ) + mat.g * factor
fb.b = fb.b * (1.0f - factor ) + mat.b * factor
fb.a = fb.a * (1.0f - factor) + mat.a * factor


I will leave the Sketchup fix in the code that inverts the transparency value as this is accepted as a Sketchup bug.

Here is an example of how an alpha blended texture could be encoded.

<blinn>
    <diffuse>
        <texture texture="material_0_1_0-image-sampler" texcoord="UVSET0"/>
    </diffuse>
    <transparency>
       <float> 1.0 </float>
    </transparency>
</blinn>

Note the presence of transparency to force the blender to be turned on and use the alpha form the texture as the blend factor.

A simliar approach can be taken for the phong, lambert, and constant techniques.

A more sophisticated approach could be acheived using GLSL shaders. Escpecially regarding the handling of a texture in the transparent element.

Comments, even flames, but not silence, please.

Roger
_______________________________________________
osg-users mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org

Reply via email to