@animech-public/playcanvas
Version:
PlayCanvas WebGL game engine
2 lines (1 loc) • 11.9 kB
JavaScript
import{Color as e}from"../../core/math/color.js";import{math as t}from"../../core/math/math.js";import{Vec2 as a}from"../../core/math/vec2.js";import{ShaderProcessorOptions as s}from"../../platform/graphics/shader-processor-options.js";import{CUBEPROJ_BOX as i,SPECULAR_PHONG as r,SHADER_DEPTH as n,SHADER_PICK as h,SHADER_PREPASS_VELOCITY as o,SPECOCC_AO as l,SPECULAR_BLINN as c,FRESNEL_SCHLICK as u,CUBEPROJ_NONE as m,DITHER_NONE as p,DETAILMODE_MUL as d}from"../constants.js";import{ShaderPass as _}from"../shader-pass.js";import{EnvLighting as f}from"../graphics/env-lighting.js";import{getProgramLibrary as M}from"../shader-lib/get-program-library.js";import{_matTex2D as y,standard as g}from"../shader-lib/programs/standard.js";import{Material as P}from"./material.js";import{StandardMaterialOptionsBuilder as v}from"./standard-material-options-builder.js";import{standardMaterialTextureParameters as b,standardMaterialCubemapParameters as x}from"./standard-material-parameters.js";const S={},A={};let T=new Set;class C extends P{constructor(){super(),this.userAttributes=new Map,this._dirtyShader=!0,this._assetReferences={},this._activeParams=new Set,this._activeLightingParams=new Set,this.shaderOptBuilder=new v,this.reset()}reset(){Object.keys(S).forEach((e=>{this[`_${e}`]=S[e].value()})),this._chunks={},this._uniformCache={}}set shader(e){}get shader(){return null}set chunks(e){this._dirtyShader=!0,this._chunks=e}get chunks(){return this._dirtyShader=!0,this._chunks}copy(e){super.copy(e),Object.keys(S).forEach((t=>{this[t]=e[t]}));for(const t in e._chunks)e._chunks.hasOwnProperty(t)&&(this._chunks[t]=e._chunks[t]);return this}setAttribute(e,t){this.userAttributes.set(t,e)}_setParameter(e,t){T.add(e),this.setParameter(e,t)}_setParameters(e){e.forEach((e=>{this._setParameter(e.name,e.value)}))}_processParameters(e){const t=this[e];t.forEach((e=>{T.has(e)||delete this.parameters[e]})),this[e]=T,T=t,T.clear()}_updateMap(e){const t=`${e}Map`,a=this[t];if(a){this._setParameter(`texture_${t}`,a);const e=`${t}Transform`,s=this.getUniform(e);s&&this._setParameters(s)}}_allocUniform(e,t){let a=this._uniformCache[e];return a||(a=t(),this._uniformCache[e]=a),a}getUniform(e,t,a){return A[e](this,t,a)}updateUniforms(e,t){const a=a=>this.getUniform(a,e,t);this._setParameter("material_ambient",a("ambient")),this.diffuseMap&&!this.diffuseTint||this._setParameter("material_diffuse",a("diffuse")),this.useMetalness?((!this.metalnessMap||this.metalness<1)&&this._setParameter("material_metalness",this.metalness),this.specularMap&&!this.specularTint||this._setParameter("material_specular",a("specular")),this.specularityFactorMap&&!this.specularityFactorTint||this._setParameter("material_specularityFactor",this.specularityFactor),this.sheenMap&&!this.sheenTint||this._setParameter("material_sheen",a("sheen")),this.sheenGlossMap&&!this.sheenGlossTint||this._setParameter("material_sheenGloss",this.sheenGloss),this._setParameter("material_refractionIndex",this.refractionIndex)):this.specularMap&&!this.specularTint||this._setParameter("material_specular",a("specular")),this.enableGGXSpecular&&this._setParameter("material_anisotropy",this.anisotropy),this.clearCoat>0&&(this._setParameter("material_clearCoat",this.clearCoat),this._setParameter("material_clearCoatGloss",this.clearCoatGloss),this._setParameter("material_clearCoatBumpiness",this.clearCoatBumpiness)),this._setParameter("material_gloss",a("gloss")),this.emissiveMap&&!this.emissiveTint||this._setParameter("material_emissive",a("emissive")),1!==this.emissiveIntensity&&this._setParameter("material_emissiveIntensity",this.emissiveIntensity),this.refraction>0&&this._setParameter("material_refraction",this.refraction),this.dispersion>0&&this._setParameter("material_dispersion",this.dispersion),this.useDynamicRefraction&&(this._setParameter("material_thickness",this.thickness),this._setParameter("material_attenuation",a("attenuation")),this._setParameter("material_invAttenuationDistance",0===this.attenuationDistance?0:1/this.attenuationDistance)),this.useIridescence&&(this._setParameter("material_iridescence",this.iridescence),this._setParameter("material_iridescenceRefractionIndex",this.iridescenceRefractionIndex),this._setParameter("material_iridescenceThicknessMin",this.iridescenceThicknessMin),this._setParameter("material_iridescenceThicknessMax",this.iridescenceThicknessMax)),this._setParameter("material_opacity",this.opacity),!1===this.opacityFadesSpecular&&this._setParameter("material_alphaFade",this.alphaFade),this.occludeSpecular&&this._setParameter("material_occludeSpecularIntensity",this.occludeSpecularIntensity),this.cubeMapProjection===i&&this._setParameter(a("cubeMapProjectionBox"));for(const e in y)this._updateMap(e);this.ambientSH&&this._setParameter("ambientSH[0]",this.ambientSH),this.normalMap&&this._setParameter("material_bumpiness",this.bumpiness),this.normalMap&&this.normalDetailMap&&this._setParameter("material_normalDetailMapBumpiness",this.normalDetailMapBumpiness),this.heightMap&&this._setParameter("material_heightMapFactor",a("heightMapFactor"));const s=this.shadingModel===r;this.envAtlas&&this.cubeMap&&!s?(this._setParameter("texture_envAtlas",this.envAtlas),this._setParameter("texture_cubeMap",this.cubeMap)):this.envAtlas&&!s?this._setParameter("texture_envAtlas",this.envAtlas):this.cubeMap?this._setParameter("texture_cubeMap",this.cubeMap):this.sphereMap&&this._setParameter("texture_sphereMap",this.sphereMap),this._setParameter("material_reflectivity",this.reflectivity),this._processParameters("_activeParams"),this._dirtyShader&&this.clearVariants()}updateEnvUniforms(e,t){const a=this.shadingModel===r;!(this.envAtlas&&!a||this.cubeMap||this.sphereMap)&&this.useSkybox&&(t.envAtlas&&t.skybox&&!a?(this._setParameter("texture_envAtlas",t.envAtlas),this._setParameter("texture_cubeMap",t.skybox)):t.envAtlas&&!a?this._setParameter("texture_envAtlas",t.envAtlas):t.skybox&&this._setParameter("texture_cubeMap",t.skybox)),this._processParameters("_activeLightingParams")}getShaderVariant(e,t,a,i,r,l,c,u,m){this.updateEnvUniforms(e,t);const p=_.get(e).getByIndex(r),d=r===n||r===h||r===o||p.isShadow;let f=d?g.optionsContextMin:g.optionsContext;d?this.shaderOptBuilder.updateMinRef(f,t,this,a,r,l):this.shaderOptBuilder.updateRef(f,t,this,a,r,l),this.onUpdateShader&&(f=this.onUpdateShader(f));const y=new s(c,u,m),P=M(e);P.register("standard",g);const v=P.getProgram("standard",f,y,this.userId);return this._dirtyShader=!1,v}destroy(){for(const e in this._assetReferences)this._assetReferences[e]._unbind();this._assetReferences=null,super.destroy()}}C.TEXTURE_PARAMETERS=b,C.CUBEMAP_PARAMETERS=x;const F=(e,t)=>{A[e]=t},k=(e,t,a,s)=>{Object.defineProperty(C.prototype,e,{get:s||function(){return this[`_${e}`]},set:a}),S[e]={value:t}},w=e=>{const t=`_${e.name}`,a=e.dirtyShaderFunc||(()=>!0);k(e.name,(()=>e.defaultValue),(function(e){const s=this[t];s!==e&&(this._dirtyShader=this._dirtyShader||a(s,e),this[t]=e)}),e.getterFunc)},j=e=>{const t=`_${e.name}`,a=e.dirtyShaderFunc||(()=>!0);k(e.name,(()=>e.defaultValue.clone()),(function(e){const s=this[t];s.equals(e)||(this._dirtyShader=this._dirtyShader||a(s,e),this[t]=s.copy(e))}),e.getterFunc)},D=e=>e.defaultValue&&e.defaultValue.clone?j(e):w(e);function $(e,s="rgb",i=!0,r=0){y[e]=s.length||-1,D({name:`${e}Map`,defaultValue:null,dirtyShaderFunc:(e,t)=>!!e!=!!t||e&&(e.type!==t.type||e.fixCubemapSeams!==t.fixCubemapSeams||e.format!==t.format)}),D({name:`${e}MapTiling`,defaultValue:new a(1,1)}),D({name:`${e}MapOffset`,defaultValue:new a(0,0)}),D({name:`${e}MapRotation`,defaultValue:0}),D({name:`${e}MapUv`,defaultValue:r}),s&&(D({name:`${e}MapChannel`,defaultValue:s}),i&&(D({name:`${e}VertexColor`,defaultValue:!1}),D({name:`${e}VertexColorChannel`,defaultValue:s})));const n=`${e}MapTiling`,h=`${e}MapOffset`,o=`${e}MapRotation`,l=`${e}MapTransform`;F(l,((e,a,s)=>{const i=e[n],r=e[h],c=e[o];if(1===i.x&&1===i.y&&0===r.x&&0===r.y&&0===c)return null;const u=e._allocUniform(l,(()=>[{name:`texture_${l}0`,value:new Float32Array(3)},{name:`texture_${l}1`,value:new Float32Array(3)}])),m=Math.cos(c*t.DEG_TO_RAD),p=Math.sin(c*t.DEG_TO_RAD),d=u[0].value;d[0]=m*i.x,d[1]=-p*i.y,d[2]=r.x;const _=u[1].value;return _[0]=p*i.x,_[1]=m*i.y,_[2]=1-i.y-r.y,u}))}function G(e,t){D({name:e,defaultValue:t,getterFunc:function(){return this._dirtyShader=!0,this[`_${e}`]}}),F(e,((t,a,s)=>{const i=t._allocUniform(e,(()=>new Float32Array(3))),r=t[e];return t.useGammaTonemap&&s.gammaCorrection?(i[0]=Math.pow(r.r,2.2),i[1]=Math.pow(r.g,2.2),i[2]=Math.pow(r.b,2.2)):(i[0]=r.r,i[1]=r.g,i[2]=r.b),i}))}function I(e,t,a){D({name:e,defaultValue:t,dirtyShaderFunc:(e,t)=>(0===e||1===e)!=(0===t||1===t)}),F(e,a)}function R(e,t){D({name:e,defaultValue:null,dirtyShaderFunc:(e,t)=>!!e==!!t}),F(e,t)}function V(e,t){D({name:e,defaultValue:t})}!function(){G("ambient",new e(.7,.7,.7)),G("diffuse",new e(1,1,1)),G("specular",new e(0,0,0)),G("emissive",new e(0,0,0)),G("sheen",new e(1,1,1)),G("attenuation",new e(1,1,1)),I("emissiveIntensity",1),I("specularityFactor",1),I("sheenGloss",0),I("gloss",.25,((e,t,a)=>e.shadingModel===r?Math.pow(2,11*e.gloss):e.gloss)),I("heightMapFactor",1,((e,t,a)=>.025*e.heightMapFactor)),I("opacity",1),I("alphaFade",1),I("alphaTest",0),I("bumpiness",1),I("normalDetailMapBumpiness",1),I("reflectivity",1),I("occludeSpecularIntensity",1),I("refraction",0),I("refractionIndex",1/1.5),I("dispersion",0),I("thickness",0),I("attenuationDistance",0),I("metalness",1),I("anisotropy",0),I("clearCoat",0),I("clearCoatGloss",1),I("clearCoatBumpiness",1),I("aoUvSet",0,null),I("iridescence",0),I("iridescenceRefractionIndex",1/1.5),I("iridescenceThicknessMin",0),I("iridescenceThicknessMax",0),R("ambientSH"),R("cubeMapProjectionBox",((e,t,a)=>{const s=e._allocUniform("cubeMapProjectionBox",(()=>[{name:"envBoxMin",value:new Float32Array(3)},{name:"envBoxMax",value:new Float32Array(3)}])),i=e.cubeMapProjectionBox.getMin(),r=s[0].value;r[0]=i.x,r[1]=i.y,r[2]=i.z;const n=e.cubeMapProjectionBox.getMax(),h=s[1].value;return h[0]=n.x,h[1]=n.y,h[2]=n.z,s})),V("ambientTint",!1),V("diffuseTint",!1),V("sheenTint",!1),V("specularTint",!1),V("specularityFactorTint",!1),V("emissiveTint",!1),V("fastTbn",!1),V("useMetalness",!1),V("useMetalnessSpecularColor",!1),V("useSheen",!1),V("enableGGXSpecular",!1),V("occludeDirect",!1),V("normalizeNormalMap",!0),V("conserveEnergy",!0),V("opacityFadesSpecular",!0),V("occludeSpecular",l),V("shadingModel",c),V("fresnelModel",u),V("useDynamicRefraction",!1),V("cubeMapProjection",m),V("customFragmentShader",null),V("useFog",!0),V("useLighting",!0),V("useGammaTonemap",!0),V("useSkybox",!0),V("forceUv1",!1),V("pixelSnap",!1),V("twoSidedLighting",!1),V("nineSlicedMode",void 0),V("msdfTextAttribute",!1),V("useIridescence",!1),V("glossInvert",!1),V("sheenGlossInvert",!1),V("clearCoatGlossInvert",!1),V("opacityDither",p),V("opacityShadowDither",p),$("diffuse"),$("specular"),$("emissive"),$("thickness","g"),$("specularityFactor","g"),$("normal",""),$("metalness","g"),$("gloss","g"),$("opacity","a"),$("refraction","g"),$("height","g",!1),$("ao","g"),$("light","rgb",!0,1),$("msdf",""),$("diffuseDetail","rgb",!1),$("normalDetail",""),$("aoDetail","g",!1),$("clearCoat","g"),$("clearCoatGloss","g"),$("clearCoatNormal",""),$("sheen","rgb"),$("sheenGloss","g"),$("iridescence","g"),$("iridescenceThickness","g"),V("diffuseDetailMode",d),V("aoDetailMode",d),R("cubeMap"),R("sphereMap"),R("envAtlas");const t=[null,null,null,null,null,null];k("prefilteredCubemaps",(()=>t.slice()),(function(e){const t=this._prefilteredCubemaps;e=e||[];let a=!1,s=!0;for(let i=0;i<6;++i){const r=e[i]||null;t[i]!==r&&(t[i]=r,a=!0),s=s&&!!t[i]}a&&(s?this.envAtlas=f.generatePrefilteredAtlas(t,{target:this.envAtlas}):this.envAtlas&&(this.envAtlas.destroy(),this.envAtlas=null),this._dirtyShader=!0)}),(function(){return this._prefilteredCubemaps}))}();export{C as StandardMaterial};