Skip to content

Effect opacity messed up when previous effect has transparent texture #651

Description

@scurest

Suppose I have two effects in the library_effects. The first has a <transparent> with a texture and a <transparency> of 0.4, and the second has neither <transparent> nor <transparency>.

Example library_effects
  <library_effects>
    <effect id="White-effect">
      <profile_COMMON>
        <newparam sid="surface">
          <surface type="2D">
            <init_from>my_image</init_from>
          </surface>
        </newparam>
        <newparam sid="sampler">
          <sampler2D>
            <source>surface</source>
          </sampler2D>
        </newparam>
        <technique sid="common">
          <lambert>
            <diffuse>
              <color sid="diffuse">0.8 0.8 0.8 1</color>
            </diffuse>
            <transparent>
              <color>1 1 1 1</color>
              <texture texture="sampler" texcoord="UVMap"/>
            </transparent>
            <transparency>
              <float sid="transparency">0.4</float>
            </transparency>
          </lambert>
        </technique>
      </profile_COMMON>
    </effect>
    <effect id="Blue-effect">
      <profile_COMMON>
        <technique sid="common">
          <lambert>
            <diffuse>
              <color sid="diffuse">0 0.32 0.8 1</color>
            </diffuse>
          </lambert>
        </technique>
      </profile_COMMON>
    </effect>
  </library_effects>

Then when I look at the second effect:

  • getOpaqueMode will be ALPHA_ONE
  • getOpacity will be 0.4 0.4 0.4 0.4
  • getTransparent will be none (this is correct)
  • getTransparency will be 0.4

ie. it's reporting stale value from the first effect! If the first effect is modified so its <transparent> is a color instead, the second effect will show the correct values.


This is caused by an early return in calculateOpacity

// If we have already a texture as opacity, we don't need to calculate the opacity color.
COLLADAFW::ColorOrTexture& opacity = mCurrentEffect->getCommonEffects ().back ()->getOpacity ();
if ( opacity.isTexture () ) return;

The early return skips the rest of the function, including the code that resets values for the next effect

// Reset the transparent, transparency and opaque values.
mTransparency = 1;
mTransparent.setType ( COLLADAFW::ColorOrTexture::UNSPECIFIED );
mOpaqueMode = LibraryEffectsLoader::UNSPECIFIED_OPAQUE;

so the next effect gets the stale values.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions