Skip to content

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

@scurest

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

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions