UNPKG

cione-comp-lib

Version:

`$ yarn add cione-comp-lib` 或者 `$ npm i cione-comp-lib -S`

302 lines (301 loc) 9.28 kB
import Base from "./core/Base.mjs"; import util from "./core/util.mjs"; import colorUtil from "./core/color.mjs"; var parseColor = colorUtil.parseToFloat; var programKeyCache = {}; function getDefineCode(defines) { var defineKeys = Object.keys(defines); defineKeys.sort(); var defineStr = []; for (var i = 0; i < defineKeys.length; i++) { var key = defineKeys[i]; var value = defines[key]; if (value === null) { defineStr.push(key); } else { defineStr.push(key + " " + value.toString()); } } return defineStr.join("\n"); } function getProgramKey(vertexDefines, fragmentDefines, enabledTextures) { enabledTextures.sort(); var defineStr = []; for (var i = 0; i < enabledTextures.length; i++) { var symbol = enabledTextures[i]; defineStr.push(symbol); } var key = getDefineCode(vertexDefines) + "\n" + getDefineCode(fragmentDefines) + "\n" + defineStr.join("\n"); if (programKeyCache[key]) { return programKeyCache[key]; } var id = util.genGUID(); programKeyCache[key] = id; return id; } var Material = Base.extend( function() { return { name: "", depthTest: true, depthMask: true, transparent: false, blend: null, autoUpdateTextureStatus: true, uniforms: {}, vertexDefines: {}, fragmentDefines: {}, _textureStatus: {}, _enabledUniforms: null }; }, function() { if (!this.name) { this.name = "MATERIAL_" + this.__uid__; } if (this.shader) { this.attachShader(this.shader, true); } }, { precision: "highp", setUniform: function(symbol, value) { if (value === void 0) { console.warn('Uniform value "' + symbol + '" is undefined'); } var uniform = this.uniforms[symbol]; if (uniform) { if (typeof value === "string") { value = parseColor(value) || value; } uniform.value = value; if (this.autoUpdateTextureStatus && uniform.type === "t") { if (value) { this.enableTexture(symbol); } else { this.disableTexture(symbol); } } } }, setUniforms: function(obj) { for (var key in obj) { var val = obj[key]; this.setUniform(key, val); } }, isUniformEnabled: function(symbol) { return this._enabledUniforms.indexOf(symbol) >= 0; }, getEnabledUniforms: function() { return this._enabledUniforms; }, getTextureUniforms: function() { return this._textureUniforms; }, set: function(symbol, value) { if (typeof symbol === "object") { for (var key in symbol) { var val = symbol[key]; this.setUniform(key, val); } } else { this.setUniform(symbol, value); } }, get: function(symbol) { var uniform = this.uniforms[symbol]; if (uniform) { return uniform.value; } }, attachShader: function(shader, keepStatus) { var originalUniforms = this.uniforms; this.uniforms = shader.createUniforms(); this.shader = shader; var uniforms = this.uniforms; this._enabledUniforms = Object.keys(uniforms); this._enabledUniforms.sort(); this._textureUniforms = this._enabledUniforms.filter(function(uniformName) { var type = this.uniforms[uniformName].type; return type === "t" || type === "tv"; }, this); var originalVertexDefines = this.vertexDefines; var originalFragmentDefines = this.fragmentDefines; this.vertexDefines = util.clone(shader.vertexDefines); this.fragmentDefines = util.clone(shader.fragmentDefines); if (keepStatus) { for (var symbol in originalUniforms) { if (uniforms[symbol]) { uniforms[symbol].value = originalUniforms[symbol].value; } } util.defaults(this.vertexDefines, originalVertexDefines); util.defaults(this.fragmentDefines, originalFragmentDefines); } var textureStatus = {}; for (var key in shader.textures) { textureStatus[key] = { shaderType: shader.textures[key].shaderType, type: shader.textures[key].type, enabled: keepStatus && this._textureStatus[key] ? this._textureStatus[key].enabled : false }; } this._textureStatus = textureStatus; this._programKey = ""; }, clone: function() { var material = new this.constructor({ name: this.name, shader: this.shader }); for (var symbol in this.uniforms) { material.uniforms[symbol].value = this.uniforms[symbol].value; } material.depthTest = this.depthTest; material.depthMask = this.depthMask; material.transparent = this.transparent; material.blend = this.blend; material.vertexDefines = util.clone(this.vertexDefines); material.fragmentDefines = util.clone(this.fragmentDefines); material.enableTexture(this.getEnabledTextures()); material.precision = this.precision; return material; }, define: function(shaderType, symbol, val) { var vertexDefines = this.vertexDefines; var fragmentDefines = this.fragmentDefines; if (shaderType !== "vertex" && shaderType !== "fragment" && shaderType !== "both" && arguments.length < 3) { val = symbol; symbol = shaderType; shaderType = "both"; } val = val != null ? val : null; if (shaderType === "vertex" || shaderType === "both") { if (vertexDefines[symbol] !== val) { vertexDefines[symbol] = val; this._programKey = ""; } } if (shaderType === "fragment" || shaderType === "both") { if (fragmentDefines[symbol] !== val) { fragmentDefines[symbol] = val; if (shaderType !== "both") { this._programKey = ""; } } } }, undefine: function(shaderType, symbol) { if (shaderType !== "vertex" && shaderType !== "fragment" && shaderType !== "both" && arguments.length < 2) { symbol = shaderType; shaderType = "both"; } if (shaderType === "vertex" || shaderType === "both") { if (this.isDefined("vertex", symbol)) { delete this.vertexDefines[symbol]; this._programKey = ""; } } if (shaderType === "fragment" || shaderType === "both") { if (this.isDefined("fragment", symbol)) { delete this.fragmentDefines[symbol]; if (shaderType !== "both") { this._programKey = ""; } } } }, isDefined: function(shaderType, symbol) { switch (shaderType) { case "vertex": return this.vertexDefines[symbol] !== void 0; case "fragment": return this.fragmentDefines[symbol] !== void 0; } }, getDefine: function(shaderType, symbol) { switch (shaderType) { case "vertex": return this.vertexDefines[symbol]; case "fragment": return this.fragmentDefines[symbol]; } }, enableTexture: function(symbol) { if (Array.isArray(symbol)) { for (var i = 0; i < symbol.length; i++) { this.enableTexture(symbol[i]); } return; } var status = this._textureStatus[symbol]; if (status) { var isEnabled = status.enabled; if (!isEnabled) { status.enabled = true; this._programKey = ""; } } }, enableTexturesAll: function() { var textureStatus = this._textureStatus; for (var symbol in textureStatus) { textureStatus[symbol].enabled = true; } this._programKey = ""; }, disableTexture: function(symbol) { if (Array.isArray(symbol)) { for (var i = 0; i < symbol.length; i++) { this.disableTexture(symbol[i]); } return; } var status = this._textureStatus[symbol]; if (status) { var isDisabled = !status.enabled; if (!isDisabled) { status.enabled = false; this._programKey = ""; } } }, disableTexturesAll: function() { var textureStatus = this._textureStatus; for (var symbol in textureStatus) { textureStatus[symbol].enabled = false; } this._programKey = ""; }, isTextureEnabled: function(symbol) { var textureStatus = this._textureStatus; return !!textureStatus[symbol] && textureStatus[symbol].enabled; }, getEnabledTextures: function() { var enabledTextures = []; var textureStatus = this._textureStatus; for (var symbol in textureStatus) { if (textureStatus[symbol].enabled) { enabledTextures.push(symbol); } } return enabledTextures; }, dirtyDefines: function() { this._programKey = ""; }, getProgramKey: function() { if (!this._programKey) { this._programKey = getProgramKey( this.vertexDefines, this.fragmentDefines, this.getEnabledTextures() ); } return this._programKey; } } ); var Material$1 = Material; export { Material$1 as default };