import { Vector4 } from '@zephyr3d/base';
import { applyMaterialMixins } from '../meshmaterial.js';
import { mixinTextureProps } from './texture.js';
import { MaterialVaryingFlags } from '../../values.js';

/**
 * Albedo color mixin
 * @param BaseCls - Class to mix in
 * @returns Mixed class
 *
 * @public
 */ function mixinAlbedoColor(BaseCls) {
    if (BaseCls.albedoColorMixed) {
        return BaseCls;
    }
    const S = applyMaterialMixins(BaseCls, mixinTextureProps('albedo'));
    const ALBEDO_COLOR_UNIFORM = S.defineInstanceUniform('albedoColor', 'rgba', 'AlbedoColor');
    return class extends S {
        static albedoColorMixed = true;
        _albedoColor;
        constructor(){
            super();
            this._albedoColor = Vector4.one();
        }
        copyFrom(other) {
            super.copyFrom(other);
            this.albedoColor = other.albedoColor;
        }
        /** Albedo color */ get albedoColor() {
            return this._albedoColor;
        }
        set albedoColor(val) {
            this._albedoColor.set(val);
            this.uniformChanged();
        }
        getUniformValueAlbedoColor(scope) {
            return this.drawContext.materialFlags & MaterialVaryingFlags.INSTANCING ? scope.$inputs.zAlbedo : scope.zAlbedo;
        }
        calculateAlbedoColor(scope, uv) {
            const pb = scope.$builder;
            if (!this.needFragmentColor()) {
                console.warn('mixinAlbedoColor.calculateAlbedoColor(): No need to calculate albedo color, make sure needFragmentColor() returns true');
                return pb.vec4(1);
            }
            let color = this.getUniformValueAlbedoColor(scope);
            if (this.albedoTexture) {
                color = pb.mul(color, this.sampleAlbedoTexture(scope, uv));
            }
            return color;
        }
        vertexShader(scope) {
            super.vertexShader(scope);
            if (this.needFragmentColor()) {
                if (this.drawContext.materialFlags & MaterialVaryingFlags.INSTANCING) {
                    scope.$outputs.zAlbedo = this.getInstancedUniform(scope, ALBEDO_COLOR_UNIFORM);
                }
            }
        }
        fragmentShader(scope) {
            super.fragmentShader(scope);
            if (this.needFragmentColor() && !(this.drawContext.materialFlags & MaterialVaryingFlags.INSTANCING)) {
                const pb = scope.$builder;
                scope.zAlbedo = pb.vec4().uniform(2);
            }
        }
        applyUniformValues(bindGroup, ctx, pass) {
            super.applyUniformValues(bindGroup, ctx, pass);
            if (this.needFragmentColor(ctx) && !(ctx.materialFlags & MaterialVaryingFlags.INSTANCING)) {
                bindGroup.setValue('zAlbedo', this._albedoColor);
            }
        }
    };
}

export { mixinAlbedoColor };
//# sourceMappingURL=albedocolor.js.map
