.effect blend modes not overwriting sprite's

Hello,
Is it possibly to have a material’s (effect’s) blend mode overwrite the modes specified in the sprite component? I think @ckhoo 's post here has me on the right track : ( [SOLVED] Support for GL min/max blend equation functions ) , but no matter what I pass as arguments to blendEq, blendSrc or blendDst, the sprite continues to its own blending.

Using arguments of “derp” for all 3 also don’t throw an error. So I’m wondering If I’m completely missing a step.

Which version of Cocos Creator are you using?

Depending on the version, Cocos Creator resets the blend equation or resets the material when a sprite image is applied. To overcome this, I wrote a RenderMaterialOverride component whose sole purpose is to enforce the material applied and its settings.

const {
    ccclass,
    property,
    menu,
    requireComponent,
    executeInEditMode
} = cc._decorator;

@ccclass
@menu('Renderer Component/Render Material Override')
@requireComponent(cc.RenderComponent)
@executeInEditMode
export default class RenderMaterialOverride extends cc.Component {
    @property({
        type: cc.Material
    })
    private material: cc.Material = null;

    private renderComp: cc.RenderComponent = null;
    private renderCompMatOriginal: cc.Material = null;

    private _materialInst: cc.Material = null;
    public get materialInst (): cc.Material {
        return this._materialInst;
    }

    // LIFE CYCLE ---------
    protected onEnable (): void {
        this.renderComp = this.node.getComponent(cc.RenderComponent);
        cc.assert(this.renderComp != null);

        // At runtime, we only apply the material once - when the override component is enabled...
        if (!CC_EDITOR)
            this.applyMaterial();

    }

    // LIFE CYCLE ---------
    protected onDisable (): void {
        // Revert to the original material
        if (this.renderComp != null && this.renderCompMatOriginal != null)
            this.renderComp.setMaterial(0, this.renderCompMatOriginal);
    }

    protected update (): void {
        // In the editor, we apply it as many times as necessary...
        if (!CC_EDITOR)
            return;

        // Keep fetching the render component in case it's removed / replace
        this.renderComp = this.node.getComponent(cc.RenderComponent); ;
        if (this.renderComp == null)
            return;

        const renderCompMat: cc.Material = this.renderComp.getMaterial(0);
        if (renderCompMat !== this._materialInst || this.material !== this._materialInst)
            this.applyMaterial();
    }

    // IMPLEMENTATION ------
    public setMaterial (mat: cc.Material): void {
        if (this.material === mat)
            return;

        this.material = mat;
        this._materialInst = null;

        if (this.enabled)
            this.applyMaterial();
    }

    public getMaterial (): cc.Material {
        return this.material;
    }

    protected setupMaterialInstanceSettings (targetMat: cc.Material, refMat: cc.Material): void {
        targetMat.define('_USE_MODEL', this.renderComp instanceof cc.Graphics);

        this.copyDefine('USE_ALPHA_TEST', targetMat, refMat);
        this.copyDefine('USE_TEXTURE', targetMat, refMat);
        this.copyProperty('texture', targetMat, refMat);
        this.copyProperty('alphaThreshold', targetMat, refMat);
    }

    private copyDefine (defineName: string, targetMat: cc.Material, refMat: cc.Material): void {
        const srcDef = refMat.getDefine(defineName);
        if (srcDef !== undefined)
            targetMat.define(defineName, srcDef);
    }

    private copyProperty (propName: string, targetMat: cc.Material, refMat: cc.Material): void {
        const srcProp = refMat.getProperty(propName);
        if (srcProp !== undefined)
            targetMat.setProperty(propName, srcProp);
    }

    protected applyMaterial (): void {
        if (this.renderComp == null)
            return;

        const renderMat = this.renderComp.getMaterial(0);
        // Render component isn't using a material (no texture?)? There's nothing left to do...
        if (renderMat == null)
            return;

        // First time replacing the render component material? Make a note of the original material
        if (this.renderCompMatOriginal == null)
            this.renderCompMatOriginal = renderMat;

        if (this._materialInst == null && this.material != null) {
            this._materialInst = cc.Material.getInstantiatedMaterial(this.material, this);
            this.setupMaterialInstanceSettings(this._materialInst, this.renderCompMatOriginal);
        } else if (CC_EDITOR)
            this._materialInst = this.material;

        // Copy over the known settings as necessary
        const appliedMatInst = this._materialInst || this.renderCompMatOriginal;
        this.renderComp.setMaterial(0, appliedMatInst);
    }
}
1 Like