2024-05-30 09:20:30 +08:00
import { c as Dl , i as Pl , e as Rl , g as Nl , m as Il , A as Ol , M as Rr , a as Bl , n as Fl , u as Ye , b as Ul , d as Gl , f as zl , h as Mt , j as za , k as Hl , L as Vl , p as os , R as ss , l as kl , r as Jn , o as Dt , q as Wl , s as Xl , t as Zl , v as jl , Z as ql , C as Hr , w as fe , x as $t , y as Yl , z as ls , B as Ki , D as Qi , E as Si , F as hs , G as us , H as fs , I as cn , J as dn , O as $l , K as Kl , N as Ql , P as ea , Q as Ei , S as Pt , T as ma , U as Jl , V as eh , W as Ha , X as th , Y as rh , _ as ih , $ as Cr , a0 as Va , a1 as nh , a2 as ah , a3 as oh , a4 as cs , a5 as St , a6 as Et , a7 as sh , a8 as lh , a9 as Mi , aa as hh , ab as uh , ac as ds , ad as fh , ae as ch , af as ka , ag as Wa , ah as Xa } from "./linkSeriesData.77e8a68a.js" ; function dh ( e ) { return Dl ( null , e ) } var _a = { isDimensionStacked : Pl , enableDataStack : Rl , getStackedDimension : Nl } ; function ga ( e , t ) { var r = t ; t instanceof Rr || ( r = new Rr ( t ) ) ; var i = Bl ( r ) ; return i . setExtent ( e [ 0 ] , e [ 1 ] ) , Fl ( i , r ) , i } function vh ( e ) { Il ( e , Ol ) } Ye ( [ Ul , Gl ] ) ; Ye ( zl ) ; function Za ( e , t , r ) { typeof t == "object" && ( r = t , t = null ) ; var i = this , n ; if ( ! ( e instanceof Function ) ) { n = [ ] ; for ( var a in e ) e . hasOwnProperty ( a ) && n . push ( a ) } var o = function ( l ) { if ( i . apply ( this , arguments ) , e instanceof Function ? ja ( this , e . call ( this , l ) ) : ph ( this , e , n ) , this . constructor === o ) for ( var h = o . _ _initializers _ _ , u = 0 ; u < h . length ; u ++ ) h [ u ] . apply ( this , arguments ) } ; o . _ _super _ _ = i , i . _ _initializers _ _ ? o . _ _initializers _ _ = i . _ _initializers _ _ . slice ( ) : o . _ _initializers _ _ = [ ] , t && o . _ _initializers _ _ . push ( t ) ; var s = function ( ) { } ; return s . prototype = i . prototype , o . prototype = new s , o . prototype . constructor = o , ja ( o . prototype , r ) , o . extend = i . extend , o . derive = i . extend , o } function ja ( e , t ) { if ( ! ! t ) for ( var r in t ) t . hasOwnProperty ( r ) && ( e [ r ] = t [ r ] ) } function ph ( e , t , r ) { for ( var i = 0 ; i < r . length ; i ++ ) { var n = r [ i ] ; e [ n ] = t [ n ] } } const mh = { extend : Za , derive : Za } ; function _h ( e , t ) { this . action = e , this . context = t } var gh = { trigger : function ( e ) { if ( ! ! this . hasOwnProperty ( "__handlers__" ) && ! ! this . _ _handlers _ _ . hasOwnProperty ( e ) ) { var t = this . _ _handlers _ _ [ e ] , r = t . length , i = - 1 , n = arguments ; switch ( n . length ) { case 1 : for ( ; ++ i < r ; ) t [ i ] . action . call ( t [ i ] . context ) ; return ; case 2 : for ( ; ++ i < r ; ) t [ i ] . action . call ( t [ i ] . context , n [ 1 ] ) ; return ; case 3 : for ( ; ++ i < r ; ) t [ i ] . action . call ( t [ i ] . context , n [ 1 ] , n [ 2 ] ) ; return ; case 4 : for ( ; ++ i < r ; ) t [ i ] . action . call ( t [ i ] . context , n [ 1 ] , n [ 2 ] , n [ 3 ] ) ; return ; case 5 : for ( ; ++ i < r ; ) t [ i ] . action . call ( t [ i ] . context , n [ 1 ] , n [ 2 ] , n [ 3 ] , n [ 4 ] ) ; return ; default : for ( ; ++ i < r ; ) t [ i ] . action . apply ( t [ i ] . context , Array . prototype . slice . call ( n , 1 ) ) ; return } } } , on : function ( e , t , r ) { if ( ! ( ! e || ! t ) ) { var i = this . _ _handlers _ _ || ( this . _ _handlers _ _ = { } ) ; if ( ! i [ e ] ) i [ e ] = [ ] ; else if ( this . has ( e , t ) ) return ; var n = new _h ( t , r || this ) ; return i [ e ] . push ( n ) , this } } , once : function ( e , t , r ) { if ( ! e || ! t ) return ; var i = this ; function n ( ) { i . off ( e , n ) , t . apply ( this , arguments ) } return this . on ( e , n , r ) } , before : function ( e , t , r ) { if ( ! ( ! e || ! t ) ) return e = "before" + e , this . on ( e , t , r ) } , after : function ( e , t , r ) { if ( ! ( ! e || ! t ) ) return e = "after" + e , this . on ( e , t , r ) } , success : function ( e , t ) { return this . once ( "success" , e , t ) } , error : function ( e , t ) { return this . once ( "error" , e , t ) } , off : function ( e , t ) { var r = this . _ _handlers _ _ || ( this . _ _handlers _ _ = { } ) ; if ( ! t ) { r [ e ] = [ ] ; return } if ( r [ e ] ) { for ( var i = r [ e ] , n = [ ] , a = 0 ; a < i . length ; a ++ ) t && i [ a ] . action !== t && n . push ( i [ a ] ) ; r [ e ] = n } return this } , has : function ( e , t ) { var r = this . _ _handlers _ _ ; if ( ! r || ! r [ e ] ) return ! 1 ; for ( var i = r [ e ] , n = 0 ; n < i . length ; n ++ ) if ( i [ n ] . action === t ) return ! 0 } } ; const ya = gh ; var yh = 0 , xh = Array . prototype , Th = xh . forEach , ai = { genGUID : function ( ) { return ++ yh } , relative2absolute : function ( e , t ) { if ( ! t || e . match ( /^\// ) ) return e ; for ( var r = e . split ( "/" ) , i = t . split ( "/" ) , n = r [ 0 ] ; n === "." || n === ".." ; ) n === ".." && i . pop ( ) , r . shift ( ) , n = r [ 0 ] ; return i . join ( "/" ) + "/" + r . join ( "/" ) } , extend : function ( e , t ) { if ( t ) for ( var r in t ) t . hasOwnProperty ( r ) && ( e [ r ] = t [ r ] ) ; return e } , defaults : function ( e , t ) { if ( t ) for ( var r in t ) e [ r ] === void 0 && ( e [ r ] = t [ r ] ) ; return e } , extendWithPropList : function ( e , t , r ) { if ( t ) for ( var i = 0 ; i < r . length ; i ++ ) { var n = r [ i ] ; e [ n ] = t [ n ] } return e } , defaultsWithPropList : function ( e , t , r ) { if ( t ) for ( var i = 0 ; i < r . length ; i ++ ) { var n = r [ i ] ; e [ n ] == null && ( e [ n ] = t [ n ] ) } return e } , each : function ( e , t , r ) { if ( ! ! ( e && t ) ) if ( e . forEach && e . forEach === Th ) e . forEach ( t , r ) ; else if ( e . length === + e . length ) for ( var i = 0 , n = e . length ; i < n ; i ++ ) t . call ( r , e [ i ] , i , e ) ; else for ( var a in e ) e . hasOwnProperty ( a ) && t . call ( r , e [ a ] , a , e ) } , is
2023-09-11 21:56:39 +08:00
` )}function Dh(e,t,r){r.sort();for(var i=[],n=0;n<r.length;n++){var a=r[n];i.push(a)}var o=Ka(e)+ `
2023-07-24 18:07:54 +08:00
` +Ka(t)+ `
2023-04-28 16:00:04 +08:00
` +i.join( `
2023-09-11 21:56:39 +08:00
` );if(Cn[o])return Cn[o];var s=je.genGUID();return Cn[o]=s,s}var Ph=nt.extend(function(){return{name:"",depthTest:!0,depthMask:!0,transparent:!1,blend:null,autoUpdateTextureStatus:!0,uniforms:{},vertexDefines:{},fragmentDefines:{},_textureStatus:{},_enabledUniforms:null}},function(){this.name||(this.name="MATERIAL_"+this.__uid__),this.shader&&this.attachShader(this.shader,!0)},{precision:"highp",setUniform:function(e,t){t===void 0&&console.warn('Uniform value "'+e+'" is undefined');var r=this.uniforms[e];r&&(typeof t=="string"&&(t=Mh(t)||t),r.value=t,this.autoUpdateTextureStatus&&r.type==="t"&&(t?this.enableTexture(e):this.disableTexture(e)))},setUniforms:function(e){for(var t in e){var r=e[t];this.setUniform(t,r)}},isUniformEnabled:function(e){return this._enabledUniforms.indexOf(e)>=0},getEnabledUniforms:function(){return this._enabledUniforms},getTextureUniforms:function(){return this._textureUniforms},set:function(e,t){if(typeof e=="object")for(var r in e){var i=e[r];this.setUniform(r,i)}else this.setUniform(e,t)},get:function(e){var t=this.uniforms[e];if(t)return t.value},attachShader:function(e,t){var r=this.uniforms;this.uniforms=e.createUniforms(),this.shader=e;var i=this.uniforms;this._enabledUniforms=Object.keys(i),this._enabledUniforms.sort(),this._textureUniforms=this._enabledUniforms.filter(function(h){var u=this.uniforms[h].type;return u==="t"||u==="tv"},this);var n=this.vertexDefines,a=this.fragmentDefines;if(this.vertexDefines=je.clone(e.vertexDefines),this.fragmentDefines=je.clone(e.fragmentDefines),t){for(var o in r)i[o]&&(i[o].value=r[o].value);je.defaults(this.vertexDefines,n),je.defaults(this.fragmentDefines,a)}var s={};for(var l in e.textures)s[l]={shaderType:e.textures[l].shaderType,type:e.textures[l].type,enabled:t&&this._textureStatus[l]?this._textureStatus[l].enabled:!1};this._textureStatus=s,this._programKey=""},clone:function(){var e=new this.constructor({name:this.name,shader:this.shader});for(var t in this.uniforms)e.uniforms[t].value=this.uniforms[t].value;return e.depthTest=this.depthTest,e.depthMask=this.depthMask,e.transparent=this.transparent,e.blend=this.blend,e.vertexDefines=je.clone(this.vertexDefines),e.fragmentDefines=je.clone(this.fragmentDefines),e.enableTexture(this.getEnabledTextures()),e.precision=this.precision,e},define:function(e,t,r){var i=this.vertexDefines,n=this.fragmentDefines;e!=="vertex"&&e!=="fragment"&&e!=="both"&&arguments.length<3&&(r=t,t=e,e="both"),r=r!=null?r:null,(e==="vertex"||e==="both")&&i[t]!==r&&(i[t]=r,this._programKey=""),(e==="fragment"||e==="both")&&n[t]!==r&&(n[t]=r,e!=="both"&&(this._programKey=""))},undefine:function(e,t){e!=="vertex"&&e!=="fragment"&&e!=="both"&&arguments.length<2&&(t=e,e="both"),(e==="vertex"||e==="both")&&this.isDefined("vertex",t)&&(delete this.vertexDefines[t],this._programKey=""),(e==="fragment"||e==="both")&&this.isDefined("fragment",t)&&(delete this.fragmentDefines[t],e!=="both"&&(this._programKey=""))},isDefined:function(e,t){switch(e){case"vertex":return this.vertexDefines[t]!==void 0;case"fragment":return this.fragmentDefines[t]!==void 0}},getDefine:function(e,t){switch(e){case"vertex":return this.vertexDefines[t];case"fragment":return this.fragmentDefines[t]}},enableTexture:function(e){if(Array.isArray(e)){for(var t=0;t<e.length;t++)this.enableTexture(e[t]);return}var r=this._textureStatus[e];if(r){var i=r.enabled;i||(r.enabled=!0,this._programKey="")}},enableTexturesAll:function(){var e=this._textureStatus;for(var t in e)e[t].enabled=!0;this._programKey=""},disableTexture:function(e){if(Array.isArray(e)){for(var t=0;t<e.length;t++)this.disableTexture(e[t]);return}var r=this._textureStatus[e];if(r){var i=!r.enabled;i||(r.enabled=!1,this._programKey="")}},disableTexturesAll:function(){var e=this._textureStatus;for(var t in e)e[t].enabled=!1;this._programKey=""},isTextureEnabled:function(e){var t=this._textureStatus;return!!t[e]&&t[e].enabled},getEnabledTextures:function(){var e=[],t=this._textureStatus;for(var r in t)t[r].enabled&&e.push(r);return e},dirtyDefines:function(){this._programKey=""},getProgramKey:function()
2023-04-28 16:00:04 +08:00
` ),r=0,i=t.length;r<i;r++)t[r]=r+1+": "+t[r];return t.join( `
2023-07-24 18:07:54 +08:00
` )}function ro(e,t,r){if(!e.getShaderParameter(t,e.COMPILE_STATUS))return[e.getShaderInfoLog(t),Rh(r)].join( `
2023-09-11 21:56:39 +08:00
` )}var io=new Pe.Float32Array(16),Nh=nt.extend({uniformSemantics:{},attributes:{}},function(){this._locations={},this._textureSlot=0,this._program=null},{bind:function(e){this._textureSlot=0,e.gl.useProgram(this._program)},hasUniform:function(e){var t=this._locations[e];return t!=null},useTextureSlot:function(e,t,r){t&&(e.gl.activeTexture(e.gl.TEXTURE0+r),t.isRenderable()?t.bind(e):t.unbind(e))},currentTextureSlot:function(){return this._textureSlot},resetTextureSlot:function(e){this._textureSlot=e||0},takeCurrentTextureSlot:function(e,t){var r=this._textureSlot;return this.useTextureSlot(e,t,r),this._textureSlot++,r},setUniform:function(e,t,r,i){var n=this._locations,a=n[r];if(a==null)return!1;switch(t){case"m4":if(!(i instanceof Float32Array)){for(var o=0;o<i.length;o++)io[o]=i[o];i=io}e.uniformMatrix4fv(a,!1,i);break;case"2i":e.uniform2i(a,i[0],i[1]);break;case"2f":e.uniform2f(a,i[0],i[1]);break;case"3i":e.uniform3i(a,i[0],i[1],i[2]);break;case"3f":e.uniform3f(a,i[0],i[1],i[2]);break;case"4i":e.uniform4i(a,i[0],i[1],i[2],i[3]);break;case"4f":e.uniform4f(a,i[0],i[1],i[2],i[3]);break;case"1i":e.uniform1i(a,i);break;case"1f":e.uniform1f(a,i);break;case"1fv":e.uniform1fv(a,i);break;case"1iv":e.uniform1iv(a,i);break;case"2iv":e.uniform2iv(a,i);break;case"2fv":e.uniform2fv(a,i);break;case"3iv":e.uniform3iv(a,i);break;case"3fv":e.uniform3fv(a,i);break;case"4iv":e.uniform4iv(a,i);break;case"4fv":e.uniform4fv(a,i);break;case"m2":case"m2v":e.uniformMatrix2fv(a,!1,i);break;case"m3":case"m3v":e.uniformMatrix3fv(a,!1,i);break;case"m4v":if(Array.isArray(i)&&Array.isArray(i[0])){for(var s=new Pe.Float32Array(i.length*16),l=0,o=0;o<i.length;o++)for(var h=i[o],u=0;u<16;u++)s[l++]=h[u];e.uniformMatrix4fv(a,!1,s)}else e.uniformMatrix4fv(a,!1,i);break}return!0},setUniformOfSemantic:function(e,t,r){var i=this.uniformSemantics[t];return i?this.setUniform(e,i.type,i.symbol,r):!1},enableAttributes:function(e,t,r){var i=e.gl,n=this._program,a=this._locations,o;r?o=r.__enabledAttributeList:o=to[e.__uid__],o||(r?o=r.__enabledAttributeList=[]:o=to[e.__uid__]=[]);for(var s=[],l=0;l<t.length;l++){var h=t[l];if(!this.attributes[h]){s[l]=-1;continue}var u=a[h];if(u==null){if(u=i.getAttribLocation(n,h),u===-1){s[l]=-1;continue}a[h]=u}s[l]=u,o[u]?o[u]=eo:o[u]=Ja}for(var l=0;l<o.length;l++)switch(o[l]){case Ja:i.enableVertexAttribArray(l),o[l]=Mn;break;case eo:o[l]=Mn;break;case Mn:i.disableVertexAttribArray(l),o[l]=0;break}return s},getAttribLocation:function(e,t){var r=this._locations,i=r[t];return i==null&&(i=e.getAttribLocation(this._program,t),r[t]=i),i},buildProgram:function(e,t,r,i){var n=e.createShader(e.VERTEX_SHADER),a=e.createProgram();e.shaderSource(n,r),e.compileShader(n);var o=e.createShader(e.FRAGMENT_SHADER);e.shaderSource(o,i),e.compileShader(o);var s=ro(e,n,r);if(s||(s=ro(e,o,i),s))return s;if(e.attachShader(a,n),e.attachShader(a,o),t.attributeSemantics.POSITION)e.bindAttribLocation(a,0,t.attributeSemantics.POSITION.symbol);else{var l=Object.keys(this.attributes);e.bindAttribLocation(a,0,l[0])}if(e.linkProgram(a),e.deleteShader(n),e.deleteShader(o),this._program=a,this.vertexCode=r,this.fragmentCode=i,!e.getProgramParameter(a,e.LINK_STATUS))return ` Could not link program
` +e.getProgramInfoLog(a);for(var h=0;h<t.uniforms.length;h++){var u=t.uniforms[h];this._locations[u]=e.getUniformLocation(a,u)}}});const Ih=Nh;var Oh=/for \s *? \( int \s *?_idx_ \s * \= \s *([ \w -]+) \; \s *_idx_ \s *< \s *([ \w -]+); \s *_idx_ \s * \+ \+ \s * \) \s * \{ \{ ([ \s \S ]+?)(?= \} \} ) \} \} /g;function no(e,t,r){function i(o,s,l,h){var u="";isNaN(s)&&(s in t?s=t[s]:s=n[s]),isNaN(l)&&(l in t?l=t[l]:l=n[l]);for(var f=parseInt(s);f<parseInt(l);f++)u+="{"+h.replace(/float \s * \( \s *_idx_ \s * \) /g,f.toFixed(1)).replace(/_idx_/g,f)+"}";return u}var n={};for(var a in r)n[a+"_COUNT"]=r[a];return e.replace(Oh,i)}function Dn(e,t,r){var i=[];if(t)for(var n in t){var a=t[n];a>0&&i.push("#define "+n.toUpperCase()+"_COUNT "+a)}if(r)for(var o=0;o<r.length;o++){var s=r[o];i.push("#define "+s.toUpperCase()+"_ENABLED")}for(var s in e){var l=e[s];l===null?i.push("#define "+s):i.push("#define "+s+" "+l.toString())}return i.join( `
2023-05-25 08:33:42 +08:00
` )}function Bh(e){for(var t=[],r=0;r<e.length;r++)t.push("#extension GL_"+e[r]+" : enable");return t.join( `
` )}function Fh(e){return["precision",e,"float"].join(" ")+ ` ;
2023-04-28 16:00:04 +08:00
` +["precision",e,"int"].join(" ")+ ` ;
` +["precision",e,"sampler2D"].join(" ")+ ` ;
2023-07-09 20:38:38 +08:00
` }function ms(e){this._renderer=e,this._cache={}}ms.prototype.getProgram=function(e,t,r){var i=this._cache,n=e.isSkinnedMesh&&e.isSkinnedMesh(),a=e.isInstancedMesh&&e.isInstancedMesh(),o="s"+t.shader.shaderID+"m"+t.getProgramKey();r&&(o+="se"+r.getProgramKey(e.lightGroup)),n&&(o+=",sk"+e.joints.length),a&&(o+=",is");var g=i[o];if(g)return g;var s=r?r.getLightsNumbers(e.lightGroup):{},l=this._renderer,h=l.gl,u=t.getEnabledTextures(),f="";if(n){var d={SKINNING:null,JOINT_COUNT:e.joints.length};e.joints.length>l.getMaxJointNumber()&&(d.USE_SKIN_MATRICES_TEXTURE=null),f+= `
2023-09-11 21:56:39 +08:00
` +Dn(d)+ `
2023-04-28 16:00:04 +08:00
` }a&&(f+= `
# define INSTANCING
2023-09-11 21:56:39 +08:00
` );var c=f+Dn(t.vertexDefines,s,u),v=f+Dn(t.fragmentDefines,s,u),p=c+ `
2023-05-05 16:32:31 +08:00
` +t.shader.vertex,m=["OES_standard_derivatives","EXT_shader_texture_lod"].filter(function(S){return l.getGLExtension(S)!=null});m.indexOf("EXT_shader_texture_lod")>=0&&(v+= `
2023-04-28 16:00:04 +08:00
# define SUPPORT _TEXTURE _LOD ` ),m.indexOf("OES_standard_derivatives")>=0&&(v+= `
2023-07-09 20:38:38 +08:00
# define SUPPORT _STANDARD _DERIVATIVES ` );var _=Bh(m)+ `
2023-05-25 08:33:42 +08:00
` +Fh(t.precision)+ `
2023-04-28 16:00:04 +08:00
` +v+ `
2023-07-24 18:07:54 +08:00
` +t.shader.fragment,x=no(p,t.vertexDefines,s),y=no(_,t.fragmentDefines,s),g=new Ih;g.uniformSemantics=t.shader.uniformSemantics,g.attributes=t.shader.attributes;var w=g.buildProgram(h,t.shader,x,y);return g.__error=w,i[o]=g,g};var ao=/uniform \s +(bool|float|int|vec2|vec3|vec4|ivec2|ivec3|ivec4|mat2|mat3|mat4|sampler2D|samplerCube) \s +([ \s \S ]*?);/g,Uh=/attribute \s +(float|int|vec2|vec3|vec4) \s +([ \s \S ]*?);/g,oo=/#define \s +( \w +)?( \s +[ \d -.]+)? \s *;? \s * \n /g,Gh={bool:"1i",int:"1i",sampler2D:"t",samplerCube:"t",float:"1f",vec2:"2f",vec3:"3f",vec4:"4f",ivec2:"2i",ivec3:"3i",ivec4:"4i",mat2:"m2",mat3:"m3",mat4:"m4"};function Rt(e){for(var t=[],r=0;r<e;r++)t[r]=0;return t}var so={bool:function(){return!0},int:function(){return 0},float:function(){return 0},sampler2D:function(){return null},samplerCube:function(){return null},vec2:function(){return Rt(2)},vec3:function(){return Rt(3)},vec4:function(){return Rt(4)},ivec2:function(){return Rt(2)},ivec3:function(){return Rt(3)},ivec4:function(){return Rt(4)},mat2:function(){return Rt(4)},mat3:function(){return Rt(9)},mat4:function(){return Rt(16)},array:function(){return[]}},ia=["POSITION","NORMAL","BINORMAL","TANGENT","TEXCOORD","TEXCOORD_0","TEXCOORD_1","COLOR","JOINT","WEIGHT"],_s=["SKIN_MATRIX","VIEWPORT_SIZE","VIEWPORT","DEVICEPIXELRATIO","WINDOW_SIZE","NEAR","FAR","TIME"],gs=["WORLD","VIEW","PROJECTION","WORLDVIEW","VIEWPROJECTION","WORLDVIEWPROJECTION","WORLDINVERSE","VIEWINVERSE","PROJECTIONINVERSE","WORLDVIEWINVERSE","VIEWPROJECTIONINVERSE","WORLDVIEWPROJECTIONINVERSE","WORLDTRANSPOSE","VIEWTRANSPOSE","PROJECTIONTRANSPOSE","WORLDVIEWTRANSPOSE","VIEWPROJECTIONTRANSPOSE","WORLDVIEWPROJECTIONTRANSPOSE","WORLDINVERSETRANSPOSE","VIEWINVERSETRANSPOSE","PROJECTIONINVERSETRANSPOSE","WORLDVIEWINVERSETRANSPOSE","VIEWPROJECTIONINVERSETRANSPOSE","WORLDVIEWPROJECTIONINVERSETRANSPOSE"],zh={vec4:4,vec3:3,vec2:2,float:1},Pn={},ys={};function Hh(e,t){var r="vertex:"+e+"fragment:"+t;if(Pn[r])return Pn[r];var i=je.genGUID();return Pn[r]=i,ys[i]={vertex:e,fragment:t},i}function lo(e){return e.replace(/[ \t ]* \/ \/ .* \n /g,"").replace(/[ \t ]* \/ \* [ \s \S ]*? \* \/ /g,"")}function xr(){console.error("Wrong uniform/attributes syntax")}function ho(e,t){for(var r=/[,= \( \) :]/,i=t.replace(/: \s * \[ \s *(.*) \s * \] /g,"="+e+"( $ 1)").replace(/ \s +/g,"").split(/(?=[,= \( \) :])/g),n=[],a=0;a<i.length;a++)i[a].match(r)?n.push(i[a].charAt(0),i[a].slice(1)):n.push(i[a]);i=n;var o=0,s=1,l=2,h=3,u=4,f=5,d=o,c={},v=null,p;m(i[0]);function m(y){y||xr();var g=y.match(/ \[ (.*?) \] /);p=y.replace(/ \[ (.*?) \] /,""),c[p]={},g&&(c[p].isArray=!0,c[p].arraySize=g[1])}for(var a=1;a<i.length;a++){var _=i[a];if(!!_){if(_==="="){if(d!==o&&d!==h){xr();break}d=s;continue}else if(_===":"){d=u;continue}else if(_===","){if(d===l){if(!(v instanceof Array)){xr();break}v.push(+i[++a])}else d=f;continue}else if(_===")"){c[p].value=new Pe.Float32Array(v),v=null,d=f;continue}else if(_==="("){if(d!==l){xr();break}if(!(v instanceof Array)){xr();break}v.push(+i[++a]);continue}else if(_.indexOf("vec")>=0){if(d!==s&&d!==u){xr();break}d=l,v=[];continue}else if(d===s){e==="bool"?c[p].value=_==="true":c[p].value=parseFloat(_),v=null;continue}else if(d===u){var x=_;ia.indexOf(x)>=0||_s.indexOf(x)>=0||gs.indexOf(x)>=0?c[p].semantic=x:x==="ignore"||x==="unconfigurable"?c[p].ignore=!0:e==="bool"?c[p].value=x==="true":c[p].value=parseFloat(x);continue}m(_),d=o}}return c}function N(e,t){typeof e=="object"&&(t=e.fragment,e=e.vertex),e=lo(e),t=lo(t),this._shaderID=Hh(e,t),this._vertexCode=N.parseImport(e),this._fragmentCode=N.parseImport(t),this.attributeSemantics={},this.matrixSemantics={},this.uniformSemantics={},this.matrixSemanticKeys=[],this.uniformTemplates={},this.attributes={},this.textures={},this.vertexDefines={},this.fragmentDefines={},this._parseAttributes(),this._parseUniforms(),this._parseDefines()}N.prototype={constructor:N,createUniforms:function(){var e={};for(var t in this.uniformTemplates){var r=this.uniformTemplates[t];e[t]={type:r.type,value:r.value()}}return e},_parseImport:function(){this._vertexCode=N.parseImport(this.vertex),this._fragmentCode=N.parseImpor
` :""}this.uniformTemplates=e},_parseAttributes:function(){var e={},t=this;this._vertexCode=this._vertexCode.replace(Uh,r);function r(i,n,a){var o=ho(n,a),s=zh[n]||1,l=[];for(var h in o){var u=o[h].semantic;if(e[h]={type:"float",size:s,semantic:u||null},u){if(ia.indexOf(u)<0)throw new Error('Unkown semantic "'+u+'"');t.attributeSemantics[u]={symbol:h,type:n}}l.push(h)}return"attribute "+n+" "+l.join(",")+ ` ;
` }this.attributes=e},_parseDefines:function(){var e=this,t="vertex";this._vertexCode=this._vertexCode.replace(oo,r),t="fragment",this._fragmentCode=this._fragmentCode.replace(oo,r);function r(i,n,a){var o=t==="vertex"?e.vertexDefines:e.fragmentDefines;return o[n]||(a==="false"?o[n]=!1:a==="true"?o[n]=!0:o[n]=a?isNaN(parseFloat(a))?a.trim():parseFloat(a):null),""}},clone:function(){var e=ys[this._shaderID],t=new N(e.vertex,e.fragment);return t}};Object.defineProperty&&(Object.defineProperty(N.prototype,"shaderID",{get:function(){return this._shaderID}}),Object.defineProperty(N.prototype,"vertex",{get:function(){return this._vertexCode}}),Object.defineProperty(N.prototype,"fragment",{get:function(){return this._fragmentCode}}),Object.defineProperty(N.prototype,"uniforms",{get:function(){return this._uniformList}}));var Vh=/(@import) \s *([0-9a-zA-Z_ \- \. ]*)/g;N.parseImport=function(e){return e=e.replace(Vh,function(n,r,i){var n=N.source(i);return n?N.parseImport(n):(console.error('Shader chunk "'+i+'" not existed in library'),"")}),e};var kh=/(@export) \s *([0-9a-zA-Z_ \- \. ]*) \s * \n ([ \s \S ]*?)@end/g;N.import=function(e){e.replace(kh,function(t,r,i,a){var a=a.replace(/(^[ \s \t \x a0 \u 3000]+)|([ \u 3000 \x a0 \s \t ]+ \x 24)/g,"");if(a){for(var o=i.split("."),s=N.codes,l=0,h;l<o.length-1;)h=o[l++],s[h]||(s[h]={}),s=s[h];h=o[l],s[h]=a}return a})};N.codes={};N.source=function(e){for(var t=e.split("."),r=N.codes,i=0;r&&i<t.length;){var n=t[i++];r=r[n]}return typeof r!="string"?(console.error('Shader "'+e+'" not existed in library'),""):r};const xs= ` @ export clay . prez . vertex
2023-04-28 16:00:04 +08:00
uniform mat4 WVP : WORLDVIEWPROJECTION ;
attribute vec3 pos : POSITION ;
attribute vec2 uv : TEXCOORD _0 ;
uniform vec2 uvRepeat : [ 1.0 , 1.0 ] ;
uniform vec2 uvOffset : [ 0.0 , 0.0 ] ;
@ import clay . chunk . skinning _header
@ import clay . chunk . instancing _header
varying vec2 v _Texcoord ;
void main ( )
{
vec4 P = vec4 ( pos , 1.0 ) ;
# ifdef SKINNING
@ import clay . chunk . skin _matrix
P = skinMatrixWS * P ;
# endif
# ifdef INSTANCING
@ import clay . chunk . instancing _matrix
P = instanceMat * P ;
# endif
gl _Position = WVP * P ;
v _Texcoord = uv * uvRepeat + uvOffset ;
}
@ end
@ export clay . prez . fragment
uniform sampler2D alphaMap ;
uniform float alphaCutoff : 0.0 ;
varying vec2 v _Texcoord ;
void main ( )
{
if ( alphaCutoff > 0.0 ) {
if ( texture2D ( alphaMap , v _Texcoord ) . a <= alphaCutoff ) {
discard ;
}
}
gl _FragColor = vec4 ( 0.0 , 0.0 , 0.0 , 1.0 ) ;
}
2023-09-11 21:56:39 +08:00
@ end ` ;var pe={};pe.create=function(){var e=new $ e(16);return e[0]=1,e[1]=0,e[2]=0,e[3]=0,e[4]=0,e[5]=1,e[6]=0,e[7]=0,e[8]=0,e[9]=0,e[10]=1,e[11]=0,e[12]=0,e[13]=0,e[14]=0,e[15]=1,e};pe.clone=function(e){var t=new $ e(16);return t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t[9]=e[9],t[10]=e[10],t[11]=e[11],t[12]=e[12],t[13]=e[13],t[14]=e[14],t[15]=e[15],t};pe.copy=function(e,t){return e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[3],e[4]=t[4],e[5]=t[5],e[6]=t[6],e[7]=t[7],e[8]=t[8],e[9]=t[9],e[10]=t[10],e[11]=t[11],e[12]=t[12],e[13]=t[13],e[14]=t[14],e[15]=t[15],e};pe.identity=function(e){return e[0]=1,e[1]=0,e[2]=0,e[3]=0,e[4]=0,e[5]=1,e[6]=0,e[7]=0,e[8]=0,e[9]=0,e[10]=1,e[11]=0,e[12]=0,e[13]=0,e[14]=0,e[15]=1,e};pe.transpose=function(e,t){if(e===t){var r=t[1],i=t[2],n=t[3],a=t[6],o=t[7],s=t[11];e[1]=t[4],e[2]=t[8],e[3]=t[12],e[4]=r,e[6]=t[9],e[7]=t[13],e[8]=i,e[9]=a,e[11]=t[14],e[12]=n,e[13]=o,e[14]=s}else e[0]=t[0],e[1]=t[4],e[2]=t[8],e[3]=t[12],e[4]=t[1],e[5]=t[5],e[6]=t[9],e[7]=t[13],e[8]=t[2],e[9]=t[6],e[10]=t[10],e[11]=t[14],e[12]=t[3],e[13]=t[7],e[14]=t[11],e[15]=t[15];return e};pe.invert=function(e,t){var r=t[0],i=t[1],n=t[2],a=t[3],o=t[4],s=t[5],l=t[6],h=t[7],u=t[8],f=t[9],d=t[10],c=t[11],v=t[12],p=t[13],m=t[14],_=t[15],x=r*s-i*o,y=r*l-n*o,g=r*h-a*o,w=i*l-n*s,S=i*h-a*s,b=n*h-a*l,E=u*p-f*v,L=u*m-d*v,P=u*_-c*v,C=f*m-d*p,R=f*_-c*p,I=d*_-c*m,D=x*I-y*R+g*C+w*P-S*L+b*E;return D?(D=1/D,e[0]=(s*I-l*R+h*C)*D,e[1]=(n*R-i*I-a*C)*D,e[2]=(p*b-m*S+_*w)*D,e[3]=(d*S-f*b-c*w)*D,e[4]=(l*P-o*I-h*L)*D,e[5]=(r*I-n*P+a*L)*D,e[6]=(m*g-v*b-_*y)*D,e[7]=(u*b-d*g+c*y)*D,e[8]=(o*R-s*P+h*E)*D,e[9]=(i*P-r*R-a*E)*D,e[10]=(v*S-p*g+_*x)*D,e[11]=(f*g-u*S-c*x)*D,e[12]=(s*L-o*C-l*E)*D,e[13]=(r*C-i*L+n*E)*D,e[14]=(p*y-v*w-m*x)*D,e[15]=(u*w-f*y+d*x)*D,e):null};pe.adjoint=function(e,t){var r=t[0],i=t[1],n=t[2],a=t[3],o=t[4],s=t[5],l=t[6],h=t[7],u=t[8],f=t[9],d=t[10],c=t[11],v=t[12],p=t[13],m=t[14],_=t[15];return e[0]=s*(d*_-c*m)-f*(l*_-h*m)+p*(l*c-h*d),e[1]=-(i*(d*_-c*m)-f*(n*_-a*m)+p*(n*c-a*d)),e[2]=i*(l*_-h*m)-s*(n*_-a*m)+p*(n*h-a*l),e[3]=-(i*(l*c-h*d)-s*(n*c-a*d)+f*(n*h-a*l)),e[4]=-(o*(d*_-c*m)-u*(l*_-h*m)+v*(l*c-h*d)),e[5]=r*(d*_-c*m)-u*(n*_-a*m)+v*(n*c-a*d),e[6]=-(r*(l*_-h*m)-o*(n*_-a*m)+v*(n*h-a*l)),e[7]=r*(l*c-h*d)-o*(n*c-a*d)+u*(n*h-a*l),e[8]=o*(f*_-c*p)-u*(s*_-h*p)+v*(s*c-h*f),e[9]=-(r*(f*_-c*p)-u*(i*_-a*p)+v*(i*c-a*f)),e[10]=r*(s*_-h*p)-o*(i*_-a*p)+v*(i*h-a*s),e[11]=-(r*(s*c-h*f)-o*(i*c-a*f)+u*(i*h-a*s)),e[12]=-(o*(f*m-d*p)-u*(s*m-l*p)+v*(s*d-l*f)),e[13]=r*(f*m-d*p)-u*(i*m-n*p)+v*(i*d-n*f),e[14]=-(r*(s*m-l*p)-o*(i*m-n*p)+v*(i*l-n*s)),e[15]=r*(s*d-l*f)-o*(i*d-n*f)+u*(i*l-n*s),e};pe.determinant=function(e){var t=e[0],r=e[1],i=e[2],n=e[3],a=e[4],o=e[5],s=e[6],l=e[7],h=e[8],u=e[9],f=e[10],d=e[11],c=e[12],v=e[13],p=e[14],m=e[15],_=t*o-r*a,x=t*s-i*a,y=t*l-n*a,g=r*s-i*o,w=r*l-n*o,S=i*l-n*s,b=h*v-u*c,E=h*p-f*c,L=h*m-d*c,P=u*p-f*v,C=u*m-d*v,R=f*m-d*p;return _*R-x*C+y*P+g*L-w*E+S*b};pe.multiply=function(e,t,r){var i=t[0],n=t[1],a=t[2],o=t[3],s=t[4],l=t[5],h=t[6],u=t[7],f=t[8],d=t[9],c=t[10],v=t[11],p=t[12],m=t[13],_=t[14],x=t[15],y=r[0],g=r[1],w=r[2],S=r[3];return e[0]=y*i+g*s+w*f+S*p,e[1]=y*n+g*l+w*d+S*m,e[2]=y*a+g*h+w*c+S*_,e[3]=y*o+g*u+w*v+S*x,y=r[4],g=r[5],w=r[6],S=r[7],e[4]=y*i+g*s+w*f+S*p,e[5]=y*n+g*l+w*d+S*m,e[6]=y*a+g*h+w*c+S*_,e[7]=y*o+g*u+w*v+S*x,y=r[8],g=r[9],w=r[10],S=r[11],e[8]=y*i+g*s+w*f+S*p,e[9]=y*n+g*l+w*d+S*m,e[10]=y*a+g*h+w*c+S*_,e[11]=y*o+g*u+w*v+S*x,y=r[12],g=r[13],w=r[14],S=r[15],e[12]=y*i+g*s+w*f+S*p,e[13]=y*n+g*l+w*d+S*m,e[14]=y*a+g*h+w*c+S*_,e[15]=y*o+g*u+w*v+S*x,e};pe.multiplyAffine=function(e,t,r){var i=t[0],n=t[1],a=t[2],o=t[4],s=t[5],l=t[6],h=t[8],u=t[9],f=t[10],d=t[12],c=t[13],v=t[14],p=r[0],m=r[1],_=r[2];return e[0]=p*i+m*o+_*h,e[1]=p*n+m*s+_*u,e[2]=p*a+m*l+_*f,p=r[4],m=r[5],_=r[6],e[4]=p*i+m*o+_*h,e[5]=p*n+m*s+_*u,e[6]=p*a+m*l+_*f,p=r[8],m=r[9],_=r[10],e[8]=p*i+m*o+_*h,e[9]=p*n+m*s+_*u,e[10]=p*a+m*l+_*f,p=r[12],m=r[13],_=r[14],e[12]=p*i+m*o+_*h+d,e[13]=p*n+m*s+_*u+c,e[14]=p*a+m*l+_*f+v,e};pe.mul=pe.multiply;pe.mulAffine=pe.multiplyAffine;pe.translate=function(e,t,r){var i=r[0],n=r[1]
2023-04-28 16:00:04 +08:00
int offset = 9 * idx ;
return ambientSHLightCoefficients [ 0 ]
+ ambientSHLightCoefficients [ 1 ] * N . x
+ ambientSHLightCoefficients [ 2 ] * N . y
+ ambientSHLightCoefficients [ 3 ] * N . z
+ ambientSHLightCoefficients [ 4 ] * N . x * N . z
+ ambientSHLightCoefficients [ 5 ] * N . z * N . y
+ ambientSHLightCoefficients [ 6 ] * N . y * N . x
+ ambientSHLightCoefficients [ 7 ] * ( 3.0 * N . z * N . z - 1.0 )
+ ambientSHLightCoefficients [ 8 ] * ( N . x * N . x - N . y * N . y ) ;
2023-07-09 20:38:38 +08:00
} ` ;var yt="uniform vec3 ",Jr="uniform float ",Sr="@export clay.header.",Er="@end",Ze=":unconfigurable;";const eu=[Sr+"directional_light",yt+"directionalLightDirection[DIRECTIONAL_LIGHT_COUNT]"+Ze,yt+"directionalLightColor[DIRECTIONAL_LIGHT_COUNT]"+Ze,Er,Sr+"ambient_light",yt+"ambientLightColor[AMBIENT_LIGHT_COUNT]"+Ze,Er,Sr+"ambient_sh_light",yt+"ambientSHLightColor[AMBIENT_SH_LIGHT_COUNT]"+Ze,yt+"ambientSHLightCoefficients[AMBIENT_SH_LIGHT_COUNT * 9]"+Ze,Jh,Er,Sr+"ambient_cubemap_light",yt+"ambientCubemapLightColor[AMBIENT_CUBEMAP_LIGHT_COUNT]"+Ze,"uniform samplerCube ambientCubemapLightCubemap[AMBIENT_CUBEMAP_LIGHT_COUNT]"+Ze,"uniform sampler2D ambientCubemapLightBRDFLookup[AMBIENT_CUBEMAP_LIGHT_COUNT]"+Ze,Er,Sr+"point_light",yt+"pointLightPosition[POINT_LIGHT_COUNT]"+Ze,Jr+"pointLightRange[POINT_LIGHT_COUNT]"+Ze,yt+"pointLightColor[POINT_LIGHT_COUNT]"+Ze,Er,Sr+"spot_light",yt+"spotLightPosition[SPOT_LIGHT_COUNT]"+Ze,yt+"spotLightDirection[SPOT_LIGHT_COUNT]"+Ze,Jr+"spotLightRange[SPOT_LIGHT_COUNT]"+Ze,Jr+"spotLightUmbraAngleCosine[SPOT_LIGHT_COUNT]"+Ze,Jr+"spotLightPenumbraAngleCosine[SPOT_LIGHT_COUNT]"+Ze,Jr+"spotLightFalloffFactor[SPOT_LIGHT_COUNT]"+Ze,yt+"spotLightColor[SPOT_LIGHT_COUNT]"+Ze,Er].join( `
2023-09-11 21:56:39 +08:00
` );N.import(eu);var tu=Ct.extend(function(){return{color:[1,1,1],intensity:1,castShadow:!0,shadowResolution:512,group:0}},{type:"",clone:function(){var e=Ct.prototype.clone.call(this);return e.color=Array.prototype.slice.call(this.color),e.intensity=this.intensity,e.castShadow=this.castShadow,e.shadowResolution=this.shadowResolution,e}});const wt=tu;var ji=function(e,t){this.normal=e||new U(0,1,0),this.distance=t||0};ji.prototype={constructor:ji,distanceToPoint:function(e){return A.dot(e.array,this.normal.array)-this.distance},projectPoint:function(e,t){t||(t=new U);var r=this.distanceToPoint(e);return A.scaleAndAdd(t.array,e.array,this.normal.array,-r),t._dirty=!0,t},normalize:function(){var e=1/A.len(this.normal.array);A.scale(this.normal.array,e),this.distance*=e},intersectFrustum:function(e){for(var t=e.vertices,r=this.normal.array,i=A.dot(t[0].array,r)>this.distance,n=1;n<8;n++)if(A.dot(t[n].array,r)>this.distance!=i)return!0},intersectLine:function(){var e=A.create();return function(t,r,i){var n=this.distanceToPoint(t),a=this.distanceToPoint(r);if(n>0&&a>0||n<0&&a<0)return null;var o=this.normal.array,s=this.distance,l=t.array;A.sub(e,r.array,t.array),A.normalize(e,e);var h=A.dot(o,e);if(h===0)return null;i||(i=new U);var u=(A.dot(o,l)-s)/h;return A.scaleAndAdd(i.array,l,e,-u),i._dirty=!0,i}}(),applyTransform:function(){var e=B.create(),t=G.create(),r=G.create();return r[3]=1,function(i){i=i.array,A.scale(r,this.normal.array,this.distance),G.transformMat4(r,r,i),this.distance=A.dot(r,this.normal.array),B.invert(e,i),B.transpose(e,e),t[3]=0,A.copy(t,this.normal.array),G.transformMat4(t,t,e),A.copy(this.normal.array,t)}}(),copy:function(e){A.copy(this.normal.array,e.normal.array),this.normal._dirty=!0,this.distance=e.distance},clone:function(){var e=new ji;return e.copy(this),e}};const bs=ji;var Ce=A.set,_o=A.copy,go=A.transformMat4,Bn=Math.min,Fn=Math.max,Ls=function(){this.planes=[];for(var e=0;e<6;e++)this.planes.push(new bs);this.boundingBox=new tt,this.vertices=[];for(var e=0;e<8;e++)this.vertices[e]=A.fromValues(0,0,0)};Ls.prototype={setFromProjection:function(e){var t=this.planes,r=e.array,i=r[0],n=r[1],a=r[2],o=r[3],s=r[4],l=r[5],h=r[6],u=r[7],f=r[8],d=r[9],c=r[10],v=r[11],p=r[12],m=r[13],_=r[14],x=r[15];Ce(t[0].normal.array,o-i,u-s,v-f),t[0].distance=-(x-p),t[0].normalize(),Ce(t[1].normal.array,o+i,u+s,v+f),t[1].distance=-(x+p),t[1].normalize(),Ce(t[2].normal.array,o+n,u+l,v+d),t[2].distance=-(x+m),t[2].normalize(),Ce(t[3].normal.array,o-n,u-l,v-d),t[3].distance=-(x-m),t[3].normalize(),Ce(t[4].normal.array,o-a,u-h,v-c),t[4].distance=-(x-_),t[4].normalize(),Ce(t[5].normal.array,o+a,u+h,v+c),t[5].distance=-(x+_),t[5].normalize();var y=this.boundingBox,g=this.vertices;if(x===0){var w=l/i,S=-_/(c-1),b=-_/(c+1),E=-b/l,L=-S/l;y.min.set(-E*w,-E,b),y.max.set(E*w,E,S),Ce(g[0],-E*w,-E,b),Ce(g[1],-E*w,E,b),Ce(g[2],E*w,-E,b),Ce(g[3],E*w,E,b),Ce(g[4],-L*w,-L,S),Ce(g[5],-L*w,L,S),Ce(g[6],L*w,-L,S),Ce(g[7],L*w,L,S)}else{var P=(-1-p)/i,C=(1-p)/i,R=(1-m)/l,I=(-1-m)/l,D=(-1-_)/c,O=(1-_)/c;y.min.set(Math.min(P,C),Math.min(I,R),Math.min(O,D)),y.max.set(Math.max(C,P),Math.max(R,I),Math.max(D,O));var z=y.min.array,k=y.max.array;Ce(g[0],z[0],z[1],z[2]),Ce(g[1],z[0],k[1],z[2]),Ce(g[2],k[0],z[1],z[2]),Ce(g[3],k[0],k[1],z[2]),Ce(g[4],z[0],z[1],k[2]),Ce(g[5],z[0],k[1],k[2]),Ce(g[6],k[0],z[1],k[2]),Ce(g[7],k[0],k[1],k[2])}},getTransformedBoundingBox:function(){var e=A.create();return function(t,r){var i=this.vertices,n=r.array,a=t.min,o=t.max,s=a.array,l=o.array,h=i[0];go(e,h,n),_o(s,e),_o(l,e);for(var u=1;u<8;u++)h=i[u],go(e,h,n),s[0]=Bn(e[0],s[0]),s[1]=Bn(e[1],s[1]),s[2]=Bn(e[2],s[2]),l[0]=Fn(e[0],l[0]),l[1]=Fn(e[1],l[1]),l[2]=Fn(e[2],l[2]);return a._dirty=!0,o._dirty=!0,t}}()};const Sa=Ls;var ru=Ct.extend(function(){return{projectionMatrix:new V,invProjectionMatrix:new V,viewMatrix:new V,frustum:new Sa}},function(){this.update(!0)},{update:function(e){Ct.prototype.update.call(this,e),V.invert(this.viewMatrix,this.worldTransform),this.updateProjectionMatrix(),V.invert(this.invProjectionMatrix,this.projectionMatrix),this.frustum.setF
` );if(Un[a])return Un[a];var o=je.genGUID();return Un[a]=o,o}function mn(){this.opaque=[],this.transparent=[],this._opaqueCount=0,this._transparentCount=0}mn.prototype.startCount=function(){this._opaqueCount=0,this._transparentCount=0};mn.prototype.add=function(e,t){t?this.transparent[this._transparentCount++]=e:this.opaque[this._opaqueCount++]=e};mn.prototype.endCount=function(){this.transparent.length=this._transparentCount,this.opaque.length=this._opaqueCount};var au=Ct.extend(function(){return{material:null,lights:[],viewBoundingBoxLastFrame:new tt,shadowUniforms:{},_cameraList:[],_lightUniforms:{},_previousLightNumber:{},_lightNumber:{},_lightProgramKeys:{},_nodeRepository:{},_renderLists:new vs(20)}},function(){this._scene=this},{addToScene:function(e){e instanceof Or?(this._cameraList.length>0&&console.warn("Found multiple camera in one scene. Use the fist one."),this._cameraList.push(e)):e instanceof wt&&this.lights.push(e),e.name&&(this._nodeRepository[e.name]=e)},removeFromScene:function(e){var t;e instanceof Or?(t=this._cameraList.indexOf(e),t>=0&&this._cameraList.splice(t,1)):e instanceof wt&&(t=this.lights.indexOf(e),t>=0&&this.lights.splice(t,1)),e.name&&delete this._nodeRepository[e.name]},getNode:function(e){return this._nodeRepository[e]},setMainCamera:function(e){var t=this._cameraList.indexOf(e);t>=0&&this._cameraList.splice(t,1),this._cameraList.unshift(e)},getMainCamera:function(){return this._cameraList[0]},getLights:function(){return this.lights},updateLights:function(){var e=this.lights;this._previousLightNumber=this._lightNumber;for(var t={},r=0;r<e.length;r++){var i=e[r];if(!i.invisible){var n=i.group;t[n]||(t[n]={}),t[n][i.type]=t[n][i.type]||0,t[n][i.type]++}}this._lightNumber=t;for(var a in t)this._lightProgramKeys[a]=nu(t[a]);this._updateLightUniforms()},cloneNode:function(e){var t=e.clone(),r={};function i(n,a){r[n.__uid__]=a;for(var o=0;o<n._children.length;o++){var s=n._children[o],l=a._children[o];i(s,l)}}return i(e,t),t.traverse(function(n){n.skeleton&&(n.skeleton=n.skeleton.clone(r)),n.material&&(n.material=n.material.clone())}),t},updateRenderList:function(e,t){var r=e.__uid__,i=this._renderLists.get(r);i||(i=new mn,this._renderLists.put(r,i)),i.startCount(),t&&(this.viewBoundingBoxLastFrame.min.set(1/0,1/0,1/0),this.viewBoundingBoxLastFrame.max.set(-1/0,-1/0,-1/0));var n=this.material&&this.material.transparent||!1;return this._doUpdateRenderList(this,e,n,i,t),i.endCount(),i},getRenderList:function(e){return this._renderLists.get(e.__uid__)},_doUpdateRenderList:function(e,t,r,i,n){if(!e.invisible)for(var a=0;a<e._children.length;a++){var o=e._children[a];if(o.isRenderable()){var s=o.isSkinnedMesh()?iu:o.worldTransform.array,l=o.geometry;B.multiplyAffine(yo,t.viewMatrix.array,s),(n&&!l.boundingBox||!this.isFrustumCulled(o,t,yo))&&i.add(o,o.material.transparent||r)}o._children.length>0&&this._doUpdateRenderList(o,t,r,i,n)}},isFrustumCulled:function(){var e=new tt,t=new V;return function(r,i,n){var a=r.boundingBox;if(a||(r.skeleton&&r.skeleton.boundingBox?a=r.skeleton.boundingBox:a=r.geometry.boundingBox),!a)return!1;if(t.array=n,e.transformFrom(a,t),r.castShadow&&this.viewBoundingBoxLastFrame.union(e),r.frustumCulling){if(!e.intersectBoundingBox(i.frustum.boundingBox))return!0;t.array=i.projectionMatrix.array,e.max.array[2]>0&&e.min.array[2]<0&&(e.max.array[2]=-1e-20),e.applyProjection(t);var o=e.min.array,s=e.max.array;if(s[0]<-1||o[0]>1||s[1]<-1||o[1]>1||s[2]<-1||o[2]>1)return!0}return!1}}(),_updateLightUniforms:function(){var e=this.lights;e.sort(ou);var t=this._lightUniforms;for(var r in t)for(var i in t[r])t[r][i].value.length=0;for(var n=0;n<e.length;n++){var a=e[n];if(!a.invisible){var r=a.group;for(var i in a.uniformTemplates){var o=a.uniformTemplates[i],s=o.value(a);if(s!=null){t[r]||(t[r]={}),t[r][i]||(t[r][i]={type:"",value:[]});var l=t[r][i];switch(l.type=o.type+"v",o.type){case"1i":case"1f":case"t":l.value.push(s);break;case"2f":case"3f":case"4f":for(var h=0;h<s.length;h++)l.value.push(s[h]);break;default:console.error("Unkown light uniform type "+o.type)}}}}}},getLightGr
2023-04-28 16:00:04 +08:00
# define SHADER _NAME skybox
uniform mat4 world : WORLD ;
uniform mat4 worldViewProjection : WORLDVIEWPROJECTION ;
attribute vec3 position : POSITION ;
varying vec3 v _WorldPosition ;
void main ( )
{
v _WorldPosition = ( world * vec4 ( position , 1.0 ) ) . xyz ;
gl _Position = worldViewProjection * vec4 ( position , 1.0 ) ;
}
@ end
@ export clay . skybox . fragment
# define PI 3.1415926
uniform mat4 viewInverse : VIEWINVERSE ;
# ifdef EQUIRECTANGULAR
uniform sampler2D environmentMap ;
# else
uniform samplerCube environmentMap ;
# endif
uniform float lod : 0.0 ;
varying vec3 v _WorldPosition ;
@ import clay . util . rgbm
@ import clay . util . srgb
@ import clay . util . ACES
void main ( )
{
vec3 eyePos = viewInverse [ 3 ] . xyz ;
vec3 V = normalize ( v _WorldPosition - eyePos ) ;
# ifdef EQUIRECTANGULAR
float phi = acos ( V . y ) ;
float theta = atan ( - V . x , V . z ) + PI * 0.5 ;
vec2 uv = vec2 ( theta / 2.0 / PI , phi / PI ) ;
vec4 texel = decodeHDR ( texture2D ( environmentMap , fract ( uv ) ) ) ;
# else
# if defined ( LOD ) || defined ( SUPPORT _TEXTURE _LOD )
vec4 texel = decodeHDR ( textureCubeLodEXT ( environmentMap , V , lod ) ) ;
# else
vec4 texel = decodeHDR ( textureCube ( environmentMap , V ) ) ;
# endif
# endif
# ifdef SRGB _DECODE
texel = sRGBToLinear ( texel ) ;
# endif
# ifdef TONEMAPPING
texel . rgb = ACESToneMapping ( texel . rgb ) ;
# endif
# ifdef SRGB _ENCODE
texel = linearTosRGB ( texel ) ;
# endif
gl _FragColor = encodeHDR ( vec4 ( texel . rgb , 1.0 ) ) ;
}
2023-09-11 21:56:39 +08:00
@ end ` ;N.import(du);var vu=lr.extend(function(){var e=new N({vertex:N.source("clay.skybox.vertex"),fragment:N.source("clay.skybox.fragment")}),t=new _t({shader:e,depthMask:!1});return{scene:null,geometry:new Ms,material:t,environmentMap:null,culling:!1,_dummyCamera:new He}},function(){var e=this.scene;e&&this.attachScene(e),this.environmentMap&&this.setEnvironmentMap(this.environmentMap)},{attachScene:function(e){this.scene&&this.detachScene(),e.skybox=this,this.scene=e,e.on("beforerender",this._beforeRenderScene,this)},detachScene:function(){this.scene&&(this.scene.off("beforerender",this._beforeRenderScene),this.scene.skybox=null),this.scene=null},dispose:function(e){this.detachScene(),this.geometry.dispose(e)},setEnvironmentMap:function(e){e.textureType==="texture2D"?(this.material.define("EQUIRECTANGULAR"),e.minFilter=W.LINEAR):this.material.undefine("EQUIRECTANGULAR"),this.material.set("environmentMap",e)},getEnvironmentMap:function(){return this.material.get("environmentMap")},_beforeRenderScene:function(e,t,r){this.renderSkybox(e,r)},renderSkybox:function(e,t){var r=this._dummyCamera;r.aspect=e.getViewportAspect(),r.fov=t.fov||50,r.updateProjectionMatrix(),V.invert(r.invProjectionMatrix,r.projectionMatrix),r.worldTransform.copy(t.worldTransform),r.viewMatrix.copy(t.viewMatrix),this.position.copy(t.getWorldPosition()),this.update(),e.gl.disable(e.gl.BLEND),this.material.get("lod")>0?this.material.define("fragment","LOD"):this.material.undefine("fragment","LOD"),e.renderPass([this],r)}});const vi=vu;var pu=542327876,mu=131072,_u=512,gu=4;function ba(e){return e.charCodeAt(0)+(e.charCodeAt(1)<<8)+(e.charCodeAt(2)<<16)+(e.charCodeAt(3)<<24)}var yu=31,xu=ba("DXT1"),Tu=ba("DXT3"),wu=ba("DXT5"),Su=0,Eu=1,Au=2,bu=3,Lu=4,Cu=7,Mu=20,Du=21,Pu=28,Ru={parse:function(e,t){var r=new Int32Array(e,0,yu);if(r[Su]!==pu||!r(Mu)&gu)return null;var i=r(Du),n=r[Lu],a=r[bu],o=r[Pu]&_u,s=r[Au]&mu,l,h;switch(i){case xu:l=8,h=W.COMPRESSED_RGB_S3TC_DXT1_EXT;break;case Tu:l=16,h=W.COMPRESSED_RGBA_S3TC_DXT3_EXT;break;case wu:l=16,h=W.COMPRESSED_RGBA_S3TC_DXT5_EXT;break;default:return null}var u=r[Eu]+4,f=o?6:1,d=1;s&&(d=Math.max(1,r[Cu]));for(var c=[],v=0;v<f;v++){var p=n,m=a;c[v]=new K({width:p,height:m,format:h});for(var _=[],x=0;x<d;x++){var y=Math.max(4,p)/4*Math.max(4,m)/4*l,g=new Uint8Array(e,u,y);u+=y,p*=.5,m*=.5,_[x]=g}c[v].pixels=_[0],s&&(c[v].mipmaps=_)}if(t)t.width=c[0].width,t.height=c[0].height,t.format=c[0].format,t.pixels=c[0].pixels,t.mipmaps=c[0].mipmaps;else return c[0]}};const Nu=Ru;var qi=String.fromCharCode,Iu=8,Ou=32767;function Bu(e,t,r,i){if(e[3]>0){var n=Math.pow(2,e[3]-128-8+i);t[r+0]=e[0]*n,t[r+1]=e[1]*n,t[r+2]=e[2]*n}else t[r+0]=0,t[r+1]=0,t[r+2]=0;return t[r+3]=1,t}function Fu(e,t,r){for(var i="",n=t;n<r;n++)i+=qi(e[n]);return i}function Uu(e,t){t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3]}function wo(e,t,r,i){for(var n=0,a=0,o=i;o>0;)if(e[a][0]=t[r++],e[a][1]=t[r++],e[a][2]=t[r++],e[a][3]=t[r++],e[a][0]===1&&e[a][1]===1&&e[a][2]===1){for(var s=e[a][3]<<n>>>0;s>0;s--)Uu(e[a-1],e[a]),a++,o--;n+=8}else a++,o--,n=0;return r}function Gu(e,t,r,i){if(i<Iu|i>Ou)return wo(e,t,r,i);var n=t[r++];if(n!=2)return wo(e,t,r-1,i);if(e[0][1]=t[r++],e[0][2]=t[r++],n=t[r++],(e[0][2]<<8>>>0|n)>>>0!==i)return null;for(var n=0;n<4;n++)for(var a=0;a<i;){var o=t[r++];if(o>128){o=(o&127)>>>0;for(var s=t[r++];o--;)e[a++][n]=s}else for(;o--;)e[a++][n]=t[r++]}return r}var zu={parseRGBE:function(e,t,r){r==null&&(r=0);var i=new Uint8Array(e),n=i.length;if(Fu(i,0,2)==="#?"){for(var a=2;a<n&&!(qi(i[a])=== `
` &&qi(i[a+1])=== `
` );a++);if(!(a>=n)){a+=2;for(var o="";a<n;a++){var s=qi(i[a]);if(s=== `
` )break;o+=s}var l=o.split(" "),h=parseInt(l[1]),u=parseInt(l[3]);if(!(!u||!h)){for(var f=a+1,d=[],c=0;c<u;c++){d[c]=[];for(var v=0;v<4;v++)d[c][v]=0}for(var p=new Float32Array(u*h*4),m=0,_=0;_<h;_++){var f=Gu(d,i,f,u);if(!f)return null;for(var c=0;c<u;c++)Bu(d[c],p,m,r),m+=4}return t||(t=new K),t.width=u,t.height=h,t.pixels=p,t.type=W.FLOAT,t}}}},parseRGBEFromPNG:function(e){}};const Hu=zu;var Yi={loadTexture:function(e,t,r,i){var n;if(typeof t=="function"?(r=t,i=r,t={}):t=t||{},typeof e=="string"){if(e.match(/.hdr $ /)||t.fileType==="hdr")return n=new K({width:0,height:0,sRGB:!1}),Yi._fetchTexture(e,function(a){Hu.parseRGBE(a,n,t.exposure),n.dirty(),r&&r(n)},i),n;e.match(/.dds $ /)||t.fileType==="dds"?(n=new K({width:0,height:0}),Yi._fetchTexture(e,function(a){Nu.parse(a,n),n.dirty(),r&&r(n)},i)):(n=new K,n.load(e),n.success(r),n.error(i))}else typeof e=="object"&&typeof e.px<"u"&&(n=new di,n.load(e),n.success(r),n.error(i));return n},loadPanorama:function(e,t,r,i,n,a){var o=this;typeof i=="function"?(n=i,a=n,i={}):i=i||{},Yi.loadTexture(t,i,function(s){s.flipY=i.flipY||!1,o.panoramaToCubeMap(e,s,r,i),s.dispose(e),n&&n(r)},a)},panoramaToCubeMap:function(e,t,r,i){var n=new Aa,a=new vi({scene:new Kt});return a.setEnvironmentMap(t),i=i||{},i.encodeRGBM&&a.material.define("fragment","RGBM_ENCODE"),r.sRGB=t.sRGB,n.texture=r,n.render(e,a.scene),n.texture=null,n.dispose(e),r},heightToNormal:function(e,t){var r=document.createElement("canvas"),i=r.width=e.width,n=r.height=e.height,a=r.getContext("2d");a.drawImage(e,0,0,i,n),t=t||!1;for(var o=a.getImageData(0,0,i,n),s=a.createImageData(i,n),l=0;l<o.data.length;l+=4){if(t){var h=o.data[l],u=o.data[l+1],f=o.data[l+2],d=Math.abs(h-u)+Math.abs(u-f);if(d>20)return console.warn("Given image is not a height map"),e}var c,v,p,m;l%(i*4)===0?(c=o.data[l],p=o.data[l+4]):l%(i*4)===(i-1)*4?(c=o.data[l-4],p=o.data[l]):(c=o.data[l-4],p=o.data[l+4]),l<i*4?(v=o.data[l],m=o.data[l+i*4]):l>i*(n-1)*4?(v=o.data[l-i*4],m=o.data[l]):(v=o.data[l-i*4],m=o.data[l+i*4]),s.data[l]=c-p+127,s.data[l+1]=v-m+127,s.data[l+2]=255,s.data[l+3]=255}return a.putImageData(s,0,0),r},isHeightImage:function(e,t,r){if(!e||!e.width||!e.height)return!1;var i=document.createElement("canvas"),n=i.getContext("2d"),a=t||32;r=r||20,i.width=i.height=a,n.drawImage(e,0,0,a,a);for(var o=n.getImageData(0,0,a,a),s=0;s<o.data.length;s+=4){var l=o.data[s],h=o.data[s+1],u=o.data[s+2],f=Math.abs(l-h)+Math.abs(h-u);if(f>r)return!1}return!0},_fetchTexture:function(e,t,r){Pe.request.get({url:e,responseType:"arraybuffer",onload:t,onerror:r})},createChessboard:function(e,t,r,i){e=e||512,t=t||64,r=r||"black",i=i||"white";var n=Math.ceil(e/t),a=document.createElement("canvas");a.width=e,a.height=e;var o=a.getContext("2d");o.fillStyle=i,o.fillRect(0,0,e,e),o.fillStyle=r;for(var s=0;s<n;s++)for(var l=0;l<n;l++){var h=l%2?s%2:s%2-1;h&&o.fillRect(s*t,l*t,t,t)}var u=new K({image:a,anisotropic:8});return u},createBlank:function(e){var t=document.createElement("canvas");t.width=1,t.height=1;var r=t.getContext("2d");r.fillStyle=e,r.fillRect(0,0,1,1);var i=new K({image:t});return i}};const fr=Yi;var aa=["mousedown","mouseup","mousemove","mouseover","mouseout","click","dblclick","contextmenu"];function oa(e){return"_on"+e}var sa=function(e){var t=this;this._texture=new K({anisotropic:32,flipY:!1,surface:this,dispose:function(r){t.dispose(),K.prototype.dispose.call(this,r)}}),aa.forEach(function(r){this[oa(r)]=function(i){!i.triangle||this._meshes.forEach(function(n){this.dispatchEvent(r,n,i.triangle,i.point)},this)}},this),this._meshes=[],e&&this.setECharts(e),this.onupdate=null};sa.prototype={constructor:sa,getTexture:function(){return this._texture},setECharts:function(e){this._chart=e;var t=e.getDom();if(!(t instanceof HTMLCanvasElement))console.error("ECharts must init on canvas if it is used as texture."),t=document.createElement("canvas");else{var r=this,i=e.getZr(),n=i.__oldRefreshImmediately||i.refreshImmediately;i.refreshImmediately=function(){n.call(this),r._texture.dirty(),r.onupdate&&r.onupdate()},i.__oldRefreshImmediately=n}this._texture.image
2023-04-28 16:00:04 +08:00
@ export clay . compositor . vertex
uniform mat4 worldViewProjection : WORLDVIEWPROJECTION ;
attribute vec3 position : POSITION ;
attribute vec2 texcoord : TEXCOORD _0 ;
varying vec2 v _Texcoord ;
void main ( )
{
v _Texcoord = texcoord ;
gl _Position = worldViewProjection * vec4 ( position , 1.0 ) ;
}
2023-09-11 21:56:39 +08:00
@ end ` ;N.import(Wu);var Xu=new _n,So=new lr({geometry:Xu,frustumCulling:!1}),Zu=new Br,ju=nt.extend(function(){return{fragment:"",outputs:null,material:null,blendWithPrevious:!1,clearColor:!1,clearDepth:!0}},function(){var e=new N(N.source("clay.compositor.vertex"),this.fragment),t=new _t({shader:e});t.enableTexturesAll(),this.material=t},{setUniform:function(e,t){this.material.setUniform(e,t)},getUniform:function(e){var t=this.material.uniforms[e];if(t)return t.value},attachOutput:function(e,t){this.outputs||(this.outputs={}),t=t||M.COLOR_ATTACHMENT0,this.outputs[t]=e},detachOutput:function(e){for(var t in this.outputs)this.outputs[t]===e&&(this.outputs[t]=null)},bind:function(e,t){if(this.outputs)for(var r in this.outputs){var i=this.outputs[r];i&&t.attach(i,r)}t&&t.bind(e)},unbind:function(e,t){t.unbind(e)},render:function(e,t){var r=e.gl;if(t){this.bind(e,t);var i=e.getGLExtension("EXT_draw_buffers");if(i&&this.outputs){var n=[];for(var a in this.outputs)a=+a,a>=r.COLOR_ATTACHMENT0&&a<=r.COLOR_ATTACHMENT0+8&&n.push(a);i.drawBuffersEXT(n)}}this.trigger("beforerender",this,e);var o=this.clearDepth?r.DEPTH_BUFFER_BIT:0;if(r.depthMask(!0),this.clearColor){o=o|r.COLOR_BUFFER_BIT,r.colorMask(!0,!0,!0,!0);var s=this.clearColor;Array.isArray(s)&&r.clearColor(s[0],s[1],s[2],s[3])}r.clear(o),this.blendWithPrevious?(r.enable(r.BLEND),this.material.transparent=!0):(r.disable(r.BLEND),this.material.transparent=!1),this.renderQuad(e),this.trigger("afterrender",this,e),t&&this.unbind(e,t)},renderQuad:function(e){So.material=this.material,e.renderPass([So],Zu)},dispose:function(e){}});const Re=ju,qu= ` # define SAMPLE _NUMBER 1024
2023-04-28 16:00:04 +08:00
# define PI 3.14159265358979
uniform sampler2D normalDistribution ;
uniform vec2 viewportSize : [ 512 , 256 ] ;
const vec3 N = vec3 ( 0.0 , 0.0 , 1.0 ) ;
const float fSampleNumber = float ( SAMPLE _NUMBER ) ;
vec3 importanceSampleNormal ( float i , float roughness , vec3 N ) {
vec3 H = texture2D ( normalDistribution , vec2 ( roughness , i ) ) . rgb ;
vec3 upVector = abs ( N . y ) > 0.999 ? vec3 ( 1.0 , 0.0 , 0.0 ) : vec3 ( 0.0 , 1.0 , 0.0 ) ;
vec3 tangentX = normalize ( cross ( N , upVector ) ) ;
vec3 tangentZ = cross ( N , tangentX ) ;
return normalize ( tangentX * H . x + N * H . y + tangentZ * H . z ) ;
}
float G _Smith ( float roughness , float NoV , float NoL ) {
float k = roughness * roughness / 2.0 ;
float G1V = NoV / ( NoV * ( 1.0 - k ) + k ) ;
float G1L = NoL / ( NoL * ( 1.0 - k ) + k ) ;
return G1L * G1V ;
}
void main ( ) {
vec2 uv = gl _FragCoord . xy / viewportSize ;
float NoV = uv . x ;
float roughness = uv . y ;
vec3 V ;
V . x = sqrt ( 1.0 - NoV * NoV ) ;
V . y = 0.0 ;
V . z = NoV ;
float A = 0.0 ;
float B = 0.0 ;
for ( int i = 0 ; i < SAMPLE _NUMBER ; i ++ ) {
vec3 H = importanceSampleNormal ( float ( i ) / fSampleNumber , roughness , N ) ;
vec3 L = reflect ( - V , H ) ;
float NoL = clamp ( L . z , 0.0 , 1.0 ) ;
float NoH = clamp ( H . z , 0.0 , 1.0 ) ;
float VoH = clamp ( dot ( V , H ) , 0.0 , 1.0 ) ;
if ( NoL > 0.0 ) {
float G = G _Smith ( roughness , NoV , NoL ) ;
float G _Vis = G * VoH / ( NoH * NoV ) ;
float Fc = pow ( 1.0 - VoH , 5.0 ) ;
A += ( 1.0 - Fc ) * G _Vis ;
B += Fc * G _Vis ;
}
}
gl _FragColor = vec4 ( vec2 ( A , B ) / fSampleNumber , 0.0 , 1.0 ) ;
}
2023-09-11 21:56:39 +08:00
` ,Yu= ` # define SHADER _NAME prefilter
2023-04-28 16:00:04 +08:00
# define SAMPLE _NUMBER 1024
# define PI 3.14159265358979
uniform mat4 viewInverse : VIEWINVERSE ;
uniform samplerCube environmentMap ;
uniform sampler2D normalDistribution ;
uniform float roughness : 0.5 ;
varying vec2 v _Texcoord ;
varying vec3 v _WorldPosition ;
@ import clay . util . rgbm
vec3 importanceSampleNormal ( float i , float roughness , vec3 N ) {
vec3 H = texture2D ( normalDistribution , vec2 ( roughness , i ) ) . rgb ;
vec3 upVector = abs ( N . y ) > 0.999 ? vec3 ( 1.0 , 0.0 , 0.0 ) : vec3 ( 0.0 , 1.0 , 0.0 ) ;
vec3 tangentX = normalize ( cross ( N , upVector ) ) ;
vec3 tangentZ = cross ( N , tangentX ) ;
return normalize ( tangentX * H . x + N * H . y + tangentZ * H . z ) ;
}
void main ( ) {
vec3 eyePos = viewInverse [ 3 ] . xyz ;
vec3 V = normalize ( v _WorldPosition - eyePos ) ;
vec3 N = V ;
vec3 prefilteredColor = vec3 ( 0.0 ) ;
float totalWeight = 0.0 ;
float fMaxSampleNumber = float ( SAMPLE _NUMBER ) ;
for ( int i = 0 ; i < SAMPLE _NUMBER ; i ++ ) {
vec3 H = importanceSampleNormal ( float ( i ) / fMaxSampleNumber , roughness , N ) ;
vec3 L = reflect ( - V , H ) ;
float NoL = clamp ( dot ( N , L ) , 0.0 , 1.0 ) ;
if ( NoL > 0.0 ) {
prefilteredColor += decodeHDR ( textureCube ( environmentMap , L ) ) . rgb * NoL ;
totalWeight += NoL ;
}
}
gl _FragColor = encodeHDR ( vec4 ( prefilteredColor / totalWeight , 1.0 ) ) ;
}
2023-09-11 21:56:39 +08:00
` ;var cr={},Hn=["px","nx","py","ny","pz","nz"];cr.prefilterEnvironmentMap=function(e,t,r,i,n){(!n||!i)&&(i=cr.generateNormalDistribution(),n=cr.integrateBRDF(e,i)),r=r||{};var a=r.width||64,o=r.height||64,s=r.type||t.type,l=new di({width:a,height:o,type:s,flipY:!1,mipmaps:[]});l.isPowerOfTwo()||console.warn("Width and height must be power of two to enable mipmap.");var h=Math.min(a,o),u=Math.log(h)/Math.log(2)+1,f=new _t({shader:new N({vertex:N.source("clay.skybox.vertex"),fragment:Yu})});f.set("normalDistribution",i),r.encodeRGBM&&f.define("fragment","RGBM_ENCODE"),r.decodeRGBM&&f.define("fragment","RGBM_DECODE");var d=new Kt,c;if(t.textureType==="texture2D"){var v=new di({width:a,height:o,type:s===W.FLOAT?W.HALF_FLOAT:s});fr.panoramaToCubeMap(e,t,v,{encodeRGBM:r.decodeRGBM}),t=v}c=new vi({scene:d,material:f}),c.material.set("environmentMap",t);var p=new Aa({texture:l});r.encodeRGBM&&(s=l.type=W.UNSIGNED_BYTE);for(var m=new K({width:a,height:o,type:s}),_=new qe({depthBuffer:!1}),x=Pe[s===W.UNSIGNED_BYTE?"Uint8Array":"Float32Array"],y=0;y<u;y++){l.mipmaps[y]={pixels:{}},c.material.set("roughness",y/(u-1));for(var g=m.width,w=2*Math.atan(g/(g-.5))/Math.PI*180,S=0;S<Hn.length;S++){var b=new x(m.width*m.height*4);_.attach(m),_.bind(e);var E=p.getCamera(Hn[S]);E.fov=w,e.render(d,E),e.gl.readPixels(0,0,m.width,m.height,W.RGBA,s,b),_.unbind(e),l.mipmaps[y].pixels[Hn[S]]=b}m.width/=2,m.height/=2,m.dirty()}return _.dispose(e),m.dispose(e),c.dispose(e),i.dispose(e),{environmentMap:l,brdfLookup:n,normalDistribution:i,maxMipmapLevel:u}};cr.integrateBRDF=function(e,t){t=t||cr.generateNormalDistribution();var r=new qe({depthBuffer:!1}),i=new Re({fragment:qu}),n=new K({width:512,height:256,type:W.HALF_FLOAT,wrapS:W.CLAMP_TO_EDGE,wrapT:W.CLAMP_TO_EDGE,minFilter:W.NEAREST,magFilter:W.NEAREST,useMipmap:!1});return i.setUniform("normalDistribution",t),i.setUniform("viewportSize",[512,256]),i.attachOutput(n),i.render(e,r),r.dispose(e),n};cr.generateNormalDistribution=function(r,i){for(var r=r||256,i=i||1024,n=new K({width:r,height:i,type:W.FLOAT,minFilter:W.NEAREST,magFilter:W.NEAREST,wrapS:W.CLAMP_TO_EDGE,wrapT:W.CLAMP_TO_EDGE,useMipmap:!1}),a=new Float32Array(i*r*4),o=[],s=0;s<r;s++){for(var l=s/r,h=l*l,u=0;u<i;u++){var f=(u<<16|u>>>16)>>>0;f=((f&1431655765)<<1|(f&2863311530)>>>1)>>>0,f=((f&858993459)<<2|(f&3435973836)>>>2)>>>0,f=((f&252645135)<<4|(f&4042322160)>>>4)>>>0,f=(((f&16711935)<<8|(f&4278255360)>>>8)>>>0)/4294967296;var d=Math.sqrt((1-f)/(1+(h*h-1)*f));o[u]=d}for(var u=0;u<i;u++){var c=(u*r+s)*4,d=o[u],v=Math.sqrt(1-d*d),p=u/i,m=2*Math.PI*p;a[c]=v*Math.cos(m),a[c+1]=d,a[c+2]=v*Math.sin(m),a[c+3]=1}}return n.pixels=a,n};const $ i=cr;var $ u=wt.extend({cubemap:null,castShadow:!1,_normalDistribution:null,_brdfLookup:null},{type:"AMBIENT_CUBEMAP_LIGHT",prefilter:function(e,t){if(!e.getGLExtension("EXT_shader_texture_lod")){console.warn("Device not support textureCubeLodEXT");return}this._brdfLookup||(this._normalDistribution= $ i.generateNormalDistribution(),this._brdfLookup= $ i.integrateBRDF(e,this._normalDistribution));var r=this.cubemap;if(!r.__prefiltered){var i= $ i.prefilterEnvironmentMap(e,r,{encodeRGBM:!0,width:t,height:t},this._normalDistribution,this._brdfLookup);this.cubemap=i.environmentMap,this.cubemap.__prefiltered=!0,r.dispose(e)}},getBRDFLookup:function(){return this._brdfLookup},uniformTemplates:{ambientCubemapLightColor:{type:"3f",value:function(e){var t=e.color,r=e.intensity;return[t[0]*r,t[1]*r,t[2]*r]}},ambientCubemapLightCubemap:{type:"t",value:function(e){return e.cubemap}},ambientCubemapLightBRDFLookup:{type:"t",value:function(e){return e._brdfLookup}}}});const Ku= $ u;var Qu=wt.extend({castShadow:!1,coefficients:[]},function(){this._coefficientsTmpArr=new Pe.Float32Array(9*3)},{type:"AMBIENT_SH_LIGHT",uniformTemplates:{ambientSHLightColor:{type:"3f",value:function(e){var t=e.color,r=e.intensity;return[t[0]*r,t[1]*r,t[2]*r]}},ambientSHLightCoefficients:{type:"3f",value:function(e){for(var t=e._coefficientsTmpArr,r=0;r<e.coefficients.length;r++)t[r]=e.coefficients[r];return t}}}});const Ju=Qu;var Ds={},hr=["px","nx",
2023-04-28 16:00:04 +08:00
@ export clay . util . rand
highp float rand ( vec2 uv ) {
const highp float a = 12.9898 , b = 78.233 , c = 43758.5453 ;
highp float dt = dot ( uv . xy , vec2 ( a , b ) ) , sn = mod ( dt , 3.141592653589793 ) ;
return fract ( sin ( sn ) * c ) ;
}
@ end
@ export clay . util . calculate _attenuation
uniform float attenuationFactor : 5.0 ;
float lightAttenuation ( float dist , float range )
{
float attenuation = 1.0 ;
attenuation = dist * dist / ( range * range + 1.0 ) ;
float att _s = attenuationFactor ;
attenuation = 1.0 / ( attenuation * att _s + 1.0 ) ;
att _s = 1.0 / ( att _s + 1.0 ) ;
attenuation = attenuation - att _s ;
attenuation /= 1.0 - att _s ;
return clamp ( attenuation , 0.0 , 1.0 ) ;
}
@ end
@ export clay . util . edge _factor
# ifdef SUPPORT _STANDARD _DERIVATIVES
float edgeFactor ( float width )
{
vec3 d = fwidth ( v _Barycentric ) ;
vec3 a3 = smoothstep ( vec3 ( 0.0 ) , d * width , v _Barycentric ) ;
return min ( min ( a3 . x , a3 . y ) , a3 . z ) ;
}
# else
float edgeFactor ( float width )
{
return 1.0 ;
}
# endif
@ end
@ export clay . util . encode _float
vec4 encodeFloat ( const in float depth )
{
const vec4 bitShifts = vec4 ( 256.0 * 256.0 * 256.0 , 256.0 * 256.0 , 256.0 , 1.0 ) ;
const vec4 bit _mask = vec4 ( 0.0 , 1.0 / 256.0 , 1.0 / 256.0 , 1.0 / 256.0 ) ;
vec4 res = fract ( depth * bitShifts ) ;
res -= res . xxyz * bit _mask ;
return res ;
}
@ end
@ export clay . util . decode _float
float decodeFloat ( const in vec4 color )
{
const vec4 bitShifts = vec4 ( 1.0 / ( 256.0 * 256.0 * 256.0 ) , 1.0 / ( 256.0 * 256.0 ) , 1.0 / 256.0 , 1.0 ) ;
return dot ( color , bitShifts ) ;
}
@ end
@ export clay . util . float
@ import clay . util . encode _float
@ import clay . util . decode _float
@ end
@ export clay . util . rgbm _decode
vec3 RGBMDecode ( vec4 rgbm , float range ) {
return range * rgbm . rgb * rgbm . a ;
}
@ end
@ export clay . util . rgbm _encode
vec4 RGBMEncode ( vec3 color , float range ) {
if ( dot ( color , color ) == 0.0 ) {
return vec4 ( 0.0 ) ;
}
vec4 rgbm ;
color /= range ;
rgbm . a = clamp ( max ( max ( color . r , color . g ) , max ( color . b , 1e-6 ) ) , 0.0 , 1.0 ) ;
rgbm . a = ceil ( rgbm . a * 255.0 ) / 255.0 ;
rgbm . rgb = color / rgbm . a ;
return rgbm ;
}
@ end
@ export clay . util . rgbm
@ import clay . util . rgbm _decode
@ import clay . util . rgbm _encode
vec4 decodeHDR ( vec4 color )
{
# if defined ( RGBM _DECODE ) || defined ( RGBM )
return vec4 ( RGBMDecode ( color , 8.12 ) , 1.0 ) ;
# else
return color ;
# endif
}
vec4 encodeHDR ( vec4 color )
{
# if defined ( RGBM _ENCODE ) || defined ( RGBM )
return RGBMEncode ( color . xyz , 8.12 ) ;
# else
return color ;
# endif
}
@ end
@ export clay . util . srgb
vec4 sRGBToLinear ( in vec4 value ) {
return vec4 ( mix ( pow ( value . rgb * 0.9478672986 + vec3 ( 0.0521327014 ) , vec3 ( 2.4 ) ) , value . rgb * 0.0773993808 , vec3 ( lessThanEqual ( value . rgb , vec3 ( 0.04045 ) ) ) ) , value . w ) ;
}
vec4 linearTosRGB ( in vec4 value ) {
return vec4 ( mix ( pow ( value . rgb , vec3 ( 0.41666 ) ) * 1.055 - vec3 ( 0.055 ) , value . rgb * 12.92 , vec3 ( lessThanEqual ( value . rgb , vec3 ( 0.0031308 ) ) ) ) , value . w ) ;
}
@ end
@ export clay . chunk . skinning _header
# ifdef SKINNING
attribute vec3 weight : WEIGHT ;
attribute vec4 joint : JOINT ;
# ifdef USE _SKIN _MATRICES _TEXTURE
uniform sampler2D skinMatricesTexture : ignore ;
uniform float skinMatricesTextureSize : ignore ;
mat4 getSkinMatrix ( sampler2D tex , float idx ) {
float j = idx * 4.0 ;
float x = mod ( j , skinMatricesTextureSize ) ;
float y = floor ( j / skinMatricesTextureSize ) + 0.5 ;
vec2 scale = vec2 ( skinMatricesTextureSize ) ;
return mat4 (
texture2D ( tex , vec2 ( x + 0.5 , y ) / scale ) ,
texture2D ( tex , vec2 ( x + 1.5 , y ) / scale ) ,
texture2D ( tex , vec2 ( x + 2.5 , y ) / scale ) ,
texture2D ( tex , vec2 ( x + 3.5 , y ) / scale )
) ;
}
mat4 getSkinMatrix ( float idx ) {
return getSkinMatrix ( skinMatricesTexture , idx ) ;
}
# else
uniform mat4 skinMatrix [ JOINT _COUNT ] : SKIN _MATRIX ;
mat4 getSkinMatrix ( float idx ) {
return skinMatrix [ int ( idx ) ] ;
}
# endif
# endif
@ end
@ export clay . chunk . skin _matrix
mat4 skinMatrixWS = getSkinMatrix ( joint . x ) * weight . x ;
if ( weight . y > 1e-4 )
{
skinMatrixWS += getSkinMatrix ( joint . y ) * weight . y ;
}
if ( weight . z > 1e-4 )
{
skinMatrixWS += getSkinMatrix ( joint . z ) * weight . z ;
}
float weightW = 1.0 - weight . x - weight . y - weight . z ;
if ( weightW > 1e-4 )
{
skinMatrixWS += getSkinMatrix ( joint . w ) * weightW ;
}
@ end
@ export clay . chunk . instancing _header
# ifdef INSTANCING
attribute vec4 instanceMat1 ;
attribute vec4 instanceMat2 ;
attribute vec4 instanceMat3 ;
# endif
@ end
@ export clay . chunk . instancing _matrix
mat4 instanceMat = mat4 (
vec4 ( instanceMat1 . xyz , 0.0 ) ,
vec4 ( instanceMat2 . xyz , 0.0 ) ,
vec4 ( instanceMat3 . xyz , 0.0 ) ,
vec4 ( instanceMat1 . w , instanceMat2 . w , instanceMat3 . w , 1.0 )
) ;
@ end
@ export clay . util . parallax _correct
vec3 parallaxCorrect ( in vec3 dir , in vec3 pos , in vec3 boxMin , in vec3 boxMax ) {
vec3 first = ( boxMax - pos ) / dir ;
vec3 second = ( boxMin - pos ) / dir ;
vec3 further = max ( first , second ) ;
float dist = min ( further . x , min ( further . y , further . z ) ) ;
vec3 fixedPos = pos + dir * dist ;
vec3 boxCenter = ( boxMax + boxMin ) * 0.5 ;
return normalize ( fixedPos - boxCenter ) ;
}
@ end
@ export clay . util . clamp _sample
vec4 clampSample ( const in sampler2D texture , const in vec2 coord )
{
# ifdef STEREO
float eye = step ( 0.5 , coord . x ) * 0.5 ;
vec2 coordClamped = clamp ( coord , vec2 ( eye , 0.0 ) , vec2 ( 0.5 + eye , 1.0 ) ) ;
# else
vec2 coordClamped = clamp ( coord , vec2 ( 0.0 ) , vec2 ( 1.0 ) ) ;
# endif
return texture2D ( texture , coordClamped ) ;
}
@ end
@ export clay . util . ACES
vec3 ACESToneMapping ( vec3 color )
{
const float A = 2.51 ;
const float B = 0.03 ;
const float C = 2.43 ;
const float D = 0.59 ;
const float E = 0.14 ;
return ( color * ( A * color + B ) ) / ( color * ( C * color + D ) + E ) ;
}
2023-05-25 08:33:42 +08:00
@ end ` ,wf= `
2023-04-28 16:00:04 +08:00
@ export ecgl . common . transformUniforms
uniform mat4 worldViewProjection : WORLDVIEWPROJECTION ;
uniform mat4 worldInverseTranspose : WORLDINVERSETRANSPOSE ;
uniform mat4 world : WORLD ;
@ end
@ export ecgl . common . attributes
attribute vec3 position : POSITION ;
attribute vec2 texcoord : TEXCOORD _0 ;
attribute vec3 normal : NORMAL ;
@ end
@ export ecgl . common . uv . header
uniform vec2 uvRepeat : [ 1.0 , 1.0 ] ;
uniform vec2 uvOffset : [ 0.0 , 0.0 ] ;
uniform vec2 detailUvRepeat : [ 1.0 , 1.0 ] ;
uniform vec2 detailUvOffset : [ 0.0 , 0.0 ] ;
varying vec2 v _Texcoord ;
varying vec2 v _DetailTexcoord ;
@ end
@ export ecgl . common . uv . main
v _Texcoord = texcoord * uvRepeat + uvOffset ;
v _DetailTexcoord = texcoord * detailUvRepeat + detailUvOffset ;
@ end
@ export ecgl . common . uv . fragmentHeader
varying vec2 v _Texcoord ;
varying vec2 v _DetailTexcoord ;
@ end
@ export ecgl . common . albedo . main
vec4 albedoTexel = vec4 ( 1.0 ) ;
# ifdef DIFFUSEMAP _ENABLED
albedoTexel = texture2D ( diffuseMap , v _Texcoord ) ;
# ifdef SRGB _DECODE
albedoTexel = sRGBToLinear ( albedoTexel ) ;
# endif
# endif
# ifdef DETAILMAP _ENABLED
vec4 detailTexel = texture2D ( detailMap , v _DetailTexcoord ) ;
# ifdef SRGB _DECODE
detailTexel = sRGBToLinear ( detailTexel ) ;
# endif
albedoTexel . rgb = mix ( albedoTexel . rgb , detailTexel . rgb , detailTexel . a ) ;
albedoTexel . a = detailTexel . a + ( 1.0 - detailTexel . a ) * albedoTexel . a ;
# endif
@ end
@ export ecgl . common . wireframe . vertexHeader
# ifdef WIREFRAME _QUAD
attribute vec4 barycentric ;
varying vec4 v _Barycentric ;
# elif defined ( WIREFRAME _TRIANGLE )
attribute vec3 barycentric ;
varying vec3 v _Barycentric ;
# endif
@ end
@ export ecgl . common . wireframe . vertexMain
# if defined ( WIREFRAME _QUAD ) || defined ( WIREFRAME _TRIANGLE )
v _Barycentric = barycentric ;
# endif
@ end
@ export ecgl . common . wireframe . fragmentHeader
uniform float wireframeLineWidth : 1 ;
uniform vec4 wireframeLineColor : [ 0 , 0 , 0 , 0.5 ] ;
# ifdef WIREFRAME _QUAD
varying vec4 v _Barycentric ;
float edgeFactor ( ) {
vec4 d = fwidth ( v _Barycentric ) ;
vec4 a4 = smoothstep ( vec4 ( 0.0 ) , d * wireframeLineWidth , v _Barycentric ) ;
return min ( min ( min ( a4 . x , a4 . y ) , a4 . z ) , a4 . w ) ;
}
# elif defined ( WIREFRAME _TRIANGLE )
varying vec3 v _Barycentric ;
float edgeFactor ( ) {
vec3 d = fwidth ( v _Barycentric ) ;
vec3 a3 = smoothstep ( vec3 ( 0.0 ) , d * wireframeLineWidth , v _Barycentric ) ;
return min ( min ( a3 . x , a3 . y ) , a3 . z ) ;
}
# endif
@ end
@ export ecgl . common . wireframe . fragmentMain
# if defined ( WIREFRAME _QUAD ) || defined ( WIREFRAME _TRIANGLE )
if ( wireframeLineWidth > 0. ) {
vec4 lineColor = wireframeLineColor ;
# ifdef SRGB _DECODE
lineColor = sRGBToLinear ( lineColor ) ;
# endif
gl _FragColor . rgb = mix ( gl _FragColor . rgb , lineColor . rgb , ( 1.0 - edgeFactor ( ) ) * lineColor . a ) ;
}
# endif
@ end
@ export ecgl . common . bumpMap . header
# ifdef BUMPMAP _ENABLED
uniform sampler2D bumpMap ;
uniform float bumpScale : 1.0 ;
vec3 bumpNormal ( vec3 surfPos , vec3 surfNormal , vec3 baseNormal )
{
vec2 dSTdx = dFdx ( v _Texcoord ) ;
vec2 dSTdy = dFdy ( v _Texcoord ) ;
float Hll = bumpScale * texture2D ( bumpMap , v _Texcoord ) . x ;
float dHx = bumpScale * texture2D ( bumpMap , v _Texcoord + dSTdx ) . x - Hll ;
float dHy = bumpScale * texture2D ( bumpMap , v _Texcoord + dSTdy ) . x - Hll ;
vec3 vSigmaX = dFdx ( surfPos ) ;
vec3 vSigmaY = dFdy ( surfPos ) ;
vec3 vN = surfNormal ;
vec3 R1 = cross ( vSigmaY , vN ) ;
vec3 R2 = cross ( vN , vSigmaX ) ;
float fDet = dot ( vSigmaX , R1 ) ;
vec3 vGrad = sign ( fDet ) * ( dHx * R1 + dHy * R2 ) ;
return normalize ( abs ( fDet ) * baseNormal - vGrad ) ;
}
# endif
@ end
@ export ecgl . common . normalMap . vertexHeader
# ifdef NORMALMAP _ENABLED
attribute vec4 tangent : TANGENT ;
varying vec3 v _Tangent ;
varying vec3 v _Bitangent ;
# endif
@ end
@ export ecgl . common . normalMap . vertexMain
# ifdef NORMALMAP _ENABLED
if ( dot ( tangent , tangent ) > 0.0 ) {
v _Tangent = normalize ( ( worldInverseTranspose * vec4 ( tangent . xyz , 0.0 ) ) . xyz ) ;
v _Bitangent = normalize ( cross ( v _Normal , v _Tangent ) * tangent . w ) ;
}
# endif
@ end
@ export ecgl . common . normalMap . fragmentHeader
# ifdef NORMALMAP _ENABLED
uniform sampler2D normalMap ;
varying vec3 v _Tangent ;
varying vec3 v _Bitangent ;
# endif
@ end
@ export ecgl . common . normalMap . fragmentMain
# ifdef NORMALMAP _ENABLED
if ( dot ( v _Tangent , v _Tangent ) > 0.0 ) {
vec3 normalTexel = texture2D ( normalMap , v _DetailTexcoord ) . xyz ;
if ( dot ( normalTexel , normalTexel ) > 0.0 ) { N = normalTexel * 2.0 - 1.0 ;
mat3 tbn = mat3 ( v _Tangent , v _Bitangent , v _Normal ) ;
N = normalize ( tbn * N ) ;
}
}
# endif
@ end
@ export ecgl . common . vertexAnimation . header
# ifdef VERTEX _ANIMATION
attribute vec3 prevPosition ;
attribute vec3 prevNormal ;
uniform float percent ;
# endif
@ end
@ export ecgl . common . vertexAnimation . main
# ifdef VERTEX _ANIMATION
vec3 pos = mix ( prevPosition , position , percent ) ;
vec3 norm = mix ( prevNormal , normal , percent ) ;
# else
vec3 pos = position ;
vec3 norm = normal ;
# endif
@ end
@ export ecgl . common . ssaoMap . header
# ifdef SSAOMAP _ENABLED
uniform sampler2D ssaoMap ;
uniform vec4 viewport : VIEWPORT ;
# endif
@ end
@ export ecgl . common . ssaoMap . main
float ao = 1.0 ;
# ifdef SSAOMAP _ENABLED
ao = texture2D ( ssaoMap , ( gl _FragCoord . xy - viewport . xy ) / viewport . zw ) . r ;
# endif
@ end
@ export ecgl . common . diffuseLayer . header
# if ( LAYER _DIFFUSEMAP _COUNT > 0 )
uniform float layerDiffuseIntensity [ LAYER _DIFFUSEMAP _COUNT ] ;
uniform sampler2D layerDiffuseMap [ LAYER _DIFFUSEMAP _COUNT ] ;
# endif
@ end
@ export ecgl . common . emissiveLayer . header
# if ( LAYER _EMISSIVEMAP _COUNT > 0 )
uniform float layerEmissionIntensity [ LAYER _EMISSIVEMAP _COUNT ] ;
uniform sampler2D layerEmissiveMap [ LAYER _EMISSIVEMAP _COUNT ] ;
# endif
@ end
@ export ecgl . common . layers . header
@ import ecgl . common . diffuseLayer . header
@ import ecgl . common . emissiveLayer . header
@ end
@ export ecgl . common . diffuseLayer . main
# if ( LAYER _DIFFUSEMAP _COUNT > 0 )
for ( int _idx _ = 0 ; _idx _ < LAYER _DIFFUSEMAP _COUNT ; _idx _ ++ ) { {
float intensity = layerDiffuseIntensity [ _idx _ ] ;
vec4 texel2 = texture2D ( layerDiffuseMap [ _idx _ ] , v _Texcoord ) ;
# ifdef SRGB _DECODE
texel2 = sRGBToLinear ( texel2 ) ;
# endif
albedoTexel . rgb = mix ( albedoTexel . rgb , texel2 . rgb * intensity , texel2 . a ) ;
albedoTexel . a = texel2 . a + ( 1.0 - texel2 . a ) * albedoTexel . a ;
} }
# endif
@ end
@ export ecgl . common . emissiveLayer . main
# if ( LAYER _EMISSIVEMAP _COUNT > 0 )
for ( int _idx _ = 0 ; _idx _ < LAYER _EMISSIVEMAP _COUNT ; _idx _ ++ )
{ {
vec4 texel2 = texture2D ( layerEmissiveMap [ _idx _ ] , v _Texcoord ) * layerEmissionIntensity [ _idx _ ] ;
# ifdef SRGB _DECODE
texel2 = sRGBToLinear ( texel2 ) ;
# endif
float intensity = layerEmissionIntensity [ _idx _ ] ;
gl _FragColor . rgb += texel2 . rgb * texel2 . a * intensity ;
} }
# endif
@ end
2023-05-25 08:33:42 +08:00
` ,Sf= ` @ export ecgl . color . vertex
2023-04-28 16:00:04 +08:00
uniform mat4 worldViewProjection : WORLDVIEWPROJECTION ;
@ import ecgl . common . uv . header
attribute vec2 texcoord : TEXCOORD _0 ;
attribute vec3 position : POSITION ;
@ import ecgl . common . wireframe . vertexHeader
# ifdef VERTEX _COLOR
attribute vec4 a _Color : COLOR ;
varying vec4 v _Color ;
# endif
# ifdef VERTEX _ANIMATION
attribute vec3 prevPosition ;
uniform float percent : 1.0 ;
# endif
# ifdef ATMOSPHERE _ENABLED
attribute vec3 normal : NORMAL ;
uniform mat4 worldInverseTranspose : WORLDINVERSETRANSPOSE ;
varying vec3 v _Normal ;
# endif
void main ( )
{
# ifdef VERTEX _ANIMATION
vec3 pos = mix ( prevPosition , position , percent ) ;
# else
vec3 pos = position ;
# endif
gl _Position = worldViewProjection * vec4 ( pos , 1.0 ) ;
@ import ecgl . common . uv . main
# ifdef VERTEX _COLOR
v _Color = a _Color ;
# endif
# ifdef ATMOSPHERE _ENABLED
v _Normal = normalize ( ( worldInverseTranspose * vec4 ( normal , 0.0 ) ) . xyz ) ;
# endif
@ import ecgl . common . wireframe . vertexMain
}
@ end
@ export ecgl . color . fragment
# define LAYER _DIFFUSEMAP _COUNT 0
# define LAYER _EMISSIVEMAP _COUNT 0
uniform sampler2D diffuseMap ;
uniform sampler2D detailMap ;
uniform vec4 color : [ 1.0 , 1.0 , 1.0 , 1.0 ] ;
# ifdef ATMOSPHERE _ENABLED
uniform mat4 viewTranspose : VIEWTRANSPOSE ;
uniform vec3 glowColor ;
uniform float glowPower ;
varying vec3 v _Normal ;
# endif
# ifdef VERTEX _COLOR
varying vec4 v _Color ;
# endif
@ import ecgl . common . layers . header
@ import ecgl . common . uv . fragmentHeader
@ import ecgl . common . wireframe . fragmentHeader
@ import clay . util . srgb
void main ( )
{
# ifdef SRGB _DECODE
gl _FragColor = sRGBToLinear ( color ) ;
# else
gl _FragColor = color ;
# endif
# ifdef VERTEX _COLOR
gl _FragColor *= v _Color ;
# endif
@ import ecgl . common . albedo . main
@ import ecgl . common . diffuseLayer . main
gl _FragColor *= albedoTexel ;
# ifdef ATMOSPHERE _ENABLED
float atmoIntensity = pow ( 1.0 - dot ( v _Normal , ( viewTranspose * vec4 ( 0.0 , 0.0 , 1.0 , 0.0 ) ) . xyz ) , glowPower ) ;
gl _FragColor . rgb += glowColor * atmoIntensity ;
# endif
@ import ecgl . common . emissiveLayer . main
@ import ecgl . common . wireframe . fragmentMain
}
2023-07-09 20:38:38 +08:00
@ end ` ,Ef= ` / * *
2023-04-28 16:00:04 +08:00
* http : * /
@ export ecgl . lambert . vertex
@ import ecgl . common . transformUniforms
@ import ecgl . common . uv . header
@ import ecgl . common . attributes
@ import ecgl . common . wireframe . vertexHeader
# ifdef VERTEX _COLOR
attribute vec4 a _Color : COLOR ;
varying vec4 v _Color ;
# endif
@ import ecgl . common . vertexAnimation . header
varying vec3 v _Normal ;
varying vec3 v _WorldPosition ;
void main ( )
{
@ import ecgl . common . uv . main
@ import ecgl . common . vertexAnimation . main
gl _Position = worldViewProjection * vec4 ( pos , 1.0 ) ;
v _Normal = normalize ( ( worldInverseTranspose * vec4 ( norm , 0.0 ) ) . xyz ) ;
v _WorldPosition = ( world * vec4 ( pos , 1.0 ) ) . xyz ;
# ifdef VERTEX _COLOR
v _Color = a _Color ;
# endif
@ import ecgl . common . wireframe . vertexMain
}
@ end
@ export ecgl . lambert . fragment
# define LAYER _DIFFUSEMAP _COUNT 0
# define LAYER _EMISSIVEMAP _COUNT 0
# define NORMAL _UP _AXIS 1
# define NORMAL _FRONT _AXIS 2
@ import ecgl . common . uv . fragmentHeader
varying vec3 v _Normal ;
varying vec3 v _WorldPosition ;
uniform sampler2D diffuseMap ;
uniform sampler2D detailMap ;
@ import ecgl . common . layers . header
uniform float emissionIntensity : 1.0 ;
uniform vec4 color : [ 1.0 , 1.0 , 1.0 , 1.0 ] ;
uniform mat4 viewInverse : VIEWINVERSE ;
# ifdef ATMOSPHERE _ENABLED
uniform mat4 viewTranspose : VIEWTRANSPOSE ;
uniform vec3 glowColor ;
uniform float glowPower ;
# endif
# ifdef AMBIENT _LIGHT _COUNT
@ import clay . header . ambient _light
# endif
# ifdef AMBIENT _SH _LIGHT _COUNT
@ import clay . header . ambient _sh _light
# endif
# ifdef DIRECTIONAL _LIGHT _COUNT
@ import clay . header . directional _light
# endif
# ifdef VERTEX _COLOR
varying vec4 v _Color ;
# endif
@ import ecgl . common . ssaoMap . header
@ import ecgl . common . bumpMap . header
@ import clay . util . srgb
@ import ecgl . common . wireframe . fragmentHeader
@ import clay . plugin . compute _shadow _map
void main ( )
{
# ifdef SRGB _DECODE
gl _FragColor = sRGBToLinear ( color ) ;
# else
gl _FragColor = color ;
# endif
# ifdef VERTEX _COLOR
# ifdef SRGB _DECODE
gl _FragColor *= sRGBToLinear ( v _Color ) ;
# else
gl _FragColor *= v _Color ;
# endif
# endif
@ import ecgl . common . albedo . main
@ import ecgl . common . diffuseLayer . main
gl _FragColor *= albedoTexel ;
vec3 N = v _Normal ;
# ifdef DOUBLE _SIDED
vec3 eyePos = viewInverse [ 3 ] . xyz ;
vec3 V = normalize ( eyePos - v _WorldPosition ) ;
if ( dot ( N , V ) < 0.0 ) {
N = - N ;
}
# endif
float ambientFactor = 1.0 ;
# ifdef BUMPMAP _ENABLED
N = bumpNormal ( v _WorldPosition , v _Normal , N ) ;
ambientFactor = dot ( v _Normal , N ) ;
# endif
vec3 N2 = vec3 ( N . x , N [ NORMAL _UP _AXIS ] , N [ NORMAL _FRONT _AXIS ] ) ;
vec3 diffuseColor = vec3 ( 0.0 , 0.0 , 0.0 ) ;
@ import ecgl . common . ssaoMap . main
# ifdef AMBIENT _LIGHT _COUNT
for ( int i = 0 ; i < AMBIENT _LIGHT _COUNT ; i ++ )
{
diffuseColor += ambientLightColor [ i ] * ambientFactor * ao ;
}
# endif
# ifdef AMBIENT _SH _LIGHT _COUNT
for ( int _idx _ = 0 ; _idx _ < AMBIENT _SH _LIGHT _COUNT ; _idx _ ++ )
{ {
diffuseColor += calcAmbientSHLight ( _idx _ , N2 ) * ambientSHLightColor [ _idx _ ] * ao ;
} }
# endif
# ifdef DIRECTIONAL _LIGHT _COUNT
# if defined ( DIRECTIONAL _LIGHT _SHADOWMAP _COUNT )
float shadowContribsDir [ DIRECTIONAL _LIGHT _COUNT ] ;
if ( shadowEnabled )
{
computeShadowOfDirectionalLights ( v _WorldPosition , shadowContribsDir ) ;
}
# endif
for ( int i = 0 ; i < DIRECTIONAL _LIGHT _COUNT ; i ++ )
{
vec3 lightDirection = - directionalLightDirection [ i ] ;
vec3 lightColor = directionalLightColor [ i ] ;
float shadowContrib = 1.0 ;
# if defined ( DIRECTIONAL _LIGHT _SHADOWMAP _COUNT )
if ( shadowEnabled )
{
shadowContrib = shadowContribsDir [ i ] ;
}
# endif
float ndl = dot ( N , normalize ( lightDirection ) ) * shadowContrib ;
diffuseColor += lightColor * clamp ( ndl , 0.0 , 1.0 ) ;
}
# endif
gl _FragColor . rgb *= diffuseColor ;
# ifdef ATMOSPHERE _ENABLED
float atmoIntensity = pow ( 1.0 - dot ( v _Normal , ( viewTranspose * vec4 ( 0.0 , 0.0 , 1.0 , 0.0 ) ) . xyz ) , glowPower ) ;
gl _FragColor . rgb += glowColor * atmoIntensity ;
# endif
@ import ecgl . common . emissiveLayer . main
@ import ecgl . common . wireframe . fragmentMain
}
2023-07-09 20:38:38 +08:00
@ end ` ,Af= ` @ export ecgl . realistic . vertex
2023-04-28 16:00:04 +08:00
@ import ecgl . common . transformUniforms
@ import ecgl . common . uv . header
@ import ecgl . common . attributes
@ import ecgl . common . wireframe . vertexHeader
# ifdef VERTEX _COLOR
attribute vec4 a _Color : COLOR ;
varying vec4 v _Color ;
# endif
# ifdef NORMALMAP _ENABLED
attribute vec4 tangent : TANGENT ;
varying vec3 v _Tangent ;
varying vec3 v _Bitangent ;
# endif
@ import ecgl . common . vertexAnimation . header
varying vec3 v _Normal ;
varying vec3 v _WorldPosition ;
void main ( )
{
@ import ecgl . common . uv . main
@ import ecgl . common . vertexAnimation . main
gl _Position = worldViewProjection * vec4 ( pos , 1.0 ) ;
v _Normal = normalize ( ( worldInverseTranspose * vec4 ( norm , 0.0 ) ) . xyz ) ;
v _WorldPosition = ( world * vec4 ( pos , 1.0 ) ) . xyz ;
# ifdef VERTEX _COLOR
v _Color = a _Color ;
# endif
# ifdef NORMALMAP _ENABLED
v _Tangent = normalize ( ( worldInverseTranspose * vec4 ( tangent . xyz , 0.0 ) ) . xyz ) ;
v _Bitangent = normalize ( cross ( v _Normal , v _Tangent ) * tangent . w ) ;
# endif
@ import ecgl . common . wireframe . vertexMain
}
@ end
@ export ecgl . realistic . fragment
# define LAYER _DIFFUSEMAP _COUNT 0
# define LAYER _EMISSIVEMAP _COUNT 0
# define PI 3.14159265358979
# define ROUGHNESS _CHANEL 0
# define METALNESS _CHANEL 1
# define NORMAL _UP _AXIS 1
# define NORMAL _FRONT _AXIS 2
# ifdef VERTEX _COLOR
varying vec4 v _Color ;
# endif
@ import ecgl . common . uv . fragmentHeader
varying vec3 v _Normal ;
varying vec3 v _WorldPosition ;
uniform sampler2D diffuseMap ;
uniform sampler2D detailMap ;
uniform sampler2D metalnessMap ;
uniform sampler2D roughnessMap ;
@ import ecgl . common . layers . header
uniform float emissionIntensity : 1.0 ;
uniform vec4 color : [ 1.0 , 1.0 , 1.0 , 1.0 ] ;
uniform float metalness : 0.0 ;
uniform float roughness : 0.5 ;
uniform mat4 viewInverse : VIEWINVERSE ;
# ifdef ATMOSPHERE _ENABLED
uniform mat4 viewTranspose : VIEWTRANSPOSE ;
uniform vec3 glowColor ;
uniform float glowPower ;
# endif
# ifdef AMBIENT _LIGHT _COUNT
@ import clay . header . ambient _light
# endif
# ifdef AMBIENT _SH _LIGHT _COUNT
@ import clay . header . ambient _sh _light
# endif
# ifdef AMBIENT _CUBEMAP _LIGHT _COUNT
@ import clay . header . ambient _cubemap _light
# endif
# ifdef DIRECTIONAL _LIGHT _COUNT
@ import clay . header . directional _light
# endif
@ import ecgl . common . normalMap . fragmentHeader
@ import ecgl . common . ssaoMap . header
@ import ecgl . common . bumpMap . header
@ import clay . util . srgb
@ import clay . util . rgbm
@ import ecgl . common . wireframe . fragmentHeader
@ import clay . plugin . compute _shadow _map
vec3 F _Schlick ( float ndv , vec3 spec ) {
return spec + ( 1.0 - spec ) * pow ( 1.0 - ndv , 5.0 ) ;
}
float D _Phong ( float g , float ndh ) {
float a = pow ( 8192.0 , g ) ;
return ( a + 2.0 ) / 8.0 * pow ( ndh , a ) ;
}
void main ( )
{
vec4 albedoColor = color ;
vec3 eyePos = viewInverse [ 3 ] . xyz ;
vec3 V = normalize ( eyePos - v _WorldPosition ) ;
# ifdef VERTEX _COLOR
# ifdef SRGB _DECODE
albedoColor *= sRGBToLinear ( v _Color ) ;
# else
albedoColor *= v _Color ;
# endif
# endif
@ import ecgl . common . albedo . main
@ import ecgl . common . diffuseLayer . main
albedoColor *= albedoTexel ;
float m = metalness ;
# ifdef METALNESSMAP _ENABLED
float m2 = texture2D ( metalnessMap , v _DetailTexcoord ) [ METALNESS _CHANEL ] ;
m = clamp ( m2 + ( m - 0.5 ) * 2.0 , 0.0 , 1.0 ) ;
# endif
vec3 baseColor = albedoColor . rgb ;
albedoColor . rgb = baseColor * ( 1.0 - m ) ;
vec3 specFactor = mix ( vec3 ( 0.04 ) , baseColor , m ) ;
float g = 1.0 - roughness ;
# ifdef ROUGHNESSMAP _ENABLED
float g2 = 1.0 - texture2D ( roughnessMap , v _DetailTexcoord ) [ ROUGHNESS _CHANEL ] ;
g = clamp ( g2 + ( g - 0.5 ) * 2.0 , 0.0 , 1.0 ) ;
# endif
vec3 N = v _Normal ;
# ifdef DOUBLE _SIDED
if ( dot ( N , V ) < 0.0 ) {
N = - N ;
}
# endif
float ambientFactor = 1.0 ;
# ifdef BUMPMAP _ENABLED
N = bumpNormal ( v _WorldPosition , v _Normal , N ) ;
ambientFactor = dot ( v _Normal , N ) ;
# endif
@ import ecgl . common . normalMap . fragmentMain
vec3 N2 = vec3 ( N . x , N [ NORMAL _UP _AXIS ] , N [ NORMAL _FRONT _AXIS ] ) ;
vec3 diffuseTerm = vec3 ( 0.0 ) ;
vec3 specularTerm = vec3 ( 0.0 ) ;
float ndv = clamp ( dot ( N , V ) , 0.0 , 1.0 ) ;
vec3 fresnelTerm = F _Schlick ( ndv , specFactor ) ;
@ import ecgl . common . ssaoMap . main
# ifdef AMBIENT _LIGHT _COUNT
for ( int _idx _ = 0 ; _idx _ < AMBIENT _LIGHT _COUNT ; _idx _ ++ )
{ {
diffuseTerm += ambientLightColor [ _idx _ ] * ambientFactor * ao ;
} }
# endif
# ifdef AMBIENT _SH _LIGHT _COUNT
for ( int _idx _ = 0 ; _idx _ < AMBIENT _SH _LIGHT _COUNT ; _idx _ ++ )
{ {
diffuseTerm += calcAmbientSHLight ( _idx _ , N2 ) * ambientSHLightColor [ _idx _ ] * ao ;
} }
# endif
# ifdef DIRECTIONAL _LIGHT _COUNT
# if defined ( DIRECTIONAL _LIGHT _SHADOWMAP _COUNT )
float shadowContribsDir [ DIRECTIONAL _LIGHT _COUNT ] ;
if ( shadowEnabled )
{
computeShadowOfDirectionalLights ( v _WorldPosition , shadowContribsDir ) ;
}
# endif
for ( int _idx _ = 0 ; _idx _ < DIRECTIONAL _LIGHT _COUNT ; _idx _ ++ )
{ {
vec3 L = - directionalLightDirection [ _idx _ ] ;
vec3 lc = directionalLightColor [ _idx _ ] ;
vec3 H = normalize ( L + V ) ;
float ndl = clamp ( dot ( N , normalize ( L ) ) , 0.0 , 1.0 ) ;
float ndh = clamp ( dot ( N , H ) , 0.0 , 1.0 ) ;
float shadowContrib = 1.0 ;
# if defined ( DIRECTIONAL _LIGHT _SHADOWMAP _COUNT )
if ( shadowEnabled )
{
shadowContrib = shadowContribsDir [ _idx _ ] ;
}
# endif
vec3 li = lc * ndl * shadowContrib ;
diffuseTerm += li ;
specularTerm += li * fresnelTerm * D _Phong ( g , ndh ) ;
} }
# endif
# ifdef AMBIENT _CUBEMAP _LIGHT _COUNT
vec3 L = reflect ( - V , N ) ;
L = vec3 ( L . x , L [ NORMAL _UP _AXIS ] , L [ NORMAL _FRONT _AXIS ] ) ;
float rough2 = clamp ( 1.0 - g , 0.0 , 1.0 ) ;
float bias2 = rough2 * 5.0 ;
vec2 brdfParam2 = texture2D ( ambientCubemapLightBRDFLookup [ 0 ] , vec2 ( rough2 , ndv ) ) . xy ;
vec3 envWeight2 = specFactor * brdfParam2 . x + brdfParam2 . y ;
vec3 envTexel2 ;
for ( int _idx _ = 0 ; _idx _ < AMBIENT _CUBEMAP _LIGHT _COUNT ; _idx _ ++ )
{ {
envTexel2 = RGBMDecode ( textureCubeLodEXT ( ambientCubemapLightCubemap [ _idx _ ] , L , bias2 ) , 8.12 ) ;
specularTerm += ambientCubemapLightColor [ _idx _ ] * envTexel2 * envWeight2 * ao ;
} }
# endif
gl _FragColor . rgb = albedoColor . rgb * diffuseTerm + specularTerm ;
gl _FragColor . a = albedoColor . a ;
# ifdef ATMOSPHERE _ENABLED
float atmoIntensity = pow ( 1.0 - dot ( v _Normal , ( viewTranspose * vec4 ( 0.0 , 0.0 , 1.0 , 0.0 ) ) . xyz ) , glowPower ) ;
gl _FragColor . rgb += glowColor * atmoIntensity ;
# endif
# ifdef SRGB _ENCODE
gl _FragColor = linearTosRGB ( gl _FragColor ) ;
# endif
@ import ecgl . common . emissiveLayer . main
@ import ecgl . common . wireframe . fragmentMain
}
2023-05-25 08:33:42 +08:00
@ end ` ,bf= ` @ export ecgl . hatching . vertex
2023-04-28 16:00:04 +08:00
@ import ecgl . realistic . vertex
@ end
@ export ecgl . hatching . fragment
# define NORMAL _UP _AXIS 1
# define NORMAL _FRONT _AXIS 2
@ import ecgl . common . uv . fragmentHeader
varying vec3 v _Normal ;
varying vec3 v _WorldPosition ;
uniform vec4 color : [ 0.0 , 0.0 , 0.0 , 1.0 ] ;
uniform vec4 paperColor : [ 1.0 , 1.0 , 1.0 , 1.0 ] ;
uniform mat4 viewInverse : VIEWINVERSE ;
# ifdef AMBIENT _LIGHT _COUNT
@ import clay . header . ambient _light
# endif
# ifdef AMBIENT _SH _LIGHT _COUNT
@ import clay . header . ambient _sh _light
# endif
# ifdef DIRECTIONAL _LIGHT _COUNT
@ import clay . header . directional _light
# endif
# ifdef VERTEX _COLOR
varying vec4 v _Color ;
# endif
@ import ecgl . common . ssaoMap . header
@ import ecgl . common . bumpMap . header
@ import clay . util . srgb
@ import ecgl . common . wireframe . fragmentHeader
@ import clay . plugin . compute _shadow _map
uniform sampler2D hatch1 ;
uniform sampler2D hatch2 ;
uniform sampler2D hatch3 ;
uniform sampler2D hatch4 ;
uniform sampler2D hatch5 ;
uniform sampler2D hatch6 ;
float shade ( in float tone ) {
vec4 c = vec4 ( 1. , 1. , 1. , 1. ) ;
float step = 1. / 6. ;
vec2 uv = v _DetailTexcoord ;
if ( tone <= step / 2.0 ) {
c = mix ( vec4 ( 0. ) , texture2D ( hatch6 , uv ) , 12. * tone ) ;
}
else if ( tone <= step ) {
c = mix ( texture2D ( hatch6 , uv ) , texture2D ( hatch5 , uv ) , 6. * tone ) ;
}
if ( tone > step && tone <= 2. * step ) {
c = mix ( texture2D ( hatch5 , uv ) , texture2D ( hatch4 , uv ) , 6. * ( tone - step ) ) ;
}
if ( tone > 2. * step && tone <= 3. * step ) {
c = mix ( texture2D ( hatch4 , uv ) , texture2D ( hatch3 , uv ) , 6. * ( tone - 2. * step ) ) ;
}
if ( tone > 3. * step && tone <= 4. * step ) {
c = mix ( texture2D ( hatch3 , uv ) , texture2D ( hatch2 , uv ) , 6. * ( tone - 3. * step ) ) ;
}
if ( tone > 4. * step && tone <= 5. * step ) {
c = mix ( texture2D ( hatch2 , uv ) , texture2D ( hatch1 , uv ) , 6. * ( tone - 4. * step ) ) ;
}
if ( tone > 5. * step ) {
c = mix ( texture2D ( hatch1 , uv ) , vec4 ( 1. ) , 6. * ( tone - 5. * step ) ) ;
}
return c . r ;
}
const vec3 w = vec3 ( 0.2125 , 0.7154 , 0.0721 ) ;
void main ( )
{
# ifdef SRGB _DECODE
vec4 inkColor = sRGBToLinear ( color ) ;
# else
vec4 inkColor = color ;
# endif
# ifdef VERTEX _COLOR
# ifdef SRGB _DECODE
inkColor *= sRGBToLinear ( v _Color ) ;
# else
inkColor *= v _Color ;
# endif
# endif
vec3 N = v _Normal ;
# ifdef DOUBLE _SIDED
vec3 eyePos = viewInverse [ 3 ] . xyz ;
vec3 V = normalize ( eyePos - v _WorldPosition ) ;
if ( dot ( N , V ) < 0.0 ) {
N = - N ;
}
# endif
float tone = 0.0 ;
float ambientFactor = 1.0 ;
# ifdef BUMPMAP _ENABLED
N = bumpNormal ( v _WorldPosition , v _Normal , N ) ;
ambientFactor = dot ( v _Normal , N ) ;
# endif
vec3 N2 = vec3 ( N . x , N [ NORMAL _UP _AXIS ] , N [ NORMAL _FRONT _AXIS ] ) ;
@ import ecgl . common . ssaoMap . main
# ifdef AMBIENT _LIGHT _COUNT
for ( int i = 0 ; i < AMBIENT _LIGHT _COUNT ; i ++ )
{
tone += dot ( ambientLightColor [ i ] , w ) * ambientFactor * ao ;
}
# endif
# ifdef AMBIENT _SH _LIGHT _COUNT
for ( int _idx _ = 0 ; _idx _ < AMBIENT _SH _LIGHT _COUNT ; _idx _ ++ )
{ {
tone += dot ( calcAmbientSHLight ( _idx _ , N2 ) * ambientSHLightColor [ _idx _ ] , w ) * ao ;
} }
# endif
# ifdef DIRECTIONAL _LIGHT _COUNT
# if defined ( DIRECTIONAL _LIGHT _SHADOWMAP _COUNT )
float shadowContribsDir [ DIRECTIONAL _LIGHT _COUNT ] ;
if ( shadowEnabled )
{
computeShadowOfDirectionalLights ( v _WorldPosition , shadowContribsDir ) ;
}
# endif
for ( int i = 0 ; i < DIRECTIONAL _LIGHT _COUNT ; i ++ )
{
vec3 lightDirection = - directionalLightDirection [ i ] ;
float lightTone = dot ( directionalLightColor [ i ] , w ) ;
float shadowContrib = 1.0 ;
# if defined ( DIRECTIONAL _LIGHT _SHADOWMAP _COUNT )
if ( shadowEnabled )
{
shadowContrib = shadowContribsDir [ i ] ;
}
# endif
float ndl = dot ( N , normalize ( lightDirection ) ) * shadowContrib ;
tone += lightTone * clamp ( ndl , 0.0 , 1.0 ) ;
}
# endif
gl _FragColor = mix ( inkColor , paperColor , shade ( clamp ( tone , 0.0 , 1.0 ) ) ) ;
}
@ end
2023-07-09 20:38:38 +08:00
` ,Lf= ` @ export ecgl . sm . depth . vertex
2023-04-28 16:00:04 +08:00
uniform mat4 worldViewProjection : WORLDVIEWPROJECTION ;
attribute vec3 position : POSITION ;
attribute vec2 texcoord : TEXCOORD _0 ;
# ifdef VERTEX _ANIMATION
attribute vec3 prevPosition ;
uniform float percent : 1.0 ;
# endif
varying vec4 v _ViewPosition ;
varying vec2 v _Texcoord ;
void main ( ) {
# ifdef VERTEX _ANIMATION
vec3 pos = mix ( prevPosition , position , percent ) ;
# else
vec3 pos = position ;
# endif
v _ViewPosition = worldViewProjection * vec4 ( pos , 1.0 ) ;
gl _Position = v _ViewPosition ;
v _Texcoord = texcoord ;
}
@ end
@ export ecgl . sm . depth . fragment
@ import clay . sm . depth . fragment
2023-09-11 21:56:39 +08:00
@ end ` ;Object.assign(Ct.prototype,Tf);N.import(Ps);N.import(xs);N.import(wf);N.import(Sf);N.import(Ef);N.import(Af);N.import(bf);N.import(Lf);function Cf(e){return!e||e==="none"}function Rs(e){return e instanceof HTMLCanvasElement||e instanceof HTMLImageElement||e instanceof Image}function Mf(e){return e.getZr&&e.setOption}var Df=Kt.prototype.addToScene,Pf=Kt.prototype.removeFromScene;Kt.prototype.addToScene=function(e){if(Df.call(this,e),this.__zr){var t=this.__zr;e.traverse(function(r){r.__zr=t,r.addAnimatorsToZr&&r.addAnimatorsToZr(t)})}};Kt.prototype.removeFromScene=function(e){Pf.call(this,e),e.traverse(function(t){var r=t.__zr;t.__zr=null,r&&t.removeAnimatorsFromZr&&t.removeAnimatorsFromZr(r)})};_t.prototype.setTextureImage=function(e,t,r,i){if(!!this.shader){var n=r.getZr(),a=this,o;return a.autoUpdateTextureStatus=!1,a.disableTexture(e),Cf(t)||(o=q.loadTexture(t,r,i,function(s){a.enableTexture(e),n&&n.refresh()}),a.set(e,o)),o}};var q={};q.Renderer=ui;q.Node=Ct;q.Mesh=lr;q.Shader=N;q.Material=_t;q.Texture=W;q.Texture2D=K;q.Geometry=oe;q.SphereGeometry=sf;q.PlaneGeometry=_n;q.CubeGeometry=Ms;q.AmbientLight=hf;q.DirectionalLight=ff;q.PointLight=df;q.SpotLight=pf;q.PerspectiveCamera=He;q.OrthographicCamera=Br;q.Vector2=ut;q.Vector3=U;q.Vector4=mf;q.Quaternion=Ts;q.Matrix2=_f;q.Matrix2d=gf;q.Matrix3=yf;q.Matrix4=V;q.Plane=bs;q.Ray=Ji;q.BoundingBox=tt;q.Frustum=Sa;var Ui=null;function Rf(){return Ui!==null||(Ui=fr.createBlank("rgba(255,255,255,0)").image),Ui}function Eo(e){return Math.pow(2,Math.round(Math.log(e)/Math.LN2))}function Ao(e){if((e.wrapS===W.REPEAT||e.wrapT===W.REPEAT)&&e.image){var t=Eo(e.width),r=Eo(e.height);if(t!==e.width||r!==e.height){var i=document.createElement("canvas");i.width=t,i.height=r;var n=i.getContext("2d");n.drawImage(e.image,0,0,t,r),e.image=i}}}q.loadTexture=function(e,t,r,i){typeof r=="function"&&(i=r,r={}),r=r||{};for(var n=Object.keys(r).sort(),a="",o=0;o<n.length;o++)a+=n[o]+"_"+r[n[o]]+"_";var s=t.__textureCache=t.__textureCache||new Vl(20);if(Mf(e)){var l=e.__textureid__,h=s.get(a+l);if(h)h.texture.surface.setECharts(e),i&&i(h.texture);else{var u=new Vu(e);u.onupdate=function(){t.getZr().refresh()},h={texture:u.getTexture()};for(var o=0;o<n.length;o++)h.texture[n[o]]=r[n[o]];l=e.__textureid__||"__ecgl_ec__"+h.texture.__uid__,e.__textureid__=l,s.put(a+l,h),i&&i(h.texture)}return h.texture}else if(Rs(e)){var l=e.__textureid__,h=s.get(a+l);if(!h){h={texture:new q.Texture2D({image:e})};for(var o=0;o<n.length;o++)h.texture[n[o]]=r[n[o]];l=e.__textureid__||"__ecgl_image__"+h.texture.__uid__,e.__textureid__=l,s.put(a+l,h),Ao(h.texture),i&&i(h.texture)}return h.texture}else{var h=s.get(a+e);if(h)h.callbacks?h.callbacks.push(i):i&&i(h.texture);else if(e.match(/.hdr $ |^data:application \/ octet-stream/)){h={callbacks:[i]};var f=fr.loadTexture(e,{exposure:r.exposure,fileType:"hdr"},function(){f.dirty(),h.callbacks.forEach(function(v){v&&v(f)}),h.callbacks=null});h.texture=f,s.put(a+e,h)}else{for(var f=new q.Texture2D({image:new Image}),o=0;o<n.length;o++)f[n[o]]=r[n[o]];h={texture:f,callbacks:[i]};var d=f.image;d.onload=function(){f.image=d,Ao(f),f.dirty(),h.callbacks.forEach(function(p){p&&p(f)}),h.callbacks=null},d.crossOrigin="Anonymous",d.src=e,f.image=Rf(),s.put(a+e,h)}return h.texture}};q.createAmbientCubemap=function(e,t,r,i){e=e||{};var n=e.texture,a=J.firstNotNull(e.exposure,1),o=new Ku({intensity:J.firstNotNull(e.specularIntensity,1)}),s=new Ju({intensity:J.firstNotNull(e.diffuseIntensity,1),coefficients:[.844,.712,.691,-.037,.083,.167,.343,.288,.299,-.041,-.021,-.009,-.003,-.041,-.064,-.011,-.007,-.004,-.031,.034,.081,-.06,-.049,-.06,.046,.056,.05]});return o.cubemap=q.loadTexture(n,r,{exposure:a},function(){o.cubemap.flipY=!1,o.prefilter(t,32),s.coefficients=nf.projectEnvironmentMap(t,o.cubemap,{lod:1}),i&&i()}),{specular:o,diffuse:s}};q.createBlankTexture=fr.createBlank;q.isImage=Rs;q.additiveBlend=function(e){e.blendEquation(e.FUNC_ADD),e.blendFunc(e.SRC_ALPHA,e.ONE)};q.parseColor=function(e,t){return e instanceof Array?(t||(t=[]),t[0]=e[0],t[1]=e[1],t[2]=e[2],e.length>3?t[3]=e[3
2023-04-28 16:00:04 +08:00
attribute vec3 position : POSITION ;
attribute vec2 texcoord : TEXCOORD _0 ;
attribute vec2 offset ;
# ifdef VERTEX _COLOR
attribute vec4 a _Color : COLOR ;
varying vec4 v _Color ;
# endif
uniform mat4 worldViewProjection : WORLDVIEWPROJECTION ;
uniform vec4 viewport : VIEWPORT ;
varying vec2 v _Texcoord ;
void main ( )
{
vec4 proj = worldViewProjection * vec4 ( position , 1.0 ) ;
vec2 screen = ( proj . xy / abs ( proj . w ) + 1.0 ) * 0.5 * viewport . zw ;
screen += offset ;
proj . xy = ( screen / viewport . zw - 0.5 ) * 2.0 * abs ( proj . w ) ;
gl _Position = proj ;
# ifdef VERTEX _COLOR
v _Color = a _Color ;
# endif
v _Texcoord = texcoord ;
}
@ end
@ export ecgl . labels . fragment
uniform vec3 color : [ 1.0 , 1.0 , 1.0 ] ;
uniform float alpha : 1.0 ;
uniform sampler2D textureAtlas ;
uniform vec2 uvScale : [ 1.0 , 1.0 ] ;
# ifdef VERTEX _COLOR
varying vec4 v _Color ;
# endif
varying float v _Miter ;
varying vec2 v _Texcoord ;
void main ( )
{
gl _FragColor = vec4 ( color , alpha ) * texture2D ( textureAtlas , v _Texcoord * uvScale ) ;
# ifdef VERTEX _COLOR
gl _FragColor *= v _Color ;
# endif
}
2023-09-11 21:56:39 +08:00
@ end ` ;T.Shader.import(kf);const La=T.Mesh.extend(function(){var e=new Vf({dynamic:!0}),t=new T.Material({shader:T.createShader("ecgl.labels"),transparent:!0,depthMask:!1});return{geometry:e,material:t,culling:!1,castShadow:!1,ignorePicking:!0}});var ir=J.firstNotNull,nr={x:0,y:2,z:1};function Ca(e,t){var r=new T.Mesh({geometry:new gr({useNativeLine:!1}),material:t,castShadow:!1,ignorePicking:!0,renderOrder:2}),i=new La;i.material.depthMask=!1;var n=new T.Node;n.add(r),n.add(i),this.rootNode=n,this.dim=e,this.linesMesh=r,this.labelsMesh=i,this.axisLineCoords=null,this.labelElements=[]}var kn={x:"y",y:"x",z:"y"};Ca.prototype.update=function(e,t,r){var i=e.coordinateSystem,n=i.getAxis(this.dim),a=this.linesMesh.geometry,o=this.labelsMesh.geometry;a.convertToDynamicArray(!0),o.convertToDynamicArray(!0);var s=n.model,l=n.getExtent(),C=r.getDevicePixelRatio(),h=s.getModel("axisLine",e.getModel("axisLine")),u=s.getModel("axisTick",e.getModel("axisTick")),f=s.getModel("axisLabel",e.getModel("axisLabel")),d=h.get("lineStyle.color");if(h.get("show")){var c=h.getModel("lineStyle"),v=[0,0,0],p=[0,0,0],m=nr[n.dim];v[m]=l[0],p[m]=l[1],this.axisLineCoords=[v,p];var _=T.parseColor(d),x=ir(c.get("width"),1),y=ir(c.get("opacity"),1);_[3]*=y,a.addLine(v,p,_,x*C)}if(u.get("show")){var g=u.getModel("lineStyle"),w=T.parseColor(ir(g.get("color"),d)),x=ir(g.get("width"),1);w[3]*=ir(g.get("opacity"),1);for(var S=n.getTicksCoords(),b=u.get("length"),E=0;E<S.length;E++){var L=S[E].coord,v=[0,0,0],p=[0,0,0],m=nr[n.dim],P=nr[kn[n.dim]];v[m]=p[m]=L,p[P]=b,a.addLine(v,p,w,x*C)}}this.labelElements=[];var C=r.getDevicePixelRatio();if(f.get("show"))for(var S=n.getTicksCoords(),R=s.get("data"),I=f.get("margin"),D=n.getViewLabels(),E=0;E<D.length;E++){var O=D[E].tickValue,z=D[E].formattedLabel,k=D[E].rawLabel,L=n.dataToCoord(O),F=[0,0,0],m=nr[n.dim],P=nr[kn[n.dim]];F[m]=F[m]=L,F[P]=I;var le=f;R&&R[O]&&R[O].textStyle&&(le=new Rr(R[O].textStyle,f,s.ecModel));var H=ir(le.get("color"),d),de=new Ki({style:Qi(le,{text:z,fill:typeof H=="function"?H(n.type==="category"?k:n.type==="value"?O+"":O,E):H,verticalAlign:"top",align:"left"})}),he=t.add(de),_e=de.getBoundingRect();o.addSprite(F,[_e.width*C,_e.height*C],he),this.labelElements.push(de)}if(s.get("name")){var ge=s.getModel("nameTextStyle"),F=[0,0,0],m=nr[n.dim],P=nr[kn[n.dim]],te=ir(ge.get("color"),d),Ne=ge.get("borderColor"),x=ge.get("borderWidth");F[m]=F[m]=(l[0]+l[1])/2,F[P]=s.get("nameGap");var de=new Ki({style:Qi(ge,{text:s.get("name"),fill:te,stroke:Ne,lineWidth:x})}),he=t.add(de),_e=de.getBoundingRect();o.addSprite(F,[_e.width*C,_e.height*C],he),de.__idx=this.labelElements.length,this.nameLabelElement=de}this.labelsMesh.material.set("textureAtlas",t.getTexture()),this.labelsMesh.material.set("uvScale",t.getCoordsScale()),a.convertToTypedArray(),o.convertToTypedArray()};Ca.prototype.setSpriteAlign=function(e,t,r){for(var i=r.getDevicePixelRatio(),n=this.labelsMesh.geometry,a=0;a<this.labelElements.length;a++){var o=this.labelElements[a],s=o.getBoundingRect();n.setSpriteAlign(a,[s.width*i,s.height*i],e,t)}var l=this.nameLabelElement;if(l){var s=l.getBoundingRect();n.setSpriteAlign(l.__idx,[s.width*i,s.height*i],e,t),n.dirty()}this.textAlign=e,this.textVerticalAlign=t};const wn= ` @ export ecgl . lines3D . vertex
2023-04-28 16:00:04 +08:00
uniform mat4 worldViewProjection : WORLDVIEWPROJECTION ;
attribute vec3 position : POSITION ;
attribute vec4 a _Color : COLOR ;
varying vec4 v _Color ;
void main ( )
{
gl _Position = worldViewProjection * vec4 ( position , 1.0 ) ;
v _Color = a _Color ;
}
@ end
@ export ecgl . lines3D . fragment
uniform vec4 color : [ 1.0 , 1.0 , 1.0 , 1.0 ] ;
varying vec4 v _Color ;
@ import clay . util . srgb
void main ( )
{
# ifdef SRGB _DECODE
gl _FragColor = sRGBToLinear ( color * v _Color ) ;
# else
gl _FragColor = color * v _Color ;
# endif
}
@ end
@ export ecgl . lines3D . clipNear
vec4 clipNear ( vec4 p1 , vec4 p2 ) {
float n = ( p1 . w - near ) / ( p1 . w - p2 . w ) ;
return vec4 ( mix ( p1 . xy , p2 . xy , n ) , - near , near ) ;
}
@ end
@ export ecgl . lines3D . expandLine
# ifdef VERTEX _ANIMATION
vec4 prevProj = worldViewProjection * vec4 ( mix ( prevPositionPrev , positionPrev , percent ) , 1.0 ) ;
vec4 currProj = worldViewProjection * vec4 ( mix ( prevPosition , position , percent ) , 1.0 ) ;
vec4 nextProj = worldViewProjection * vec4 ( mix ( prevPositionNext , positionNext , percent ) , 1.0 ) ;
# else
vec4 prevProj = worldViewProjection * vec4 ( positionPrev , 1.0 ) ;
vec4 currProj = worldViewProjection * vec4 ( position , 1.0 ) ;
vec4 nextProj = worldViewProjection * vec4 ( positionNext , 1.0 ) ;
# endif
if ( currProj . w < 0.0 ) {
if ( nextProj . w > 0.0 ) {
currProj = clipNear ( currProj , nextProj ) ;
}
else if ( prevProj . w > 0.0 ) {
currProj = clipNear ( currProj , prevProj ) ;
}
}
vec2 prevScreen = ( prevProj . xy / abs ( prevProj . w ) + 1.0 ) * 0.5 * viewport . zw ;
vec2 currScreen = ( currProj . xy / abs ( currProj . w ) + 1.0 ) * 0.5 * viewport . zw ;
vec2 nextScreen = ( nextProj . xy / abs ( nextProj . w ) + 1.0 ) * 0.5 * viewport . zw ;
vec2 dir ;
float len = offset ;
if ( position == positionPrev ) {
dir = normalize ( nextScreen - currScreen ) ;
}
else if ( position == positionNext ) {
dir = normalize ( currScreen - prevScreen ) ;
}
else {
vec2 dirA = normalize ( currScreen - prevScreen ) ;
vec2 dirB = normalize ( nextScreen - currScreen ) ;
vec2 tanget = normalize ( dirA + dirB ) ;
float miter = 1.0 / max ( dot ( tanget , dirA ) , 0.5 ) ;
len *= miter ;
dir = tanget ;
}
dir = vec2 ( - dir . y , dir . x ) * len ;
currScreen += dir ;
currProj . xy = ( currScreen / viewport . zw - 0.5 ) * 2.0 * abs ( currProj . w ) ;
@ end
@ export ecgl . meshLines3D . vertex
attribute vec3 position : POSITION ;
attribute vec3 positionPrev ;
attribute vec3 positionNext ;
attribute float offset ;
attribute vec4 a _Color : COLOR ;
# ifdef VERTEX _ANIMATION
attribute vec3 prevPosition ;
attribute vec3 prevPositionPrev ;
attribute vec3 prevPositionNext ;
uniform float percent : 1.0 ;
# endif
uniform mat4 worldViewProjection : WORLDVIEWPROJECTION ;
uniform vec4 viewport : VIEWPORT ;
uniform float near : NEAR ;
varying vec4 v _Color ;
@ import ecgl . common . wireframe . vertexHeader
@ import ecgl . lines3D . clipNear
void main ( )
{
@ import ecgl . lines3D . expandLine
gl _Position = currProj ;
v _Color = a _Color ;
@ import ecgl . common . wireframe . vertexMain
}
@ end
@ export ecgl . meshLines3D . fragment
uniform vec4 color : [ 1.0 , 1.0 , 1.0 , 1.0 ] ;
varying vec4 v _Color ;
@ import ecgl . common . wireframe . fragmentHeader
@ import clay . util . srgb
void main ( )
{
# ifdef SRGB _DECODE
gl _FragColor = sRGBToLinear ( color * v _Color ) ;
# else
gl _FragColor = color * v _Color ;
# endif
@ import ecgl . common . wireframe . fragmentMain
}
2023-09-11 21:56:39 +08:00
@ end ` ;var Do=J.firstNotNull;T.Shader.import(wn);var ar={x:0,y:2,z:1};const Wf=Si.extend({type:"grid3D",__ecgl__:!0,init:function(e,t){var r=[["y","z","x",-1,"left"],["y","z","x",1,"right"],["x","y","z",-1,"bottom"],["x","y","z",1,"top"],["x","z","y",-1,"far"],["x","z","y",1,"near"]],i=["x","y","z"],n=new T.Material({shader:T.createShader("ecgl.color"),depthMask:!1,transparent:!0}),a=new T.Material({shader:T.createShader("ecgl.meshLines3D"),depthMask:!1,transparent:!0});n.define("fragment","DOUBLE_SIDED"),n.define("both","VERTEX_COLOR"),this.groupGL=new T.Node,this._control=new xn({zr:t.getZr()}),this._control.init(),this._faces=r.map(function(s){var l=new Tn(s,a,n);return this.groupGL.add(l.rootNode),l},this),this._axes=i.map(function(s){var l=new Ca(s,a);return this.groupGL.add(l.rootNode),l},this);var o=t.getDevicePixelRatio();this._axisLabelSurface=new an({width:256,height:256,devicePixelRatio:o}),this._axisLabelSurface.onupdate=function(){t.getZr().refresh()},this._axisPointerLineMesh=new T.Mesh({geometry:new gr({useNativeLine:!1}),material:a,castShadow:!1,ignorePicking:!0,renderOrder:3}),this.groupGL.add(this._axisPointerLineMesh),this._axisPointerLabelsSurface=new an({width:128,height:128,devicePixelRatio:o}),this._axisPointerLabelsMesh=new La({ignorePicking:!0,renderOrder:4,castShadow:!1}),this._axisPointerLabelsMesh.material.set("textureAtlas",this._axisPointerLabelsSurface.getTexture()),this.groupGL.add(this._axisPointerLabelsMesh),this._lightRoot=new T.Node,this._sceneHelper=new Yt,this._sceneHelper.initLight(this._lightRoot)},render:function(e,t,r){this._model=e,this._api=r;var i=e.coordinateSystem;i.viewGL.add(this._lightRoot),e.get("show")?i.viewGL.add(this.groupGL):i.viewGL.remove(this.groupGL);var n=this._control;n.setViewGL(i.viewGL);var a=e.getModel("viewControl");n.setFromViewControlModel(a,0),this._axisLabelSurface.clear(),n.off("update"),e.get("show")&&(this._faces.forEach(function(o){o.update(e,t,r)},this),this._axes.forEach(function(o){o.update(e,this._axisLabelSurface,r)},this)),n.on("update",this._onCameraChange.bind(this,e,r),this),this._sceneHelper.setScene(i.viewGL.scene),this._sceneHelper.updateLight(e),i.viewGL.setPostEffect(e.getModel("postEffect"),r),i.viewGL.setTemporalSuperSampling(e.getModel("temporalSuperSampling")),this._initMouseHandler(e)},afterRender:function(e,t,r,i){var n=i.renderer;this._sceneHelper.updateAmbientCubemap(n,e,r),this._sceneHelper.updateSkybox(n,e,r)},showAxisPointer:function(e,t,r,i){this._doShowAxisPointer(),this._updateAxisPointer(i.value)},hideAxisPointer:function(e,t,r,i){this._doHideAxisPointer()},_initMouseHandler:function(e){var t=e.coordinateSystem,r=t.viewGL;e.get("show")&&e.get("axisPointer.show")?r.on("mousemove",this._updateAxisPointerOnMousePosition,this):r.off("mousemove",this._updateAxisPointerOnMousePosition)},_updateAxisPointerOnMousePosition:function(e){if(!e.target){for(var t=this._model,r=t.coordinateSystem,i=r.viewGL,n=i.castRay(e.offsetX,e.offsetY,new T.Ray),a,o=0;o<this._faces.length;o++){var s=this._faces[o];if(!s.rootNode.invisible){s.plane.normal.dot(i.camera.worldTransform.z)<0&&s.plane.normal.negate();var l=n.intersectPlane(s.plane);if(!!l){var h=r.getAxis(s.faceInfo[0]),u=r.getAxis(s.faceInfo[1]),f=ar[s.faceInfo[0]],d=ar[s.faceInfo[1]];h.contain(l.array[f])&&u.contain(l.array[d])&&(a=l)}}}if(a){var c=r.pointToData(a.array,[],!0);this._updateAxisPointer(c),this._doShowAxisPointer()}else this._doHideAxisPointer()}},_onCameraChange:function(e,t){e.get("show")&&(this._updateFaceVisibility(),this._updateAxisLinePosition());var r=this._control;t.dispatchAction({type:"grid3DChangeCamera",alpha:r.getAlpha(),beta:r.getBeta(),distance:r.getDistance(),center:r.getCenter(),from:this.uid,grid3DId:e.id})},_updateFaceVisibility:function(){var e=this._control.getCamera(),t=new T.Vector3;e.update();for(var r=0;r<this._faces.length/2;r++){for(var i=[],n=0;n<2;n++){var a=this._faces[r*2+n];a.rootNode.getWorldPosition(t),t.transformMat4(e.viewMatrix),i[n]=t.z}var o=i[0]>i[1]?0:1,s=this._faces[r*2+o],l=this._faces[r*2+1-o];s.rootNode.invisible=!0,l.rootNod
2023-04-28 16:00:04 +08:00
uniform mat4 worldViewProjection : WORLDVIEWPROJECTION ;
attribute vec3 position : POSITION ;
attribute vec2 texcoord : TEXCOORD _0 ;
uniform vec2 uvRepeat = vec2 ( 1.0 , 1.0 ) ;
uniform vec2 uvOffset = vec2 ( 0.0 , 0.0 ) ;
@ import clay . chunk . skinning _header
@ import clay . chunk . instancing _header
varying vec4 v _ViewPosition ;
varying vec2 v _Texcoord ;
void main ( ) {
vec4 P = vec4 ( position , 1.0 ) ;
# ifdef SKINNING
@ import clay . chunk . skin _matrix
P = skinMatrixWS * P ;
# endif
# ifdef INSTANCING
@ import clay . chunk . instancing _matrix
P = instanceMat * P ;
# endif
v _ViewPosition = worldViewProjection * P ;
gl _Position = v _ViewPosition ;
v _Texcoord = texcoord * uvRepeat + uvOffset ;
}
@ end
@ export clay . sm . depth . fragment
varying vec4 v _ViewPosition ;
varying vec2 v _Texcoord ;
uniform float bias : 0.001 ;
uniform float slopeScale : 1.0 ;
uniform sampler2D alphaMap ;
uniform float alphaCutoff : 0.0 ;
@ import clay . util . encode _float
void main ( ) {
float depth = v _ViewPosition . z / v _ViewPosition . w ;
if ( alphaCutoff > 0.0 ) {
if ( texture2D ( alphaMap , v _Texcoord ) . a <= alphaCutoff ) {
discard ;
}
}
# ifdef USE _VSM
depth = depth * 0.5 + 0.5 ;
float moment1 = depth ;
float moment2 = depth * depth ;
# ifdef SUPPORT _STANDARD _DERIVATIVES
float dx = dFdx ( depth ) ;
float dy = dFdy ( depth ) ;
moment2 += 0.25 * ( dx * dx + dy * dy ) ;
# endif
gl _FragColor = vec4 ( moment1 , moment2 , 0.0 , 1.0 ) ;
# else
# ifdef SUPPORT _STANDARD _DERIVATIVES
float dx = dFdx ( depth ) ;
float dy = dFdy ( depth ) ;
depth += sqrt ( dx * dx + dy * dy ) * slopeScale + bias ;
# else
depth += bias ;
# endif
gl _FragColor = encodeFloat ( depth * 0.5 + 0.5 ) ;
# endif
}
@ end
@ export clay . sm . debug _depth
uniform sampler2D depthMap ;
varying vec2 v _Texcoord ;
@ import clay . util . decode _float
void main ( ) {
vec4 tex = texture2D ( depthMap , v _Texcoord ) ;
# ifdef USE _VSM
gl _FragColor = vec4 ( tex . rgb , 1.0 ) ;
# else
float depth = decodeFloat ( tex ) ;
gl _FragColor = vec4 ( depth , depth , depth , 1.0 ) ;
# endif
}
@ end
@ export clay . sm . distance . vertex
uniform mat4 worldViewProjection : WORLDVIEWPROJECTION ;
uniform mat4 world : WORLD ;
attribute vec3 position : POSITION ;
@ import clay . chunk . skinning _header
varying vec3 v _WorldPosition ;
void main ( ) {
vec4 P = vec4 ( position , 1.0 ) ;
# ifdef SKINNING
@ import clay . chunk . skin _matrix
P = skinMatrixWS * P ;
# endif
# ifdef INSTANCING
@ import clay . chunk . instancing _matrix
P = instanceMat * P ;
# endif
gl _Position = worldViewProjection * P ;
v _WorldPosition = ( world * P ) . xyz ;
}
@ end
@ export clay . sm . distance . fragment
uniform vec3 lightPosition ;
uniform float range : 100 ;
varying vec3 v _WorldPosition ;
@ import clay . util . encode _float
void main ( ) {
float dist = distance ( lightPosition , v _WorldPosition ) ;
# ifdef USE _VSM
gl _FragColor = vec4 ( dist , dist * dist , 0.0 , 0.0 ) ;
# else
dist = dist / range ;
gl _FragColor = encodeFloat ( dist ) ;
# endif
}
@ end
@ export clay . plugin . shadow _map _common
@ import clay . util . decode _float
float tapShadowMap ( sampler2D map , vec2 uv , float z ) {
vec4 tex = texture2D ( map , uv ) ;
return step ( z , decodeFloat ( tex ) * 2.0 - 1.0 ) ;
}
float pcf ( sampler2D map , vec2 uv , float z , float textureSize , vec2 scale ) {
float shadowContrib = tapShadowMap ( map , uv , z ) ;
vec2 offset = vec2 ( 1.0 / textureSize ) * scale ;
# ifdef PCF _KERNEL _SIZE
for ( int _idx _ = 0 ; _idx _ < PCF _KERNEL _SIZE ; _idx _ ++ ) { {
shadowContrib += tapShadowMap ( map , uv + offset * pcfKernel [ _idx _ ] , z ) ;
} }
return shadowContrib / float ( PCF _KERNEL _SIZE + 1 ) ;
# else
shadowContrib += tapShadowMap ( map , uv + vec2 ( offset . x , 0.0 ) , z ) ;
shadowContrib += tapShadowMap ( map , uv + vec2 ( offset . x , offset . y ) , z ) ;
shadowContrib += tapShadowMap ( map , uv + vec2 ( - offset . x , offset . y ) , z ) ;
shadowContrib += tapShadowMap ( map , uv + vec2 ( 0.0 , offset . y ) , z ) ;
shadowContrib += tapShadowMap ( map , uv + vec2 ( - offset . x , 0.0 ) , z ) ;
shadowContrib += tapShadowMap ( map , uv + vec2 ( - offset . x , - offset . y ) , z ) ;
shadowContrib += tapShadowMap ( map , uv + vec2 ( offset . x , - offset . y ) , z ) ;
shadowContrib += tapShadowMap ( map , uv + vec2 ( 0.0 , - offset . y ) , z ) ;
return shadowContrib / 9.0 ;
# endif
}
float pcf ( sampler2D map , vec2 uv , float z , float textureSize ) {
return pcf ( map , uv , z , textureSize , vec2 ( 1.0 ) ) ;
}
float chebyshevUpperBound ( vec2 moments , float z ) {
float p = 0.0 ;
z = z * 0.5 + 0.5 ;
if ( z <= moments . x ) {
p = 1.0 ;
}
float variance = moments . y - moments . x * moments . x ;
variance = max ( variance , 0.0000001 ) ;
float mD = moments . x - z ;
float pMax = variance / ( variance + mD * mD ) ;
pMax = clamp ( ( pMax - 0.4 ) / ( 1.0 - 0.4 ) , 0.0 , 1.0 ) ;
return max ( p , pMax ) ;
}
float computeShadowContrib (
sampler2D map , mat4 lightVPM , vec3 position , float textureSize , vec2 scale , vec2 offset
) {
vec4 posInLightSpace = lightVPM * vec4 ( position , 1.0 ) ;
posInLightSpace . xyz /= posInLightSpace . w ;
float z = posInLightSpace . z ;
if ( all ( greaterThan ( posInLightSpace . xyz , vec3 ( - 0.99 , - 0.99 , - 1.0 ) ) ) &&
all ( lessThan ( posInLightSpace . xyz , vec3 ( 0.99 , 0.99 , 1.0 ) ) ) ) {
vec2 uv = ( posInLightSpace . xy + 1.0 ) / 2.0 ;
# ifdef USE _VSM
vec2 moments = texture2D ( map , uv * scale + offset ) . xy ;
return chebyshevUpperBound ( moments , z ) ;
# else
return pcf ( map , uv * scale + offset , z , textureSize , scale ) ;
# endif
}
return 1.0 ;
}
float computeShadowContrib ( sampler2D map , mat4 lightVPM , vec3 position , float textureSize ) {
return computeShadowContrib ( map , lightVPM , position , textureSize , vec2 ( 1.0 ) , vec2 ( 0.0 ) ) ;
}
float computeShadowContribOmni ( samplerCube map , vec3 direction , float range )
{
float dist = length ( direction ) ;
vec4 shadowTex = textureCube ( map , direction ) ;
# ifdef USE _VSM
vec2 moments = shadowTex . xy ;
float variance = moments . y - moments . x * moments . x ;
float mD = moments . x - dist ;
float p = variance / ( variance + mD * mD ) ;
if ( moments . x + 0.001 < dist ) {
return clamp ( p , 0.0 , 1.0 ) ;
} else {
return 1.0 ;
}
# else
return step ( dist , ( decodeFloat ( shadowTex ) + 0.0002 ) * range ) ;
# endif
}
@ end
@ export clay . plugin . compute _shadow _map
# if defined ( SPOT _LIGHT _SHADOWMAP _COUNT ) || defined ( DIRECTIONAL _LIGHT _SHADOWMAP _COUNT ) || defined ( POINT _LIGHT _SHADOWMAP _COUNT )
# ifdef SPOT _LIGHT _SHADOWMAP _COUNT
uniform sampler2D spotLightShadowMaps [ SPOT _LIGHT _SHADOWMAP _COUNT ] : unconfigurable ;
uniform mat4 spotLightMatrices [ SPOT _LIGHT _SHADOWMAP _COUNT ] : unconfigurable ;
uniform float spotLightShadowMapSizes [ SPOT _LIGHT _SHADOWMAP _COUNT ] : unconfigurable ;
# endif
# ifdef DIRECTIONAL _LIGHT _SHADOWMAP _COUNT
# if defined ( SHADOW _CASCADE )
uniform sampler2D directionalLightShadowMaps [ 1 ] : unconfigurable ;
uniform mat4 directionalLightMatrices [ SHADOW _CASCADE ] : unconfigurable ;
uniform float directionalLightShadowMapSizes [ 1 ] : unconfigurable ;
uniform float shadowCascadeClipsNear [ SHADOW _CASCADE ] : unconfigurable ;
uniform float shadowCascadeClipsFar [ SHADOW _CASCADE ] : unconfigurable ;
# else
uniform sampler2D directionalLightShadowMaps [ DIRECTIONAL _LIGHT _SHADOWMAP _COUNT ] : unconfigurable ;
uniform mat4 directionalLightMatrices [ DIRECTIONAL _LIGHT _SHADOWMAP _COUNT ] : unconfigurable ;
uniform float directionalLightShadowMapSizes [ DIRECTIONAL _LIGHT _SHADOWMAP _COUNT ] : unconfigurable ;
# endif
# endif
# ifdef POINT _LIGHT _SHADOWMAP _COUNT
uniform samplerCube pointLightShadowMaps [ POINT _LIGHT _SHADOWMAP _COUNT ] : unconfigurable ;
# endif
uniform bool shadowEnabled : true ;
# ifdef PCF _KERNEL _SIZE
uniform vec2 pcfKernel [ PCF _KERNEL _SIZE ] ;
# endif
@ import clay . plugin . shadow _map _common
# if defined ( SPOT _LIGHT _SHADOWMAP _COUNT )
void computeShadowOfSpotLights ( vec3 position , inout float shadowContribs [ SPOT _LIGHT _COUNT ] ) {
float shadowContrib ;
for ( int _idx _ = 0 ; _idx _ < SPOT _LIGHT _SHADOWMAP _COUNT ; _idx _ ++ ) { {
shadowContrib = computeShadowContrib (
spotLightShadowMaps [ _idx _ ] , spotLightMatrices [ _idx _ ] , position ,
spotLightShadowMapSizes [ _idx _ ]
) ;
shadowContribs [ _idx _ ] = shadowContrib ;
} }
for ( int _idx _ = SPOT _LIGHT _SHADOWMAP _COUNT ; _idx _ < SPOT _LIGHT _COUNT ; _idx _ ++ ) { {
shadowContribs [ _idx _ ] = 1.0 ;
} }
}
# endif
# if defined ( DIRECTIONAL _LIGHT _SHADOWMAP _COUNT )
# ifdef SHADOW _CASCADE
void computeShadowOfDirectionalLights ( vec3 position , inout float shadowContribs [ DIRECTIONAL _LIGHT _COUNT ] ) {
float depth = ( 2.0 * gl _FragCoord . z - gl _DepthRange . near - gl _DepthRange . far )
/ ( g l _ D e p t h R a n g e . f a r - g l _ D e p t h R a n g e . n e a r ) ;
float shadowContrib ;
shadowContribs [ 0 ] = 1.0 ;
for ( int _idx _ = 0 ; _idx _ < SHADOW _CASCADE ; _idx _ ++ ) { {
if (
depth >= shadowCascadeClipsNear [ _idx _ ] &&
depth <= shadowCascadeClipsFar [ _idx _ ]
) {
shadowContrib = computeShadowContrib (
directionalLightShadowMaps [ 0 ] , directionalLightMatrices [ _idx _ ] , position ,
directionalLightShadowMapSizes [ 0 ] ,
vec2 ( 1.0 / float ( SHADOW _CASCADE ) , 1.0 ) ,
vec2 ( float ( _idx _ ) / float ( SHADOW _CASCADE ) , 0.0 )
) ;
shadowContribs [ 0 ] = shadowContrib ;
}
} }
for ( int _idx _ = DIRECTIONAL _LIGHT _SHADOWMAP _COUNT ; _idx _ < DIRECTIONAL _LIGHT _COUNT ; _idx _ ++ ) { {
shadowContribs [ _idx _ ] = 1.0 ;
} }
}
# else
void computeShadowOfDirectionalLights ( vec3 position , inout float shadowContribs [ DIRECTIONAL _LIGHT _COUNT ] ) {
float shadowContrib ;
for ( int _idx _ = 0 ; _idx _ < DIRECTIONAL _LIGHT _SHADOWMAP _COUNT ; _idx _ ++ ) { {
shadowContrib = computeShadowContrib (
directionalLightShadowMaps [ _idx _ ] , directionalLightMatrices [ _idx _ ] , position ,
directionalLightShadowMapSizes [ _idx _ ]
) ;
shadowContribs [ _idx _ ] = shadowContrib ;
} }
for ( int _idx _ = DIRECTIONAL _LIGHT _SHADOWMAP _COUNT ; _idx _ < DIRECTIONAL _LIGHT _COUNT ; _idx _ ++ ) { {
shadowContribs [ _idx _ ] = 1.0 ;
} }
}
# endif
# endif
# if defined ( POINT _LIGHT _SHADOWMAP _COUNT )
void computeShadowOfPointLights ( vec3 position , inout float shadowContribs [ POINT _LIGHT _COUNT ] ) {
vec3 lightPosition ;
vec3 direction ;
for ( int _idx _ = 0 ; _idx _ < POINT _LIGHT _SHADOWMAP _COUNT ; _idx _ ++ ) { {
lightPosition = pointLightPosition [ _idx _ ] ;
direction = position - lightPosition ;
shadowContribs [ _idx _ ] = computeShadowContribOmni ( pointLightShadowMaps [ _idx _ ] , direction , pointLightRange [ _idx _ ] ) ;
} }
for ( int _idx _ = POINT _LIGHT _SHADOWMAP _COUNT ; _idx _ < POINT _LIGHT _COUNT ; _idx _ ++ ) { {
shadowContribs [ _idx _ ] = 1.0 ;
} }
}
# endif
# endif
2023-09-11 21:56:39 +08:00
@ end ` ;var Vt=["px","nx","py","ny","pz","nz"];N.import(jf);function Xn(e,t,r){if(r==="alphaMap")return e.material.get("diffuseMap");if(r==="alphaCutoff"){if(e.material.isDefined("fragment","ALPHA_TEST")&&e.material.get("diffuseMap")){var i=e.material.get("alphaCutoff");return i||0}return 0}else return r==="uvRepeat"?e.material.get("uvRepeat"):r==="uvOffset"?e.material.get("uvOffset"):t.get(r)}function Ro(e,t){var r=e.material,i=t.material;return r.get("diffuseMap")!==i.get("diffuseMap")||(r.get("alphaCutoff")||0)!==(i.get("alphaCutoff")||0)}var Lt=nt.extend(function(){return{softShadow:Lt.PCF,shadowBlur:1,lightFrustumBias:"auto",kernelPCF:new Float32Array([1,0,1,1,-1,1,0,1,-1,0,-1,-1,1,-1,0,-1]),precision:"highp",_lastRenderNotCastShadow:!1,_frameBuffer:new qe,_textures:{},_shadowMapNumber:{POINT_LIGHT:0,DIRECTIONAL_LIGHT:0,SPOT_LIGHT:0},_depthMaterials:{},_distanceMaterials:{},_receivers:[],_lightsCastShadow:[],_lightCameras:{},_lightMaterials:{},_texturePool:new Hs}},function(){this._gaussianPassH=new Re({fragment:N.source("clay.compositor.gaussian_blur")}),this._gaussianPassV=new Re({fragment:N.source("clay.compositor.gaussian_blur")}),this._gaussianPassH.setUniform("blurSize",this.shadowBlur),this._gaussianPassH.setUniform("blurDir",0),this._gaussianPassV.setUniform("blurSize",this.shadowBlur),this._gaussianPassV.setUniform("blurDir",1),this._outputDepthPass=new Re({fragment:N.source("clay.sm.debug_depth")})},{render:function(e,t,r,i){r||(r=t.getMainCamera()),this.trigger("beforerender",this,e,t,r),this._renderShadowPass(e,t,r,i),this.trigger("afterrender",this,e,t,r)},renderDebug:function(e,t){e.saveClear();var r=e.viewport,i=0,n=0,a=t||r.width/4,o=a;this.softShadow===Lt.VSM?this._outputDepthPass.material.define("fragment","USE_VSM"):this._outputDepthPass.material.undefine("fragment","USE_VSM");for(var s in this._textures){var l=this._textures[s];e.setViewport(i,n,a*l.width/l.height,o),this._outputDepthPass.setUniform("depthMap",l),this._outputDepthPass.render(e),i+=a*l.width/l.height}e.setViewport(r),e.restoreClear()},_updateReceivers:function(e,t){if(t.receiveShadow?(this._receivers.push(t),t.material.set("shadowEnabled",1),t.material.set("pcfKernel",this.kernelPCF)):t.material.set("shadowEnabled",0),this.softShadow===Lt.VSM)t.material.define("fragment","USE_VSM"),t.material.undefine("fragment","PCF_KERNEL_SIZE");else{t.material.undefine("fragment","USE_VSM");var r=this.kernelPCF;r&&r.length?t.material.define("fragment","PCF_KERNEL_SIZE",r.length/2):t.material.undefine("fragment","PCF_KERNEL_SIZE")}},_update:function(e,t){var r=this;t.traverse(function(a){a.isRenderable()&&r._updateReceivers(e,a)});for(var i=0;i<t.lights.length;i++){var n=t.lights[i];n.castShadow&&!n.invisible&&this._lightsCastShadow.push(n)}},_renderShadowPass:function(e,t,r,i){for(var n in this._shadowMapNumber)this._shadowMapNumber[n]=0;this._lightsCastShadow.length=0,this._receivers.length=0;var a=e.gl;if(i||t.update(),r&&r.update(),t.updateLights(),this._update(e,t),!this._lightsCastShadow.length&&this._lastRenderNotCastShadow)return;this._lastRenderNotCastShadow=this._lightsCastShadow===0,a.enable(a.DEPTH_TEST),a.depthMask(!0),a.disable(a.BLEND),a.clearColor(1,1,1,1);for(var o=[],s=[],l=[],h=[],u=[],f=[],d,c=0;c<this._lightsCastShadow.length;c++){var v=this._lightsCastShadow[c];if(v.type==="DIRECTIONAL_LIGHT"){if(d){console.warn("Only one direectional light supported with shadow cascade");continue}if(v.shadowCascade>4){console.warn("Support at most 4 cascade");continue}v.shadowCascade>1&&(d=v),this.renderDirectionalLightShadow(e,t,r,v,u,h,l)}else v.type==="SPOT_LIGHT"?this.renderSpotLightShadow(e,t,v,s,o):v.type==="POINT_LIGHT"&&this.renderPointLightShadow(e,t,v,f);this._shadowMapNumber[v.type]++}for(var p in this._shadowMapNumber)for(var m=this._shadowMapNumber[p],_=p+"_SHADOWMAP_COUNT",c=0;c<this._receivers.length;c++){var x=this._receivers[c],y=x.material;y.fragmentDefines[_]!==m&&(m>0?y.define("fragment",_,m):y.isDefined("fragment",_)&&y.undefine("fragment",_))}for(var c=0;c<this._receivers.length;c++){var x=this._receivers[c],y=x.materi
2023-04-28 16:00:04 +08:00
varying vec2 v _Texcoord ;
uniform sampler2D texture ;
uniform float brightness : 0.0 ;
uniform float contrast : 1.0 ;
uniform float exposure : 0.0 ;
uniform float gamma : 1.0 ;
uniform float saturation : 1.0 ;
const vec3 w = vec3 ( 0.2125 , 0.7154 , 0.0721 ) ;
void main ( )
{
vec4 tex = texture2D ( texture , v _Texcoord ) ;
vec3 color = clamp ( tex . rgb + vec3 ( brightness ) , 0.0 , 1.0 ) ;
color = clamp ( ( color - vec3 ( 0.5 ) ) * contrast + vec3 ( 0.5 ) , 0.0 , 1.0 ) ;
color = clamp ( color * pow ( 2.0 , exposure ) , 0.0 , 1.0 ) ;
color = clamp ( pow ( color , vec3 ( gamma ) ) , 0.0 , 1.0 ) ;
float luminance = dot ( color , w ) ;
color = mix ( vec3 ( luminance ) , color , saturation ) ;
gl _FragColor = vec4 ( color , tex . a ) ;
}
@ end
@ export clay . compositor . brightness
varying vec2 v _Texcoord ;
uniform sampler2D texture ;
uniform float brightness : 0.0 ;
void main ( )
{
vec4 tex = texture2D ( texture , v _Texcoord ) ;
vec3 color = tex . rgb + vec3 ( brightness ) ;
gl _FragColor = vec4 ( color , tex . a ) ;
}
@ end
@ export clay . compositor . contrast
varying vec2 v _Texcoord ;
uniform sampler2D texture ;
uniform float contrast : 1.0 ;
void main ( )
{
vec4 tex = texture2D ( texture , v _Texcoord ) ;
vec3 color = ( tex . rgb - vec3 ( 0.5 ) ) * contrast + vec3 ( 0.5 ) ;
gl _FragColor = vec4 ( color , tex . a ) ;
}
@ end
@ export clay . compositor . exposure
varying vec2 v _Texcoord ;
uniform sampler2D texture ;
uniform float exposure : 0.0 ;
void main ( )
{
vec4 tex = texture2D ( texture , v _Texcoord ) ;
vec3 color = tex . rgb * pow ( 2.0 , exposure ) ;
gl _FragColor = vec4 ( color , tex . a ) ;
}
@ end
@ export clay . compositor . gamma
varying vec2 v _Texcoord ;
uniform sampler2D texture ;
uniform float gamma : 1.0 ;
void main ( )
{
vec4 tex = texture2D ( texture , v _Texcoord ) ;
vec3 color = pow ( tex . rgb , vec3 ( gamma ) ) ;
gl _FragColor = vec4 ( color , tex . a ) ;
}
@ end
@ export clay . compositor . saturation
varying vec2 v _Texcoord ;
uniform sampler2D texture ;
uniform float saturation : 1.0 ;
const vec3 w = vec3 ( 0.2125 , 0.7154 , 0.0721 ) ;
void main ( )
{
vec4 tex = texture2D ( texture , v _Texcoord ) ;
vec3 color = tex . rgb ;
float luminance = dot ( color , w ) ;
color = mix ( vec3 ( luminance ) , color , saturation ) ;
gl _FragColor = vec4 ( color , tex . a ) ;
}
2023-05-25 08:33:42 +08:00
@ end ` ,Vs= ` @ export clay . compositor . kernel . gaussian _9
2023-04-28 16:00:04 +08:00
float gaussianKernel [ 9 ] ;
gaussianKernel [ 0 ] = 0.07 ;
gaussianKernel [ 1 ] = 0.09 ;
gaussianKernel [ 2 ] = 0.12 ;
gaussianKernel [ 3 ] = 0.14 ;
gaussianKernel [ 4 ] = 0.16 ;
gaussianKernel [ 5 ] = 0.14 ;
gaussianKernel [ 6 ] = 0.12 ;
gaussianKernel [ 7 ] = 0.09 ;
gaussianKernel [ 8 ] = 0.07 ;
@ end
@ export clay . compositor . kernel . gaussian _13
float gaussianKernel [ 13 ] ;
gaussianKernel [ 0 ] = 0.02 ;
gaussianKernel [ 1 ] = 0.03 ;
gaussianKernel [ 2 ] = 0.06 ;
gaussianKernel [ 3 ] = 0.08 ;
gaussianKernel [ 4 ] = 0.11 ;
gaussianKernel [ 5 ] = 0.13 ;
gaussianKernel [ 6 ] = 0.14 ;
gaussianKernel [ 7 ] = 0.13 ;
gaussianKernel [ 8 ] = 0.11 ;
gaussianKernel [ 9 ] = 0.08 ;
gaussianKernel [ 10 ] = 0.06 ;
gaussianKernel [ 11 ] = 0.03 ;
gaussianKernel [ 12 ] = 0.02 ;
@ end
@ export clay . compositor . gaussian _blur
# define SHADER _NAME gaussian _blur
uniform sampler2D texture ; varying vec2 v _Texcoord ;
uniform float blurSize : 2.0 ;
uniform vec2 textureSize : [ 512.0 , 512.0 ] ;
uniform float blurDir : 0.0 ;
@ import clay . util . rgbm
@ import clay . util . clamp _sample
void main ( void )
{
@ import clay . compositor . kernel . gaussian _9
vec2 off = blurSize / textureSize ;
off *= vec2 ( 1.0 - blurDir , blurDir ) ;
vec4 sum = vec4 ( 0.0 ) ;
float weightAll = 0.0 ;
for ( int i = 0 ; i < 9 ; i ++ ) {
float w = gaussianKernel [ i ] ;
vec4 texel = decodeHDR ( clampSample ( texture , v _Texcoord + float ( i - 4 ) * off ) ) ;
sum += texel * w ;
weightAll += w ;
}
gl _FragColor = encodeHDR ( sum / max ( weightAll , 0.01 ) ) ;
}
@ end
2023-05-25 08:33:42 +08:00
` ,oc= ` @ export clay . compositor . hdr . log _lum
2023-04-28 16:00:04 +08:00
varying vec2 v _Texcoord ;
uniform sampler2D texture ;
const vec3 w = vec3 ( 0.2125 , 0.7154 , 0.0721 ) ;
@ import clay . util . rgbm
void main ( )
{
vec4 tex = decodeHDR ( texture2D ( texture , v _Texcoord ) ) ;
float luminance = dot ( tex . rgb , w ) ;
luminance = log ( luminance + 0.001 ) ;
gl _FragColor = encodeHDR ( vec4 ( vec3 ( luminance ) , 1.0 ) ) ;
}
@ end
@ export clay . compositor . hdr . lum _adaption
varying vec2 v _Texcoord ;
uniform sampler2D adaptedLum ;
uniform sampler2D currentLum ;
uniform float frameTime : 0.02 ;
@ import clay . util . rgbm
void main ( )
{
float fAdaptedLum = decodeHDR ( texture2D ( adaptedLum , vec2 ( 0.5 , 0.5 ) ) ) . r ;
float fCurrentLum = exp ( encodeHDR ( texture2D ( currentLum , vec2 ( 0.5 , 0.5 ) ) ) . r ) ;
fAdaptedLum += ( fCurrentLum - fAdaptedLum ) * ( 1.0 - pow ( 0.98 , 30.0 * frameTime ) ) ;
gl _FragColor = encodeHDR ( vec4 ( vec3 ( fAdaptedLum ) , 1.0 ) ) ;
}
@ end
@ export clay . compositor . lum
varying vec2 v _Texcoord ;
uniform sampler2D texture ;
const vec3 w = vec3 ( 0.2125 , 0.7154 , 0.0721 ) ;
void main ( )
{
vec4 tex = texture2D ( texture , v _Texcoord ) ;
float luminance = dot ( tex . rgb , w ) ;
gl _FragColor = vec4 ( vec3 ( luminance ) , 1.0 ) ;
}
2023-05-25 08:33:42 +08:00
@ end ` ,ks= `
2023-04-28 16:00:04 +08:00
@ export clay . compositor . lut
varying vec2 v _Texcoord ;
uniform sampler2D texture ;
uniform sampler2D lookup ;
void main ( )
{
vec4 tex = texture2D ( texture , v _Texcoord ) ;
float blueColor = tex . b * 63.0 ;
vec2 quad1 ;
quad1 . y = floor ( floor ( blueColor ) / 8.0 ) ;
quad1 . x = floor ( blueColor ) - ( quad1 . y * 8.0 ) ;
vec2 quad2 ;
quad2 . y = floor ( ceil ( blueColor ) / 8.0 ) ;
quad2 . x = ceil ( blueColor ) - ( quad2 . y * 8.0 ) ;
vec2 texPos1 ;
texPos1 . x = ( quad1 . x * 0.125 ) + 0.5 / 512.0 + ( ( 0.125 - 1.0 / 512.0 ) * tex . r ) ;
texPos1 . y = ( quad1 . y * 0.125 ) + 0.5 / 512.0 + ( ( 0.125 - 1.0 / 512.0 ) * tex . g ) ;
vec2 texPos2 ;
texPos2 . x = ( quad2 . x * 0.125 ) + 0.5 / 512.0 + ( ( 0.125 - 1.0 / 512.0 ) * tex . r ) ;
texPos2 . y = ( quad2 . y * 0.125 ) + 0.5 / 512.0 + ( ( 0.125 - 1.0 / 512.0 ) * tex . g ) ;
vec4 newColor1 = texture2D ( lookup , texPos1 ) ;
vec4 newColor2 = texture2D ( lookup , texPos2 ) ;
vec4 newColor = mix ( newColor1 , newColor2 , fract ( blueColor ) ) ;
gl _FragColor = vec4 ( newColor . rgb , tex . w ) ;
}
2023-05-25 08:33:42 +08:00
@ end ` ,sc= ` @ export clay . compositor . vignette
2023-04-28 16:00:04 +08:00
# define OUTPUT _ALPHA
varying vec2 v _Texcoord ;
uniform sampler2D texture ;
uniform float darkness : 1 ;
uniform float offset : 1 ;
@ import clay . util . rgbm
void main ( )
{
vec4 texel = decodeHDR ( texture2D ( texture , v _Texcoord ) ) ;
gl _FragColor . rgb = texel . rgb ;
vec2 uv = ( v _Texcoord - vec2 ( 0.5 ) ) * vec2 ( offset ) ;
gl _FragColor = encodeHDR ( vec4 ( mix ( texel . rgb , vec3 ( 1.0 - darkness ) , dot ( uv , uv ) ) , texel . a ) ) ;
}
2023-05-25 08:33:42 +08:00
@ end ` ,Ws= ` @ export clay . compositor . output
2023-04-28 16:00:04 +08:00
# define OUTPUT _ALPHA
varying vec2 v _Texcoord ;
uniform sampler2D texture ;
@ import clay . util . rgbm
void main ( )
{
vec4 tex = decodeHDR ( texture2D ( texture , v _Texcoord ) ) ;
gl _FragColor . rgb = tex . rgb ;
# ifdef OUTPUT _ALPHA
gl _FragColor . a = tex . a ;
# else
gl _FragColor . a = 1.0 ;
# endif
gl _FragColor = encodeHDR ( gl _FragColor ) ;
# ifdef PREMULTIPLY _ALPHA
gl _FragColor . rgb *= gl _FragColor . a ;
# endif
}
2023-05-25 08:33:42 +08:00
@ end ` ,Xs= ` @ export clay . compositor . bright
2023-04-28 16:00:04 +08:00
uniform sampler2D texture ;
uniform float threshold : 1 ;
uniform float scale : 1.0 ;
uniform vec2 textureSize : [ 512 , 512 ] ;
varying vec2 v _Texcoord ;
const vec3 lumWeight = vec3 ( 0.2125 , 0.7154 , 0.0721 ) ;
@ import clay . util . rgbm
vec4 median ( vec4 a , vec4 b , vec4 c )
{
return a + b + c - min ( min ( a , b ) , c ) - max ( max ( a , b ) , c ) ;
}
void main ( )
{
vec4 texel = decodeHDR ( texture2D ( texture , v _Texcoord ) ) ;
# ifdef ANTI _FLICKER
vec3 d = 1.0 / textureSize . xyx * vec3 ( 1.0 , 1.0 , 0.0 ) ;
vec4 s1 = decodeHDR ( texture2D ( texture , v _Texcoord - d . xz ) ) ;
vec4 s2 = decodeHDR ( texture2D ( texture , v _Texcoord + d . xz ) ) ;
vec4 s3 = decodeHDR ( texture2D ( texture , v _Texcoord - d . zy ) ) ;
vec4 s4 = decodeHDR ( texture2D ( texture , v _Texcoord + d . zy ) ) ;
texel = median ( median ( texel , s1 , s2 ) , s3 , s4 ) ;
# endif
float lum = dot ( texel . rgb , lumWeight ) ;
vec4 color ;
if ( lum > threshold && texel . a > 0.0 )
{
color = vec4 ( texel . rgb * scale , texel . a * scale ) ;
}
else
{
color = vec4 ( 0.0 ) ;
}
gl _FragColor = encodeHDR ( color ) ;
}
@ end
2023-05-25 08:33:42 +08:00
` ,Zs= ` @ export clay . compositor . downsample
2023-04-28 16:00:04 +08:00
uniform sampler2D texture ;
uniform vec2 textureSize : [ 512 , 512 ] ;
varying vec2 v _Texcoord ;
@ import clay . util . rgbm
float brightness ( vec3 c )
{
return max ( max ( c . r , c . g ) , c . b ) ;
}
@ import clay . util . clamp _sample
void main ( )
{
vec4 d = vec4 ( - 1.0 , - 1.0 , 1.0 , 1.0 ) / textureSize . xyxy ;
# ifdef ANTI _FLICKER
vec3 s1 = decodeHDR ( clampSample ( texture , v _Texcoord + d . xy ) ) . rgb ;
vec3 s2 = decodeHDR ( clampSample ( texture , v _Texcoord + d . zy ) ) . rgb ;
vec3 s3 = decodeHDR ( clampSample ( texture , v _Texcoord + d . xw ) ) . rgb ;
vec3 s4 = decodeHDR ( clampSample ( texture , v _Texcoord + d . zw ) ) . rgb ;
float s1w = 1.0 / ( brightness ( s1 ) + 1.0 ) ;
float s2w = 1.0 / ( brightness ( s2 ) + 1.0 ) ;
float s3w = 1.0 / ( brightness ( s3 ) + 1.0 ) ;
float s4w = 1.0 / ( brightness ( s4 ) + 1.0 ) ;
float oneDivideSum = 1.0 / ( s1w + s2w + s3w + s4w ) ;
vec4 color = vec4 (
( s1 * s1w + s2 * s2w + s3 * s3w + s4 * s4w ) * oneDivideSum ,
1.0
) ;
# else
vec4 color = decodeHDR ( clampSample ( texture , v _Texcoord + d . xy ) ) ;
color += decodeHDR ( clampSample ( texture , v _Texcoord + d . zy ) ) ;
color += decodeHDR ( clampSample ( texture , v _Texcoord + d . xw ) ) ;
color += decodeHDR ( clampSample ( texture , v _Texcoord + d . zw ) ) ;
color *= 0.25 ;
# endif
gl _FragColor = encodeHDR ( color ) ;
}
2023-05-25 08:33:42 +08:00
@ end ` ,js= `
2023-04-28 16:00:04 +08:00
@ export clay . compositor . upsample
# define HIGH _QUALITY
uniform sampler2D texture ;
uniform vec2 textureSize : [ 512 , 512 ] ;
uniform float sampleScale : 0.5 ;
varying vec2 v _Texcoord ;
@ import clay . util . rgbm
@ import clay . util . clamp _sample
void main ( )
{
# ifdef HIGH _QUALITY
vec4 d = vec4 ( 1.0 , 1.0 , - 1.0 , 0.0 ) / textureSize . xyxy * sampleScale ;
vec4 s ;
s = decodeHDR ( clampSample ( texture , v _Texcoord - d . xy ) ) ;
s += decodeHDR ( clampSample ( texture , v _Texcoord - d . wy ) ) * 2.0 ;
s += decodeHDR ( clampSample ( texture , v _Texcoord - d . zy ) ) ;
s += decodeHDR ( clampSample ( texture , v _Texcoord + d . zw ) ) * 2.0 ;
s += decodeHDR ( clampSample ( texture , v _Texcoord ) ) * 4.0 ;
s += decodeHDR ( clampSample ( texture , v _Texcoord + d . xw ) ) * 2.0 ;
s += decodeHDR ( clampSample ( texture , v _Texcoord + d . zy ) ) ;
s += decodeHDR ( clampSample ( texture , v _Texcoord + d . wy ) ) * 2.0 ;
s += decodeHDR ( clampSample ( texture , v _Texcoord + d . xy ) ) ;
gl _FragColor = encodeHDR ( s / 16.0 ) ;
# else
vec4 d = vec4 ( - 1.0 , - 1.0 , + 1.0 , + 1.0 ) / textureSize . xyxy ;
vec4 s ;
s = decodeHDR ( clampSample ( texture , v _Texcoord + d . xy ) ) ;
s += decodeHDR ( clampSample ( texture , v _Texcoord + d . zy ) ) ;
s += decodeHDR ( clampSample ( texture , v _Texcoord + d . xw ) ) ;
s += decodeHDR ( clampSample ( texture , v _Texcoord + d . zw ) ) ;
gl _FragColor = encodeHDR ( s / 4.0 ) ;
# endif
}
2023-09-11 21:56:39 +08:00
@ end ` ,qs= ` @ export clay . compositor . hdr . composite
2023-04-28 16:00:04 +08:00
# define TONEMAPPING
uniform sampler2D texture ;
# ifdef BLOOM _ENABLED
uniform sampler2D bloom ;
# endif
# ifdef LENSFLARE _ENABLED
uniform sampler2D lensflare ;
uniform sampler2D lensdirt ;
# endif
# ifdef LUM _ENABLED
uniform sampler2D lum ;
# endif
# ifdef LUT _ENABLED
uniform sampler2D lut ;
# endif
# ifdef COLOR _CORRECTION
uniform float brightness : 0.0 ;
uniform float contrast : 1.0 ;
uniform float saturation : 1.0 ;
# endif
# ifdef VIGNETTE
uniform float vignetteDarkness : 1.0 ;
uniform float vignetteOffset : 1.0 ;
# endif
uniform float exposure : 1.0 ;
uniform float bloomIntensity : 0.25 ;
uniform float lensflareIntensity : 1 ;
varying vec2 v _Texcoord ;
@ import clay . util . srgb
vec3 ACESToneMapping ( vec3 color )
{
const float A = 2.51 ;
const float B = 0.03 ;
const float C = 2.43 ;
const float D = 0.59 ;
const float E = 0.14 ;
return ( color * ( A * color + B ) ) / ( color * ( C * color + D ) + E ) ;
}
float eyeAdaption ( float fLum )
{
return mix ( 0.2 , fLum , 0.5 ) ;
}
# ifdef LUT _ENABLED
vec3 lutTransform ( vec3 color ) {
float blueColor = color . b * 63.0 ;
vec2 quad1 ;
quad1 . y = floor ( floor ( blueColor ) / 8.0 ) ;
quad1 . x = floor ( blueColor ) - ( quad1 . y * 8.0 ) ;
vec2 quad2 ;
quad2 . y = floor ( ceil ( blueColor ) / 8.0 ) ;
quad2 . x = ceil ( blueColor ) - ( quad2 . y * 8.0 ) ;
vec2 texPos1 ;
texPos1 . x = ( quad1 . x * 0.125 ) + 0.5 / 512.0 + ( ( 0.125 - 1.0 / 512.0 ) * color . r ) ;
texPos1 . y = ( quad1 . y * 0.125 ) + 0.5 / 512.0 + ( ( 0.125 - 1.0 / 512.0 ) * color . g ) ;
vec2 texPos2 ;
texPos2 . x = ( quad2 . x * 0.125 ) + 0.5 / 512.0 + ( ( 0.125 - 1.0 / 512.0 ) * color . r ) ;
texPos2 . y = ( quad2 . y * 0.125 ) + 0.5 / 512.0 + ( ( 0.125 - 1.0 / 512.0 ) * color . g ) ;
vec4 newColor1 = texture2D ( lut , texPos1 ) ;
vec4 newColor2 = texture2D ( lut , texPos2 ) ;
vec4 newColor = mix ( newColor1 , newColor2 , fract ( blueColor ) ) ;
return newColor . rgb ;
}
# endif
@ import clay . util . rgbm
void main ( )
{
vec4 texel = vec4 ( 0.0 ) ;
vec4 originalTexel = vec4 ( 0.0 ) ;
# ifdef TEXTURE _ENABLED
texel = decodeHDR ( texture2D ( texture , v _Texcoord ) ) ;
originalTexel = texel ;
# endif
# ifdef BLOOM _ENABLED
vec4 bloomTexel = decodeHDR ( texture2D ( bloom , v _Texcoord ) ) ;
texel . rgb += bloomTexel . rgb * bloomIntensity ;
texel . a += bloomTexel . a * bloomIntensity ;
# endif
# ifdef LENSFLARE _ENABLED
texel += decodeHDR ( texture2D ( lensflare , v _Texcoord ) ) * texture2D ( lensdirt , v _Texcoord ) * lensflareIntensity ;
# endif
texel . a = min ( texel . a , 1.0 ) ;
# ifdef LUM _ENABLED
float fLum = texture2D ( lum , vec2 ( 0.5 , 0.5 ) ) . r ;
float adaptedLumDest = 3.0 / ( max ( 0.1 , 1.0 + 10.0 * eyeAdaption ( fLum ) ) ) ;
float exposureBias = adaptedLumDest * exposure ;
# else
float exposureBias = exposure ;
# endif
# ifdef TONEMAPPING
texel . rgb *= exposureBias ;
texel . rgb = ACESToneMapping ( texel . rgb ) ;
# endif
texel = linearTosRGB ( texel ) ;
# ifdef LUT _ENABLED
texel . rgb = lutTransform ( clamp ( texel . rgb , vec3 ( 0.0 ) , vec3 ( 1.0 ) ) ) ;
# endif
# ifdef COLOR _CORRECTION
texel . rgb = clamp ( texel . rgb + vec3 ( brightness ) , 0.0 , 1.0 ) ;
texel . rgb = clamp ( ( texel . rgb - vec3 ( 0.5 ) ) * contrast + vec3 ( 0.5 ) , 0.0 , 1.0 ) ;
float lum = dot ( texel . rgb , vec3 ( 0.2125 , 0.7154 , 0.0721 ) ) ;
texel . rgb = mix ( vec3 ( lum ) , texel . rgb , saturation ) ;
# endif
# ifdef VIGNETTE
vec2 uv = ( v _Texcoord - vec2 ( 0.5 ) ) * vec2 ( vignetteOffset ) ;
texel . rgb = mix ( texel . rgb , vec3 ( 1.0 - vignetteDarkness ) , dot ( uv , uv ) ) ;
# endif
gl _FragColor = encodeHDR ( texel ) ;
# ifdef DEBUG
# if DEBUG == 1
gl _FragColor = encodeHDR ( decodeHDR ( texture2D ( texture , v _Texcoord ) ) ) ;
# elif DEBUG == 2
gl _FragColor = encodeHDR ( decodeHDR ( texture2D ( bloom , v _Texcoord ) ) * bloomIntensity ) ;
# elif DEBUG == 3
gl _FragColor = encodeHDR ( decodeHDR ( texture2D ( lensflare , v _Texcoord ) * lensflareIntensity ) ) ;
# endif
# endif
if ( originalTexel . a <= 0.01 && gl _FragColor . a > 1e-5 ) {
gl _FragColor . a = dot ( gl _FragColor . rgb , vec3 ( 0.2125 , 0.7154 , 0.0721 ) ) ;
}
# ifdef PREMULTIPLY _ALPHA
gl _FragColor . rgb *= gl _FragColor . a ;
# endif
}
2023-05-25 08:33:42 +08:00
@ end ` ,lc= ` @ export clay . compositor . lensflare
2023-04-28 16:00:04 +08:00
# define SAMPLE _NUMBER 8
uniform sampler2D texture ;
uniform sampler2D lenscolor ;
uniform vec2 textureSize : [ 512 , 512 ] ;
uniform float dispersal : 0.3 ;
uniform float haloWidth : 0.4 ;
uniform float distortion : 1.0 ;
varying vec2 v _Texcoord ;
@ import clay . util . rgbm
vec4 textureDistorted (
in vec2 texcoord ,
in vec2 direction ,
in vec3 distortion
) {
return vec4 (
decodeHDR ( texture2D ( texture , texcoord + direction * distortion . r ) ) . r ,
decodeHDR ( texture2D ( texture , texcoord + direction * distortion . g ) ) . g ,
decodeHDR ( texture2D ( texture , texcoord + direction * distortion . b ) ) . b ,
1.0
) ;
}
void main ( )
{
vec2 texcoord = - v _Texcoord + vec2 ( 1.0 ) ; vec2 textureOffset = 1.0 / textureSize ;
vec2 ghostVec = ( vec2 ( 0.5 ) - texcoord ) * dispersal ;
vec2 haloVec = normalize ( ghostVec ) * haloWidth ;
vec3 distortion = vec3 ( - textureOffset . x * distortion , 0.0 , textureOffset . x * distortion ) ;
vec4 result = vec4 ( 0.0 ) ;
for ( int i = 0 ; i < SAMPLE _NUMBER ; i ++ )
{
vec2 offset = fract ( texcoord + ghostVec * float ( i ) ) ;
float weight = length ( vec2 ( 0.5 ) - offset ) / length ( vec2 ( 0.5 ) ) ;
weight = pow ( 1.0 - weight , 10.0 ) ;
result += textureDistorted ( offset , normalize ( ghostVec ) , distortion ) * weight ;
}
result *= texture2D ( lenscolor , vec2 ( length ( vec2 ( 0.5 ) - texcoord ) ) / length ( vec2 ( 0.5 ) ) ) ;
float weight = length ( vec2 ( 0.5 ) - fract ( texcoord + haloVec ) ) / length ( vec2 ( 0.5 ) ) ;
weight = pow ( 1.0 - weight , 10.0 ) ;
vec2 offset = fract ( texcoord + haloVec ) ;
result += textureDistorted ( offset , normalize ( ghostVec ) , distortion ) * weight ;
gl _FragColor = result ;
}
2023-09-11 21:56:39 +08:00
@ end ` ,Ys= ` @ export clay . compositor . blend
2023-04-28 16:00:04 +08:00
# define SHADER _NAME blend
# ifdef TEXTURE1 _ENABLED
uniform sampler2D texture1 ;
uniform float weight1 : 1.0 ;
# endif
# ifdef TEXTURE2 _ENABLED
uniform sampler2D texture2 ;
uniform float weight2 : 1.0 ;
# endif
# ifdef TEXTURE3 _ENABLED
uniform sampler2D texture3 ;
uniform float weight3 : 1.0 ;
# endif
# ifdef TEXTURE4 _ENABLED
uniform sampler2D texture4 ;
uniform float weight4 : 1.0 ;
# endif
# ifdef TEXTURE5 _ENABLED
uniform sampler2D texture5 ;
uniform float weight5 : 1.0 ;
# endif
# ifdef TEXTURE6 _ENABLED
uniform sampler2D texture6 ;
uniform float weight6 : 1.0 ;
# endif
varying vec2 v _Texcoord ;
@ import clay . util . rgbm
void main ( )
{
vec4 tex = vec4 ( 0.0 ) ;
# ifdef TEXTURE1 _ENABLED
tex += decodeHDR ( texture2D ( texture1 , v _Texcoord ) ) * weight1 ;
# endif
# ifdef TEXTURE2 _ENABLED
tex += decodeHDR ( texture2D ( texture2 , v _Texcoord ) ) * weight2 ;
# endif
# ifdef TEXTURE3 _ENABLED
tex += decodeHDR ( texture2D ( texture3 , v _Texcoord ) ) * weight3 ;
# endif
# ifdef TEXTURE4 _ENABLED
tex += decodeHDR ( texture2D ( texture4 , v _Texcoord ) ) * weight4 ;
# endif
# ifdef TEXTURE5 _ENABLED
tex += decodeHDR ( texture2D ( texture5 , v _Texcoord ) ) * weight5 ;
# endif
# ifdef TEXTURE6 _ENABLED
tex += decodeHDR ( texture2D ( texture6 , v _Texcoord ) ) * weight6 ;
# endif
gl _FragColor = encodeHDR ( tex ) ;
}
2023-07-09 20:38:38 +08:00
@ end ` , $ s= ` @ export clay . compositor . fxaa
2023-04-28 16:00:04 +08:00
uniform sampler2D texture ;
uniform vec4 viewport : VIEWPORT ;
varying vec2 v _Texcoord ;
# define FXAA _REDUCE _MIN ( 1.0 / 128.0 )
# define FXAA _REDUCE _MUL ( 1.0 / 8.0 )
# define FXAA _SPAN _MAX 8.0
@ import clay . util . rgbm
void main ( )
{
vec2 resolution = 1.0 / viewport . zw ;
vec3 rgbNW = decodeHDR ( texture2D ( texture , ( gl _FragCoord . xy + vec2 ( - 1.0 , - 1.0 ) ) * resolution ) ) . xyz ;
vec3 rgbNE = decodeHDR ( texture2D ( texture , ( gl _FragCoord . xy + vec2 ( 1.0 , - 1.0 ) ) * resolution ) ) . xyz ;
vec3 rgbSW = decodeHDR ( texture2D ( texture , ( gl _FragCoord . xy + vec2 ( - 1.0 , 1.0 ) ) * resolution ) ) . xyz ;
vec3 rgbSE = decodeHDR ( texture2D ( texture , ( gl _FragCoord . xy + vec2 ( 1.0 , 1.0 ) ) * resolution ) ) . xyz ;
vec4 rgbaM = decodeHDR ( texture2D ( texture , gl _FragCoord . xy * resolution ) ) ;
vec3 rgbM = rgbaM . xyz ;
float opacity = rgbaM . w ;
vec3 luma = vec3 ( 0.299 , 0.587 , 0.114 ) ;
float lumaNW = dot ( rgbNW , luma ) ;
float lumaNE = dot ( rgbNE , luma ) ;
float lumaSW = dot ( rgbSW , luma ) ;
float lumaSE = dot ( rgbSE , luma ) ;
float lumaM = dot ( rgbM , luma ) ;
float lumaMin = min ( lumaM , min ( min ( lumaNW , lumaNE ) , min ( lumaSW , lumaSE ) ) ) ;
float lumaMax = max ( lumaM , max ( max ( lumaNW , lumaNE ) , max ( lumaSW , lumaSE ) ) ) ;
vec2 dir ;
dir . x = - ( ( lumaNW + lumaNE ) - ( lumaSW + lumaSE ) ) ;
dir . y = ( ( lumaNW + lumaSW ) - ( lumaNE + lumaSE ) ) ;
float dirReduce = max ( ( lumaNW + lumaNE + lumaSW + lumaSE ) * ( 0.25 * FXAA _REDUCE _MUL ) , FXAA _REDUCE _MIN ) ;
float rcpDirMin = 1.0 / ( min ( abs ( dir . x ) , abs ( dir . y ) ) + dirReduce ) ;
dir = min ( vec2 ( FXAA _SPAN _MAX , FXAA _SPAN _MAX ) ,
max ( vec2 ( - FXAA _SPAN _MAX , - FXAA _SPAN _MAX ) ,
dir * rcpDirMin ) ) * resolution ;
vec3 rgbA = decodeHDR ( texture2D ( texture , gl _FragCoord . xy * resolution + dir * ( 1.0 / 3.0 - 0.5 ) ) ) . xyz ;
rgbA += decodeHDR ( texture2D ( texture , gl _FragCoord . xy * resolution + dir * ( 2.0 / 3.0 - 0.5 ) ) ) . xyz ;
rgbA *= 0.5 ;
vec3 rgbB = decodeHDR ( texture2D ( texture , gl _FragCoord . xy * resolution + dir * - 0.5 ) ) . xyz ;
rgbB += decodeHDR ( texture2D ( texture , gl _FragCoord . xy * resolution + dir * 0.5 ) ) . xyz ;
rgbB *= 0.25 ;
rgbB += rgbA * 0.5 ;
float lumaB = dot ( rgbB , luma ) ;
if ( ( lumaB < lumaMin ) || ( lumaB > lumaMax ) )
{
gl _FragColor = vec4 ( rgbA , opacity ) ;
}
else {
gl _FragColor = vec4 ( rgbB , opacity ) ;
}
}
2023-09-11 21:56:39 +08:00
@ end ` ;function hc(e){e.import(ac),e.import(Vs),e.import(oc),e.import(ks),e.import(sc),e.import(Ws),e.import(Xs),e.import(Zs),e.import(js),e.import(qs),e.import(lc),e.import(Ys),e.import( $ s)}hc(N);var uc=/^#source \( (.*?) \) /;function fc(e,t){var r=new Qf;t=t||{};var i={textures:{},parameters:{}},n=function(s,l){for(var h=0;h<e.nodes.length;h++){var u=e.nodes[h],f=cc(u,i,t);f&&r.addNode(f)}};for(var a in e.parameters){var o=e.parameters[a];i.parameters[a]=Ma(o)}return pc(e,i,t,function(s){i.textures=s,n()}),r}function cc(e,t,r){var i=e.type||"filter",n,a,o;if(i==="filter"){var s=e.shader.trim(),l=uc.exec(s);if(l?n=N.source(l[1].trim()):s.charAt(0)==="#"&&(n=t.shaders[s.substr(1)]),n||(n=s),!n)return}if(e.inputs){a={};for(var h in e.inputs)typeof e.inputs[h]=="string"?a[h]=e.inputs[h]:a[h]={node:e.inputs[h].node,pin:e.inputs[h].pin}}if(e.outputs){o={};for(var h in e.outputs){var u=e.outputs[h];o[h]={},u.attachment!=null&&(o[h].attachment=u.attachment),u.keepLastFrame!=null&&(o[h].keepLastFrame=u.keepLastFrame),u.outputLastFrame!=null&&(o[h].outputLastFrame=u.outputLastFrame),u.parameters&&(o[h].parameters=Ma(u.parameters))}}var f;if(i==="scene"?f=new ec({name:e.name,scene:r.scene,camera:r.camera,outputs:o}):i==="texture"?f=new rc({name:e.name,outputs:o}):f=new nc({name:e.name,shader:n,inputs:a,outputs:o}),f){if(e.parameters)for(var h in e.parameters){var d=e.parameters[h];typeof d=="string"?(d=d.trim(),d.charAt(0)==="#"?d=t.textures[d.substr(1)]:f.on("beforerender",mc(h,Ks(d)))):typeof d=="function"&&f.on("beforerender",d),f.setParameter(h,d)}if(e.defines&&f.pass)for(var h in e.defines){var d=e.defines[h];f.pass.material.define("fragment",h,d)}}return f}function dc(e,t){return e}function vc(e,t){return t}function Ma(e){var t={};if(!e)return t;["type","minFilter","magFilter","wrapS","wrapT","flipY","useMipmap"].forEach(function(i){var n=e[i];n!=null&&(typeof n=="string"&&(n=W[n]),t[i]=n)});var r=e.scale||1;return["width","height"].forEach(function(i){if(e[i]!=null){var n=e[i];typeof n=="string"?(n=n.trim(),t[i]=_c(i,Ks(n),r)):t[i]=n}}),t.width||(t.width=dc),t.height||(t.height=vc),e.useMipmap!=null&&(t.useMipmap=e.useMipmap),t}function pc(e,t,r,i){if(!e.textures){i({});return}var n={},a=0,o=!1,s=r.textureRootPath;je.each(e.textures,function(l,h){var u,f=l.path,d=Ma(l.parameters);if(Array.isArray(f)&&f.length===6)s&&(f=f.map(function(c){return je.relative2absolute(c,s)})),u=new di(d);else if(typeof f=="string")s&&(f=je.relative2absolute(f,s)),u=new K(d);else return;u.load(f),a++,u.once("success",function(){n[h]=u,a--,a===0&&(i(n),o=!0)})}),a===0&&!o&&i(n)}function mc(e,t){return function(r){var i=r.getDevicePixelRatio(),n=r.getWidth(),a=r.getHeight(),o=t(n,a,i);this.setParameter(e,o)}}function _c(e,t,r){return r=r||1,function(i){var n=i.getDevicePixelRatio(),a=i.getWidth()*r,o=i.getHeight()*r;return t(a,o,n)}}function Ks(e){var t=/^expr \( (.*) \) $ /.exec(e);if(t)try{var r=new Function("width","height","dpr","return "+t[1]);return r(1,1),r}catch{throw new Error("Invalid expression.")}}function Fr(e,t){for(var r=0,i=1/t,n=e;n>0;)r=r+i*(n%t),n=Math.floor(n/t),i=i/t;return r}const gc= ` @ export ecgl . ssao . estimate
2023-04-28 16:00:04 +08:00
uniform sampler2D depthTex ;
uniform sampler2D normalTex ;
uniform sampler2D noiseTex ;
uniform vec2 depthTexSize ;
uniform vec2 noiseTexSize ;
uniform mat4 projection ;
uniform mat4 projectionInv ;
uniform mat4 viewInverseTranspose ;
uniform vec3 kernel [ KERNEL _SIZE ] ;
uniform float radius : 1 ;
uniform float power : 1 ;
uniform float bias : 1e-2 ;
uniform float intensity : 1.0 ;
varying vec2 v _Texcoord ;
float ssaoEstimator ( in vec3 originPos , in mat3 kernelBasis ) {
float occlusion = 0.0 ;
for ( int i = 0 ; i < KERNEL _SIZE ; i ++ ) {
vec3 samplePos = kernel [ i ] ;
# ifdef NORMALTEX _ENABLED
samplePos = kernelBasis * samplePos ;
# endif
samplePos = samplePos * radius + originPos ;
vec4 texCoord = projection * vec4 ( samplePos , 1.0 ) ;
texCoord . xy /= texCoord . w ;
vec4 depthTexel = texture2D ( depthTex , texCoord . xy * 0.5 + 0.5 ) ;
float sampleDepth = depthTexel . r * 2.0 - 1.0 ;
if ( projection [ 3 ] [ 3 ] == 0.0 ) {
sampleDepth = projection [ 3 ] [ 2 ] / ( sampleDepth * projection [ 2 ] [ 3 ] - projection [ 2 ] [ 2 ] ) ;
}
else {
sampleDepth = ( sampleDepth - projection [ 3 ] [ 2 ] ) / projection [ 2 ] [ 2 ] ;
}
float rangeCheck = smoothstep ( 0.0 , 1.0 , radius / abs ( originPos . z - sampleDepth ) ) ;
occlusion += rangeCheck * step ( samplePos . z , sampleDepth - bias ) ;
}
# ifdef NORMALTEX _ENABLED
occlusion = 1.0 - occlusion / float ( KERNEL _SIZE ) ;
# else
occlusion = 1.0 - clamp ( ( occlusion / float ( KERNEL _SIZE ) - 0.6 ) * 2.5 , 0.0 , 1.0 ) ;
# endif
return pow ( occlusion , power ) ;
}
void main ( )
{
vec4 depthTexel = texture2D ( depthTex , v _Texcoord ) ;
# ifdef NORMALTEX _ENABLED
vec4 tex = texture2D ( normalTex , v _Texcoord ) ;
if ( dot ( tex . rgb , tex . rgb ) == 0.0 ) {
gl _FragColor = vec4 ( 1.0 ) ;
return ;
}
vec3 N = tex . rgb * 2.0 - 1.0 ;
N = ( viewInverseTranspose * vec4 ( N , 0.0 ) ) . xyz ;
vec2 noiseTexCoord = depthTexSize / vec2 ( noiseTexSize ) * v _Texcoord ;
vec3 rvec = texture2D ( noiseTex , noiseTexCoord ) . rgb * 2.0 - 1.0 ;
vec3 T = normalize ( rvec - N * dot ( rvec , N ) ) ;
vec3 BT = normalize ( cross ( N , T ) ) ;
mat3 kernelBasis = mat3 ( T , BT , N ) ;
# else
if ( depthTexel . r > 0.99999 ) {
gl _FragColor = vec4 ( 1.0 ) ;
return ;
}
mat3 kernelBasis ;
# endif
float z = depthTexel . r * 2.0 - 1.0 ;
vec4 projectedPos = vec4 ( v _Texcoord * 2.0 - 1.0 , z , 1.0 ) ;
vec4 p4 = projectionInv * projectedPos ;
vec3 position = p4 . xyz / p4 . w ;
float ao = ssaoEstimator ( position , kernelBasis ) ;
ao = clamp ( 1.0 - ( 1.0 - ao ) * intensity , 0.0 , 1.0 ) ;
gl _FragColor = vec4 ( vec3 ( ao ) , 1.0 ) ;
}
@ end
@ export ecgl . ssao . blur
# define SHADER _NAME SSAO _BLUR
uniform sampler2D ssaoTexture ;
# ifdef NORMALTEX _ENABLED
uniform sampler2D normalTex ;
# endif
varying vec2 v _Texcoord ;
uniform vec2 textureSize ;
uniform float blurSize : 1.0 ;
uniform int direction : 0.0 ;
# ifdef DEPTHTEX _ENABLED
uniform sampler2D depthTex ;
uniform mat4 projection ;
uniform float depthRange : 0.5 ;
float getLinearDepth ( vec2 coord )
{
float depth = texture2D ( depthTex , coord ) . r * 2.0 - 1.0 ;
return projection [ 3 ] [ 2 ] / ( depth * projection [ 2 ] [ 3 ] - projection [ 2 ] [ 2 ] ) ;
}
# endif
void main ( )
{
float kernel [ 5 ] ;
kernel [ 0 ] = 0.122581 ;
kernel [ 1 ] = 0.233062 ;
kernel [ 2 ] = 0.288713 ;
kernel [ 3 ] = 0.233062 ;
kernel [ 4 ] = 0.122581 ;
vec2 off = vec2 ( 0.0 ) ;
if ( direction == 0 ) {
off [ 0 ] = blurSize / textureSize . x ;
}
else {
off [ 1 ] = blurSize / textureSize . y ;
}
vec2 coord = v _Texcoord ;
float sum = 0.0 ;
float weightAll = 0.0 ;
# ifdef NORMALTEX _ENABLED
vec3 centerNormal = texture2D ( normalTex , v _Texcoord ) . rgb * 2.0 - 1.0 ;
# endif
# if defined ( DEPTHTEX _ENABLED )
float centerDepth = getLinearDepth ( v _Texcoord ) ;
# endif
for ( int i = 0 ; i < 5 ; i ++ ) {
vec2 coord = clamp ( v _Texcoord + vec2 ( float ( i ) - 2.0 ) * off , vec2 ( 0.0 ) , vec2 ( 1.0 ) ) ;
float w = kernel [ i ] ;
# ifdef NORMALTEX _ENABLED
vec3 normal = texture2D ( normalTex , coord ) . rgb * 2.0 - 1.0 ;
w *= clamp ( dot ( normal , centerNormal ) , 0.0 , 1.0 ) ;
# endif
# ifdef DEPTHTEX _ENABLED
float d = getLinearDepth ( coord ) ;
w *= ( 1.0 - smoothstep ( abs ( centerDepth - d ) / depthRange , 0.0 , 1.0 ) ) ;
# endif
weightAll += w ;
sum += texture2D ( ssaoTexture , coord ) . r * w ;
}
gl _FragColor = vec4 ( vec3 ( sum / weightAll ) , 1.0 ) ;
}
@ end
2023-09-11 21:56:39 +08:00
` ;N.import(gc);function Qs(e){for(var t=new Uint8Array(e*e*4),r=0,i=new U,n=0;n<e;n++)for(var a=0;a<e;a++)i.set(Math.random()*2-1,Math.random()*2-1,0).normalize(),t[r++]=(i.x*.5+.5)*255,t[r++]=(i.y*.5+.5)*255,t[r++]=0,t[r++]=255;return t}function Io(e){return new K({pixels:Qs(e),wrapS:W.REPEAT,wrapT:W.REPEAT,width:e,height:e})}function yc(e,t,r){var i=new Float32Array(e*3);t=t||0;for(var n=0;n<e;n++){var a=Fr(n+t,2)*(r?1:2)*Math.PI,o=Fr(n+t,3)*Math.PI,s=Math.random(),l=Math.cos(a)*Math.sin(o)*s,h=Math.cos(o)*s,u=Math.sin(a)*Math.sin(o)*s;i[n*3]=l,i[n*3+1]=h,i[n*3+2]=u}return i}function Ft(e){e=e||{},this._ssaoPass=new Re({fragment:N.source("ecgl.ssao.estimate")}),this._blurPass=new Re({fragment:N.source("ecgl.ssao.blur")}),this._framebuffer=new qe({depthBuffer:!1}),this._ssaoTexture=new K,this._blurTexture=new K,this._blurTexture2=new K,this._depthTex=e.depthTexture,this._normalTex=e.normalTexture,this.setNoiseSize(4),this.setKernelSize(e.kernelSize||12),e.radius!=null&&this.setParameter("radius",e.radius),e.power!=null&&this.setParameter("power",e.power),this._normalTex||(this._ssaoPass.material.disableTexture("normalTex"),this._blurPass.material.disableTexture("normalTex")),this._depthTex||this._blurPass.material.disableTexture("depthTex"),this._blurPass.material.setUniform("normalTex",this._normalTex),this._blurPass.material.setUniform("depthTex",this._depthTex)}Ft.prototype.setDepthTexture=function(e){this._depthTex=e};Ft.prototype.setNormalTexture=function(e){this._normalTex=e,this._ssaoPass.material[e?"enableTexture":"disableTexture"]("normalTex"),this.setKernelSize(this._kernelSize)};Ft.prototype.update=function(e,t,r){var i=e.getWidth(),n=e.getHeight(),a=this._ssaoPass,o=this._blurPass;a.setUniform("kernel",this._kernels[r%this._kernels.length]),a.setUniform("depthTex",this._depthTex),this._normalTex!=null&&a.setUniform("normalTex",this._normalTex),a.setUniform("depthTexSize",[this._depthTex.width,this._depthTex.height]);var s=new V;V.transpose(s,t.worldTransform),a.setUniform("projection",t.projectionMatrix.array),a.setUniform("projectionInv",t.invProjectionMatrix.array),a.setUniform("viewInverseTranspose",s.array);var l=this._ssaoTexture,h=this._blurTexture,u=this._blurTexture2;l.width=i/2,l.height=n/2,h.width=i,h.height=n,u.width=i,u.height=n,this._framebuffer.attach(l),this._framebuffer.bind(e),e.gl.clearColor(1,1,1,1),e.gl.clear(e.gl.COLOR_BUFFER_BIT),a.render(e),o.setUniform("textureSize",[i/2,n/2]),o.setUniform("projection",t.projectionMatrix.array),this._framebuffer.attach(h),o.setUniform("direction",0),o.setUniform("ssaoTexture",l),o.render(e),this._framebuffer.attach(u),o.setUniform("textureSize",[i,n]),o.setUniform("direction",1),o.setUniform("ssaoTexture",h),o.render(e),this._framebuffer.unbind(e);var f=e.clearColor;e.gl.clearColor(f[0],f[1],f[2],f[3])};Ft.prototype.getTargetTexture=function(){return this._blurTexture2};Ft.prototype.setParameter=function(e,t){e==="noiseTexSize"?this.setNoiseSize(t):e==="kernelSize"?this.setKernelSize(t):e==="intensity"?this._ssaoPass.material.set("intensity",t):this._ssaoPass.setUniform(e,t)};Ft.prototype.setKernelSize=function(e){this._kernelSize=e,this._ssaoPass.material.define("fragment","KERNEL_SIZE",e),this._kernels=this._kernels||[];for(var t=0;t<30;t++)this._kernels[t]=yc(e,t*e,!!this._normalTex)};Ft.prototype.setNoiseSize=function(e){var t=this._ssaoPass.getUniform("noiseTex");t?(t.data=Qs(e),t.width=t.height=e,t.dirty()):(t=Io(e),this._ssaoPass.setUniform("noiseTex",Io(e))),this._ssaoPass.setUniform("noiseTexSize",[e,e])};Ft.prototype.dispose=function(e){this._blurTexture.dispose(e),this._ssaoTexture.dispose(e),this._blurTexture2.dispose(e)};const xc= ` @ export ecgl . ssr . main
2023-04-28 16:00:04 +08:00
# define SHADER _NAME SSR
# define MAX _ITERATION 20 ;
# define SAMPLE _PER _FRAME 5 ;
# define TOTAL _SAMPLES 128 ;
uniform sampler2D sourceTexture ;
uniform sampler2D gBufferTexture1 ;
uniform sampler2D gBufferTexture2 ;
uniform sampler2D gBufferTexture3 ;
uniform samplerCube specularCubemap ;
uniform float specularIntensity : 1 ;
uniform mat4 projection ;
uniform mat4 projectionInv ;
uniform mat4 toViewSpace ;
uniform mat4 toWorldSpace ;
uniform float maxRayDistance : 200 ;
uniform float pixelStride : 16 ;
uniform float pixelStrideZCutoff : 50 ;
uniform float screenEdgeFadeStart : 0.9 ;
uniform float eyeFadeStart : 0.2 ; uniform float eyeFadeEnd : 0.8 ;
uniform float minGlossiness : 0.2 ; uniform float zThicknessThreshold : 1 ;
uniform float nearZ ;
uniform vec2 viewportSize : VIEWPORT _SIZE ;
uniform float jitterOffset : 0 ;
varying vec2 v _Texcoord ;
# ifdef DEPTH _DECODE
@ import clay . util . decode _float
# endif
# ifdef PHYSICALLY _CORRECT
uniform sampler2D normalDistribution ;
uniform float sampleOffset : 0 ;
uniform vec2 normalDistributionSize ;
vec3 transformNormal ( vec3 H , vec3 N ) {
vec3 upVector = N . y > 0.999 ? vec3 ( 1.0 , 0.0 , 0.0 ) : vec3 ( 0.0 , 1.0 , 0.0 ) ;
vec3 tangentX = normalize ( cross ( N , upVector ) ) ;
vec3 tangentZ = cross ( N , tangentX ) ;
return normalize ( tangentX * H . x + N * H . y + tangentZ * H . z ) ;
}
vec3 importanceSampleNormalGGX ( float i , float roughness , vec3 N ) {
float p = fract ( ( i + sampleOffset ) / float ( TOTAL _SAMPLES ) ) ;
vec3 H = texture2D ( normalDistribution , vec2 ( roughness , p ) ) . rgb ;
return transformNormal ( H , N ) ;
}
float G _Smith ( float g , float ndv , float ndl ) {
float roughness = 1.0 - g ;
float k = roughness * roughness / 2.0 ;
float G1V = ndv / ( ndv * ( 1.0 - k ) + k ) ;
float G1L = ndl / ( ndl * ( 1.0 - k ) + k ) ;
return G1L * G1V ;
}
vec3 F _Schlick ( float ndv , vec3 spec ) {
return spec + ( 1.0 - spec ) * pow ( 1.0 - ndv , 5.0 ) ;
}
# endif
float fetchDepth ( sampler2D depthTexture , vec2 uv )
{
vec4 depthTexel = texture2D ( depthTexture , uv ) ;
return depthTexel . r * 2.0 - 1.0 ;
}
float linearDepth ( float depth )
{
if ( projection [ 3 ] [ 3 ] == 0.0 ) {
return projection [ 3 ] [ 2 ] / ( depth * projection [ 2 ] [ 3 ] - projection [ 2 ] [ 2 ] ) ;
}
else {
return ( depth - projection [ 3 ] [ 2 ] ) / projection [ 2 ] [ 2 ] ;
}
}
bool rayIntersectDepth ( float rayZNear , float rayZFar , vec2 hitPixel )
{
if ( rayZFar > rayZNear )
{
float t = rayZFar ; rayZFar = rayZNear ; rayZNear = t ;
}
float cameraZ = linearDepth ( fetchDepth ( gBufferTexture2 , hitPixel ) ) ;
return rayZFar <= cameraZ && rayZNear >= cameraZ - zThicknessThreshold ;
}
bool traceScreenSpaceRay (
vec3 rayOrigin , vec3 rayDir , float jitter ,
out vec2 hitPixel , out vec3 hitPoint , out float iterationCount
)
{
float rayLength = ( ( rayOrigin . z + rayDir . z * maxRayDistance ) > - nearZ )
? ( - nearZ - rayOrigin . z ) / rayDir . z : maxRayDistance ;
vec3 rayEnd = rayOrigin + rayDir * rayLength ;
vec4 H0 = projection * vec4 ( rayOrigin , 1.0 ) ;
vec4 H1 = projection * vec4 ( rayEnd , 1.0 ) ;
float k0 = 1.0 / H0 . w , k1 = 1.0 / H1 . w ;
vec3 Q0 = rayOrigin * k0 , Q1 = rayEnd * k1 ;
vec2 P0 = ( H0 . xy * k0 * 0.5 + 0.5 ) * viewportSize ;
vec2 P1 = ( H1 . xy * k1 * 0.5 + 0.5 ) * viewportSize ;
P1 += dot ( P1 - P0 , P1 - P0 ) < 0.0001 ? 0.01 : 0.0 ;
vec2 delta = P1 - P0 ;
bool permute = false ;
if ( abs ( delta . x ) < abs ( delta . y ) ) {
permute = true ;
delta = delta . yx ;
P0 = P0 . yx ;
P1 = P1 . yx ;
}
float stepDir = sign ( delta . x ) ;
float invdx = stepDir / delta . x ;
vec3 dQ = ( Q1 - Q0 ) * invdx ;
float dk = ( k1 - k0 ) * invdx ;
vec2 dP = vec2 ( stepDir , delta . y * invdx ) ;
float strideScaler = 1.0 - min ( 1.0 , - rayOrigin . z / pixelStrideZCutoff ) ;
float pixStride = 1.0 + strideScaler * pixelStride ;
dP *= pixStride ; dQ *= pixStride ; dk *= pixStride ;
vec4 pqk = vec4 ( P0 , Q0 . z , k0 ) ;
vec4 dPQK = vec4 ( dP , dQ . z , dk ) ;
pqk += dPQK * jitter ;
float rayZFar = ( dPQK . z * 0.5 + pqk . z ) / ( dPQK . w * 0.5 + pqk . w ) ;
float rayZNear ;
bool intersect = false ;
vec2 texelSize = 1.0 / viewportSize ;
iterationCount = 0.0 ;
for ( int i = 0 ; i < MAX _ITERATION ; i ++ )
{
pqk += dPQK ;
rayZNear = rayZFar ;
rayZFar = ( dPQK . z * 0.5 + pqk . z ) / ( dPQK . w * 0.5 + pqk . w ) ;
hitPixel = permute ? pqk . yx : pqk . xy ;
hitPixel *= texelSize ;
intersect = rayIntersectDepth ( rayZNear , rayZFar , hitPixel ) ;
iterationCount += 1.0 ;
dPQK *= 1.2 ;
if ( intersect ) {
break ;
}
}
Q0 . xy += dQ . xy * iterationCount ;
Q0 . z = pqk . z ;
hitPoint = Q0 / pqk . w ;
return intersect ;
}
float calculateAlpha (
float iterationCount , float reflectivity ,
vec2 hitPixel , vec3 hitPoint , float dist , vec3 rayDir
)
{
float alpha = clamp ( reflectivity , 0.0 , 1.0 ) ;
alpha *= 1.0 - ( iterationCount / float ( MAX _ITERATION ) ) ;
vec2 hitPixelNDC = hitPixel * 2.0 - 1.0 ;
float maxDimension = min ( 1.0 , max ( abs ( hitPixelNDC . x ) , abs ( hitPixelNDC . y ) ) ) ;
alpha *= 1.0 - max ( 0.0 , maxDimension - screenEdgeFadeStart ) / ( 1.0 - screenEdgeFadeStart ) ;
float _eyeFadeStart = eyeFadeStart ;
float _eyeFadeEnd = eyeFadeEnd ;
if ( _eyeFadeStart > _eyeFadeEnd ) {
float tmp = _eyeFadeEnd ;
_eyeFadeEnd = _eyeFadeStart ;
_eyeFadeStart = tmp ;
}
float eyeDir = clamp ( rayDir . z , _eyeFadeStart , _eyeFadeEnd ) ;
alpha *= 1.0 - ( eyeDir - _eyeFadeStart ) / ( _eyeFadeEnd - _eyeFadeStart ) ;
alpha *= 1.0 - clamp ( dist / maxRayDistance , 0.0 , 1.0 ) ;
return alpha ;
}
@ import clay . util . rand
@ import clay . util . rgbm
void main ( )
{
vec4 normalAndGloss = texture2D ( gBufferTexture1 , v _Texcoord ) ;
if ( dot ( normalAndGloss . rgb , vec3 ( 1.0 ) ) == 0.0 ) {
discard ;
}
float g = normalAndGloss . a ;
# if ! defined ( PHYSICALLY _CORRECT )
if ( g <= minGlossiness ) {
discard ;
}
# endif
float reflectivity = ( g - minGlossiness ) / ( 1.0 - minGlossiness ) ;
vec3 N = normalize ( normalAndGloss . rgb * 2.0 - 1.0 ) ;
N = normalize ( ( toViewSpace * vec4 ( N , 0.0 ) ) . xyz ) ;
vec4 projectedPos = vec4 ( v _Texcoord * 2.0 - 1.0 , fetchDepth ( gBufferTexture2 , v _Texcoord ) , 1.0 ) ;
vec4 pos = projectionInv * projectedPos ;
vec3 rayOrigin = pos . xyz / pos . w ;
vec3 V = - normalize ( rayOrigin ) ;
float ndv = clamp ( dot ( N , V ) , 0.0 , 1.0 ) ;
float iterationCount ;
float jitter = rand ( fract ( v _Texcoord + jitterOffset ) ) ;
# ifdef PHYSICALLY _CORRECT
vec4 color = vec4 ( vec3 ( 0.0 ) , 1.0 ) ;
vec4 albedoMetalness = texture2D ( gBufferTexture3 , v _Texcoord ) ;
vec3 albedo = albedoMetalness . rgb ;
float m = albedoMetalness . a ;
vec3 diffuseColor = albedo * ( 1.0 - m ) ;
vec3 spec = mix ( vec3 ( 0.04 ) , albedo , m ) ;
float jitter2 = rand ( fract ( v _Texcoord ) ) * float ( TOTAL _SAMPLES ) ;
for ( int i = 0 ; i < SAMPLE _PER _FRAME ; i ++ ) {
vec3 H = importanceSampleNormalGGX ( float ( i ) + jitter2 , 1.0 - g , N ) ;
vec3 rayDir = normalize ( reflect ( - V , H ) ) ;
# else
vec3 rayDir = normalize ( reflect ( - V , N ) ) ;
# endif
vec2 hitPixel ;
vec3 hitPoint ;
bool intersect = traceScreenSpaceRay ( rayOrigin , rayDir , jitter , hitPixel , hitPoint , iterationCount ) ;
float dist = distance ( rayOrigin , hitPoint ) ;
vec3 hitNormal = texture2D ( gBufferTexture1 , hitPixel ) . rgb * 2.0 - 1.0 ;
hitNormal = normalize ( ( toViewSpace * vec4 ( hitNormal , 0.0 ) ) . xyz ) ;
# ifdef PHYSICALLY _CORRECT
float ndl = clamp ( dot ( N , rayDir ) , 0.0 , 1.0 ) ;
float vdh = clamp ( dot ( V , H ) , 0.0 , 1.0 ) ;
float ndh = clamp ( dot ( N , H ) , 0.0 , 1.0 ) ;
vec3 litTexel = vec3 ( 0.0 ) ;
if ( dot ( hitNormal , rayDir ) < 0.0 && intersect ) {
litTexel = texture2D ( sourceTexture , hitPixel ) . rgb ;
litTexel *= pow ( clamp ( 1.0 - dist / 200.0 , 0.0 , 1.0 ) , 3.0 ) ;
}
else {
# ifdef SPECULARCUBEMAP _ENABLED
vec3 rayDirW = normalize ( toWorldSpace * vec4 ( rayDir , 0.0 ) ) . rgb ;
litTexel = RGBMDecode ( textureCubeLodEXT ( specularCubemap , rayDirW , 0.0 ) , 8.12 ) . rgb * specularIntensity ;
# endif
}
color . rgb += ndl * litTexel * (
F _Schlick ( ndl , spec ) * G _Smith ( g , ndv , ndl ) * vdh / ( ndh * ndv + 0.001 )
) ;
}
color . rgb /= float ( SAMPLE _PER _FRAME ) ;
# else
# if ! defined ( SPECULARCUBEMAP _ENABLED )
if ( dot ( hitNormal , rayDir ) >= 0.0 ) {
discard ;
}
if ( ! intersect ) {
discard ;
}
# endif
float alpha = clamp ( calculateAlpha ( iterationCount , reflectivity , hitPixel , hitPoint , dist , rayDir ) , 0.0 , 1.0 ) ;
vec4 color = texture2D ( sourceTexture , hitPixel ) ;
color . rgb *= alpha ;
# ifdef SPECULARCUBEMAP _ENABLED
vec3 rayDirW = normalize ( toWorldSpace * vec4 ( rayDir , 0.0 ) ) . rgb ;
alpha = alpha * ( intersect ? 1.0 : 0.0 ) ;
float bias = ( 1.0 - g ) * 5.0 ;
color . rgb += ( 1.0 - alpha )
* RGBMDecode ( textureCubeLodEXT ( specularCubemap , rayDirW , bias ) , 8.12 ) . rgb
* specularIntensity ;
# endif
# endif
gl _FragColor = encodeHDR ( color ) ;
}
@ end
@ export ecgl . ssr . blur
uniform sampler2D texture ;
uniform sampler2D gBufferTexture1 ;
uniform sampler2D gBufferTexture2 ;
uniform mat4 projection ;
uniform float depthRange : 0.05 ;
varying vec2 v _Texcoord ;
uniform vec2 textureSize ;
uniform float blurSize : 1.0 ;
# ifdef BLEND
# ifdef SSAOTEX _ENABLED
uniform sampler2D ssaoTex ;
# endif
uniform sampler2D sourceTexture ;
# endif
float getLinearDepth ( vec2 coord )
{
float depth = texture2D ( gBufferTexture2 , coord ) . r * 2.0 - 1.0 ;
return projection [ 3 ] [ 2 ] / ( depth * projection [ 2 ] [ 3 ] - projection [ 2 ] [ 2 ] ) ;
}
@ import clay . util . rgbm
void main ( )
{
@ import clay . compositor . kernel . gaussian _9
vec4 centerNTexel = texture2D ( gBufferTexture1 , v _Texcoord ) ;
float g = centerNTexel . a ;
float maxBlurSize = clamp ( 1.0 - g , 0.0 , 1.0 ) * blurSize ;
# ifdef VERTICAL
vec2 off = vec2 ( 0.0 , maxBlurSize / textureSize . y ) ;
# else
vec2 off = vec2 ( maxBlurSize / textureSize . x , 0.0 ) ;
# endif
vec2 coord = v _Texcoord ;
vec4 sum = vec4 ( 0.0 ) ;
float weightAll = 0.0 ;
vec3 cN = centerNTexel . rgb * 2.0 - 1.0 ;
float cD = getLinearDepth ( v _Texcoord ) ;
for ( int i = 0 ; i < 9 ; i ++ ) {
vec2 coord = clamp ( ( float ( i ) - 4.0 ) * off + v _Texcoord , vec2 ( 0.0 ) , vec2 ( 1.0 ) ) ;
float w = gaussianKernel [ i ]
* clamp ( dot ( cN , texture2D ( gBufferTexture1 , coord ) . rgb * 2.0 - 1.0 ) , 0.0 , 1.0 ) ;
float d = getLinearDepth ( coord ) ;
w *= ( 1.0 - smoothstep ( abs ( cD - d ) / depthRange , 0.0 , 1.0 ) ) ;
weightAll += w ;
sum += decodeHDR ( texture2D ( texture , coord ) ) * w ;
}
# ifdef BLEND
float aoFactor = 1.0 ;
# ifdef SSAOTEX _ENABLED
aoFactor = texture2D ( ssaoTex , v _Texcoord ) . r ;
# endif
gl _FragColor = encodeHDR (
sum / weightAll * aoFactor + decodeHDR ( texture2D ( sourceTexture , v _Texcoord ) )
) ;
# else
gl _FragColor = encodeHDR ( sum / weightAll ) ;
# endif
}
2023-09-11 21:56:39 +08:00
@ end ` ;N.import(xc);function Ut(e){e=e||{},this._ssrPass=new Re({fragment:N.source("ecgl.ssr.main"),clearColor:[0,0,0,0]}),this._blurPass1=new Re({fragment:N.source("ecgl.ssr.blur"),clearColor:[0,0,0,0]}),this._blurPass2=new Re({fragment:N.source("ecgl.ssr.blur"),clearColor:[0,0,0,0]}),this._blendPass=new Re({fragment:N.source("clay.compositor.blend")}),this._blendPass.material.disableTexturesAll(),this._blendPass.material.enableTexture(["texture1","texture2"]),this._ssrPass.setUniform("gBufferTexture1",e.normalTexture),this._ssrPass.setUniform("gBufferTexture2",e.depthTexture),this._blurPass1.setUniform("gBufferTexture1",e.normalTexture),this._blurPass1.setUniform("gBufferTexture2",e.depthTexture),this._blurPass2.setUniform("gBufferTexture1",e.normalTexture),this._blurPass2.setUniform("gBufferTexture2",e.depthTexture),this._blurPass2.material.define("fragment","VERTICAL"),this._blurPass2.material.define("fragment","BLEND"),this._ssrTexture=new K({type:W.HALF_FLOAT}),this._texture2=new K({type:W.HALF_FLOAT}),this._texture3=new K({type:W.HALF_FLOAT}),this._prevTexture=new K({type:W.HALF_FLOAT}),this._currentTexture=new K({type:W.HALF_FLOAT}),this._frameBuffer=new qe({depthBuffer:!1}),this._normalDistribution=null,this._totalSamples=256,this._samplePerFrame=4,this._ssrPass.material.define("fragment","SAMPLE_PER_FRAME",this._samplePerFrame),this._ssrPass.material.define("fragment","TOTAL_SAMPLES",this._totalSamples),this._downScale=1}Ut.prototype.setAmbientCubemap=function(e,t){this._ssrPass.material.set("specularCubemap",e),this._ssrPass.material.set("specularIntensity",t);var r=e&&t;this._ssrPass.material[r?"enableTexture":"disableTexture"]("specularCubemap")};Ut.prototype.update=function(e,t,r,i){var n=e.getWidth(),a=e.getHeight(),o=this._ssrTexture,s=this._texture2,l=this._texture3;o.width=this._prevTexture.width=this._currentTexture.width=n/this._downScale,o.height=this._prevTexture.height=this._currentTexture.height=a/this._downScale,s.width=l.width=n,s.height=l.height=a;var h=this._frameBuffer,u=this._ssrPass,f=this._blurPass1,d=this._blurPass2,c=this._blendPass,v=new V,p=new V;V.transpose(v,t.worldTransform),V.transpose(p,t.viewMatrix),u.setUniform("sourceTexture",r),u.setUniform("projection",t.projectionMatrix.array),u.setUniform("projectionInv",t.invProjectionMatrix.array),u.setUniform("toViewSpace",v.array),u.setUniform("toWorldSpace",p.array),u.setUniform("nearZ",t.near);var m=i/this._totalSamples*this._samplePerFrame;if(u.setUniform("jitterOffset",m),u.setUniform("sampleOffset",i*this._samplePerFrame),f.setUniform("textureSize",[o.width,o.height]),d.setUniform("textureSize",[n,a]),d.setUniform("sourceTexture",r),f.setUniform("projection",t.projectionMatrix.array),d.setUniform("projection",t.projectionMatrix.array),h.attach(o),h.bind(e),u.render(e),this._physicallyCorrect&&(h.attach(this._currentTexture),c.setUniform("texture1",this._prevTexture),c.setUniform("texture2",o),c.material.set({weight1:i>=1?.95:0,weight2:i>=1?.05:1}),c.render(e)),h.attach(s),f.setUniform("texture",this._physicallyCorrect?this._currentTexture:o),f.render(e),h.attach(l),d.setUniform("texture",s),d.render(e),h.unbind(e),this._physicallyCorrect){var _=this._prevTexture;this._prevTexture=this._currentTexture,this._currentTexture=_}};Ut.prototype.getTargetTexture=function(){return this._texture3};Ut.prototype.setParameter=function(e,t){e==="maxIteration"?this._ssrPass.material.define("fragment","MAX_ITERATION",t):this._ssrPass.setUniform(e,t)};Ut.prototype.setPhysicallyCorrect=function(e){e?(this._normalDistribution||(this._normalDistribution= $ i.generateNormalDistribution(64,this._totalSamples)),this._ssrPass.material.define("fragment","PHYSICALLY_CORRECT"),this._ssrPass.material.set("normalDistribution",this._normalDistribution),this._ssrPass.material.set("normalDistributionSize",[64,this._totalSamples])):this._ssrPass.material.undefine("fragment","PHYSICALLY_CORRECT"),this._physicallyCorrect=e};Ut.prototype.setSSAOTexture=function(e){var t=this._blurPass2;e?(t.material.enableTexture("ssaoTex"),t.material.set("ssaoTex",e)):t.material.disab
2023-04-28 16:00:04 +08:00
@ import ecgl . common . transformUniforms
@ import ecgl . common . uv . header
@ import ecgl . common . attributes
varying vec3 v _Normal ;
varying vec3 v _WorldPosition ;
@ import ecgl . common . normalMap . vertexHeader
@ import ecgl . common . vertexAnimation . header
void main ( )
{
@ import ecgl . common . vertexAnimation . main
@ import ecgl . common . uv . main
v _Normal = normalize ( ( worldInverseTranspose * vec4 ( normal , 0.0 ) ) . xyz ) ;
v _WorldPosition = ( world * vec4 ( pos , 1.0 ) ) . xyz ;
@ import ecgl . common . normalMap . vertexMain
gl _Position = worldViewProjection * vec4 ( pos , 1.0 ) ;
}
@ end
@ export ecgl . normal . fragment
# define ROUGHNESS _CHANEL 0
uniform bool useBumpMap ;
uniform bool useRoughnessMap ;
uniform bool doubleSide ;
uniform float roughness ;
@ import ecgl . common . uv . fragmentHeader
varying vec3 v _Normal ;
varying vec3 v _WorldPosition ;
uniform mat4 viewInverse : VIEWINVERSE ;
@ import ecgl . common . normalMap . fragmentHeader
@ import ecgl . common . bumpMap . header
uniform sampler2D roughnessMap ;
void main ( )
{
vec3 N = v _Normal ;
bool flipNormal = false ;
if ( doubleSide ) {
vec3 eyePos = viewInverse [ 3 ] . xyz ;
vec3 V = normalize ( eyePos - v _WorldPosition ) ;
if ( dot ( N , V ) < 0.0 ) {
flipNormal = true ;
}
}
@ import ecgl . common . normalMap . fragmentMain
if ( useBumpMap ) {
N = bumpNormal ( v _WorldPosition , v _Normal , N ) ;
}
float g = 1.0 - roughness ;
if ( useRoughnessMap ) {
float g2 = 1.0 - texture2D ( roughnessMap , v _DetailTexcoord ) [ ROUGHNESS _CHANEL ] ;
g = clamp ( g2 + ( g - 0.5 ) * 2.0 , 0.0 , 1.0 ) ;
}
if ( flipNormal ) {
N = - N ;
}
gl _FragColor . rgb = ( N . xyz + 1.0 ) * 0.5 ;
gl _FragColor . a = g ;
}
2023-09-11 21:56:39 +08:00
@ end ` ;N.import(Tc);function Zn(e,t,r,i,n){var a=e.gl;t.setUniform(a,"1i",r,n),a.activeTexture(a.TEXTURE0+n),i.isRenderable()?i.bind(e):i.unbind(e)}function wc(e,t,r,i,n){var a,o,s,l,h=e.gl;return function(u,f,d){if(!(l&&l.material===u.material)){var c=u.material,v=u.__program,p=c.get("roughness");p==null&&(p=1);var m=c.get("normalMap")||t,_=c.get("roughnessMap"),x=c.get("bumpMap"),y=c.get("uvRepeat"),g=c.get("uvOffset"),w=c.get("detailUvRepeat"),S=c.get("detailUvOffset"),b=!!x&&c.isTextureEnabled("bumpMap"),E=!!_&&c.isTextureEnabled("roughnessMap"),L=c.isDefined("fragment","DOUBLE_SIDED");x=x||r,_=_||i,d!==f?(f.set("normalMap",m),f.set("bumpMap",x),f.set("roughnessMap",_),f.set("useBumpMap",b),f.set("useRoughnessMap",E),f.set("doubleSide",L),y!=null&&f.set("uvRepeat",y),g!=null&&f.set("uvOffset",g),w!=null&&f.set("detailUvRepeat",w),S!=null&&f.set("detailUvOffset",S),f.set("roughness",p)):(v.setUniform(h,"1f","roughness",p),a!==m&&Zn(e,v,"normalMap",m,0),o!==x&&x&&Zn(e,v,"bumpMap",x,1),s!==_&&_&&Zn(e,v,"roughnessMap",_,2),y!=null&&v.setUniform(h,"2f","uvRepeat",y),g!=null&&v.setUniform(h,"2f","uvOffset",g),w!=null&&v.setUniform(h,"2f","detailUvRepeat",w),S!=null&&v.setUniform(h,"2f","detailUvOffset",S),v.setUniform(h,"1i","useBumpMap",+b),v.setUniform(h,"1i","useRoughnessMap",+E),v.setUniform(h,"1i","doubleSide",+L)),a=m,o=x,s=_,l=u}}}function Xr(e){this._depthTex=new K({format:W.DEPTH_COMPONENT,type:W.UNSIGNED_INT}),this._normalTex=new K({type:W.HALF_FLOAT}),this._framebuffer=new qe,this._framebuffer.attach(this._normalTex),this._framebuffer.attach(this._depthTex,qe.DEPTH_ATTACHMENT),this._normalMaterial=new _t({shader:new N(N.source("ecgl.normal.vertex"),N.source("ecgl.normal.fragment"))}),this._normalMaterial.enableTexture(["normalMap","bumpMap","roughnessMap"]),this._defaultNormalMap=fr.createBlank("#000"),this._defaultBumpMap=fr.createBlank("#000"),this._defaultRoughessMap=fr.createBlank("#000"),this._debugPass=new Re({fragment:N.source("clay.compositor.output")}),this._debugPass.setUniform("texture",this._normalTex),this._debugPass.material.undefine("fragment","OUTPUT_ALPHA")}Xr.prototype.getDepthTexture=function(){return this._depthTex};Xr.prototype.getNormalTexture=function(){return this._normalTex};Xr.prototype.update=function(e,t,r){var i=e.getWidth(),n=e.getHeight(),a=this._depthTex,o=this._normalTex,s=this._normalMaterial;a.width=i,a.height=n,o.width=i,o.height=n;var l=t.getRenderList(r).opaque;this._framebuffer.bind(e),e.gl.clearColor(0,0,0,0),e.gl.clear(e.gl.COLOR_BUFFER_BIT|e.gl.DEPTH_BUFFER_BIT),e.gl.disable(e.gl.BLEND),e.renderPass(l,r,{getMaterial:function(){return s},ifRender:function(h){return h.renderNormal},beforeRender:wc(e,this._defaultNormalMap,this._defaultBumpMap,this._defaultRoughessMap,this._normalMaterial),sort:e.opaqueSortCompare}),this._framebuffer.unbind(e)};Xr.prototype.renderDebug=function(e){this._debugPass.render(e)};Xr.prototype.dispose=function(e){this._depthTex.dispose(e),this._normalTex.dispose(e)};function Li(e){e=e||{},this._edgePass=new Re({fragment:N.source("ecgl.edge")}),this._edgePass.setUniform("normalTexture",e.normalTexture),this._edgePass.setUniform("depthTexture",e.depthTexture),this._targetTexture=new K({type:W.HALF_FLOAT}),this._frameBuffer=new qe,this._frameBuffer.attach(this._targetTexture)}Li.prototype.update=function(e,t,r,i){var n=e.getWidth(),a=e.getHeight(),o=this._targetTexture;o.width=n,o.height=a;var s=this._frameBuffer;s.bind(e),this._edgePass.setUniform("projectionInv",t.invProjectionMatrix.array),this._edgePass.setUniform("textureSize",[n,a]),this._edgePass.setUniform("texture",r),this._edgePass.render(e),s.unbind(e)};Li.prototype.getTargetTexture=function(){return this._targetTexture};Li.prototype.setParameter=function(e,t){this._edgePass.setUniform(e,t)};Li.prototype.dispose=function(e){this._targetTexture.dispose(e),this._frameBuffer.dispose(e)};const Sc={type:"compositor",nodes:[{name:"source",type:"texture",outputs:{color:{}}},{name:"source_half",shader:"#source(clay.compositor.downsample)",inputs:{texture:"source"},outputs:{color:{parameters:{width
2023-04-28 16:00:04 +08:00
uniform sampler2D depth ;
uniform float zNear : 0.1 ;
uniform float zFar : 2000 ;
uniform float focalDistance : 3 ;
uniform float focalRange : 1 ;
uniform float focalLength : 30 ;
uniform float fstop : 2.8 ;
varying vec2 v _Texcoord ;
@ import clay . util . encode _float
void main ( )
{
float z = texture2D ( depth , v _Texcoord ) . r * 2.0 - 1.0 ;
float dist = 2.0 * zNear * zFar / ( zFar + zNear - z * ( zFar - zNear ) ) ;
float aperture = focalLength / fstop ;
float coc ;
float uppper = focalDistance + focalRange ;
float lower = focalDistance - focalRange ;
if ( dist <= uppper && dist >= lower ) {
coc = 0.5 ;
}
else {
float focalAdjusted = dist > uppper ? uppper : lower ;
coc = abs ( aperture * ( focalLength * ( dist - focalAdjusted ) ) / ( dist * ( focalAdjusted - focalLength ) ) ) ;
coc = clamp ( coc , 0.0 , 2.0 ) / 2.00001 ;
if ( dist < lower ) {
coc = - coc ;
}
coc = coc * 0.5 + 0.5 ;
}
gl _FragColor = encodeFloat ( coc ) ;
}
@ end
@ export ecgl . dof . composite
# define DEBUG 0
uniform sampler2D original ;
uniform sampler2D blurred ;
uniform sampler2D nearfield ;
uniform sampler2D coc ;
uniform sampler2D nearcoc ;
varying vec2 v _Texcoord ;
@ import clay . util . rgbm
@ import clay . util . float
void main ( )
{
vec4 blurredColor = texture2D ( blurred , v _Texcoord ) ;
vec4 originalColor = texture2D ( original , v _Texcoord ) ;
float fCoc = decodeFloat ( texture2D ( coc , v _Texcoord ) ) ;
fCoc = abs ( fCoc * 2.0 - 1.0 ) ;
float weight = smoothstep ( 0.0 , 1.0 , fCoc ) ;
# ifdef NEARFIELD _ENABLED
vec4 nearfieldColor = texture2D ( nearfield , v _Texcoord ) ;
float fNearCoc = decodeFloat ( texture2D ( nearcoc , v _Texcoord ) ) ;
fNearCoc = abs ( fNearCoc * 2.0 - 1.0 ) ;
gl _FragColor = encodeHDR (
mix (
nearfieldColor , mix ( originalColor , blurredColor , weight ) ,
pow ( 1.0 - fNearCoc , 4.0 )
)
) ;
# else
gl _FragColor = encodeHDR ( mix ( originalColor , blurredColor , weight ) ) ;
# endif
}
@ end
@ export ecgl . dof . diskBlur
# define POISSON _KERNEL _SIZE 16 ;
uniform sampler2D texture ;
uniform sampler2D coc ;
varying vec2 v _Texcoord ;
uniform float blurRadius : 10.0 ;
uniform vec2 textureSize : [ 512.0 , 512.0 ] ;
uniform vec2 poissonKernel [ POISSON _KERNEL _SIZE ] ;
uniform float percent ;
float nrand ( const in vec2 n ) {
return fract ( sin ( dot ( n . xy , vec2 ( 12.9898 , 78.233 ) ) ) * 43758.5453 ) ;
}
@ import clay . util . rgbm
@ import clay . util . float
void main ( )
{
vec2 offset = blurRadius / textureSize ;
float rnd = 6.28318 * nrand ( v _Texcoord + 0.07 * percent ) ;
float cosa = cos ( rnd ) ;
float sina = sin ( rnd ) ;
vec4 basis = vec4 ( cosa , - sina , sina , cosa ) ;
# if ! defined ( BLUR _NEARFIELD ) && ! defined ( BLUR _COC )
offset *= abs ( decodeFloat ( texture2D ( coc , v _Texcoord ) ) * 2.0 - 1.0 ) ;
# endif
# ifdef BLUR _COC
float cocSum = 0.0 ;
# else
vec4 color = vec4 ( 0.0 ) ;
# endif
float weightSum = 0.0 ;
for ( int i = 0 ; i < POISSON _KERNEL _SIZE ; i ++ ) {
vec2 ofs = poissonKernel [ i ] ;
ofs = vec2 ( dot ( ofs , basis . xy ) , dot ( ofs , basis . zw ) ) ;
vec2 uv = v _Texcoord + ofs * offset ;
vec4 texel = texture2D ( texture , uv ) ;
float w = 1.0 ;
# ifdef BLUR _COC
float fCoc = decodeFloat ( texel ) * 2.0 - 1.0 ;
cocSum += clamp ( fCoc , - 1.0 , 0.0 ) * w ;
# else
texel = texel ;
# if ! defined ( BLUR _NEARFIELD )
float fCoc = decodeFloat ( texture2D ( coc , uv ) ) * 2.0 - 1.0 ;
w *= abs ( fCoc ) ;
# endif
texel . rgb *= texel . a ;
color += texel * w ;
# endif
weightSum += w ;
}
# ifdef BLUR _COC
gl _FragColor = encodeFloat ( clamp ( cocSum / weightSum , - 1.0 , 0.0 ) * 0.5 + 0.5 ) ;
# else
color /= weightSum ;
color . rgb /= ( color . a + 0.0001 ) ;
gl _FragColor = color ;
# endif
}
2023-07-09 20:38:38 +08:00
@ end ` ,Ac= ` @ export ecgl . edge
2023-04-28 16:00:04 +08:00
uniform sampler2D texture ;
uniform sampler2D normalTexture ;
uniform sampler2D depthTexture ;
uniform mat4 projectionInv ;
uniform vec2 textureSize ;
uniform vec4 edgeColor : [ 0 , 0 , 0 , 0.8 ] ;
varying vec2 v _Texcoord ;
vec3 packColor ( vec2 coord ) {
float z = texture2D ( depthTexture , coord ) . r * 2.0 - 1.0 ;
vec4 p = vec4 ( v _Texcoord * 2.0 - 1.0 , z , 1.0 ) ;
vec4 p4 = projectionInv * p ;
return vec3 (
texture2D ( normalTexture , coord ) . rg ,
- p4 . z / p4 . w / 5.0
) ;
}
void main ( ) {
vec2 cc = v _Texcoord ;
vec3 center = packColor ( cc ) ;
float size = clamp ( 1.0 - ( center . z - 10.0 ) / 100.0 , 0.0 , 1.0 ) * 0.5 ;
float dx = size / textureSize . x ;
float dy = size / textureSize . y ;
vec2 coord ;
vec3 topLeft = packColor ( cc + vec2 ( - dx , - dy ) ) ;
vec3 top = packColor ( cc + vec2 ( 0.0 , - dy ) ) ;
vec3 topRight = packColor ( cc + vec2 ( dx , - dy ) ) ;
vec3 left = packColor ( cc + vec2 ( - dx , 0.0 ) ) ;
vec3 right = packColor ( cc + vec2 ( dx , 0.0 ) ) ;
vec3 bottomLeft = packColor ( cc + vec2 ( - dx , dy ) ) ;
vec3 bottom = packColor ( cc + vec2 ( 0.0 , dy ) ) ;
vec3 bottomRight = packColor ( cc + vec2 ( dx , dy ) ) ;
vec3 v = - topLeft - 2.0 * top - topRight + bottomLeft + 2.0 * bottom + bottomRight ;
vec3 h = - bottomLeft - 2.0 * left - topLeft + bottomRight + 2.0 * right + topRight ;
float edge = sqrt ( dot ( h , h ) + dot ( v , v ) ) ;
edge = smoothstep ( 0.8 , 1.0 , edge ) ;
gl _FragColor = mix ( texture2D ( texture , v _Texcoord ) , vec4 ( edgeColor . rgb , 1.0 ) , edgeColor . a * edge ) ;
}
2023-09-11 21:56:39 +08:00
@ end ` ;N.import(Vs);N.import(ks);N.import(Ws);N.import(Xs);N.import(Zs);N.import(js);N.import(qs);N.import(Ys);N.import( $ s);N.import(Ec);N.import(Ac);function Js(e,t){return{color:{parameters:{width:e,height:t}}}}var Da=["composite","FXAA"];function re(){this._width,this._height,this._dpr,this._sourceTexture=new K({type:W.HALF_FLOAT}),this._depthTexture=new K({format:W.DEPTH_COMPONENT,type:W.UNSIGNED_INT}),this._framebuffer=new qe,this._framebuffer.attach(this._sourceTexture),this._framebuffer.attach(this._depthTexture,qe.DEPTH_ATTACHMENT),this._normalPass=new Xr,this._compositor=fc(Sc);var e=this._compositor.getNodeByName("source");e.texture=this._sourceTexture;var t=this._compositor.getNodeByName("coc");this._sourceNode=e,this._cocNode=t,this._compositeNode=this._compositor.getNodeByName("composite"),this._fxaaNode=this._compositor.getNodeByName("FXAA"),this._dofBlurNodes=["dof_far_blur","dof_near_blur","dof_coc_blur"].map(function(i){return this._compositor.getNodeByName(i)},this),this._dofBlurKernel=0,this._dofBlurKernelSize=new Float32Array(0),this._finalNodesChain=Da.map(function(i){return this._compositor.getNodeByName(i)},this);var r={normalTexture:this._normalPass.getNormalTexture(),depthTexture:this._normalPass.getDepthTexture()};this._ssaoPass=new Ft(r),this._ssrPass=new Ut(r),this._edgePass=new Li(r)}re.prototype.resize=function(i,n,r){r=r||1;var i=i*r,n=n*r,a=this._sourceTexture,o=this._depthTexture;a.width=i,a.height=n,o.width=i,o.height=n;var s={getWidth:function(){return i},getHeight:function(){return n},getDevicePixelRatio:function(){return r}};function l(h,u){if(typeof h[u]=="function"){var f=h[u].__original||h[u];h[u]=function(d){return f.call(this,s)},h[u].__original=f}}this._compositor.nodes.forEach(function(h){for(var u in h.outputs){var f=h.outputs[u].parameters;f&&(l(f,"width"),l(f,"height"))}for(var d in h.parameters)l(h.parameters,d)}),this._width=i,this._height=n,this._dpr=r};re.prototype.getWidth=function(){return this._width};re.prototype.getHeight=function(){return this._height};re.prototype._ifRenderNormalPass=function(){return this._enableSSAO||this._enableEdge||this._enableSSR};re.prototype._getPrevNode=function(e){for(var t=Da.indexOf(e.name)-1,r=this._finalNodesChain[t];r&&!this._compositor.getNodeByName(r.name);)t-=1,r=this._finalNodesChain[t];return r};re.prototype._getNextNode=function(e){for(var t=Da.indexOf(e.name)+1,r=this._finalNodesChain[t];r&&!this._compositor.getNodeByName(r.name);)t+=1,r=this._finalNodesChain[t];return r};re.prototype._addChainNode=function(e){var t=this._getPrevNode(e),r=this._getNextNode(e);!t||(e.inputs.texture=t.name,r?(e.outputs=Js(this.getWidth.bind(this),this.getHeight.bind(this)),r.inputs.texture=e.name):e.outputs=null,this._compositor.addNode(e))};re.prototype._removeChainNode=function(e){var t=this._getPrevNode(e),r=this._getNextNode(e);!t||(r?(t.outputs=Js(this.getWidth.bind(this),this.getHeight.bind(this)),r.inputs.texture=t.name):t.outputs=null,this._compositor.removeNode(e))};re.prototype.updateNormal=function(e,t,r,i){this._ifRenderNormalPass()&&this._normalPass.update(e,t,r)};re.prototype.updateSSAO=function(e,t,r,i){this._ssaoPass.update(e,r,i)};re.prototype.enableSSAO=function(){this._enableSSAO=!0};re.prototype.disableSSAO=function(){this._enableSSAO=!1};re.prototype.enableSSR=function(){this._enableSSR=!0};re.prototype.disableSSR=function(){this._enableSSR=!1};re.prototype.getSSAOTexture=function(){return this._ssaoPass.getTargetTexture()};re.prototype.getSourceFrameBuffer=function(){return this._framebuffer};re.prototype.getSourceTexture=function(){return this._sourceTexture};re.prototype.disableFXAA=function(){this._removeChainNode(this._fxaaNode)};re.prototype.enableFXAA=function(){this._addChainNode(this._fxaaNode)};re.prototype.enableBloom=function(){this._compositeNode.inputs.bloom="bloom_composite",this._compositor.dirty()};re.prototype.disableBloom=function(){this._compositeNode.inputs.bloom=null,this._compositor.dirty()};re.prototype.enableDOF=function(){this._compositeNode.inputs.texture="dof_composite",this._compositor.dirty()};
` +h}t=t||{},r=r||{};for(var n=this.regions,a={},o=0;o<n.length;o++){var s=n[o].name;s=r[s]||s,n[o].name=s,a[s]=n[o],this.addGeoCoord(s,n[o].getCenter());var l=t[s];l&&n[o].transformTo(l.left,l.top,l.width,l.height)}this._regionsMap=a,this._geoRect=null,ad.forEach(function(h){h(this)},this)},getGeoBoundingRect:function(){if(this._geoRect)return this._geoRect;for(var e,t=this.regions,r=0;r<t.length;r++){var i=t[r].getBoundingRect();e=e||i.clone(),e.union(i)}return this._geoRect=e||new Jl(0,0,0,0)},addGeoCoord:function(e,t){this._nameCoordMap[e]=t},getRegion:function(e){return this._regionsMap[e]},getRegionByCoord:function(e){for(var t=this.regions,r=0;r<t.length;r++)if(t[r].contain(e))return t[r]},setSize:function(e,t,r){this.size=[e,t,r];var i=this.getGeoBoundingRect(),n=e/i.width,a=-r/i.height,o=-e/2-i.x*n,s=r/2-i.y*a,l=this.extrudeY?[o,0,s]:[o,s,0],h=this.extrudeY?[n,1,a]:[n,a,1],u=this.transform;Dr.identity(u),Dr.translate(u,u,l),Dr.scale(u,u,h),Dr.invert(this.invTransform,u)},dataToPoint:function(e,t){t=t||[];var r=this.extrudeY?1:2,i=this.extrudeY?2:1,n=e[2];return isNaN(n)&&(n=0),t[0]=e[0],t[i]=e[1],this.altitudeAxis?t[r]=this.altitudeAxis.dataToCoord(n):t[r]=0,t[r]+=this.regionHeight,nd.transformMat4(t,t,this.transform),t},pointToData:function(e,t){}};function od(e,t){var r=e.getBoxLayoutParams(),i=dn(r,{width:t.getWidth(),height:t.getHeight()});i.y=t.getHeight()-i.y-i.height,this.viewGL.setViewport(i.x,i.y,i.width,i.height,t.getDevicePixelRatio());var n=this.getGeoBoundingRect(),a=n.width/n.height*(e.get("aspectScale")||.75),o=e.get("boxWidth"),s=e.get("boxDepth"),l=e.get("boxHeight");l==null&&(l=5),isNaN(o)&&isNaN(s)&&(o=100),isNaN(s)?s=o/a:isNaN(o)&&(o=s/a),this.setSize(o,l,s),this.regionHeight=e.get("regionHeight"),this.altitudeAxis&&this.altitudeAxis.setExtent(0,Math.max(l-this.regionHeight,0))}function sd(e,t){var r=[1/0,-1/0];if(e.eachSeries(function(n){if(n.coordinateSystem===this&&n.type!=="series.map3D"){var a=n.getData(),o=n.coordDimToDataDim("alt"),s=o&&o[0];if(s){var l=a.getDataExtent(s,!0);r[0]=Math.min(r[0],l[0]),r[1]=Math.max(r[1],l[1])}}},this),r&&isFinite(r[1]-r[0])){var i=ga(r,{type:"value",min:"dataMin",max:"dataMax"});this.altitudeAxis=new cn("altitude",i),this.resize(this.model,t)}}var Ho=0,fl={dimensions:hn.prototype.dimensions,create:function(e,t){var r=[];if(!ea)throw new Error("geo3D component depends on geo component");function i(n,a){var o=fl.createGeo3D(n);n.__viewGL=n.__viewGL||new ce,o.viewGL=n.__viewGL,n.coordinateSystem=o,o.model=n,r.push(o),o.resize=od,o.resize(n,t),o.update=sd}return e.eachComponent("geo3D",function(n,a){i(n)}),e.eachSeriesByType("map3D",function(n,a){var o=n.get("coordinateSystem");o==null&&(o="geo3D"),o==="geo3D"&&i(n)}),e.eachSeries(function(n){if(n.get("coordinateSystem")==="geo3D"){if(n.type==="series.map3D")return;var a=n.getReferringComponents("geo3D").models[0];if(a||(a=e.getComponent("geo3D")),!a)throw new Error('geo "'+J.firstNotNull(n.get("geo3DIndex"),n.get("geo3DId"),0)+'" not found');n.coordinateSystem=a.coordinateSystem}}),r},createGeo3D:function(e){var t=e.get("map"),r;return typeof t=="string"?(r=t,t=ea(t)):t&&t.features&&(t={geoJson:t}),r==null&&(r="GEO_ANONYMOUS_"+Ho++),new hn(r+Ho++,r,t&&t.geoJson,t&&t.specialAreas,e.get("nameMap"))}};const cl=fl;function dl(e){e.registerComponentModel(Uc),e.registerComponentView(td),e.registerAction({type:"geo3DChangeCamera",event:"geo3dcamerachanged",update:"series:updateCamera"},function(t,r){r.eachComponent({mainType:"geo3D",query:t},function(i){i.setView(t)})}),e.registerCoordinateSystem("geo3D",cl)}Ye(dl);function Vo(e,t){e.id=e.id||e.name||t+""}var dr=Hr.extend({type:"globe",layoutMode:"box",coordinateSystem:null,init:function(){dr.superApply(this,"init",arguments),Dt(this.option.layers,function(e,t){fe(e,this.defaultLayerOption),Vo(e,t)},this)},mergeOption:function(e){var t=this.option.layers;this.option.layers=null,dr.superApply(this,"mergeOption",arguments);function r(o){return th(o,function(s,l,h){return Vo(l,h),s[l.id]=l,s},{})}if(t&&t.length){var i=r(e.layers),n=r(t);for(var a in i)n[a]?fe(n[a],i[
2023-04-28 16:00:04 +08:00
attribute vec3 position : POSITION ;
attribute vec3 normal : NORMAL ;
uniform mat4 worldViewProjection : WORLDVIEWPROJECTION ;
uniform mat4 normalMatrix : WORLDINVERSETRANSPOSE ;
varying vec3 v _Normal ;
void main ( ) {
v _Normal = normalize ( ( normalMatrix * vec4 ( normal , 0.0 ) ) . xyz ) ;
gl _Position = worldViewProjection * vec4 ( position , 1.0 ) ;
}
@ end
@ export ecgl . atmosphere . fragment
uniform mat4 viewTranspose : VIEWTRANSPOSE ;
uniform float glowPower ;
uniform vec3 glowColor ;
varying vec3 v _Normal ;
void main ( ) {
float intensity = pow ( 1.0 - dot ( v _Normal , ( viewTranspose * vec4 ( 0.0 , 0.0 , 1.0 , 0.0 ) ) . xyz ) , glowPower ) ;
gl _FragColor = vec4 ( glowColor , intensity * intensity ) ;
}
2023-09-11 21:56:39 +08:00
@ end ` ;T.Shader.import(Ps);T.Shader.import(Sd);const Ed=Si.extend({type:"globe",__ecgl__:!0,_displacementScale:0,init:function(e,t){this.groupGL=new T.Node,this._sphereGeometry=new T.SphereGeometry({widthSegments:200,heightSegments:100,dynamic:!0}),this._overlayGeometry=new T.SphereGeometry({widthSegments:80,heightSegments:40}),this._planeGeometry=new T.PlaneGeometry,this._earthMesh=new T.Mesh({renderNormal:!0}),this._atmosphereMesh=new T.Mesh,this._atmosphereGeometry=new T.SphereGeometry({widthSegments:80,heightSegments:40}),this._atmosphereMaterial=new T.Material({shader:new T.Shader(T.Shader.source("ecgl.atmosphere.vertex"),T.Shader.source("ecgl.atmosphere.fragment")),transparent:!0}),this._atmosphereMesh.geometry=this._atmosphereGeometry,this._atmosphereMesh.material=this._atmosphereMaterial,this._atmosphereMesh.frontFace=T.Mesh.CW,this._lightRoot=new T.Node,this._sceneHelper=new Yt,this._sceneHelper.initLight(this._lightRoot),this.groupGL.add(this._atmosphereMesh),this.groupGL.add(this._earthMesh),this._control=new xn({zr:t.getZr()}),this._control.init(),this._layerMeshes={}},render:function(e,t,r){var i=e.coordinateSystem,n=e.get("shading");i.viewGL.add(this._lightRoot),e.get("show")?i.viewGL.add(this.groupGL):i.viewGL.remove(this.groupGL),this._sceneHelper.setScene(i.viewGL.scene),i.viewGL.setPostEffect(e.getModel("postEffect"),r),i.viewGL.setTemporalSuperSampling(e.getModel("temporalSuperSampling"));var a=this._earthMesh;a.geometry=this._sphereGeometry;var o="ecgl."+n;(!a.material||a.material.shader.name!==o)&&(a.material=T.createMaterial(o)),T.setMaterialFromModel(n,a.material,e,r),["roughnessMap","metalnessMap","detailMap","normalMap"].forEach(function(f){var d=a.material.get(f);d&&(d.flipY=!1)}),a.material.set("color",T.parseColor(e.get("baseColor")));var s=i.radius*.99;if(a.scale.set(s,s,s),e.get("atmosphere.show")){a.material.define("both","ATMOSPHERE_ENABLED"),this._atmosphereMesh.invisible=!1,this._atmosphereMaterial.setUniforms({glowPower:e.get("atmosphere.glowPower")||6,glowColor:e.get("atmosphere.color")||"#ffffff"}),a.material.setUniforms({glowPower:e.get("atmosphere.innerGlowPower")||2,glowColor:e.get("atmosphere.color")||"#ffffff"});var l=e.get("atmosphere.offset")||5;this._atmosphereMesh.scale.set(s+l,s+l,s+l)}else a.material.undefine("both","ATMOSPHERE_ENABLED"),this._atmosphereMesh.invisible=!0;var h=a.material.setTextureImage("diffuseMap",e.get("baseTexture"),r,{flipY:!1,anisotropic:8});h&&h.surface&&h.surface.attachToMesh(a);var u=a.material.setTextureImage("bumpMap",e.get("heightTexture"),r,{flipY:!1,anisotropic:8});u&&u.surface&&u.surface.attachToMesh(a),a.material[e.get("postEffect.enable")?"define":"undefine"]("fragment","SRGB_DECODE"),this._updateLight(e,r),this._displaceVertices(e,r),this._updateViewControl(e,r),this._updateLayers(e,r)},afterRender:function(e,t,r,i){var n=i.renderer;this._sceneHelper.updateAmbientCubemap(n,e,r),this._sceneHelper.updateSkybox(n,e,r)},_updateLayers:function(e,t){var r=e.coordinateSystem,i=e.get("layers"),n=r.radius,a=[],o=[],s=[],l=[];Dt(i,function(c){var v=new Rr(c),p=v.get("type"),m=T.loadTexture(v.get("texture"),t,{flipY:!1,anisotropic:8});if(m.surface&&m.surface.attachToMesh(this._earthMesh),p==="blend"){var _=v.get("blendTo"),x=J.firstNotNull(v.get("intensity"),1);_==="emission"?(s.push(m),l.push(x)):(a.push(m),o.push(x))}else{var y=v.get("id"),g=this._layerMeshes[y];g||(g=this._layerMeshes[y]=new T.Mesh({geometry:this._overlayGeometry,castShadow:!1,ignorePicking:!0}));var w=v.get("shading");w==="lambert"?(g.material=g.__lambertMaterial||new T.Material({autoUpdateTextureStatus:!1,shader:T.createShader("ecgl.lambert"),transparent:!0,depthMask:!1}),g.__lambertMaterial=g.material):(g.material=g.__colorMaterial||new T.Material({autoUpdateTextureStatus:!1,shader:T.createShader("ecgl.color"),transparent:!0,depthMask:!1}),g.__colorMaterial=g.material),g.material.enableTexture("diffuseMap");var S=v.get("distance"),b=n+(S==null?r.radius/100:S);g.scale.set(b,b,b),n=b;var E=this._blankTexture||(this._blankTexture=T.createBlankTexture("rgba(255, 255, 255, 0)"));g.m
2023-04-28 16:00:04 +08:00
@ export ecgl . displayShadow . vertex
@ import ecgl . common . transformUniforms
@ import ecgl . common . uv . header
@ import ecgl . common . attributes
varying vec3 v _WorldPosition ;
varying vec3 v _Normal ;
void main ( )
{
@ import ecgl . common . uv . main
v _Normal = normalize ( ( worldInverseTranspose * vec4 ( normal , 0.0 ) ) . xyz ) ;
v _WorldPosition = ( world * vec4 ( position , 1.0 ) ) . xyz ;
gl _Position = worldViewProjection * vec4 ( position , 1.0 ) ;
}
@ end
@ export ecgl . displayShadow . fragment
@ import ecgl . common . uv . fragmentHeader
varying vec3 v _Normal ;
varying vec3 v _WorldPosition ;
uniform float roughness : 0.2 ;
# ifdef DIRECTIONAL _LIGHT _COUNT
@ import clay . header . directional _light
# endif
@ import ecgl . common . ssaoMap . header
@ import clay . plugin . compute _shadow _map
void main ( )
{
float shadow = 1.0 ;
@ import ecgl . common . ssaoMap . main
# if defined ( DIRECTIONAL _LIGHT _COUNT ) && defined ( DIRECTIONAL _LIGHT _SHADOWMAP _COUNT )
float shadowContribsDir [ DIRECTIONAL _LIGHT _COUNT ] ;
if ( shadowEnabled )
{
computeShadowOfDirectionalLights ( v _WorldPosition , shadowContribsDir ) ;
}
for ( int i = 0 ; i < DIRECTIONAL _LIGHT _COUNT ; i ++ ) {
shadow = min ( shadow , shadowContribsDir [ i ] * 0.5 + 0.5 ) ;
}
# endif
shadow *= 0.5 + ao * 0.5 ;
shadow = clamp ( shadow , 0.0 , 1.0 ) ;
gl _FragColor = vec4 ( vec3 ( 0.0 ) , 1.0 - shadow ) ;
}
2023-09-11 21:56:39 +08:00
@ end ` ;T.Shader.import(xl);const Nd=Si.extend({type:"mapbox3D",__ecgl__:!0,init:function(e,t){var r=t.getZr();this._zrLayer=new Qt("mapbox3D",r),r.painter.insertLayer(-1e3,this._zrLayer),this._lightRoot=new T.Node,this._sceneHelper=new Yt(this._lightRoot),this._sceneHelper.initLight(this._lightRoot);var i=this._zrLayer.getMapbox(),n=this._dispatchInteractAction.bind(this,t,i);["zoom","rotate","drag","pitch","rotate","move"].forEach(function(a){i.on(a,n)}),this._groundMesh=new T.Mesh({geometry:new T.PlaneGeometry,material:new T.Material({shader:new T.Shader({vertex:T.Shader.source("ecgl.displayShadow.vertex"),fragment:T.Shader.source("ecgl.displayShadow.fragment")}),depthMask:!1}),renderOrder:-100,culling:!1,castShadow:!1, $ ignorePicking:!0,renderNormal:!0})},render:function(e,t,r){var i=this._zrLayer.getMapbox(),n=e.get("style"),a=JSON.stringify(n);a!==this._oldStyleStr&&n&&i.setStyle(n),this._oldStyleStr=a,i.setCenter(e.get("center")),i.setZoom(e.get("zoom")),i.setPitch(e.get("pitch")),i.setBearing(e.get("bearing")),e.setMapbox(i);var o=e.coordinateSystem;o.viewGL.scene.add(this._lightRoot),o.viewGL.add(this._groundMesh),this._updateGroundMesh(),this._sceneHelper.setScene(o.viewGL.scene),this._sceneHelper.updateLight(e),o.viewGL.setPostEffect(e.getModel("postEffect"),r),o.viewGL.setTemporalSuperSampling(e.getModel("temporalSuperSampling")),this._mapbox3DModel=e},afterRender:function(e,t,r,i){var n=i.renderer;this._sceneHelper.updateAmbientCubemap(n,e,r),this._sceneHelper.updateSkybox(n,e,r),e.coordinateSystem.viewGL.scene.traverse(function(a){a.material&&(a.material.define("fragment","NORMAL_UP_AXIS",2),a.material.define("fragment","NORMAL_FRONT_AXIS",1))})},updateCamera:function(e,t,r,i){e.coordinateSystem.setCameraOption(i),this._updateGroundMesh(),r.getZr().refresh()},_dispatchInteractAction:function(e,t,r){e.dispatchAction({type:"mapbox3DChangeCamera",pitch:t.getPitch(),zoom:t.getZoom(),center:t.getCenter().toArray(),bearing:t.getBearing(),mapbox3DId:this._mapbox3DModel&&this._mapbox3DModel.id})},_updateGroundMesh:function(){if(this._mapbox3DModel){var e=this._mapbox3DModel.coordinateSystem,t=e.dataToPoint(e.center);this._groundMesh.position.set(t[0],t[1],-.001);var r=new T.Plane(new T.Vector3(0,0,1),0),i=e.viewGL.camera.castRay(new T.Vector2(-1,-1)),n=e.viewGL.camera.castRay(new T.Vector2(1,1)),a=i.intersectPlane(r),o=n.intersectPlane(r),s=a.dist(o)/e.viewGL.rootNode.scale.x;this._groundMesh.scale.set(s,s,1)}},dispose:function(e,t){this._zrLayer&&this._zrLayer.dispose(),t.getZr().painter.delLayer(-1e3)}});var kt=Me.mat4,ii=512,qn=.6435011087932844,st=Math.PI,Lr=1/10;function zr(){this.width=0,this.height=0,this.altitudeScale=1,this.boxHeight="auto",this.altitudeExtent,this.bearing=0,this.pitch=0,this.center=[0,0],this._origin,this.zoom=0,this._initialZoom,this.maxPitch=60,this.zoomOffset=0}zr.prototype={constructor:zr,dimensions:["lng","lat","alt"],containPoint:function(){},setCameraOption:function(e){this.bearing=e.bearing,this.pitch=e.pitch,this.center=e.center,this.zoom=e.zoom,this._origin||(this._origin=this.projectOnTileWithScale(this.center,ii)),this._initialZoom==null&&(this._initialZoom=this.zoom),this.updateTransform()},updateTransform:function(){if(!!this.height){var e=.5/Math.tan(qn/2)*this.height*Lr,t=Math.max(Math.min(this.pitch,this.maxPitch),0)/180*Math.PI,r=qn/2,i=Math.PI/2+t,n=Math.sin(r)*e/Math.sin(Math.PI-i-r),a=Math.cos(Math.PI/2-t)*n+e,o=a*1.1;this.pitch>50&&(o=1e3);var s=[];kt.perspective(s,qn,this.width/this.height,1,o),this.viewGL.camera.projectionMatrix.setArray(s),this.viewGL.camera.decomposeProjectionMatrix();var s=kt.identity([]),l=this.dataToPoint(this.center);kt.scale(s,s,[1,-1,1]),kt.translate(s,s,[0,0,-e]),kt.rotateX(s,s,t),kt.rotateZ(s,s,-this.bearing/180*Math.PI),kt.translate(s,s,[-l[0]*this.getScale()*Lr,-l[1]*this.getScale()*Lr,0]),this.viewGL.camera.viewMatrix.array=s;var h=[];kt.invert(h,s),this.viewGL.camera.worldTransform.array=h,this.viewGL.camera.decomposeWorldTransform();var u=ii*this.getScale(),f;if(this.altitudeExtent&&!isNaN(this.boxHeight)){var d=this.altitudeExtent[1]-
2023-04-28 16:00:04 +08:00
uniform mat4 worldViewProjection : WORLDVIEWPROJECTION ;
uniform float elapsedTime : 0 ;
attribute vec3 position : POSITION ;
# ifdef VERTEX _SIZE
attribute float size ;
# else
uniform float u _Size ;
# endif
# ifdef VERTEX _COLOR
attribute vec4 a _FillColor : COLOR ;
varying vec4 v _Color ;
# endif
# ifdef VERTEX _ANIMATION
attribute vec3 prevPosition ;
attribute float prevSize ;
uniform float percent : 1.0 ;
# endif
# ifdef POSITIONTEXTURE _ENABLED
uniform sampler2D positionTexture ;
# endif
varying float v _Size ;
void main ( )
{
# ifdef POSITIONTEXTURE _ENABLED
gl _Position = worldViewProjection * vec4 ( texture2D ( positionTexture , position . xy ) . xy , - 10.0 , 1.0 ) ;
# else
# ifdef VERTEX _ANIMATION
vec3 pos = mix ( prevPosition , position , percent ) ;
# else
vec3 pos = position ;
# endif
gl _Position = worldViewProjection * vec4 ( pos , 1.0 ) ;
# endif
# ifdef VERTEX _SIZE
# ifdef VERTEX _ANIMATION
v _Size = mix ( prevSize , size , percent ) ;
# else
v _Size = size ;
# endif
# else
v _Size = u _Size ;
# endif
# ifdef VERTEX _COLOR
v _Color = a _FillColor ;
# endif
gl _PointSize = v _Size ;
}
@ end
@ export ecgl . sdfSprite . fragment
uniform vec4 color : [ 1 , 1 , 1 , 1 ] ;
uniform vec4 strokeColor : [ 1 , 1 , 1 , 1 ] ;
uniform float smoothing : 0.07 ;
uniform float lineWidth : 0.0 ;
# ifdef VERTEX _COLOR
varying vec4 v _Color ;
# endif
varying float v _Size ;
uniform sampler2D sprite ;
@ import clay . util . srgb
void main ( )
{
gl _FragColor = color ;
vec4 _strokeColor = strokeColor ;
# ifdef VERTEX _COLOR
gl _FragColor *= v _Color ;
# endif
# ifdef SPRITE _ENABLED
float d = texture2D ( sprite , gl _PointCoord ) . r ;
gl _FragColor . a *= smoothstep ( 0.5 - smoothing , 0.5 + smoothing , d ) ;
if ( lineWidth > 0.0 ) {
float sLineWidth = lineWidth / 2.0 ;
float outlineMaxValue0 = 0.5 + sLineWidth ;
float outlineMaxValue1 = 0.5 + sLineWidth + smoothing ;
float outlineMinValue0 = 0.5 - sLineWidth - smoothing ;
float outlineMinValue1 = 0.5 - sLineWidth ;
if ( d <= outlineMaxValue1 && d >= outlineMinValue0 ) {
float a = _strokeColor . a ;
if ( d <= outlineMinValue1 ) {
a = a * smoothstep ( outlineMinValue0 , outlineMinValue1 , d ) ;
}
else {
a = a * smoothstep ( outlineMaxValue1 , outlineMaxValue0 , d ) ;
}
gl _FragColor . rgb = mix ( gl _FragColor . rgb * gl _FragColor . a , _strokeColor . rgb , a ) ;
gl _FragColor . a = gl _FragColor . a * ( 1.0 - a ) + a ;
}
}
# endif
# ifdef SRGB _DECODE
gl _FragColor = sRGBToLinear ( gl _FragColor ) ;
# endif
}
2023-09-11 21:56:39 +08:00
@ end ` ;var $ n=Me.vec4;T.Shader.import(pv);var mv=T.Mesh.extend(function(){var e=new T.Geometry({dynamic:!0,attributes:{color:new T.Geometry.Attribute("color","float",4,"COLOR"),position:new T.Geometry.Attribute("position","float",3,"POSITION"),size:new T.Geometry.Attribute("size","float",1),prevPosition:new T.Geometry.Attribute("prevPosition","float",3),prevSize:new T.Geometry.Attribute("prevSize","float",1)}});Object.assign(e,vv);var t=new T.Material({shader:T.createShader("ecgl.sdfSprite"),transparent:!0,depthMask:!1});t.enableTexture("sprite"),t.define("both","VERTEX_COLOR"),t.define("both","VERTEX_SIZE");var r=new T.Texture2D({image:document.createElement("canvas"),flipY:!1});return t.set("sprite",r),e.pick=this._pick.bind(this),{geometry:e,material:t,mode:T.Mesh.POINTS,sizeScale:1}},{_pick:function(e,t,r,i,n,a){var o=this._positionNDC;if(!!o)for(var s=r.viewport,l=2/s.width,h=2/s.height,u=this.geometry.vertexCount-1;u>=0;u--){var f;this.geometry.indices?f=this.geometry.indices[u]:f=u;var d=o[f*2],c=o[f*2+1],v=this.geometry.attributes.size.get(f)/this.sizeScale,p=v/2;if(e>d-p*l&&e<d+p*l&&t>c-p*h&&t<c+p*h){var m=new T.Vector3,_=new T.Vector3;this.geometry.attributes.position.get(f,m.array),T.Vector3.transformMat4(_,m,this.worldTransform),a.push({vertexIndex:f,point:m,pointWorld:_,target:this,distance:_.distance(i.getWorldPosition())})}}},updateNDCPosition:function(e,t,r){var i=this._positionNDC,n=this.geometry;(!i||i.length/2!==n.vertexCount)&&(i=this._positionNDC=new Float32Array(n.vertexCount*2));for(var a= $ n.create(),o=0;o<n.vertexCount;o++)n.attributes.position.get(o,a),a[3]=1, $ n.transformMat4(a,a,e.array), $ n.scale(a,a,1/a[3]),i[o*2]=a[0],i[o*2+1]=a[1]}});const _v=mv;var qo=20,Yo=-10;function gv(e,t){return e&&t&&e[0]===t[0]&&e[1]===t[1]}function pr(e,t){this.rootNode=new T.Node,this.is2D=e,this._labelsBuilder=new Gt(256,256,t),this._labelsBuilder.getMesh().renderOrder=100,this.rootNode.add(this._labelsBuilder.getMesh()),this._api=t,this._spriteImageCanvas=document.createElement("canvas"),this._startDataIndex=0,this._endDataIndex=0,this._sizeScale=1}pr.prototype={constructor:pr,highlightOnMouseover:!0,update:function(e,t,r,i,n){var a=this._prevMesh;this._prevMesh=this._mesh,this._mesh=a;var o=e.getData();if(i==null&&(i=0),n==null&&(n=o.count()),this._startDataIndex=i,this._endDataIndex=n-1,!this._mesh){var s=this._prevMesh&&this._prevMesh.material;this._mesh=new _v({renderOrder:10,frustumCulling:!1}),s&&(this._mesh.material=s)}var s=this._mesh.material,l=this._mesh.geometry,h=l.attributes;this.rootNode.remove(this._prevMesh),this.rootNode.add(this._mesh),this._setPositionTextureToMesh(this._mesh,this._positionTexture);var u=this._getSymbolInfo(e,i,n),f=r.getDevicePixelRatio(),d=e.getModel("itemStyle").getItemStyle(),c=e.get("large"),v=1;u.maxSize>2?(v=this._updateSymbolSprite(e,d,u,f),s.enableTexture("sprite")):s.disableTexture("sprite"),h.position.init(n-i);var p=[];if(c){s.undefine("VERTEX_SIZE"),s.undefine("VERTEX_COLOR");var m=Jc(o),_=ed(o);T.parseColor(m,p),p[3]*=_,s.set({color:p,u_Size:u.maxSize*this._sizeScale})}else s.set({color:[1,1,1,1]}),s.define("VERTEX_SIZE"),s.define("VERTEX_COLOR"),h.size.init(n-i),h.color.init(n-i),this._originalOpacity=new Float32Array(n-i);for(var x=o.getLayout("points"),y=h.position.value,g=0;g<n-i;g++){var w=g*3,S=g*2;if(this.is2D?(y[w]=x[S],y[w+1]=x[S+1],y[w+2]=Yo):(y[w]=x[w],y[w+1]=x[w+1],y[w+2]=x[w+2]),!c){var m=ke(o,g),_=Ve(o,g);T.parseColor(m,p),p[3]*=_,h.color.set(g,p),p[3]<.99;var b=o.getItemVisual(g,"symbolSize");b=b instanceof Array?Math.max(b[0],b[1]):b,isNaN(b)&&(b=0),h.size.value[g]=b*v*this._sizeScale,this._originalOpacity[g]=p[3]}}this._mesh.sizeScale=v,l.updateBoundingBox(),l.dirty(),this._updateMaterial(e,d);var E=e.coordinateSystem;if(E&&E.viewGL){var L=E.viewGL.isLinearSpace()?"define":"undefine";s[L]("fragment","SRGB_DECODE")}c||this._updateLabelBuilder(e,i,n),this._updateHandler(e,t,r),this._updateAnimation(e),this._api=r},getPointsMesh:function(){return this._mesh},updateLabels:function(e){this._labelsBuilder.updateLabels(e)},hideLabels:function(){this.root
2023-04-28 16:00:04 +08:00
attribute vec3 position : POSITION ;
attribute vec3 positionPrev ;
attribute vec3 positionNext ;
attribute float offset ;
attribute float dist ;
attribute float distAll ;
attribute float start ;
attribute vec4 a _Color : COLOR ;
uniform mat4 worldViewProjection : WORLDVIEWPROJECTION ;
uniform vec4 viewport : VIEWPORT ;
uniform float near : NEAR ;
uniform float speed : 0 ;
uniform float trailLength : 0.3 ;
uniform float time ;
uniform float period : 1000 ;
uniform float spotSize : 1 ;
varying vec4 v _Color ;
varying float v _Percent ;
varying float v _SpotPercent ;
@ import ecgl . common . wireframe . vertexHeader
@ import ecgl . lines3D . clipNear
void main ( )
{
@ import ecgl . lines3D . expandLine
gl _Position = currProj ;
v _Color = a _Color ;
@ import ecgl . common . wireframe . vertexMain
# ifdef CONSTANT _SPEED
float t = mod ( ( speed * time + start ) / distAll , 1. + trailLength ) - trailLength ;
# else
float t = mod ( ( time + start ) / period , 1. + trailLength ) - trailLength ;
# endif
float trailLen = distAll * trailLength ;
v _Percent = ( dist - t * distAll ) / trailLen ;
v _SpotPercent = spotSize / distAll ;
}
@ end
@ export ecgl . trail2 . fragment
uniform vec4 color : [ 1.0 , 1.0 , 1.0 , 1.0 ] ;
uniform float spotIntensity : 5 ;
varying vec4 v _Color ;
varying float v _Percent ;
varying float v _SpotPercent ;
@ import ecgl . common . wireframe . fragmentHeader
@ import clay . util . srgb
void main ( )
{
if ( v _Percent > 1.0 || v _Percent < 0.0 ) {
discard ;
}
float fade = v _Percent ;
# ifdef SRGB _DECODE
gl _FragColor = sRGBToLinear ( color * v _Color ) ;
# else
gl _FragColor = color * v _Color ;
# endif
@ import ecgl . common . wireframe . fragmentMain
if ( v _Percent > ( 1.0 - v _SpotPercent ) ) {
gl _FragColor . rgb *= spotIntensity ;
}
gl _FragColor . a *= fade ;
}
2023-09-11 21:56:39 +08:00
@ end ` ;var ts=Me.vec3;function Lv(e){return e>0?1:-1}T.Shader.import(bv);const Cv=T.Mesh.extend(function(){var e=new T.Material({shader:new T.Shader(T.Shader.source("ecgl.trail2.vertex"),T.Shader.source("ecgl.trail2.fragment")),transparent:!0,depthMask:!1}),t=new gr({dynamic:!0});return t.createAttribute("dist","float",1),t.createAttribute("distAll","float",1),t.createAttribute("start","float",1),{geometry:t,material:e,culling:!1, $ ignorePicking:!0}},{updateData:function(e,t,r){var i=e.hostModel,n=this.geometry,a=i.getModel("effect"),o=a.get("trailWidth")*t.getDevicePixelRatio(),s=a.get("trailLength"),l=i.get("effect.constantSpeed"),h=i.get("effect.period")*1e3,u=l!=null;u?this.material.set("speed",l/1e3):this.material.set("period",h),this.material[u?"define":"undefine"]("vertex","CONSTANT_SPEED");var f=i.get("polyline");n.trailLength=s,this.material.set("trailLength",s),n.resetOffset(),["position","positionPrev","positionNext"].forEach(function(b){n.attributes[b].value=r.attributes[b].value});var d=["dist","distAll","start","offset","color"];d.forEach(function(b){n.attributes[b].init(n.vertexCount)}),n.indices=r.indices;var c=[],v=a.get("trailColor"),p=a.get("trailOpacity"),m=v!=null,_=p!=null;this.updateWorldTransform();var x=this.worldTransform.x.len(),y=this.worldTransform.y.len(),g=this.worldTransform.z.len(),w=0,S=0;e.each(function(b){var E=e.getItemLayout(b),L=_?p:Ve(e,b),P=ke(e,b);L==null&&(L=1),c=T.parseColor(m?v:P,c),c[3]*=L;for(var C=f?r.getPolylineVertexCount(E):r.getCubicCurveVertexCount(E[0],E[1],E[2],E[3]),R=0,I=[],D=[],O=w;O<w+C;O++)n.attributes.position.get(O,I),I[0]*=x,I[1]*=y,I[2]*=g,O>w&&(R+=ts.dist(I,D)),n.attributes.dist.set(O,R),ts.copy(D,I);S=Math.max(S,R);for(var z=Math.random()*(u?R:h),O=w;O<w+C;O++)n.attributes.distAll.set(O,R),n.attributes.start.set(O,z),n.attributes.offset.set(O,Lv(r.attributes.offset.get(O))*o/2),n.attributes.color.set(O,c);w+=C}),this.material.set("spotSize",S*.1*s),this.material.set("spotIntensity",a.get("spotIntensity")),n.dirty()},setAnimationTime:function(e){this.material.set("time",e)}});T.Shader.import(wn);function Mv(e){return e.radius!=null?e.radius:e.size!=null?Math.max(e.size[0],e.size[1],e.size[2]):100}const Dv=Et.extend({type:"lines3D",__ecgl__:!0,init:function(e,t){this.groupGL=new T.Node,this._meshLinesMaterial=new T.Material({shader:T.createShader("ecgl.meshLines3D"),transparent:!0,depthMask:!1}),this._linesMesh=new T.Mesh({geometry:new gr,material:this._meshLinesMaterial, $ ignorePicking:!0}),this._trailMesh=new Cv},render:function(e,t,r){this.groupGL.add(this._linesMesh);var i=e.coordinateSystem,n=e.getData();if(i&&i.viewGL){var a=i.viewGL;a.add(this.groupGL),this._updateLines(e,t,r);var o=i.viewGL.isLinearSpace()?"define":"undefine";this._linesMesh.material[o]("fragment","SRGB_DECODE"),this._trailMesh.material[o]("fragment","SRGB_DECODE")}var s=this._trailMesh;if(s.stopAnimation(),e.get("effect.show")){this.groupGL.add(s),s.updateData(n,r,this._linesMesh.geometry),s.__time=s.__time||0;var l=3600*1e3;this._curveEffectsAnimator=s.animate("",{loop:!0}).when(l,{__time:l}).during(function(){s.setAnimationTime(s.__time)}).start()}else this.groupGL.remove(s),this._curveEffectsAnimator=null;this._linesMesh.material.blend=this._trailMesh.material.blend=e.get("blendMode")==="lighter"?T.additiveBlend:null},pauseEffect:function(){this._curveEffectsAnimator&&this._curveEffectsAnimator.pause()},resumeEffect:function(){this._curveEffectsAnimator&&this._curveEffectsAnimator.resume()},toggleEffect:function(){var e=this._curveEffectsAnimator;e&&(e.isPaused()?e.resume():e.pause())},_updateLines:function(e,t,r){var i=e.getData(),n=e.coordinateSystem,a=this._linesMesh.geometry,o=e.get("polyline");a.expandLine=!0;var s=Mv(n);a.segmentScale=s/20;var l="lineStyle.width".split("."),h=r.getDevicePixelRatio();i.each(function(c){var v=i.getItemModel(c),p=v.get(l);p==null&&(p=1),i.setItemVisual(c,"lineWidth",p)}),a.useNativeLine=!1;var u=0,f=0;i.each(function(c){var v=i.getItemLayout(c);o?(u+=a.getPolylineVertexCount(v),f+=a.getPolylineTriangleCount(v)):(u+=a.getCubicCurveVertexCount(v[0
2023-04-28 16:00:04 +08:00
# define NODE _COUNT 0
uniform sampler2D positionTex ;
uniform vec2 textureSize ;
uniform float gravity ;
uniform float scaling ;
uniform vec2 gravityCenter ;
uniform bool strongGravityMode ;
uniform bool preventOverlap ;
varying vec2 v _Texcoord ;
void main ( ) {
vec4 n0 = texture2D ( positionTex , v _Texcoord ) ;
vec2 force = vec2 ( 0.0 ) ;
for ( int i = 0 ; i < NODE _COUNT ; i ++ ) {
vec2 uv = vec2 (
mod ( float ( i ) , textureSize . x ) / ( textureSize . x - 1.0 ) ,
floor ( float ( i ) / textureSize . x ) / ( textureSize . y - 1.0 )
) ;
vec4 n1 = texture2D ( positionTex , uv ) ;
vec2 dir = n0 . xy - n1 . xy ;
float d2 = dot ( dir , dir ) ;
if ( d2 > 0.0 ) {
float factor = 0.0 ;
if ( preventOverlap ) {
float d = sqrt ( d2 ) ;
d = d - n0 . w - n1 . w ;
if ( d > 0.0 ) {
factor = scaling * n0 . z * n1 . z / ( d * d ) ;
}
else if ( d < 0.0 ) {
factor = scaling * 100.0 * n0 . z * n1 . z ;
}
}
else {
factor = scaling * n0 . z * n1 . z / d2 ;
}
force += dir * factor ;
}
}
vec2 dir = gravityCenter - n0 . xy ;
float d = 1.0 ;
if ( ! strongGravityMode ) {
d = length ( dir ) ;
}
force += dir * n0 . z * gravity / ( d + 1.0 ) ;
gl _FragColor = vec4 ( force , 0.0 , 1.0 ) ;
}
@ end
@ export ecgl . forceAtlas2 . updateEdgeAttraction . vertex
attribute vec2 node1 ;
attribute vec2 node2 ;
attribute float weight ;
uniform sampler2D positionTex ;
uniform float edgeWeightInfluence ;
uniform bool preventOverlap ;
uniform bool linLogMode ;
uniform vec2 windowSize : WINDOW _SIZE ;
varying vec2 v _Force ;
void main ( ) {
vec4 n0 = texture2D ( positionTex , node1 ) ;
vec4 n1 = texture2D ( positionTex , node2 ) ;
vec2 dir = n1 . xy - n0 . xy ;
float d = length ( dir ) ;
float w ;
if ( edgeWeightInfluence == 0.0 ) {
w = 1.0 ;
}
else if ( edgeWeightInfluence == 1.0 ) {
w = weight ;
}
else {
w = pow ( weight , edgeWeightInfluence ) ;
}
vec2 offset = vec2 ( 1.0 / windowSize . x , 1.0 / windowSize . y ) ;
vec2 scale = vec2 ( ( windowSize . x - 1.0 ) / windowSize . x , ( windowSize . y - 1.0 ) / windowSize . y ) ;
vec2 pos = node1 * scale * 2.0 - 1.0 ;
gl _Position = vec4 ( pos + offset , 0.0 , 1.0 ) ;
gl _PointSize = 1.0 ;
float factor ;
if ( preventOverlap ) {
d = d - n1 . w - n0 . w ;
}
if ( d <= 0.0 ) {
v _Force = vec2 ( 0.0 ) ;
return ;
}
if ( linLogMode ) {
factor = w * log ( d ) / d ;
}
else {
factor = w ;
}
v _Force = dir * factor ;
}
@ end
@ export ecgl . forceAtlas2 . updateEdgeAttraction . fragment
varying vec2 v _Force ;
void main ( ) {
gl _FragColor = vec4 ( v _Force , 0.0 , 0.0 ) ;
}
@ end
@ export ecgl . forceAtlas2 . calcWeightedSum . vertex
attribute vec2 node ;
varying vec2 v _NodeUv ;
void main ( ) {
v _NodeUv = node ;
gl _Position = vec4 ( 0.0 , 0.0 , 0.0 , 1.0 ) ;
gl _PointSize = 1.0 ;
}
@ end
@ export ecgl . forceAtlas2 . calcWeightedSum . fragment
varying vec2 v _NodeUv ;
uniform sampler2D positionTex ;
uniform sampler2D forceTex ;
uniform sampler2D forcePrevTex ;
void main ( ) {
vec2 force = texture2D ( forceTex , v _NodeUv ) . rg ;
vec2 forcePrev = texture2D ( forcePrevTex , v _NodeUv ) . rg ;
float mass = texture2D ( positionTex , v _NodeUv ) . z ;
float swing = length ( force - forcePrev ) * mass ;
float traction = length ( force + forcePrev ) * 0.5 * mass ;
gl _FragColor = vec4 ( swing , traction , 0.0 , 0.0 ) ;
}
@ end
@ export ecgl . forceAtlas2 . calcGlobalSpeed
uniform sampler2D globalSpeedPrevTex ;
uniform sampler2D weightedSumTex ;
uniform float jitterTolerence ;
void main ( ) {
vec2 weightedSum = texture2D ( weightedSumTex , vec2 ( 0.5 ) ) . xy ;
float prevGlobalSpeed = texture2D ( globalSpeedPrevTex , vec2 ( 0.5 ) ) . x ;
float globalSpeed = jitterTolerence * jitterTolerence
* weightedSum . y / weightedSum . x ;
if ( prevGlobalSpeed > 0.0 ) {
globalSpeed = min ( globalSpeed / prevGlobalSpeed , 1.5 ) * prevGlobalSpeed ;
}
gl _FragColor = vec4 ( globalSpeed , 0.0 , 0.0 , 1.0 ) ;
}
@ end
@ export ecgl . forceAtlas2 . updatePosition
uniform sampler2D forceTex ;
uniform sampler2D forcePrevTex ;
uniform sampler2D positionTex ;
uniform sampler2D globalSpeedTex ;
varying vec2 v _Texcoord ;
void main ( ) {
vec2 force = texture2D ( forceTex , v _Texcoord ) . xy ;
vec2 forcePrev = texture2D ( forcePrevTex , v _Texcoord ) . xy ;
vec4 node = texture2D ( positionTex , v _Texcoord ) ;
float globalSpeed = texture2D ( globalSpeedTex , vec2 ( 0.5 ) ) . r ;
float swing = length ( force - forcePrev ) ;
float speed = 0.1 * globalSpeed / ( 0.1 + globalSpeed * sqrt ( swing ) ) ;
float df = length ( force ) ;
if ( df > 0.0 ) {
speed = min ( df * speed , 10.0 ) / df ;
gl _FragColor = vec4 ( node . xy + speed * force , node . zw ) ;
}
else {
gl _FragColor = node ;
}
}
@ end
@ export ecgl . forceAtlas2 . edges . vertex
uniform mat4 worldViewProjection : WORLDVIEWPROJECTION ;
attribute vec2 node ;
attribute vec4 a _Color : COLOR ;
varying vec4 v _Color ;
uniform sampler2D positionTex ;
void main ( )
{
gl _Position = worldViewProjection * vec4 (
texture2D ( positionTex , node ) . xy , - 10.0 , 1.0
) ;
v _Color = a _Color ;
}
@ end
@ export ecgl . forceAtlas2 . edges . fragment
uniform vec4 color : [ 1.0 , 1.0 , 1.0 , 1.0 ] ;
varying vec4 v _Color ;
void main ( ) {
gl _FragColor = color * v _Color ;
}
2023-09-11 21:56:39 +08:00
@ end ` ;T.Shader.import(jv);var Qn={repulsionByDegree:!0,linLogMode:!1,strongGravityMode:!1,gravity:1,scaling:1,edgeWeightInfluence:1,jitterTolerence:.1,preventOverlap:!1,dissuadeHubs:!1,gravityCenter:null};function Ue(e){var t={type:T.Texture.FLOAT,minFilter:T.Texture.NEAREST,magFilter:T.Texture.NEAREST};this._positionSourceTex=new T.Texture2D(t),this._positionSourceTex.flipY=!1,this._positionTex=new T.Texture2D(t),this._positionPrevTex=new T.Texture2D(t),this._forceTex=new T.Texture2D(t),this._forcePrevTex=new T.Texture2D(t),this._weightedSumTex=new T.Texture2D(t),this._weightedSumTex.width=this._weightedSumTex.height=1,this._globalSpeedTex=new T.Texture2D(t),this._globalSpeedPrevTex=new T.Texture2D(t),this._globalSpeedTex.width=this._globalSpeedTex.height=1,this._globalSpeedPrevTex.width=this._globalSpeedPrevTex.height=1,this._nodeRepulsionPass=new Re({fragment:T.Shader.source("ecgl.forceAtlas2.updateNodeRepulsion")}),this._positionPass=new Re({fragment:T.Shader.source("ecgl.forceAtlas2.updatePosition")}),this._globalSpeedPass=new Re({fragment:T.Shader.source("ecgl.forceAtlas2.calcGlobalSpeed")}),this._copyPass=new Re({fragment:T.Shader.source("clay.compositor.output")});var r=function(i){i.blendEquation(i.FUNC_ADD),i.blendFunc(i.ONE,i.ONE)};this._edgeForceMesh=new T.Mesh({geometry:new T.Geometry({attributes:{node1:new T.Geometry.Attribute("node1","float",2),node2:new T.Geometry.Attribute("node2","float",2),weight:new T.Geometry.Attribute("weight","float",1)},dynamic:!0,mainAttribute:"node1"}),material:new T.Material({transparent:!0,shader:T.createShader("ecgl.forceAtlas2.updateEdgeAttraction"),blend:r,depthMask:!1,depthText:!1}),mode:T.Mesh.POINTS}),this._weightedSumMesh=new T.Mesh({geometry:new T.Geometry({attributes:{node:new T.Geometry.Attribute("node","float",2)},dynamic:!0,mainAttribute:"node"}),material:new T.Material({transparent:!0,shader:T.createShader("ecgl.forceAtlas2.calcWeightedSum"),blend:r,depthMask:!1,depthText:!1}),mode:T.Mesh.POINTS}),this._framebuffer=new qe({depthBuffer:!1}),this._dummyCamera=new T.OrthographicCamera({left:-1,right:1,top:1,bottom:-1,near:0,far:100}),this._globalSpeed=0}Ue.prototype.updateOption=function(e){for(var t in Qn)this[t]=Qn[t];var r=this._nodes.length;if(r>5e4?this.jitterTolerence=10:r>5e3?this.jitterTolerence=1:this.jitterTolerence=.1,r>100?this.scaling=2:this.scaling=10,e)for(var t in Qn)e[t]!=null&&(this[t]=e[t]);if(this.repulsionByDegree)for(var i=this._positionSourceTex.pixels,n=0;n<this._nodes.length;n++)i[n*4+2]=(this._nodes[n].degree||0)+1};Ue.prototype._updateGravityCenter=function(e){var t=this._nodes,r=this._edges;if(this.gravityCenter)this._gravityCenter=this.gravityCenter;else{for(var i=[1/0,1/0],n=[-1/0,-1/0],a=0;a<t.length;a++)i[0]=Math.min(t[a].x,i[0]),i[1]=Math.min(t[a].y,i[1]),n[0]=Math.max(t[a].x,n[0]),n[1]=Math.max(t[a].y,n[1]);this._gravityCenter=[(i[0]+n[0])*.5,(i[1]+n[1])*.5]}for(var a=0;a<r.length;a++){var o=r[a].node1,s=r[a].node2;t[o].degree=(t[o].degree||0)+1,t[s].degree=(t[s].degree||0)+1}};Ue.prototype.initData=function(e,t){this._nodes=e,this._edges=t,this._updateGravityCenter();var r=Math.ceil(Math.sqrt(e.length)),i=r,n=new Float32Array(r*i*4);this._resize(r,i);for(var a=0,o=0;o<e.length;o++){var s=e[o];n[a++]=s.x||0,n[a++]=s.y||0,n[a++]=s.mass||1,n[a++]=s.size||1}this._positionSourceTex.pixels=n;var l=this._edgeForceMesh.geometry,h=t.length;l.attributes.node1.init(h*2),l.attributes.node2.init(h*2),l.attributes.weight.init(h*2);for(var u=[],o=0;o<t.length;o++){var f=l.attributes,d=t[o].weight;d==null&&(d=1),f.node1.set(o,this.getNodeUV(t[o].node1,u)),f.node2.set(o,this.getNodeUV(t[o].node2,u)),f.weight.set(o,d),f.node1.set(o+h,this.getNodeUV(t[o].node2,u)),f.node2.set(o+h,this.getNodeUV(t[o].node1,u)),f.weight.set(o+h,d)}var c=this._weightedSumMesh.geometry;c.attributes.node.init(e.length);for(var o=0;o<e.length;o++)c.attributes.node.set(o,this.getNodeUV(o,u));l.dirty(),c.dirty(),this._nodeRepulsionPass.material.define("fragment","NODE_COUNT",e.length),this._nodeRepulsionPass.material.setUniform("textureSize",[r,i]),this._inited=!1,this._fram
2023-04-28 16:00:04 +08:00
uniform mat4 worldViewProjection : WORLDVIEWPROJECTION ;
attribute vec2 position : POSITION ;
attribute vec4 a _Color : COLOR ;
varying vec4 v _Color ;
# ifdef POSITIONTEXTURE _ENABLED
uniform sampler2D positionTexture ;
# endif
void main ( )
{
gl _Position = worldViewProjection * vec4 ( position , - 10.0 , 1.0 ) ;
v _Color = a _Color ;
}
@ end
@ export ecgl . lines2D . fragment
uniform vec4 color : [ 1.0 , 1.0 , 1.0 , 1.0 ] ;
varying vec4 v _Color ;
void main ( )
{
gl _FragColor = color * v _Color ;
}
@ end
@ export ecgl . meshLines2D . vertex
attribute vec2 position : POSITION ;
attribute vec2 normal ;
attribute float offset ;
attribute vec4 a _Color : COLOR ;
uniform mat4 worldViewProjection : WORLDVIEWPROJECTION ;
uniform vec4 viewport : VIEWPORT ;
varying vec4 v _Color ;
varying float v _Miter ;
void main ( )
{
vec4 p2 = worldViewProjection * vec4 ( position + normal , - 10.0 , 1.0 ) ;
gl _Position = worldViewProjection * vec4 ( position , - 10.0 , 1.0 ) ;
p2 . xy /= p2 . w ;
gl _Position . xy /= gl _Position . w ;
vec2 N = normalize ( p2 . xy - gl _Position . xy ) ;
gl _Position . xy += N * offset / viewport . zw * 2.0 ;
gl _Position . xy *= gl _Position . w ;
v _Color = a _Color ;
}
@ end
@ export ecgl . meshLines2D . fragment
uniform vec4 color : [ 1.0 , 1.0 , 1.0 , 1.0 ] ;
varying vec4 v _Color ;
varying float v _Miter ;
void main ( )
{
gl _FragColor = color * v _Color ;
}
2023-09-11 21:56:39 +08:00
@ end ` ;var Vi=Me.vec2;T.Shader.import(Kv);var Qv=1;const Jv=Et.extend({type:"graphGL",__ecgl__:!0,init:function(e,t){this.groupGL=new T.Node,this.viewGL=new ce("orthographic"),this.viewGL.camera.left=this.viewGL.camera.right=0,this.viewGL.add(this.groupGL),this._pointsBuilder=new pr(!0,t),this._forceEdgesMesh=new T.Mesh({material:new T.Material({shader:T.createShader("ecgl.forceAtlas2.edges"),transparent:!0,depthMask:!1,depthTest:!1}), $ ignorePicking:!0,geometry:new T.Geometry({attributes:{node:new T.Geometry.Attribute("node","float",2),color:new T.Geometry.Attribute("color","float",4,"COLOR")},dynamic:!0,mainAttribute:"node"}),renderOrder:-1,mode:T.Mesh.LINES}),this._edgesMesh=new T.Mesh({material:new T.Material({shader:T.createShader("ecgl.meshLines2D"),transparent:!0,depthMask:!1,depthTest:!1}), $ ignorePicking:!0,geometry:new Ml({useNativeLine:!1,dynamic:!0}),renderOrder:-1,culling:!1}),this._layoutId=0,this._control=new $ v({zr:t.getZr(),viewGL:this.viewGL}),this._control.setTarget(this.groupGL),this._control.init(),this._clickHandler=this._clickHandler.bind(this)},render:function(e,t,r){this.groupGL.add(this._pointsBuilder.rootNode),this._model=e,this._api=r,this._initLayout(e,t,r),this._pointsBuilder.update(e,t,r),this._forceLayoutInstance instanceof Ue||this.groupGL.remove(this._forceEdgesMesh),this._updateCamera(e,r),this._control.off("update"),this._control.on("update",function(){r.dispatchAction({type:"graphGLRoam",seriesId:e.id,zoom:this._control.getZoom(),offset:this._control.getOffset()}),this._pointsBuilder.updateView(this.viewGL.camera)},this),this._control.setZoom(J.firstNotNull(e.get("zoom"),1)),this._control.setOffset(e.get("offset")||[0,0]);var i=this._pointsBuilder.getPointsMesh();if(i.off("mousemove",this._mousemoveHandler),i.off("mouseout",this._mouseOutHandler,this),r.getZr().off("click",this._clickHandler),this._pointsBuilder.highlightOnMouseover=!0,e.get("focusNodeAdjacency")){var n=e.get("focusNodeAdjacencyOn");n==="click"?r.getZr().on("click",this._clickHandler):n==="mouseover"&&(i.on("mousemove",this._mousemoveHandler,this),i.on("mouseout",this._mouseOutHandler,this),this._pointsBuilder.highlightOnMouseover=!1)}this._lastMouseOverDataIndex=-1},_clickHandler:function(e){if(!this._layouting){var t=this._pointsBuilder.getPointsMesh().dataIndex;t>=0?this._api.dispatchAction({type:"graphGLFocusNodeAdjacency",seriesId:this._model.id,dataIndex:t}):this._api.dispatchAction({type:"graphGLUnfocusNodeAdjacency",seriesId:this._model.id})}},_mousemoveHandler:function(e){if(!this._layouting){var t=this._pointsBuilder.getPointsMesh().dataIndex;t>=0?t!==this._lastMouseOverDataIndex&&this._api.dispatchAction({type:"graphGLFocusNodeAdjacency",seriesId:this._model.id,dataIndex:t}):this._mouseOutHandler(e),this._lastMouseOverDataIndex=t}},_mouseOutHandler:function(e){this._layouting||(this._api.dispatchAction({type:"graphGLUnfocusNodeAdjacency",seriesId:this._model.id}),this._lastMouseOverDataIndex=-1)},_updateForceEdgesGeometry:function(e,t){var r=this._forceEdgesMesh.geometry,i=t.getEdgeData(),n=0,a=this._forceLayoutInstance,o=i.count()*2;r.attributes.node.init(o),r.attributes.color.init(o),i.each(function(s){var l=e[s];r.attributes.node.set(n,a.getNodeUV(l.node1)),r.attributes.node.set(n+1,a.getNodeUV(l.node2));var h=ke(i,l.dataIndex),u=T.parseColor(h);u[3]*=J.firstNotNull(Ve(i,l.dataIndex),1),r.attributes.color.set(n,u),r.attributes.color.set(n+1,u),n+=2}),r.dirty()},_updateMeshLinesGeometry:function(){var t=this._model.getEdgeData(),e=this._edgesMesh.geometry,t=this._model.getEdgeData(),r=this._model.getData().getLayout("points");e.resetOffset(),e.setVertexCount(t.count()*e.getLineVertexCount()),e.setTriangleCount(t.count()*e.getLineTriangleCount());var i=[],n=[],a=["lineStyle","width"];this._originalEdgeColors=new Float32Array(t.count()*4),this._edgeIndicesMap=new Float32Array(t.count()),t.each(function(o){var s=t.graph.getEdgeByIndex(o),l=s.node1.dataIndex*2,h=s.node2.dataIndex*2;i[0]=r[l],i[1]=r[l+1],n[0]=r[h],n[1]=r[h+1];var u=ke(t,s.dataIndex),f=T.parseColor(u);f[3]*=J.firstNotNull(Ve(t,s.dataIndex),1);var
2023-04-28 16:00:04 +08:00
uniform sampler2D particleTexture ;
uniform sampler2D spawnTexture ;
uniform sampler2D velocityTexture ;
uniform float deltaTime ;
uniform float elapsedTime ;
uniform float speedScaling : 1.0 ;
uniform vec2 textureSize ;
uniform vec4 region : [ 0 , 0 , 1 , 1 ] ;
uniform float firstFrameTime ;
varying vec2 v _Texcoord ;
void main ( )
{
vec4 p = texture2D ( particleTexture , v _Texcoord ) ;
bool spawn = false ;
if ( p . w <= 0.0 ) {
p = texture2D ( spawnTexture , fract ( v _Texcoord + elapsedTime / 10.0 ) ) ;
p . w -= firstFrameTime ;
spawn = true ;
}
vec2 v = texture2D ( velocityTexture , fract ( p . xy * region . zw + region . xy ) ) . xy ;
v = ( v - 0.5 ) * 2.0 ;
p . z = length ( v ) ;
p . xy += v * deltaTime / 10.0 * speedScaling ;
p . w -= deltaTime ;
if ( spawn || p . xy != fract ( p . xy ) ) {
p . z = 0.0 ;
}
p . xy = fract ( p . xy ) ;
gl _FragColor = p ;
}
@ end
@ export ecgl . vfParticle . renderPoints . vertex
# define PI 3.1415926
attribute vec2 texcoord : TEXCOORD _0 ;
uniform sampler2D particleTexture ;
uniform mat4 worldViewProjection : WORLDVIEWPROJECTION ;
uniform float size : 1.0 ;
varying float v _Mag ;
varying vec2 v _Uv ;
void main ( )
{
vec4 p = texture2D ( particleTexture , texcoord ) ;
if ( p . w > 0.0 && p . z > 1e-5 ) {
gl _Position = worldViewProjection * vec4 ( p . xy * 2.0 - 1.0 , 0.0 , 1.0 ) ;
}
else {
gl _Position = vec4 ( 100000.0 , 100000.0 , 100000.0 , 1.0 ) ;
}
v _Mag = p . z ;
v _Uv = p . xy ;
gl _PointSize = size ;
}
@ end
@ export ecgl . vfParticle . renderPoints . fragment
uniform vec4 color : [ 1.0 , 1.0 , 1.0 , 1.0 ] ;
uniform sampler2D gradientTexture ;
uniform sampler2D colorTexture ;
uniform sampler2D spriteTexture ;
varying float v _Mag ;
varying vec2 v _Uv ;
void main ( )
{
gl _FragColor = color ;
# ifdef SPRITETEXTURE _ENABLED
gl _FragColor *= texture2D ( spriteTexture , gl _PointCoord ) ;
if ( color . a == 0.0 ) {
discard ;
}
# endif
# ifdef GRADIENTTEXTURE _ENABLED
gl _FragColor *= texture2D ( gradientTexture , vec2 ( v _Mag , 0.5 ) ) ;
# endif
# ifdef COLORTEXTURE _ENABLED
gl _FragColor *= texture2D ( colorTexture , v _Uv ) ;
# endif
}
@ end
@ export ecgl . vfParticle . renderLines . vertex
# define PI 3.1415926
attribute vec3 position : POSITION ;
uniform sampler2D particleTexture ;
uniform sampler2D prevParticleTexture ;
uniform float size : 1.0 ;
uniform vec4 vp : VIEWPORT ;
uniform mat4 worldViewProjection : WORLDVIEWPROJECTION ;
varying float v _Mag ;
varying vec2 v _Uv ;
@ import clay . util . rand
void main ( )
{
vec4 p = texture2D ( particleTexture , position . xy ) ;
vec4 p2 = texture2D ( prevParticleTexture , position . xy ) ;
p . xy = p . xy * 2.0 - 1.0 ;
p2 . xy = p2 . xy * 2.0 - 1.0 ;
if ( p . w > 0.0 && p . z > 1e-5 ) {
vec2 dir = normalize ( p . xy - p2 . xy ) ;
vec2 norm = vec2 ( dir . y / vp . z , - dir . x / vp . w ) * sign ( position . z ) * size ;
if ( abs ( position . z ) == 2.0 ) {
gl _Position = vec4 ( p . xy + norm , 0.0 , 1.0 ) ;
v _Uv = p . xy ;
v _Mag = p . z ;
}
else {
gl _Position = vec4 ( p2 . xy + norm , 0.0 , 1.0 ) ;
v _Mag = p2 . z ;
v _Uv = p2 . xy ;
}
gl _Position = worldViewProjection * gl _Position ;
}
else {
gl _Position = vec4 ( 100000.0 , 100000.0 , 100000.0 , 1.0 ) ;
}
}
@ end
@ export ecgl . vfParticle . renderLines . fragment
uniform vec4 color : [ 1.0 , 1.0 , 1.0 , 1.0 ] ;
uniform sampler2D gradientTexture ;
uniform sampler2D colorTexture ;
varying float v _Mag ;
varying vec2 v _Uv ;
void main ( )
{
gl _FragColor = color ;
# ifdef GRADIENTTEXTURE _ENABLED
gl _FragColor *= texture2D ( gradientTexture , vec2 ( v _Mag , 0.5 ) ) ;
# endif
# ifdef COLORTEXTURE _ENABLED
gl _FragColor *= texture2D ( colorTexture , v _Uv ) ;
# endif
}
@ end
2023-09-11 21:56:39 +08:00
` ;N.import(np);function ap(e){var t=document.createElement("canvas");t.width=t.height=e;var r=t.getContext("2d");return r.fillStyle="#fff",r.arc(e/2,e/2,e/2,0,Math.PI*2),r.fill(),t}var va=function(){this.motionBlurFactor=.99,this.vectorFieldTexture=new K({type:W.FLOAT,flipY:!1}),this.particleLife=[5,20],this._particleType="point",this._particleSize=1,this.particleColor=[1,1,1,1],this.particleSpeedScaling=1,this._thisFrameTexture=null,this._particlePass=null,this._spawnTexture=null,this._particleTexture0=null,this._particleTexture1=null,this._particlePointsMesh=null,this._surfaceFrameBuffer=null,this._elapsedTime=0,this._scene=null,this._camera=null,this._lastFrameTexture=null,this._supersampling=1,this._downsampleTextures=[],this._width=512,this._height=512,this.init()};va.prototype={constructor:va,init:function(){var e={type:W.FLOAT,minFilter:W.NEAREST,magFilter:W.NEAREST,useMipmap:!1};this._spawnTexture=new K(e),this._particleTexture0=new K(e),this._particleTexture1=new K(e),this._frameBuffer=new qe({depthBuffer:!1}),this._particlePass=new Re({fragment:N.source("ecgl.vfParticle.particle.fragment")}),this._particlePass.setUniform("velocityTexture",this.vectorFieldTexture),this._particlePass.setUniform("spawnTexture",this._spawnTexture),this._downsamplePass=new Re({fragment:N.source("clay.compositor.downsample")});var t=new lr({renderOrder:10,material:new _t({shader:new N(N.source("ecgl.vfParticle.renderPoints.vertex"),N.source("ecgl.vfParticle.renderPoints.fragment"))}),mode:lr.POINTS,geometry:new oe({dynamic:!0,mainAttribute:"texcoord0"})}),r=new lr({renderOrder:10,material:new _t({shader:new N(N.source("ecgl.vfParticle.renderLines.vertex"),N.source("ecgl.vfParticle.renderLines.fragment"))}),geometry:new ip,culling:!1}),i=new lr({material:new _t({shader:new N(N.source("ecgl.color.vertex"),N.source("ecgl.color.fragment"))}),geometry:new _n});i.material.enableTexture("diffuseMap"),this._particlePointsMesh=t,this._particleLinesMesh=r,this._lastFrameFullQuadMesh=i,this._camera=new Br,this._thisFrameTexture=new K,this._lastFrameTexture=new K},setParticleDensity:function(e,t){for(var r=e*t,i=new Float32Array(r*4),n=0,a=this.particleLife,o=0;o<e;o++)for(var s=0;s<t;s++,n++){i[n*4]=Math.random(),i[n*4+1]=Math.random(),i[n*4+2]=Math.random();var l=(a[1]-a[0])*Math.random()+a[0];i[n*4+3]=l}this._particleType==="line"?this._setLineGeometry(e,t):this._setPointsGeometry(e,t),this._spawnTexture.width=e,this._spawnTexture.height=t,this._spawnTexture.pixels=i,this._particleTexture0.width=this._particleTexture1.width=e,this._particleTexture0.height=this._particleTexture1.height=t,this._particlePass.setUniform("textureSize",[e,t])},_setPointsGeometry:function(e,t){var r=e*t,i=this._particlePointsMesh.geometry,n=i.attributes;n.texcoord0.init(r);for(var a=0,o=0;o<e;o++)for(var s=0;s<t;s++,a++)n.texcoord0.value[a*2]=o/e,n.texcoord0.value[a*2+1]=s/t;i.dirty()},_setLineGeometry:function(e,t){var r=e*t,i=this._getParticleMesh().geometry;i.setLineCount(r),i.resetOffset();for(var n=0;n<e;n++)for(var a=0;a<t;a++)i.addLine([n/e,a/t]);i.dirty()},_getParticleMesh:function(){return this._particleType==="line"?this._particleLinesMesh:this._particlePointsMesh},update:function(e,t,r,i){var n=this._getParticleMesh(),a=this._frameBuffer,o=this._particlePass;i&&this._updateDownsampleTextures(e,t),n.material.set("size",this._particleSize*this._supersampling),n.material.set("color",this.particleColor),o.setUniform("speedScaling",this.particleSpeedScaling),a.attach(this._particleTexture1),o.setUniform("firstFrameTime",i?(this.particleLife[1]+this.particleLife[0])/2:0),o.setUniform("particleTexture",this._particleTexture0),o.setUniform("deltaTime",r),o.setUniform("elapsedTime",this._elapsedTime),o.render(e,a),n.material.set("particleTexture",this._particleTexture1),n.material.set("prevParticleTexture",this._particleTexture0),a.attach(this._thisFrameTexture),a.bind(e),e.gl.clear(e.gl.DEPTH_BUFFER_BIT|e.gl.COLOR_BUFFER_BIT);var s=this._lastFrameFullQuadMesh;s.material.set("diffuseMap",this._lastFrameTexture),s.material.set("color",[1,1,1,this.motionBlurFactor]