@soonspacejs/plugin-heat-cloud 2.13.16 → 2.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.esm.js CHANGED
@@ -1 +1,3218 @@
1
- import{TextureLoader as t,Texture as e,Matrix3 as n,Vector4 as i,Vector3 as a,Vector2 as o,AlphaFormat as r,RedFormat as s,RedIntegerFormat as l,RGFormat as c,RGIntegerFormat as u,RGBAFormat as d,RGBAIntegerFormat as m,LuminanceFormat as p,LuminanceAlphaFormat as f,DepthFormat as h,DepthStencilFormat as v,ShaderMaterial as g,GLSL3 as x,Matrix4 as _,DoubleSide as y,Mesh as w,BoxGeometry as M,Data3DTexture as z,FloatType as D,LinearFilter as S,UnsignedByteType as b,Color as C,FrontSide as N,UniformsUtils as U,ShaderLib as A,Points as P,PlaneGeometry as O,Box3 as I,Line3 as T,Quaternion as F,BackSide as R,RawShaderMaterial as V,BufferGeometry as E,Float32BufferAttribute as G,Uint8ClampedBufferAttribute as j}from"three";import L from"soonspacejs";var B,k=(t=>(t[t.x=0]="x",t[t.y=1]="y",t[t.z=2]="z",t))(k||{});(B=k||(k={})).toKey=function(t){return B[t]},B.toIndex=function(t){return B[t]},B.getCrossAxiss=function(t){return[(t+1)%3,(t+2)%3]};var H=(t=>(t[t.x=0]="x",t[t.y=1]="y",t[t.z=2]="z",t[t.w=3]="w",t))(H||{});(t=>{t.toKey=function(e){return t[e]},t.toIndex=function(e){return t[e]},t.getCrossAxiss=function(t){return[(t+1)%4,(t+2)%4]}})(H||(H={}));var q=Object.defineProperty,K=(t,e,n)=>(((t,e,n)=>{e in t?q(t,e,{enumerable:!0,configurable:!0,writable:!0,value:n}):t[e]=n})(t,"symbol"!=typeof e?e+"":e,n),n);function W(t,e,n,i="srgb"){const a=new OffscreenCanvas(e,n).getContext("2d"),o=a.createLinearGradient(0,0,256,1);for(const[e,n]of t)o.addColorStop(Number(e),n);return a.fillStyle=o,a.fillRect(0,0,e,n),a.getImageData(0,0,e,n,{colorSpace:i})}function Y(t,e){let{area:n,width:i,height:a,colorSpace:o}=e||{};o=o??"srgb",n=n||{};const r=n.x??0,s=n.y??0,l=X(t),c=n.width??l.width,u=n.height??l.height;i=i??c,a=a??u;const d=new OffscreenCanvas(i,a).getContext("2d");return d.drawImage(t,r,s,c,u,0,0,i,a),d.getImageData(0,0,i,a,{colorSpace:o})}function X(t){let e=0,n=0;return t instanceof HTMLImageElement?(e=t.naturalWidth,n=t.naturalHeight):t instanceof HTMLVideoElement?(e=t.videoWidth,n=t.videoHeight):(e=t.width,n=t.height),{width:e,height:n}}function Z(t){const{data:e,width:n,height:i,colorSpace:a}=t,o=e.length,r=new Uint8ClampedArray(o);for(let t=0;t<i;t++){const i=t*n,a=-(i+n),o=a+n,s=e.slice(4*a,4*o);r.set(s,4*i)}return new ImageData(r,n,i,{colorSpace:a})}function J(t,e){const{data:n,width:i}=t,a=e*i,o=a+i;return n.slice(4*a,4*o)}function Q(t,e,n){const{data:i,width:a}=t,o=4*(e*a+n);return i.slice(o,o+4)}function $(t){const e=document.createElement("canvas"),n=e.getContext("2d");return e.width=t.width,e.height=t.height,n.putImageData(t,0,0),e}function tt(t){return $(t).toDataURL()}function et(t){return t&&null!=t.data&&null!=t.width&&null!=t.height}function nt(t){return et(t)&&null!=t.depth}function it(t,e){for(const[n,i]of Object.entries(t))if(0<=i&&i<=e[n])return!0;return!1}function at(t,e){const{x:n,y:i}=e;return t.z*i*n+t.y*n+t.x}function ot(t,e){const{x:n,y:i}=e,a=Math.trunc(t/n),o=t-a*n,r=Math.trunc(a/i);return{x:o,y:a-r*i,z:r}}function rt(t,e,n=1){let{x:i,y:a,z:o}=e;const r=t.size;return i=Math.max(0,Math.min(r.x-1,i)),a=Math.max(0,Math.min(r.y-1,a)),o=Math.max(0,Math.min(r.z-1,o)),st(t,{x:i,y:a,z:o},n)}function st(t,e,n=1){const{data:i,size:a}=t,o=at(e,a);let r=[];if(n>0){const t=o*n;for(let e=0;e<n;e++)r.push(i[t+e])}return{index:o,value:r}}function lt(t,e){let{x:n,y:i,z:a}=e;const o=t.size;return n=Math.max(0,Math.min(o.x-1,n)),i=Math.max(0,Math.min(o.y-1,i)),a=Math.max(0,Math.min(o.z-1,a)),ct(t,{x:n,y:i,z:a})}function ct(t,e){const{data:n,size:i}=t,a=at(e,i);return{index:a,value:n[a]}}function ut(t,e){const{voidValue:n,valuesAccumulate:i,verifyVoid:a=()=>!1}=e;let{x:o,y:r,z:s}=t[0].size;const l=t.length;for(let e=1;e<l;e++){const n=t[e].size;o=Math.max(o,n.x),r=Math.max(r,n.y),s=Math.max(s,n.z)}const c=new Array(o*r*s),u=o*r;for(let e=0;e<s;e++){const s=e*u;for(let l=0;l<r;l++){const r=s+l*o;for(let s=0;s<o;s++){const o=r+s,u={x:s,y:l,z:e},d=[];for(const n of t){const t=n.size;if(s<t.x&&l<t.y&&e<t.z)continue;const{index:i,value:o}=ct(n,u);a(o,n,i)||d.push({value:o,index:i,data3D:n,coord:u})}const m=d.length;let p=n;m>1?p=i(d):1===m&&(p=d[0].value),c[o]=p}}}return{data:c,size:{x:o,y:r,z:s}}}function dt(t,e,n,i=1){const{size:a}=t,o=k.toKey(e),[r,s]=k.getCrossAxiss(e),l=k.toKey(r),c=k.toKey(s),u=a[l],d=a[c],m=[],p=a[o];n=Math.trunc(n),n=Math.max(0,Math.min(p-1,n));let f={x:0,y:0,z:0};f[o]=n;for(let e=0;e<d;e++){f[c]=e;for(let e=0;e<u;e++){f[l]=e;const{value:n}=st(t,f,i);m.push(...n)}}return{data:m,size:{x:u,y:d}}}function mt(t,e,n){e=Math.trunc(e);const{data:i,width:a,height:o,colorSpace:r}=n?Z(t):t,s=i.length,l=new Uint8ClampedArray(s*e);for(let t=0;t<e;t++)l.set(i,t*s);return{data:l,width:a,height:o,depth:e,colorSpace:r}}function pt(t,e,n){const i=n||{},a=i.reverseY,o=i.axis??"z",r=et(t)?t:Y(t,i);return"z"===o?mt(r,e,a):ft(r,o,e,a)}function ft(t,e,n,i){n=Math.trunc(n);const{data:a,width:o,height:r,colorSpace:s}=i?Z(t):t,l=k.toKey(e),c=(e+1)%3,u=(e+2)%3,d=k.toKey(c),m=k.toKey(u),p={[d]:o,[m]:r,[l]:n},f=new Uint8ClampedArray(a.length*n),h={x:0,y:0,z:0};for(let t=0;t<n;t++){h[l]=t;for(let t=0;t<r;t++){h[m]=t;for(let e=0;e<o;e++){h[d]=e;const n=4*(t*o+e),i=n+4,r=a.subarray(n,i),s=4*at(h,p);f.set(r,s)}}}return{data:f,width:p.x,height:p.y,depth:p.z,colorSpace:s}}function ht(t,e){return t.y*e.x+t.x}function vt(t,e){const{x:n}=e,i=Math.trunc(t/n);return{x:t-i*n,y:i}}function gt(t,e,n=1){let{x:i,y:a}=e;const o=t.size;return i=Math.max(0,Math.min(o.x-1,i)),a=Math.max(0,Math.min(o.y-1,a)),xt(t,{x:i,y:a},n)}function xt(t,e,n=1){const{data:i,size:a}=t,o=ht(e,a);let r=[];if(n>0){const t=o*n;for(let e=0;e<n;e++)r.push(i[t+e])}return{index:o,value:r}}function _t(t,e){let{x:n,y:i}=e;const a=t.size;return n=Math.max(0,Math.min(a.x-1,n)),i=Math.max(0,Math.min(a.y-1,i)),yt(t,{x:n,y:i})}function yt(t,e){const{data:n,size:i}=t,a=ht(e,i);return{index:a,value:n[a]}}function wt(t,e,n=1){const{data:i,size:a}=t,o=a.x,r=e*o,s=r+o;return("function"==typeof i.slice?i:Array.from(i)).slice(r*n,s*n)}class Mt{constructor(t){K(this,"isImageData3DSlice",!0),K(this,"_image3D"),K(this,"_canvas"),K(this,"_context"),K(this,"_axis",k.z),K(this,"_depth",0),K(this,"_sliceSize",null),K(this,"_slice"),this.image3D=t}get image3D(){return this._image3D}set image3D(t){this._image3D=t,this.updateSize()}get canvas(){let t=this._canvas;return t||(t=this._canvas=document.createElement("canvas"),t.width=this.sliceSize.x,t.height=this.sliceSize.y),t}get context(){return this._context??(this._context=this.canvas.getContext("2d"))}get axis(){return this._axis}set axis(t){this._axis=t,this.updateSize()}get depth(){return this._depth}set depth(t){this._depth=t,this.updateSlice()}get sliceSize(){let t=this._sliceSize;if(!t){const{axis:e,image3D:n}=this,{width:i,height:a,depth:o}=n,[r,s]=k.getCrossAxiss(e),l=[i,a,o];this._sliceSize=t={x:l[r],y:l[s]}}return t}get slice(){return this._slice??(this._slice=this.getSlice(this.axis,this.depth))}getSlice(t,e){const{data:n,width:i,height:a,depth:o,colorSpace:r}=this.image3D,{data:s,size:l}=dt({data:n,size:{x:i,y:a,z:o}},t,e,4),c=s instanceof Uint8ClampedArray?s:Uint8ClampedArray.from(s);return new ImageData(c,l.x,l.y,{colorSpace:r})}getDataURL(){return this.canvas.toDataURL()}getColor(t){const{x:e,y:n}=t;return Q(this.slice,n,e)}updateSize(){this._sliceSize=null;const t=this.canvas;t.width=this.sliceSize.x,t.height=this.sliceSize.y,this.updateSlice()}updateSlice(){this._slice=null,this.context.putImageData(this.slice,0,0)}}var zt=Object.defineProperty,Dt=(t,e,n)=>(((t,e,n)=>{e in t?zt(t,e,{enumerable:!0,configurable:!0,writable:!0,value:n}):t[e]=n})(t,"symbol"!=typeof e?e+"":e,n),n);function St(t){const e=t.length,n=[];if(0===e)return n;const[r,s]=function(t){return void 0!==t.w?[i,4]:void 0!==t.z?[a,3]:[o,2]}(t[0]);for(let i=0;i<e;i++){const a=t[i],o=(new r).copy(a),s=a.radius,l=n[i]??(n[i]=[]);for(let a=i+1;a<e;a++){const e=t[a];o.distanceToSquared(e)<=(e.radius+s)**2&&(l.push(a),(n[a]=[]).push(i))}}return n}let bt;function Ct(n){if("string"==typeof n)return(bt||(bt=new t)).load(n);if(n.isTexture)return n;const i=Array.isArray(n)?W(n,256,1):n,a=new e(i);return"srgb"===i.colorSpace&&(a.colorSpace="srgb"),a.needsUpdate=!0,a}function Nt(t,e,n){let i=function(t,e){const n=Math.sqrt(t.lengthSq()*e.lengthSq());if(0===n)return 0;let i=t.dot(e)/n;return i=Math.max(-1,Math.min(1,i)),Math.acos(i)}(t,e);return 0===i?i:t.clone().cross(e).dot(n)<0?-i:i}const Ut=180/Math.PI,At={yaw:[{name:"前",range:[-15,15]},{name:"左",range:[15,165]},{name:"右",range:[-165,-15]},{name:"后",range:[-180.1,-165]},{name:"后",range:[165,180.1]}],pitch:[{name:"前",range:[-15,15]},{name:"上",range:[15,165]},{name:"下",range:[-165,-15]},{name:"后",range:[-180.1,-165]},{name:"后",range:[165,180.1]}],roll:[{name:"上",range:[-15,15]},{name:"左",range:[15,165]},{name:"右",range:[-165,-15]},{name:"下",range:[-180.1,-165]},{name:"下",range:[165,180.1]}]};const Pt={degrees:!0,map:At,front:{x:0,y:0,z:1},up:{x:0,y:1,z:0}};let Ot=class{constructor(t){Dt(this,"_options"),Dt(this,"_listMap"),Dt(this,"_front"),Dt(this,"_up"),t&&(this.options=t)}static get options(){return this._options??(this.options=Pt)}static set options(t){this._options=Object.assign({},structuredClone(At),t)}get defaultOptions(){return this.constructor.options}get options(){return this._options??(this.options=this.defaultOptions)}set options(t){this._options=Object.assign({},structuredClone(this.defaultOptions),t),this._listMap=null,this._front=null,this._up=null}get degrees(){return this.options.degrees??(this.options.degrees=this.defaultOptions.degrees??!0)}set degrees(t){this.options.degrees=t}get map(){return this.options.map||(this.map=this.defaultOptions.map),this.options.map}set map(t){const e=structuredClone(this.defaultOptions.map),n=structuredClone(At);t=t?{yaw:t.yaw??e.yaw??n.yaw,pitch:t.pitch??e.pitch??n.pitch,roll:t.roll??e.roll??n.roll}:e,this.options.map=t,this._listMap=null}get listMap(){return this._listMap??(this._listMap=function(t){const e={};for(const[n,i]of Object.entries(t))e[n]=Array.isArray(i)?i:Object.entries(i).map(([t,e])=>({name:t,range:e}));return e}(this.map??{}))}get front(){return this._front||(this.front=this.options.front??this.defaultOptions.front??Pt.front),this._front}set front(t){this._front=(new a).copy(t)}get up(){return this._up||(this.up=this.options.up??this.defaultOptions.up??Pt.up),this._up}set up(t){this._up=(new a).copy(t)}computeAzimuth(t,e,n){const i=(new a).copy(t),o=(new a).copy(e??this.front),r=(new a).copy(n??this.up);let{yaw:s,pitch:l,roll:c}=function(t,e,n){const i=e.clone().negate(),a=n.clone().projectOnPlane(e),o=Nt(e,t.clone().projectOnPlane(a),a),r=e.clone().cross(a);return{yaw:o,pitch:Nt(e,t.clone().projectOnPlane(r),r),roll:Nt(a,t.clone().projectOnPlane(i),i)}}(i,o,r);return this.degrees&&(s*=Ut,l*=Ut,c*=Ut),{yaw:{angle:s,name:this.findAzimuthNames("yaw",s)},pitch:{angle:l,name:this.findAzimuthNames("pitch",l)},roll:{angle:c,name:this.findAzimuthNames("roll",c)}}}findAzimuthNames(t,e){const n=[],i=this.listMap[t];if(!i)return n;for(const{name:t,range:[a,o]}of i)(e>=a&&e<o||e<=a&&e>o)&&n.push(t);return n}};Dt(Ot,"_options"),new Ot;const It={[r]:1,[s]:1,[l]:1,[c]:3,[u]:2,[d]:4,[m]:4,[p]:1,[f]:2,[h]:1,[v]:2};function Tt(t){return It[t]}new n;var Ft=Object.defineProperty,Rt=(t,e,n)=>(((t,e,n)=>{e in t?Ft(t,e,{enumerable:!0,configurable:!0,writable:!0,value:n}):t[e]=n})(t,"symbol"!=typeof e?e+"":e,n),n);var Vt=(t=>(t[t.Fill=0]="Fill",t[t.Align=1]="Align",t[t.Raw=2]="Raw",t))(Vt||{});class Et extends g{constructor(t){const{map:e,opacity:n,accFactor:i,steps:r,alphaRange:s,fit:l,atomize:c,side:u,containerMin:d,containerMax:m,uniforms:p,...f}=t??{},h=n??1,v=i??1,g=r??100,_=(new o).copy(s??{x:0,y:.95}),y=l??0,w=c??!0,M=u??N,z=(new a).copy(d??{x:0,y:0,z:0}),D=new a;if(m)D.copy(m);else if(e){const{width:t,height:n,depth:i}=e.image,o=new a(t-1,n-1,i-1);D.addVectors(z,o)}const S={map:{value:e},containerMin:{value:z},containerMax:{value:D},fit:{value:y},opacity:{value:h},alphaRange:{value:_},accFactor:{value:v},steps:{value:g},isDoubleSide:{value:!1},atomize:{value:w},...p};super({glslVersion:x,uniforms:S,transparent:!0,vertexShader:"precision highp sampler3D;\n\nuniform sampler3D map;\nuniform vec3 containerMin;\nuniform vec3 containerMax;\n\n// 0: 充满;1: 对齐;2: 原始\nuniform int fit;\n\n\nout vec3 cameraPos;\nout vec3 lookDir;\nout vec3 displayMin;\nout vec3 displayMax;\n\n\n\nvoid main() {\n cameraPos = vec3( inverse( modelMatrix ) * vec4( cameraPosition, 1.0 ) ).xyz;\n lookDir = position - cameraPos;\n\n vec3 containerSize = containerMax - containerMin;\n vec3 origin = containerMin;\n vec3 textSize = vec3(textureSize(map,0));\n displayMin = containerMin;\n displayMax = containerMax;\n\n switch (fit) {\n case 1:\n displayMax = displayMin + textSize;\n break;\n case 2:\n origin = vec3(0.0);\n break;\n default:\n textSize = containerSize;\n }\n\n vec3 scale = 1.0/textSize;\n cameraPos = (cameraPos - origin)*scale;\n lookDir *= scale;\n\n displayMin = max((displayMin - origin)*scale,vec3(0.0));\n displayMax = min((displayMax - origin)*scale,vec3(1.0));\n \n gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n}",...f}),Rt(this,"isVolumeMaterial",!0),Rt(this,"_side",N),this.opacity=h,this.side=M}get map(){return this.uniforms.map.value}set map(t){this.uniforms.map.value=t,this.uniformsNeedUpdate=!0}get containerMin(){return this.uniforms.containerMin.value}set containerMin(t){this.uniforms.containerMin.value.copy(t),this.uniformsNeedUpdate=!0}get containerMax(){return this.uniforms.containerMax.value}set containerMax(t){this.uniforms.containerMax.value.copy(t),this.uniformsNeedUpdate=!0}get containerSize(){return this.containerMax.clone().sub(this.containerMin)}get fit(){return this.uniforms.fit.value}set fit(t){this.uniforms.fit.value=t,this.uniformsNeedUpdate=!0}getFitTranslate(){return 2===this.fit?new a:this.containerMin.clone()}getFitScale(){var t;const e=new a(1,1,1),n=null==(t=this.map)?void 0:t.image,i=this.fit;if(!n||2===i||1===i)return e;const o=new a(n.width,n.height,n.depth);return e.copy(this.containerSize).divide(o),e}getFitMatrix(){var t;const e=new _,n=null==(t=this.map)?void 0:t.image,i=this.fit;if(!n||2===i)return e;if(0===i){const t=new a(n.width,n.height,n.depth),i=this.containerSize.divide(t);e.makeScale(i.x,i.y,i.z)}return e.setPosition(this.containerMin),e}getFitMatrixInvert(){return this.getFitMatrix().invert()}get side(){return this._side}set side(t){this._side=t,this.uniforms&&(this.uniforms.isDoubleSide.value=t===y,this.uniformsNeedUpdate=!0)}get opacity(){return this.uniforms.opacity.value}set opacity(t){this.uniforms&&(this.uniforms.opacity.value=t),this.uniformsNeedUpdate=!0}get alphaRange(){return this.uniforms.alphaRange.value}set alphaRange(t){this.uniforms.alphaRange.value.copy(t),this.uniformsNeedUpdate=!0}get atomize(){return this.uniforms.atomize.value}set atomize(t){this.uniforms.atomize.value=t,this.uniformsNeedUpdate=!0}get steps(){return this.uniforms.steps.value}set steps(t){this.uniforms.steps.value=t,this.uniformsNeedUpdate=!0}get accFactor(){return this.uniforms.accFactor.value}set accFactor(t){this.uniforms&&(this.uniforms.accFactor.value=t),this.uniformsNeedUpdate=!0}toMapPosition(t){const e=new a(t.x,t.y,t.z).applyMatrix4(this.getFitMatrixInvert());return e.set(Math.trunc(e.x),Math.trunc(e.y),Math.trunc(e.z)),e}toMapDepth(t,e){const i=k.toKey(t),o=new a;o[i]=1;const r=(new n).setFromMatrix4(this.getFitMatrix());return o.applyMatrix3(r),e/=o.length(),Math.trunc(e)}getData3DSlice(t,e){const n=this.map;return null!=n&&n.image?function(t,e,n){const{data:i,width:a,height:o,depth:r}=t.image;return dt({data:i,size:{x:a,y:o,z:r}},e,n,Tt(t.format))}(n,t,e=this.toMapDepth(t,e)):null}getItem(t){const e=this.map;return null!=e&&e.image?function(t,e){const{data:n,width:i,height:a,depth:o}=t.image;return rt({data:n,size:{x:i,y:a,z:o}},e,Tt(t.format))}(e,this.toMapPosition(t)).value:null}}function Gt(t){t.boundingBox||t.computeBoundingBox();const{x:e,y:n,z:i}=t.boundingBox.min;return t.translate(-e,-n,-i),t}class jt extends w{constructor(t){var e;const{width:n,height:i,depth:a}=(null==(e=t.map)?void 0:e.image)||{},o=new M(n,i,a);Gt(o),super(o,t),Rt(this,"isVolumeMesh",!0),Rt(this,"_geometry"),Rt(this,"autoUpdateMaterial",!0),Rt(this,"_material"),Rt(this,"autoUpdateGeometry",!0),Rt(this,"autoNormalize",!1),Object.defineProperties(this,{geometry:{get:()=>this._geometry,set:t=>{this._geometry=t,this.autoNormalize?this.normalize():this.autoUpdateMaterial&&this.updateMaterial()}},material:{get:()=>this._material,set:t=>{this._material=t,this.autoUpdateGeometry&&this.updateGeometry()}}}),this.geometry=o,this.material=t}updateMaterial(){const{geometry:t,material:e}=this;if(!e||!t)return!1;t.boundingBox||t.computeBoundingBox();const{min:n,max:i}=t.boundingBox;e.containerMin=n,e.containerMax=i}updateGeometry(){var t;const{geometry:e,material:n,autoUpdateMaterial:i}=this,o=null==(t=n.map)?void 0:t.image;if(!o)return!1;e.boundingBox||e.computeBoundingBox();const{width:r,height:s,depth:l}=o,c=e.boundingBox.getSize(new a);e.scale(r/c.x,s/c.y,l/c.z),i&&this.updateMaterial()}normalize(){const{geometry:t,autoUpdateMaterial:e}=this;t.boundingBox||t.computeBoundingBox();const{x:n,y:i,z:a}=t.boundingBox.min;t.translate(-n,-i,-a),e&&this.updateMaterial()}toMapPosition(t){const e=this.worldToLocal(new a(t.x,t.y,t.z));return this.material.toMapPosition(e)}toMaterialDepth(t,e){const i=k.toKey(t),o=new a;o[i]=1;const r=(new n).setFromMatrix4(this.matrixWorld);return o.applyMatrix3(r),e/=o.length()}toMapDepth(t,e){return e=this.toMaterialDepth(t,e),this.material.toMapDepth(t,e)}getData3DSlice(t,e){return e=this.toMaterialDepth(t,e),this.material.getData3DSlice(t,e)}getItem(t){const e=this.worldToLocal(new a(t.x,t.y,t.z));return this.material.getItem(e)}}class Lt extends Et{constructor(t){const{gradient:e,range:n,discardOut:i,voidRange:a,...r}=t??{},s=(new o).copy(n??{x:0,y:100}),l=i??!0,c=(new o).copy(a??{x:-100,y:-1});super({...r,fragmentShader:"precision highp float;\nprecision highp sampler3D;\n\nuniform sampler3D map;\nuniform sampler2D gradient;\n\nuniform bool atomize;\nuniform float steps;\n// 颜色累积系数\nuniform float accFactor;\nuniform vec2 range;\n// 是否丢弃超出范围的像素\nuniform bool discardOut;\n// 空值范围\nuniform vec2 voidRange;\nuniform float opacity;\nuniform vec2 alphaRange;\nuniform bool isDoubleSide;\n\nin vec3 cameraPos;\nin vec3 lookDir;\nin vec3 displayMin;\nin vec3 displayMax;\nout vec4 fragColor;\n\nvec4 colorBlend(vec4 near,vec4 far){\n float nA = near.a;\n if (nA >= 1.0){\n return near;\n }\n if (nA <= 0.0){\n return far;\n }\n \n float fA = far.a;\n float a = fA + nA - fA*nA;\n vec3 color = (far.rgb * fA * (1.0 - nA) + near.rgb*nA)/a;\n return vec4(color,a);\n}\n\n\n\n\nvec2 intersectBox( vec3 orig, vec3 dir ) {\n vec3 inv_dir = 1.0 / dir;\n vec3 tmin_tmp = (displayMin - orig ) * inv_dir;\n vec3 tmax_tmp = (displayMax - orig ) * inv_dir;\n vec3 tmin = min( tmin_tmp, tmax_tmp );\n vec3 tmax = max( tmin_tmp, tmax_tmp );\n float t0 = max( tmin.x, max( tmin.y, tmin.z ) );\n float t1 = min( tmax.x, min( tmax.y, tmax.z ) );\n return vec2( t0, t1 );\n}\n\nfloat getValue( vec3 point ) {\n return texture( map, point ).r;\n}\n\n// 获取梯度颜色\nvec4 getGradientColor(float val) {\n val = clamp( val, 0.0,1.0);\n return texture2D(gradient, vec2(val, 0.5));\n}\n\n\n\n\nvoid main(){\n vec3 rayDir = normalize( lookDir );\n\n vec2 times = intersectBox( cameraPos, rayDir );\n float tMin = times.x;\n float tMax = times.y;\n if ( tMin > tMax || tMax < 0.0 ) discard;\n tMin = max( tMin, 0.0 );\n\n vec3 point = cameraPos + tMin * rayDir;\n \n float step = 1.0/steps;\n float opacityFactor = atomize ? step * accFactor : 1.0;\n\n\n float invRangeLen = 1.0/(range.y - range.x);\n vec3 stepDir = rayDir * step;\n\n vec4 finalColor = vec4( 0,0,0,0);\n float alphaMax = alphaRange.y;\n\n for ( float t = tMin; t <= tMax; t += step,point += stepDir ) {\n float val = getValue( point);\n if (voidRange.x <= val && val <= voidRange.y ) continue;\n val = (val - range.x) * invRangeLen;\n if (discardOut && (val < 0.0 || val > 1.0)) continue;\n\n vec4 gradientColor = getGradientColor(val);\n gradientColor.a *= opacityFactor;\n finalColor = colorBlend(finalColor,gradientColor);\n if ( finalColor.a >= alphaMax ) break;\n }\n\n finalColor.a *= opacity;\n if ( finalColor.a <= alphaRange.x ) discard;\n if (isDoubleSide){\n finalColor.a = 1.0 - sqrt(1.0 - finalColor.a);\n }\n fragColor = finalColor;\n\n}",uniforms:{gradient:{value:null==e?e:Ct(e)},range:{value:s},discardOut:{value:l},voidRange:{value:c}}}),Rt(this,"isGradientVolumeMaterial",!0)}get gradient(){return this.uniforms.gradient.value}set gradient(t){this.uniforms.gradient.value=t,this.uniformsNeedUpdate=!0}get range(){return this.uniforms.range.value}set range(t){this.uniforms.range.value.copy(t),this.uniformsNeedUpdate=!0}get discardOut(){return this.uniforms.discardOut.value}set discardOut(t){this.uniforms.discardOut.value=t,this.uniformsNeedUpdate=!0}get voidRange(){return this.uniforms.voidRange.value}set voidRange(t){this.uniforms.voidRange.value.copy(t),this.uniformsNeedUpdate=!0}}class Bt extends z{constructor(t,e,n,i,a){super(t,e,n,i),Rt(this,"isGradientData3DTexture",!0),this.format=s,this.type=a??D,this.minFilter=this.magFilter=S,this.unpackAlignment=1,this.needsUpdate=!0}getData3DSlice(t,e){const{data:n,width:i,height:a,depth:o}=this.image;return dt({data:n,size:{x:i,y:a,z:o}},t,e,1)}getItem(t){const{data:e,width:n,height:i,depth:a}=this.image;return rt({data:e,size:{x:n,y:i,z:a}},t).value}getValue(t){const{data:e,width:n,height:i,depth:a}=this.image;return lt({data:e,size:{x:n,y:i,z:a}},t).value}}function kt(t,e){const{data:n,size:i}=t,{x:a,y:o,z:r}=i,s=a*o*r,{voidValue:l=0,uint8:c}=e??{};let u;if(c){u=new Uint8Array(s);for(let t=0;t<s;t++){const e=n[t]??l;u[t]=Math.trunc(e)}}else{u=new Float32Array(s);for(let t=0;t<s;t++){const e=n[t]??l;u[t]=e}}return new Bt(u,a,o,r,c?b:D)}class Ht extends Et{constructor(t){super({...t,fragmentShader:"precision highp float;\nprecision highp sampler3D;\n\nuniform sampler3D map;\n\n\n\n// 颜色累积系数\nuniform float accFactor;\nuniform bool isDoubleSide;\nuniform bool atomize;\n\n\nuniform float opacity;\nuniform vec2 alphaRange;\nuniform float steps;\n\nin vec3 cameraPos;\nin vec3 lookDir;\nin vec3 displayMin;\nin vec3 displayMax;\nout vec4 fragColor;\n\n// 混合颜色\nvec4 colorBlend(vec4 near,vec4 far){\n float nA = near.a;\n if (nA >= 1.0){\n return near;\n }\n if (nA <= 0.0){\n return far;\n }\n \n float fA = far.a;\n float a = fA + nA - fA*nA;\n vec3 color = (far.rgb * fA * (1.0 - nA) + near.rgb*nA)/a;\n return vec4(color,a);\n}\n\n\n\n\n// 包围盒求交\nvec2 intersectBox( vec3 orig, vec3 dir ) {\n vec3 inv_dir = 1.0 / dir;\n vec3 tmin_tmp = (displayMin - orig ) * inv_dir;\n vec3 tmax_tmp = (displayMax - orig ) * inv_dir;\n vec3 tmin = min( tmin_tmp, tmax_tmp );\n vec3 tmax = max( tmin_tmp, tmax_tmp );\n float t0 = max( tmin.x, max( tmin.y, tmin.z ) );\n float t1 = min( tmax.x, min( tmax.y, tmax.z ) );\n return vec2( t0, t1 );\n}\n\n\n\nvoid main(){\n vec3 rayDir = normalize( lookDir );\n\n vec2 times = intersectBox( cameraPos, rayDir );\n float tMin = times.x;\n float tMax = times.y;\n if ( tMin > tMax || tMax < 0.0 ) discard;\n tMin = max( tMin, 0.0 );\n\n vec3 point = cameraPos + tMin * rayDir;\n \n float step = 1.0/steps;\n float opacityFactor = atomize ? step * accFactor : 1.0;\n\n vec3 stepDir = rayDir * step;\n\n vec4 finalColor = vec4( 0,0,0,0);\n float alphaMax = alphaRange.y;\n\n for ( float t = tMin; t <= tMax; t += step,point += stepDir ) {\n vec4 textureColor = texture( map, point );\n textureColor.a *= opacityFactor;\n finalColor = colorBlend(finalColor,textureColor);\n if ( finalColor.a >= alphaMax ) break;\n }\n\n finalColor.a *= opacity;\n if ( finalColor.a <= alphaRange.x ) discard;\n if (isDoubleSide){\n finalColor.a = 1.0 - sqrt(1.0 - finalColor.a);\n }\n fragColor = finalColor;\n\n}"}),Rt(this,"isImageVolumeMaterial",!0)}}function qt(t,e,n){const i=n??{},{x:a,y:o}=i.range??{x:0,y:100},r=i.discardOut??!0,{x:s,y:l}=i.voidRange??{x:-100,y:-1},c=i.voidColor??[0,0,0,0],{width:u,height:d}=e,m=Math.trunc(d/2),p=u-1;function f(t){const n=Math.trunc(p*t);return Q(e,m,n)}const h=1/(o-a),{data:v,size:g}=t,x=v.length,_=[];for(let t=0;t<x;t++){let e=c,n=v[t];(n<=s||l<=n)&&(n=(n-a)*h,r&&(n<0||n>1)||(n=Math.min(Math.max(n,0),1),e=f(n))),_.push(...e)}return{data:_,size:g}}class Kt extends z{constructor(t,e,n,i){super(t,e,n,i),Rt(this,"isImageData3DTexture",!0),this.format=d,this.type=b,this.minFilter=this.magFilter=S,this.unpackAlignment=1,this.needsUpdate=!0}getData3DSlice(t,e){const{data:n,width:i,height:a,depth:o}=this.image;return dt({data:n,size:{x:i,y:a,z:o}},t,e,4)}getItem(t){return this.getColor(t)}getColor(t){const{data:e,width:n,height:i,depth:a}=this.image;return rt({data:e,size:{x:n,y:i,z:a}},t,4).value}}function Wt(t,e,n){const i=(null==n?void 0:n.reverseY)??!0,{data:a,width:o,height:r,depth:s,colorSpace:l}=pt(t,e,{...n,reverseY:i}),c=new Kt(a,o,r,s);return"srgb"===l&&(c.colorSpace="srgb"),c}function Yt(t,e){const n=e.gradient,i=Array.isArray(n)?W(n,256,1):et(n)?n:Y(n);let a=t;nt(t)&&(a={data:t.data,size:{x:t.width,y:t.height,z:t.depth}});const{data:o,size:r}=qt(a,i,e),s=Uint8ClampedArray.from(o);return new Kt(s,r.x,r.y,r.z)}class Xt extends g{constructor(t){const e=t??{},n=e.color??new C(1,1,1),i=e.solid??0,a=e.exp??1,o=e.opacity??1,r=e.side??N;super({glslVersion:x,uniforms:{color:{value:n},solid:{value:i},exp:{value:a},opacity:{value:o},isDoubleSide:{value:!1}},vertexShader:"out vec3 lookDir;\nout vec3 normalDir;\n\n#if defined( USE_COLOR_ALPHA ) || defined( USE_COLOR )\n out vec4 verColor;\n#endif\n\nvoid main() {\n vec3 cameraPos = vec3( inverse( modelMatrix ) * vec4( cameraPosition, 1.0 ) ).xyz;\n lookDir = position - cameraPos;\n normalDir = normal;\n\n #if defined( USE_COLOR_ALPHA )\n verColor = color;\n #elif defined( USE_INSTANCING_COLOR )\n overColor = vec3(instanceColor,1.0);\n #elif defined( USE_COLOR )\n overColor = vec3(color,1.0);\n #endif\n gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n}",fragmentShader:"uniform vec3 color;\nuniform float solid;\nuniform float exp;\n\nuniform float opacity;\nuniform bool isDoubleSide;\n\nin vec3 lookDir;\nin vec3 normalDir;\n\n#if defined( USE_COLOR_ALPHA ) || defined( USE_COLOR )\n in vec4 verColor;\n#endif\n\nout vec4 fragColor;\n\n\nvoid main(){\n #if defined( USE_COLOR_ALPHA ) || defined( USE_COLOR )\n fragColor = verColor;\n #else\n fragColor = vec4(color,1.0);\n #endif\n\n vec3 dir = normalize(lookDir);\n vec3 nor = normalize(normalDir);\n float depth = abs(dot(nor,dir));\n float dist = sqrt(1.0 - pow(depth,2.0));\n\n float finalAlpha = fragColor.a * depth;\n if (dist > solid) {\n float distAlpha = 1.0 - (dist - solid)/(1.0 - solid);\n finalAlpha *= pow(distAlpha,exp);\n }\n \n finalAlpha *= opacity;\n if ( finalAlpha == 0.0 ) discard;\n if (isDoubleSide){\n finalAlpha = 1.0 - sqrt(1.0 - finalAlpha);\n }\n fragColor.a = finalAlpha;\n}",side:N,transparent:!0}),Rt(this,"isSphereFogMaterial",!0),Rt(this,"_side",N),this.opacity=o,this.side=r}get side(){return this._side}set side(t){this._side=t,this.uniforms&&(this.uniforms.isDoubleSide.value=t===y,this.uniformsNeedUpdate=!0)}get color(){return this.uniforms.color.value}set color(t){this.uniforms.color.value.copy(t),this.uniformsNeedUpdate=!0}get opacity(){return this.uniforms.opacity.value}set opacity(t){this.uniforms&&(this.uniforms.opacity.value=t),this.uniformsNeedUpdate=!0}get solid(){return this.uniforms.solid.value}set solid(t){this.uniforms&&(this.uniforms.solid.value=t),this.uniformsNeedUpdate=!0}get exp(){return this.uniforms.exp.value}set exp(t){this.uniforms&&(this.uniforms.exp.value=t),this.uniformsNeedUpdate=!0}}class Zt extends g{constructor(t,e){const{solid:n=0,exp:i=1,useRadius:a=!0,sizeAttenuation:o=!0,star:r=!1,...s}=t??{},{uniforms:l,...c}=e||{},u={star:{value:r},solid:{value:n},exp:{value:i}};super({uniforms:U.merge([A.points.uniforms,u,l]),transparent:!0,depthTest:!1,defines:{useRadius:a},...c}),Rt(this,"isFogPointsMaterial",!0),Rt(this,"sizeAttenuation",!0),Object.assign(this,{...s,solid:n,exp:i,sizeAttenuation:o})}get map(){return this.uniforms.map.value}set map(t){this.uniforms.map.value=t,this.uniformsNeedUpdate=!0}get star(){return this.uniforms.star.value}set star(t){this.uniforms.star.value=t,this.uniformsNeedUpdate=!0}get size(){return this.uniforms.size.value}set size(t){this.uniforms.size.value=t,this.uniformsNeedUpdate=!0}get opacity(){return this.uniforms.opacity.value}set opacity(t){this.uniforms&&(this.uniforms.opacity.value=t),this.uniformsNeedUpdate=!0}get solid(){return this.uniforms.solid.value}set solid(t){this.uniforms&&(this.uniforms.solid.value=t),this.uniformsNeedUpdate=!0}get exp(){return this.uniforms.exp.value}set exp(t){this.uniforms&&(this.uniforms.exp.value=t),this.uniformsNeedUpdate=!0}get scale(){return this.uniforms.scale.value}set scale(t){this.uniforms&&(this.uniforms.scale.value=t),this.uniformsNeedUpdate=!0}get fogDensity(){return this.uniforms.fogDensity.value}set fogDensity(t){this.uniforms&&(this.uniforms.fogDensity.value=t),this.uniformsNeedUpdate=!0}get fogNear(){return this.uniforms.fogNear.value}set fogNear(t){this.uniforms&&(this.uniforms.fogNear.value=t),this.uniformsNeedUpdate=!0}get fogFar(){return this.uniforms.fogFar.value}set fogFar(t){this.uniforms&&(this.uniforms.fogFar.value=t),this.uniformsNeedUpdate=!0}get fogColor(){return this.uniforms.fogColor.value}set fogColor(t){this.uniforms.fogColor.value.copy(t),this.uniformsNeedUpdate=!0}}class Jt extends Zt{constructor(t){super(t,{vertexShader:"#ifdef useRadius\n\tattribute float radius;\n#endif\n\nuniform float size;\nuniform float scale;\n\n#include <common>\n#include <color_pars_vertex>\n#include <fog_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\n\n#ifdef USE_POINTS_UV\n\n\tvarying vec2 vUv;\n\tuniform mat3 uvTransform;\n\n#endif\n\nvoid main() {\n\n\t#ifdef USE_POINTS_UV\n\n\t\tvUv = ( uvTransform * vec3( uv, 1 ) ).xy;\n\n\t#endif\n\n\t#include <color_vertex>\n\t#include <morphcolor_vertex>\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <project_vertex>\n\n\t#ifdef useRadius\n\t\tgl_PointSize = radius;\n\t#else\n\t\tgl_PointSize = size;\n\t#endif\n\n\t#ifdef USE_SIZEATTENUATION\n\n\t\tbool isPerspective = isPerspectiveMatrix( projectionMatrix );\n\n\t\tif ( isPerspective ) gl_PointSize *= ( scale / - mvPosition.z );\n\n\t#endif\n\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\t#include <worldpos_vertex>\n\t#include <fog_vertex>\n\n}",fragmentShader:"uniform float solid;\nuniform float exp;\nuniform bool star;\n\nuniform vec3 diffuse;\nuniform float opacity;\n\n#include <common>\n#include <color_pars_fragment>\n#include <map_particle_pars_fragment>\n#include <alphatest_pars_fragment>\n#include <fog_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\n\n\nvec4 getColor(vec4 originColor){\n\tfloat finalAlpha = originColor.a;\n\tfloat dist = 0.0;\n\tif (star){\n\t\tvec2 coord = abs(gl_PointCoord - vec2(0.5));\n\t\tdist = max(coord.x,coord.y);\n\t}else{\n\t\tdist = distance(gl_PointCoord,vec2(0.5));\n\t\tif (dist>0.5) discard;\n\t}\n\tdist /= 0.5;\n\tfloat depth = sqrt(1.0 - pow(dist,2.0));\n\tfinalAlpha *= depth;\n if (dist > solid) {\n float distAlpha = 1.0 - (dist - solid)/(1.0 - solid);\n finalAlpha *= pow(distAlpha,exp);\n }\n\toriginColor.a = finalAlpha;\n\treturn originColor;\n}\n\nvoid main() {\n\n\t#include <clipping_planes_fragment>\n\n\tvec3 outgoingLight = vec3( 0.0 );\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\n\t#include <logdepthbuf_fragment>\n\t#include <map_particle_fragment>\n\t#include <color_fragment>\n\t#include <alphatest_fragment>\n\n\tdiffuseColor = getColor(diffuseColor);\n\toutgoingLight = diffuseColor.rgb;\n\n\t#include <output_fragment>\n\t#include <tonemapping_fragment>\n\t#include <encodings_fragment>\n\t#include <fog_fragment>\n\t#include <premultiplied_alpha_fragment>\n\n}"}),Rt(this,"isColorFogPointsMaterial",!0)}get color(){return this.uniforms.diffuse.value}set color(t){this.uniforms.diffuse.value.copy(t),this.uniformsNeedUpdate=!0}get alphaMap(){return this.uniforms.alphaMap.value}set alphaMap(t){this.uniforms&&(this.uniforms.alphaMap.value=t),this.uniformsNeedUpdate=!0}get uvTransform(){return this.uniforms.uvTransform.value}set uvTransform(t){this.uniforms&&this.uniforms.uvTransform.value.copy(t),this.uniformsNeedUpdate=!0}}function Qt(t){const e=new Jt(t),n=function(t){const{points:e,radius:n=10,color:i=[0,0,0,0]}=t,a=[],o=[],r=[];for(const{x:t,y:s,z:l,radius:c,color:u}of e){a.push(t,s,l),o.push(c??n);const e=u??i,d=e[3];e[3]=Math.trunc(255*d),r.push(...e)}const s=new E;return s.setAttribute("position",new G(a,3)),s.setAttribute("radius",new G(o,1)),s.setAttribute("color",new j(r,4,!0)),s}(t);return new P(n,e)}class $t extends Zt{constructor(t){const{range:e,...n}=t||{};super(n,{vertexShader:"attribute float value;\nuniform vec2 range;\nvarying float vValue;\n#ifdef useRadius\n\tattribute float radius;\n#endif\n\n\nuniform float size;\nuniform float scale;\n\n#include <common>\n// #include <color_pars_vertex>\n#include <fog_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\n\n#ifdef USE_POINTS_UV\n\n\tvarying vec2 vUv;\n\tuniform mat3 uvTransform;\n\n#endif\n\nvoid main() {\n\tvValue = (value - range.x)/(range.y - range.x);\n\n\t#ifdef USE_POINTS_UV\n\n\t\tvUv = ( uvTransform * vec3( uv, 1 ) ).xy;\n\n\t#endif\n\n\t// #include <color_vertex>\n\t// #include <morphcolor_vertex>\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <project_vertex>\n\n\t#ifdef useRadius\n\t\tgl_PointSize = radius;\n\t#else\n\t\tgl_PointSize = size;\n\t#endif\n\n\t#ifdef USE_SIZEATTENUATION\n\n\t\tbool isPerspective = isPerspectiveMatrix( projectionMatrix );\n\n\t\tif ( isPerspective ) gl_PointSize *= ( scale / - mvPosition.z );\n\n\t#endif\n\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\t#include <worldpos_vertex>\n\t#include <fog_vertex>\n\n}",fragmentShader:"varying float vValue;\nuniform sampler2D map;\n\n\nuniform float solid;\nuniform float exp;\nuniform bool star;\n\n// uniform vec3 diffuse;\nuniform float opacity;\n\n#include <common>\n// #include <color_pars_fragment>\n// #include <map_particle_pars_fragment>\n#include <alphatest_pars_fragment>\n#include <fog_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\n\n\n// 获取梯度颜色\nvec4 getGradientColor(float val) {\n\tval = clamp( val, 0.0,1.0);\n return texture2D(map, vec2(val, 0.5));\n}\n\n\nvec4 getColor(){\n\tfloat val = vValue;\n\tfloat dist = 0.0;\n\tif (star){\n\t\tvec2 coord = abs(gl_PointCoord - vec2(0.5));\n\t\tdist = max(coord.x,coord.y);\n\t}else{\n\t\tdist = distance(gl_PointCoord,vec2(0.5));\n\t\tif (dist>0.5) discard;\n\t}\n\tdist /= 0.5;\n\tfloat depth = sqrt(1.0 - pow(dist,2.0));\n if (dist > solid) {\n float solidDist = 1.0 - (dist - solid)/(1.0 - solid);\n val *= pow(solidDist,exp);\n }\n\tvec4 valColor = getGradientColor(val);\n\tvalColor.a *= depth * opacity;\n\treturn valColor;\n}\n\nvoid main() {\n\n\t#include <clipping_planes_fragment>\n\n\tvec3 outgoingLight = vec3( 0.0 );\n\tvec4 diffuseColor = getColor();\n\n\t#include <logdepthbuf_fragment>\n\t// #include <map_particle_fragment>\n\t// #include <color_fragment>\n\t#include <alphatest_fragment>\n\n\toutgoingLight = diffuseColor.rgb;\n\n\t#include <output_fragment>\n\t#include <tonemapping_fragment>\n\t#include <encodings_fragment>\n\t#include <fog_fragment>\n\t#include <premultiplied_alpha_fragment>\n\n}",uniforms:{range:{value:(new o).copy(e??{x:0,y:100})}}}),Rt(this,"isColorFogPointsMaterial",!0)}get range(){return this.uniforms.range.value}set range(t){this.uniforms.range.value.copy(t),this.uniformsNeedUpdate=!0}}function te(t){const e=t.gradient,n=null==e?e:Ct(e),i=new $t({...t,map:n}),a=function(t){const{points:e,radius:n=10,value:i=100}=t,a=[],o=[],r=[];for(const{x:t,y:s,z:l,radius:c,value:u}of e)a.push(t,s,l),o.push(c??n),r.push(u??i);const s=new E;return s.setAttribute("position",new G(a,3)),s.setAttribute("radius",new G(o,1)),s.setAttribute("value",new G(r,1)),s}(t);return new P(a,i)}class ee extends g{constructor(t){const e=t??{};let{map:n,opacity:i,axis:a,depth:o,side:r,...s}=e;i=i??1,a=a??k.z,o=o??0,r=r??y,super({...s,glslVersion:x,uniforms:{map:{value:n},opacity:{value:i},axis:{value:a},depth:{value:o}},transparent:!0,vertexShader:"\tout vec2 vUv;\n \n\tvoid main() {\n\t\tvUv = uv;\n\t\tgl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n\t}",fragmentShader:"precision highp float;\nprecision highp sampler3D;\n\nuniform sampler3D map;\n\nuniform float opacity;\nuniform int axis;\nuniform float depth;\n\nin vec2 vUv;\nout vec4 fragColor;\n\nvoid main(){\n vec3 uv3 = vec3(0.0);\n int depthSize = textureSize(map,0)[axis];\n uv3[axis] = depth/float(depthSize);\n int xIndex = (axis + 1)%3;\n int yIndex = (axis + 2)%3;\n uv3[xIndex] = vUv.x;\n uv3[yIndex] = vUv.y;\n\n fragColor = texture(map, uv3);\n fragColor.a *= opacity;\n}",side:r}),Rt(this,"isSliceMaterial",!0),Rt(this,"_sliceSize",null),this.opacity=i}get map(){return this.uniforms.map.value}set map(t){this.uniforms.map.value=t,this._sliceSize=null,this.uniformsNeedUpdate=!0}get opacity(){return this.uniforms.opacity.value}set opacity(t){this.uniforms&&(this.uniforms.opacity.value=t),this.uniformsNeedUpdate=!0}get axis(){return this.uniforms.axis.value}set axis(t){this.uniforms.axis.value=t,this._sliceSize=null,this.uniformsNeedUpdate=!0}get depth(){return this.uniforms.depth.value}set depth(t){this.uniforms.depth.value=t,this.uniformsNeedUpdate=!0}get sliceSize(){let t=this._sliceSize;if(!t){this._sliceSize=t=new o(1,1);const{axis:e,map:n}=this;if(n){const{width:i,height:a,depth:o}=n.image,[r,s]=k.getCrossAxiss(e),l=[i,a,o];t.set(l[r],l[s])}}return t}}class ne extends w{constructor(t){const e=new ee(t),n=new O;super(n,e),Rt(this,"isSliceMesh",!0),Rt(this,"_geometry"),Rt(this,"_material"),Rt(this,"autoUpdateGeometry",!0),Object.defineProperties(this,{geometry:{get:()=>this._geometry,set:t=>{this._geometry=t,this.autoUpdateGeometry&&this.updateGeometry()}},material:{get:()=>this._material,set:t=>{this._material=t,this.autoUpdateGeometry&&this.updateGeometry()}}}),this.geometry=n,this.material=e}updateGeometry(){var t;const{geometry:e,material:n}=this;if(!n||!(null==(t=n.map)?void 0:t.image))return!1;e.boundingBox||e.computeBoundingBox();const i=n.sliceSize,o=e.boundingBox.getSize(new a);e.scale(i.x/o.x,i.y/o.y,1)}get map(){return this.material.map}set map(t){this.material.map=t,this.material=this.material}get axis(){return this.material.axis}set axis(t){this.material.axis=t,this.material=this.material}get depth(){return this.material.depth}set depth(t){this.material.depth=t}get sliceSize(){return this.material.sliceSize}}class ie extends Mt{constructor(t){super(nt(t)?t:t.image),Rt(this,"isImageData3DTextureSlice",!0)}set texture(t){this.image3D=nt(t)?t:t.image}}function ae({ratio:t,value:e}){return e-e*t}function oe(t,e){const{x:n,y:i}=e;let a=0;for(const{value:e,clim:{x:n,y:i}}of t)a+=(e-n)/(i-n);return a*(i-n)+n}function re(t,e,n){const{size:i,data3D:o,tags:r}=e,{clim:s,radius:l,value:c,hollow:u,valueGradient:d,valuesAccumulate:m}=t,p=(new a).copy(t),f=[],h=[],v={particles:f,values:h},g=l*u,x=p.clone().subScalar(l),_=p.clone().addScalar(l);x.max(new a(0,0,0));const y=(new a).copy(i).subScalar(1);_.min(y);let{x:w,y:M,z:z}=x;w=Math.trunc(w),M=Math.trunc(M),z=Math.trunc(z);let{x:D,y:S,z:b}=_;if(D=Math.trunc(D),S=Math.trunc(S),b=Math.trunc(b),w>D||M>S||z>b)return v;const{x:C,y:N}=i,U=C*N;for(let e=z;e<=b;e++){const i=e*U;for(let v=M;v<=S;v++){const x=i+v*C;t:for(let i=w;i<=D;i++){const _=x+i;if(r[_])continue;const y=new a(i,v,e),w=y.distanceTo(p);if(w>l||w<g)continue;r[_]=!0;const M=[],z={...{radius:l,hollow:u,hollowRadius:g,distance:w,clim:s,value:c},ratio:w/l,distance:w,point:y},D=d(z);M.push({...t,...z,value:D});for(const t of n){const e=y.distanceTo(t),{hollow:n,radius:i}=t;if(e<=i){const a=i*n;if(e<a)continue t;const o={...t,ratio:e/i,distance:e,hollowRadius:a,point:y},r=d(o);M.push({...o,value:r})}}const S=m(M,s);o[_]=S,f.push(y),h.push(S)}}}return v}function se(t){const{points:e,clim:n={x:0,y:100},radius:i=10,value:a=100,hollow:o=0,valueGradient:r=ae,valuesAccumulate:s=oe,size:l}=t,c={clim:n,radius:i,value:a,hollow:o,valueGradient:r,valuesAccumulate:s},u=e.map(t=>({...c,...t}));let d=l;l||(d=(new I).setFromPoints(u).max.addScalar(1));const m=St(u);let{x:p,y:f,z:h}=d;p=d.x=Math.trunc(p),f=d.y=Math.trunc(f),h=d.z=Math.trunc(h);const v=new Array(p*f*h),g={size:d,data3D:v,tags:new Array(p*f*h)},x=u.length;for(let t=0;t<x;t++){re(u[t],g,m[t].map(t=>u[t]))}return{data:v,size:d}}function le({startRadius:t,addedRadius:e,ratio:n}){return e*n+t}function ce({startHollow:t,addedHollow:e,ratio:n}){return e*n+t}function ue({startValue:t,addedValue:e,ratio:n}){return e*n+t}function de(t,e){const{x:n,y:i}=e;return t.reduce((t,e)=>t+e-n,0)}function me(t){const{points:e,size:n,clim:i={x:0,y:100},radius:o=10,value:r=100,hollow:s=0,valueGradient:l=ae,radiusGradient:c=le,hollowGradient:u=ce,lineValueGradient:d=ue,valuesAccumulate:m=de}=t,p={radius:o,value:r,hollow:s},f=e.map(function(t){return Object.assign(new a,p,t)}),h=n?(new a).copy(n).subScalar(1):(new I).setFromPoints(f).max;h.x=Math.trunc(h.x),h.y=Math.trunc(h.y),h.z=Math.trunc(h.z);const v=h.clone().addScalar(1),{x:g,y:x,z:y}=v,w=g*x,M=new Array(w*y),z=[],D=[],S={particles:z,values:D,size:v,data:M},b=new a(0,0,0),C=e.length,N=Math.trunc(C/2);for(let t=0;t<N;t++){const e=2*t,n=f[e],p=f[e+1],v=new T(n,p),x=v.distance(),y=v.delta(new a).normalize(),C=new F;C.setFromUnitVectors(new a(0,1,0),y);const N=(new _).makeRotationFromQuaternion(C);N.setPosition(n);const{radius:U,value:A,hollow:P}=n,{radius:O,value:R,hollow:V}=p,E={length:x,startRadius:U,endRadius:O,addedRadius:O-U,defaultRadius:o,radius:o,startValue:A,endValue:R,addedValue:R-A,defaultValue:r,startHollow:P,endHollow:V,addedHollow:V-P,defaultHollow:s,clim:i},G=Math.max(U,O),j=new a(-G,0,-G),L=new a(G,x,G),B=new I(j,L);B.applyMatrix4(N);const{min:k,max:H}=B;k.max(b),H.min(h);let{x:q,y:K,z:W}=k;q=Math.trunc(q),K=Math.trunc(K),W=Math.trunc(W);let{x:Y,y:X,z:Z}=H;if(Y=Math.trunc(Y),X=Math.trunc(X),Z=Math.trunc(Z),q>Y||K>X||W>Z)return S;N.invert();for(let t=W;t<=Z;t++){const e=t*w;for(let n=K;n<=X;n++){const o=e+n*g;for(let e=q;e<=Y;e++){const r=o+e,s=new a(e,n,t),p=s.clone();p.applyMatrix4(N);const{x:f,y:h,z:v}=p;if(h<0||h>x)continue;const g=Math.hypot(f,v),_={...E,ratio:h/x,point:s},y=c(_);_.radius=y;const w=u(_),S=y*w;if(g>y||g<S)continue;const b=d(_);let C=l({...E,value:b,ratio:g/y,radius:y,hollow:w,hollowRadius:S,distance:g,point:s});const U=D[r];void 0!==U&&(C=m([U,C],i)),M[r]=C,z.push(s),D.push(C)}}}}return S}function pe(t,e){const i=(new a).setFromMatrixScale(e),o=Math.sqrt(i.lengthSq()/3),r=(new n).setFromMatrix4(e);let{points:s,size:l,radius:c,...u}=t;if(l&&(l=(new a).copy(l).applyMatrix3(r)),c&&(c*=o),s){const t=[];for(let{x:n,y:i,z:r,radius:l,...c}of s){l&&(l*=o);const s=new a(n,i,r).applyMatrix4(e);Object.assign(s,c,{radius:l}),t.push(s)}s=t}return{points:s,size:l,radius:c,...u}}function fe(t,e,n=1){let{points:i,size:o,radius:r,...s}=t;if(r&&(r*=n),i){const t=[];for(let{x:o,y:r,z:s,radius:l,...c}of i){l&&(l*=n);const i=new a(o,r,s).add(e).multiplyScalar(n);Object.assign(i,c,{radius:l}),t.push(i)}i=t}return o&&(o=(new a).copy(o).add(e).multiplyScalar(n)),{points:i,size:o,radius:r,...s}}function he(t,e){const{points:n,radius:i}=t;if(!n)return{options:t,position:new a,scale:1};const o=new I;for(const t of n){const e=(new a).copy(t),n=t.radius??i;n?(o.expandByPoint(e.clone().subScalar(n)),o.expandByPoint(e.addScalar(n))):o.expandByPoint(e)}const r=(new a).max(o.min),s=o.max.clone().sub(r).addScalar(1);t.size&&s.min(t.size);let{scale:l,maxSize:c}=e||{};l||(c=c??100,l=c/Math.max(s.x,s.y,s.z)),s.multiplyScalar(l);const u=fe(t,r.clone().negate(),l);return u.size=s,{options:u,position:r,scale:1/l}}const ve={uniforms:{u_size:{value:new a(1,1,1)},u_renderstyle:{value:0},u_renderthreshold:{value:.5},u_clim:{value:new o(1,1)},u_data:{value:null},u_cmdata:{value:null}},vertexShader:'\n\n\t\tvarying vec4 v_nearpos;\n\t\tvarying vec4 v_farpos;\n\t\tvarying vec3 v_position;\n\n\t\tvoid main() {\n\t\t\t\t// Prepare transforms to map to "camera view". See also:\n\t\t\t\t// https://threejs.org/docs/#api/renderers/webgl/WebGLProgram\n\t\t\t\tmat4 viewtransformf = modelViewMatrix;\n\t\t\t\tmat4 viewtransformi = inverse(modelViewMatrix);\n\n\t\t\t\t// Project local vertex coordinate to camera position. Then do a step\n\t\t\t\t// backward (in cam coords) to the near clipping plane, and project back. Do\n\t\t\t\t// the same for the far clipping plane. This gives us all the information we\n\t\t\t\t// need to calculate the ray and truncate it to the viewing cone.\n\t\t\t\tvec4 position4 = vec4(position, 1.0);\n\t\t\t\tvec4 pos_in_cam = viewtransformf * position4;\n\n\t\t\t\t// Intersection of ray and near clipping plane (z = -1 in clip coords)\n\t\t\t\tpos_in_cam.z = -pos_in_cam.w;\n\t\t\t\tv_nearpos = viewtransformi * pos_in_cam;\n\n\t\t\t\t// Intersection of ray and far clipping plane (z = +1 in clip coords)\n\t\t\t\tpos_in_cam.z = pos_in_cam.w;\n\t\t\t\tv_farpos = viewtransformi * pos_in_cam;\n\n\t\t\t\t// Set varyings and output pos\n\t\t\t\tv_position = position;\n\t\t\t\tgl_Position = projectionMatrix * viewMatrix * modelMatrix * position4;\n\t\t}',fragmentShader:"\n\n\t\t\t\tprecision highp float;\n\t\t\t\tprecision mediump sampler3D;\n\n\t\t\t\tuniform vec3 u_size;\n\t\t\t\tuniform int u_renderstyle;\n\t\t\t\tuniform float u_renderthreshold;\n\t\t\t\tuniform vec2 u_clim;\n\n\t\t\t\tuniform sampler3D u_data;\n\t\t\t\tuniform sampler2D u_cmdata;\n\n\t\t\t\tvarying vec3 v_position;\n\t\t\t\tvarying vec4 v_nearpos;\n\t\t\t\tvarying vec4 v_farpos;\n\n\t\t\t\t// The maximum distance through our rendering volume is sqrt(3).\n\t\t\t\tconst int MAX_STEPS = 887;\t// 887 for 512^3, 1774 for 1024^3\n\t\t\t\tconst int REFINEMENT_STEPS = 4;\n\t\t\t\tconst float relative_step_size = 1.0;\n\t\t\t\tconst vec4 ambient_color = vec4(0.2, 0.4, 0.2, 1.0);\n\t\t\t\tconst vec4 diffuse_color = vec4(0.8, 0.2, 0.2, 1.0);\n\t\t\t\tconst vec4 specular_color = vec4(1.0, 1.0, 1.0, 1.0);\n\t\t\t\tconst float shininess = 40.0;\n\n\t\t\t\tvoid cast_mip(vec3 start_loc, vec3 step, int nsteps, vec3 view_ray);\n\t\t\t\tvoid cast_iso(vec3 start_loc, vec3 step, int nsteps, vec3 view_ray);\n\n\t\t\t\tfloat sample1(vec3 texcoords);\n\t\t\t\tvec4 apply_colormap(float val);\n\t\t\t\tvec4 add_lighting(float val, vec3 loc, vec3 step, vec3 view_ray);\n\n\n\t\t\t\tvoid main() {\n\t\t\t\t\t\t// Normalize clipping plane info\n\t\t\t\t\t\tvec3 farpos = v_farpos.xyz / v_farpos.w;\n\t\t\t\t\t\tvec3 nearpos = v_nearpos.xyz / v_nearpos.w;\n\n\t\t\t\t\t\t// Calculate unit vector pointing in the view direction through this fragment.\n\t\t\t\t\t\tvec3 view_ray = normalize(nearpos.xyz - farpos.xyz);\n\n\t\t\t\t\t\t// Compute the (negative) distance to the front surface or near clipping plane.\n\t\t\t\t\t\t// v_position is the back face of the cuboid, so the initial distance calculated in the dot\n\t\t\t\t\t\t// product below is the distance from near clip plane to the back of the cuboid\n\t\t\t\t\t\tfloat distance = dot(nearpos - v_position, view_ray);\n\t\t\t\t\t\tdistance = max(distance, min((-0.5 - v_position.x) / view_ray.x,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t(u_size.x - 0.5 - v_position.x) / view_ray.x));\n\t\t\t\t\t\tdistance = max(distance, min((-0.5 - v_position.y) / view_ray.y,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t(u_size.y - 0.5 - v_position.y) / view_ray.y));\n\t\t\t\t\t\tdistance = max(distance, min((-0.5 - v_position.z) / view_ray.z,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t(u_size.z - 0.5 - v_position.z) / view_ray.z));\n\n\t\t\t\t\t\t// Now we have the starting position on the front surface\n\t\t\t\t\t\tvec3 front = v_position + view_ray * distance;\n\n\t\t\t\t\t\t// Decide how many steps to take\n\t\t\t\t\t\tint nsteps = int(-distance / relative_step_size + 0.5);\n\t\t\t\t\t\tif ( nsteps < 1 )\n\t\t\t\t\t\t\t\tdiscard;\n\n\t\t\t\t\t\t// Get starting location and step vector in texture coordinates\n\t\t\t\t\t\tvec3 step = ((v_position - front) / u_size) / float(nsteps);\n\t\t\t\t\t\tvec3 start_loc = front / u_size;\n\n\t\t\t\t\t\t// For testing: show the number of steps. This helps to establish\n\t\t\t\t\t\t// whether the rays are correctly oriented\n\t\t\t\t\t\t//'gl_FragColor = vec4(0.0, float(nsteps) / 1.0 / u_size.x, 1.0, 1.0);\n\t\t\t\t\t\t//'return;\n\n\t\t\t\t\t\tif (u_renderstyle == 0)\n\t\t\t\t\t\t\t\tcast_mip(start_loc, step, nsteps, view_ray);\n\t\t\t\t\t\telse if (u_renderstyle == 1)\n\t\t\t\t\t\t\t\tcast_iso(start_loc, step, nsteps, view_ray);\n\n\t\t\t\t\t\tif (gl_FragColor.a < 0.05)\n\t\t\t\t\t\t\t\tdiscard;\n\t\t\t\t}\n\n\n\t\t\t\tfloat sample1(vec3 texcoords) {\n\t\t\t\t\t\t/* Sample float value from a 3D texture. Assumes intensity data. */\n\t\t\t\t\t\treturn texture(u_data, texcoords.xyz).r;\n\t\t\t\t}\n\n\n\t\t\t\tvec4 apply_colormap(float val) {\n\t\t\t\t\t\tval = (val - u_clim[0]) / (u_clim[1] - u_clim[0]);\n\t\t\t\t\t\treturn texture2D(u_cmdata, vec2(val, 0.5));\n\t\t\t\t}\n\n\n\t\t\t\tvoid cast_mip(vec3 start_loc, vec3 step, int nsteps, vec3 view_ray) {\n\n\t\t\t\t\t\tfloat max_val = -1e6;\n\t\t\t\t\t\tint max_i = 100;\n\t\t\t\t\t\tvec3 loc = start_loc;\n\n\t\t\t\t\t\t// Enter the raycasting loop. In WebGL 1 the loop index cannot be compared with\n\t\t\t\t\t\t// non-constant expression. So we use a hard-coded max, and an additional condition\n\t\t\t\t\t\t// inside the loop.\n\t\t\t\t\t\tfor (int iter=0; iter<MAX_STEPS; iter++) {\n\t\t\t\t\t\t\t\tif (iter >= nsteps)\n\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t// Sample from the 3D texture\n\t\t\t\t\t\t\t\tfloat val = sample1(loc);\n\t\t\t\t\t\t\t\t// Apply MIP operation\n\t\t\t\t\t\t\t\tif (val > max_val) {\n\t\t\t\t\t\t\t\t\t\tmax_val = val;\n\t\t\t\t\t\t\t\t\t\tmax_i = iter;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t// Advance location deeper into the volume\n\t\t\t\t\t\t\t\tloc += step;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Refine location, gives crispier images\n\t\t\t\t\t\tvec3 iloc = start_loc + step * (float(max_i) - 0.5);\n\t\t\t\t\t\tvec3 istep = step / float(REFINEMENT_STEPS);\n\t\t\t\t\t\tfor (int i=0; i<REFINEMENT_STEPS; i++) {\n\t\t\t\t\t\t\t\tmax_val = max(max_val, sample1(iloc));\n\t\t\t\t\t\t\t\tiloc += istep;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Resolve final color\n\t\t\t\t\t\tgl_FragColor = apply_colormap(max_val);\n\t\t\t\t}\n\n\n\t\t\t\tvoid cast_iso(vec3 start_loc, vec3 step, int nsteps, vec3 view_ray) {\n\n\t\t\t\t\t\tgl_FragColor = vec4(0.0);\t// init transparent\n\t\t\t\t\t\tvec4 color3 = vec4(0.0);\t// final color\n\t\t\t\t\t\tvec3 dstep = 1.5 / u_size;\t// step to sample derivative\n\t\t\t\t\t\tvec3 loc = start_loc;\n\n\t\t\t\t\t\tfloat low_threshold = u_renderthreshold - 0.02 * (u_clim[1] - u_clim[0]);\n\n\t\t\t\t\t\t// Enter the raycasting loop. In WebGL 1 the loop index cannot be compared with\n\t\t\t\t\t\t// non-constant expression. So we use a hard-coded max, and an additional condition\n\t\t\t\t\t\t// inside the loop.\n\t\t\t\t\t\tfor (int iter=0; iter<MAX_STEPS; iter++) {\n\t\t\t\t\t\t\t\tif (iter >= nsteps)\n\t\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\t// Sample from the 3D texture\n\t\t\t\t\t\t\t\tfloat val = sample1(loc);\n\n\t\t\t\t\t\t\t\tif (val > low_threshold) {\n\t\t\t\t\t\t\t\t\t\t// Take the last interval in smaller steps\n\t\t\t\t\t\t\t\t\t\tvec3 iloc = loc - 0.5 * step;\n\t\t\t\t\t\t\t\t\t\tvec3 istep = step / float(REFINEMENT_STEPS);\n\t\t\t\t\t\t\t\t\t\tfor (int i=0; i<REFINEMENT_STEPS; i++) {\n\t\t\t\t\t\t\t\t\t\t\t\tval = sample1(iloc);\n\t\t\t\t\t\t\t\t\t\t\t\tif (val > u_renderthreshold) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tgl_FragColor = add_lighting(val, iloc, dstep, view_ray);\n\t\t\t\t\t\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\tiloc += istep;\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t// Advance location deeper into the volume\n\t\t\t\t\t\t\t\tloc += step;\n\t\t\t\t\t\t}\n\t\t\t\t}\n\n\n\t\t\t\tvec4 add_lighting(float val, vec3 loc, vec3 step, vec3 view_ray)\n\t\t\t\t{\n\t\t\t\t\t// Calculate color by incorporating lighting\n\n\t\t\t\t\t\t// View direction\n\t\t\t\t\t\tvec3 V = normalize(view_ray);\n\n\t\t\t\t\t\t// calculate normal vector from gradient\n\t\t\t\t\t\tvec3 N;\n\t\t\t\t\t\tfloat val1, val2;\n\t\t\t\t\t\tval1 = sample1(loc + vec3(-step[0], 0.0, 0.0));\n\t\t\t\t\t\tval2 = sample1(loc + vec3(+step[0], 0.0, 0.0));\n\t\t\t\t\t\tN[0] = val1 - val2;\n\t\t\t\t\t\tval = max(max(val1, val2), val);\n\t\t\t\t\t\tval1 = sample1(loc + vec3(0.0, -step[1], 0.0));\n\t\t\t\t\t\tval2 = sample1(loc + vec3(0.0, +step[1], 0.0));\n\t\t\t\t\t\tN[1] = val1 - val2;\n\t\t\t\t\t\tval = max(max(val1, val2), val);\n\t\t\t\t\t\tval1 = sample1(loc + vec3(0.0, 0.0, -step[2]));\n\t\t\t\t\t\tval2 = sample1(loc + vec3(0.0, 0.0, +step[2]));\n\t\t\t\t\t\tN[2] = val1 - val2;\n\t\t\t\t\t\tval = max(max(val1, val2), val);\n\n\t\t\t\t\t\tfloat gm = length(N); // gradient magnitude\n\t\t\t\t\t\tN = normalize(N);\n\n\t\t\t\t\t\t// Flip normal so it points towards viewer\n\t\t\t\t\t\tfloat Nselect = float(dot(N, V) > 0.0);\n\t\t\t\t\t\tN = (2.0 * Nselect - 1.0) * N;\t// ==\tNselect * N - (1.0-Nselect)*N;\n\n\t\t\t\t\t\t// Init colors\n\t\t\t\t\t\tvec4 ambient_color = vec4(0.0, 0.0, 0.0, 0.0);\n\t\t\t\t\t\tvec4 diffuse_color = vec4(0.0, 0.0, 0.0, 0.0);\n\t\t\t\t\t\tvec4 specular_color = vec4(0.0, 0.0, 0.0, 0.0);\n\n\t\t\t\t\t\t// note: could allow multiple lights\n\t\t\t\t\t\tfor (int i=0; i<1; i++)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t // Get light direction (make sure to prevent zero devision)\n\t\t\t\t\t\t\t\tvec3 L = normalize(view_ray);\t//lightDirs[i];\n\t\t\t\t\t\t\t\tfloat lightEnabled = float( length(L) > 0.0 );\n\t\t\t\t\t\t\t\tL = normalize(L + (1.0 - lightEnabled));\n\n\t\t\t\t\t\t\t\t// Calculate lighting properties\n\t\t\t\t\t\t\t\tfloat lambertTerm = clamp(dot(N, L), 0.0, 1.0);\n\t\t\t\t\t\t\t\tvec3 H = normalize(L+V); // Halfway vector\n\t\t\t\t\t\t\t\tfloat specularTerm = pow(max(dot(H, N), 0.0), shininess);\n\n\t\t\t\t\t\t\t\t// Calculate mask\n\t\t\t\t\t\t\t\tfloat mask1 = lightEnabled;\n\n\t\t\t\t\t\t\t\t// Calculate colors\n\t\t\t\t\t\t\t\tambient_color +=\tmask1 * ambient_color;\t// * gl_LightSource[i].ambient;\n\t\t\t\t\t\t\t\tdiffuse_color +=\tmask1 * lambertTerm;\n\t\t\t\t\t\t\t\tspecular_color += mask1 * specularTerm * specular_color;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Calculate final color by componing different components\n\t\t\t\t\t\tvec4 final_color;\n\t\t\t\t\t\tvec4 color = apply_colormap(val);\n\t\t\t\t\t\tfinal_color = color * (ambient_color + diffuse_color) + specular_color;\n\t\t\t\t\t\tfinal_color.a = color.a;\n\t\t\t\t\t\treturn final_color;\n\t\t\t\t}"};var ge=(t=>(t[t.MIP=0]="MIP",t[t.ISO=1]="ISO",t))(ge||{});class xe extends g{constructor(t){const{style:e,threshold:n,clim:i,map:r,gradient:s}=t??{},l=new a(1,1,1);if(r){const{width:t,height:e,depth:n}=r.image;l.set(t,e,n)}const c=null==s?s:Ct(s),u=U.clone(ve.uniforms);u.u_size.value.copy(l),u.u_clim.value.copy(i??new o(1,1)),u.u_renderstyle.value=e??1,u.u_renderthreshold.value=n??.5,u.u_data.value=r??null,u.u_cmdata.value=c??null,super({...ve,uniforms:u,side:R}),Rt(this,"isExampleVolumeMaterial_1",!0),Rt(this,"_gradient")}get map(){return this.uniforms.u_data.value}set map(t){this.uniforms.u_data.value=t,this.uniformsNeedUpdate=!0}get gradientMap(){return this.uniforms.u_cmdata.value}get gradient(){return this._gradient}set gradient(t){this._gradient=t;const e=null==t?t:Ct(t);this.uniforms.u_cmdata.value=e??null,this.uniformsNeedUpdate=!0}get size(){return this.uniforms.u_size.value}set size(t){this.uniforms.u_size.value.copy(t),this.uniformsNeedUpdate=!0}get style(){return this.uniforms.u_renderstyle.value}set style(t){this.uniforms.u_renderstyle.value=t,this.uniformsNeedUpdate=!0}get clim(){return this.uniforms.u_clim.value}set clim(t){this.uniforms.u_clim.value=t,this.uniformsNeedUpdate=!0}get threshold(){return this.uniforms.u_renderthreshold.value}set threshold(t){this.uniforms.u_renderthreshold.value=t,this.uniformsNeedUpdate=!0}}const _e="in vec3 position;\n\nuniform mat4 modelMatrix;\nuniform mat4 modelViewMatrix;\nuniform mat4 projectionMatrix;\nuniform vec3 cameraPos;\n\nout vec3 vOrigin;\nout vec3 vDirection;\n\nvoid main() {\n vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );\n vOrigin = vec3( inverse( modelMatrix ) * vec4( cameraPos, 1.0 ) ).xyz;\n vDirection = position - vOrigin;\n gl_Position = projectionMatrix * mvPosition;\n}";class ye extends V{constructor(t){let{color:e,threshold:n,map:i,opacity:o,range:r,steps:s,frame:l,cameraPos:c}=t??{};e=e??new C(1,1,1),n=n??.25,o=o??.25,r=r??.1,s=s??100,l=l??100,c=c??new a,super({glslVersion:x,uniforms:{base:{value:e},map:{value:i},cameraPos:{value:c},threshold:{value:n},opacity:{value:o},range:{value:r},steps:{value:s},frame:{value:l}},vertexShader:_e,fragmentShader:"precision highp float;\nprecision highp sampler3D;\n\nuniform mat4 modelViewMatrix;\nuniform mat4 projectionMatrix;\n\nin vec3 vOrigin;\nin vec3 vDirection;\n\nout vec4 color;\n\nuniform vec3 base;\nuniform sampler3D map;\n\nuniform float threshold;\nuniform float range;\nuniform float opacity;\nuniform float steps;\nuniform float frame;\n\nuint wang_hash(uint seed)\n{\n seed = (seed ^ 61u) ^ (seed >> 16u);\n seed *= 9u;\n seed = seed ^ (seed >> 4u);\n seed *= 0x27d4eb2du;\n seed = seed ^ (seed >> 15u);\n return seed;\n}\n\nfloat randomFloat(inout uint seed)\n{\n return float(wang_hash(seed)) / 4294967296.;\n}\n\nvec2 hitBox( vec3 orig, vec3 dir ) {\n const vec3 box_min = vec3( - 0.5 );\n const vec3 box_max = vec3( 0.5 );\n vec3 inv_dir = 1.0 / dir;\n vec3 tmin_tmp = ( box_min - orig ) * inv_dir;\n vec3 tmax_tmp = ( box_max - orig ) * inv_dir;\n vec3 tmin = min( tmin_tmp, tmax_tmp );\n vec3 tmax = max( tmin_tmp, tmax_tmp );\n float t0 = max( tmin.x, max( tmin.y, tmin.z ) );\n float t1 = min( tmax.x, min( tmax.y, tmax.z ) );\n return vec2( t0, t1 );\n}\n\nfloat sample1( vec3 p ) {\n return texture( map, p ).r;\n}\n\nfloat shading( vec3 coord ) {\n float step = 0.01;\n return sample1( coord + vec3( - step ) ) - sample1( coord + vec3( step ) );\n}\n\nvoid main(){\n vec3 rayDir = normalize( vDirection );\n vec2 bounds = hitBox( vOrigin, rayDir );\n\n if ( bounds.x > bounds.y ) discard;\n\n bounds.x = max( bounds.x, 0.0 );\n\n vec3 p = vOrigin + bounds.x * rayDir;\n vec3 inc = 1.0 / abs( rayDir );\n float delta = min( inc.x, min( inc.y, inc.z ) );\n delta /= steps;\n\n // Jitter\n\n // Nice little seed from\n // https://blog.demofox.org/2020/05/25/casual-shadertoy-path-tracing-1-basic-camera-diffuse-emissive/\n uint seed = uint( gl_FragCoord.x ) * uint( 1973 ) + uint( gl_FragCoord.y ) * uint( 9277 ) + uint( frame ) * uint( 26699 );\n vec3 size = vec3( textureSize( map, 0 ) );\n float randNum = randomFloat( seed ) * 2.0 - 1.0;\n p += rayDir * randNum * ( 1.0 / size );\n\n //\n\n vec4 ac = vec4( base, 0.0 );\n\n for ( float t = bounds.x; t < bounds.y; t += delta ) {\n\n float d = sample1( p + 0.5 );\n\n d = smoothstep( threshold - range, threshold + range, d ) * opacity;\n\n float col = shading( p + 0.5 ) * 3.0 + ( ( p.x + p.y ) * 0.25 ) + 0.2;\n\n ac.rgb += ( 1.0 - ac.a ) * d * col;\n\n ac.a += ( 1.0 - ac.a ) * d;\n\n if ( ac.a >= 0.95 ) break;\n\n p += rayDir * delta;\n\n }\n\n color = ac;\n\n if ( color.a == 0.0 ) discard;\n\n}",side:R,transparent:!0}),Rt(this,"isExampleVolumeMaterial_Cloud",!0),this.opacity=o}get map(){return this.uniforms.map.value}set map(t){this.uniforms.map.value=t,this.uniformsNeedUpdate=!0}get color(){return this.uniforms.base.value}set color(t){this.uniforms.base.value=t,this.uniformsNeedUpdate=!0}get opacity(){return this.uniforms.opacity.value}set opacity(t){this.uniforms&&(this.uniforms.opacity.value=t),this.uniformsNeedUpdate=!0}get threshold(){return this.uniforms.threshold.value}set threshold(t){this.uniforms.threshold.value=t,this.uniformsNeedUpdate=!0}get range(){return this.uniforms.range.value}set range(t){this.uniforms.range.value=t,this.uniformsNeedUpdate=!0}get steps(){return this.uniforms.steps.value}set steps(t){this.uniforms.steps.value=t,this.uniformsNeedUpdate=!0}get frame(){return this.uniforms.frame.value}set frame(t){this.uniforms.frame.value=t,this.uniformsNeedUpdate=!0}get cameraPos(){return this.uniforms.cameraPos.value}set cameraPos(t){this.uniforms.cameraPos.value.copy(t),this.uniformsNeedUpdate=!0}}class we extends V{constructor(t){let{threshold:e,map:n,steps:i,cameraPos:o}=t??{};e=e??.25,i=i??100,o=o??new a,super({glslVersion:x,uniforms:{map:{value:n},cameraPos:{value:o},threshold:{value:e},steps:{value:i}},vertexShader:_e,fragmentShader:"precision highp float;\nprecision highp sampler3D;\n\nuniform mat4 modelViewMatrix;\nuniform mat4 projectionMatrix;\n\nin vec3 vOrigin;\nin vec3 vDirection;\n\nout vec4 color;\n\nuniform sampler3D map;\n\nuniform float threshold;\nuniform float steps;\n\nvec2 hitBox( vec3 orig, vec3 dir ) {\n const vec3 box_min = vec3( - 0.5 );\n const vec3 box_max = vec3( 0.5 );\n vec3 inv_dir = 1.0 / dir;\n vec3 tmin_tmp = ( box_min - orig ) * inv_dir;\n vec3 tmax_tmp = ( box_max - orig ) * inv_dir;\n vec3 tmin = min( tmin_tmp, tmax_tmp );\n vec3 tmax = max( tmin_tmp, tmax_tmp );\n float t0 = max( tmin.x, max( tmin.y, tmin.z ) );\n float t1 = min( tmax.x, min( tmax.y, tmax.z ) );\n return vec2( t0, t1 );\n}\n\nfloat sample1( vec3 p ) {\n return texture( map, p ).r;\n}\n\n#define epsilon .0001\n\nvec3 normal( vec3 coord ) {\n if ( coord.x < epsilon ) return vec3( 1.0, 0.0, 0.0 );\n if ( coord.y < epsilon ) return vec3( 0.0, 1.0, 0.0 );\n if ( coord.z < epsilon ) return vec3( 0.0, 0.0, 1.0 );\n if ( coord.x > 1.0 - epsilon ) return vec3( - 1.0, 0.0, 0.0 );\n if ( coord.y > 1.0 - epsilon ) return vec3( 0.0, - 1.0, 0.0 );\n if ( coord.z > 1.0 - epsilon ) return vec3( 0.0, 0.0, - 1.0 );\n\n float step = 0.01;\n float x = sample1( coord + vec3( - step, 0.0, 0.0 ) ) - sample1( coord + vec3( step, 0.0, 0.0 ) );\n float y = sample1( coord + vec3( 0.0, - step, 0.0 ) ) - sample1( coord + vec3( 0.0, step, 0.0 ) );\n float z = sample1( coord + vec3( 0.0, 0.0, - step ) ) - sample1( coord + vec3( 0.0, 0.0, step ) );\n\n return normalize( vec3( x, y, z ) );\n}\n\nvoid main(){\n\n vec3 rayDir = normalize( vDirection );\n vec2 bounds = hitBox( vOrigin, rayDir );\n\n if ( bounds.x > bounds.y ) discard;\n\n bounds.x = max( bounds.x, 0.0 );\n\n vec3 p = vOrigin + bounds.x * rayDir;\n vec3 inc = 1.0 / abs( rayDir );\n float delta = min( inc.x, min( inc.y, inc.z ) );\n delta /= steps;\n\n for ( float t = bounds.x; t < bounds.y; t += delta ) {\n\n float d = sample1( p + 0.5 );\n\n if ( d > threshold ) {\n\n color.rgb = normal( p + 0.5 ) * 0.5 + ( p * 1.5 + 0.25 );\n color.a = 1.;\n break;\n\n }\n\n p += rayDir * delta;\n\n }\n\n if ( color.a == 0.0 ) discard;\n\n}",side:R,transparent:!0}),Rt(this,"isExampleVolumeMaterial_Perlin",!0)}get map(){return this.uniforms.map.value}set map(t){this.uniforms.map.value=t,this.uniformsNeedUpdate=!0}get threshold(){return this.uniforms.threshold.value}set threshold(t){this.uniforms.threshold.value=t,this.uniformsNeedUpdate=!0}get steps(){return this.uniforms.steps.value}set steps(t){this.uniforms.steps.value=t,this.uniformsNeedUpdate=!0}get cameraPos(){return this.uniforms.cameraPos.value}set cameraPos(t){this.uniforms.cameraPos.value.copy(t),this.uniformsNeedUpdate=!0}}class Me{constructor(t){this.ssp=t,this.defaultColorGradient=[[0,"rgba(0,255,0,0)"],[.5,"rgba(64,255,255,0.5)"],[1,"rgba(255,64,255,1)"]],this.defaultGradientVolumeMaterialOptions={fit:Vt.Raw,accFactor:2,depthTest:!1,side:R,discardOut:!1,gradient:Ct(this.defaultColorGradient)}}_createTexture(t,e,n=!1){const i=he(Object.assign({points:t},e),Object.assign({maxSize:60},e)),{options:a,position:o,scale:r}=i,s=kt(n?me(a):se(a),Object.assign({},e)),l=new Lt(Object.assign(Object.assign(Object.assign({},this.defaultGradientVolumeMaterialOptions),{map:s}),e)),c=new jt(l);return c.position.copy(o),c.scale.set(r,r,r),this.ssp.addObject(c),c}createHeatCloud(t,e){return this._createTexture(t,e)}createLineHeat(t,e){return this._createTexture(t,e,!0)}async createImageExtrusion(t,e){var n;const i=new Ht(Object.assign({side:R,depthTest:!1},e)),a=Wt(await L.utils.imageLoader.loadAsync(t),null!==(n=null==e?void 0:e.depth)&&void 0!==n?n:200,e);i.map=a;const o=new jt(i);return this.ssp.addObject(o),o}createSliceMesh(t,e){let n=t.map;if(!n)return;if(t instanceof Lt){const{gradient:i,range:a,discardOut:o,voidRange:r}=t;n=Yt(n.image,Object.assign({gradient:null==i?void 0:i.image,range:a,discardOut:o,voidRange:r},e))}const i=new ne(Object.assign({map:n},e));return this.ssp.addObject(i),i}createImageSlice(t,e){const n=t.map;if(!n)return;let i=null;if(t instanceof Lt){const{gradient:a,range:o,discardOut:r,voidRange:s}=t;i=Yt(n.image,Object.assign({gradient:null==a?void 0:a.image,range:o,discardOut:r,voidRange:s},e))}if(t instanceof Ht&&(i=n),!i)return;return new ie(i)}}export{Jt as ColorFogPointsMaterial,xe as ExampleVolumeMaterial_1,ye as ExampleVolumeMaterial_Cloud,we as ExampleVolumeMaterial_Perlin,Zt as FogPointsMaterial,Bt as GradientData3DTexture,$t as GradientFogPointsMaterial,Lt as GradientVolumeMaterial,Me as HeatMapPlugin,Mt as ImageData3DSlice,Kt as ImageData3DTexture,ie as ImageData3DTextureSlice,Ht as ImageVolumeMaterial,ee as SliceMaterial,ne as SliceMesh,Xt as SphereFogMaterial,Vt as VolumeFit,Et as VolumeMaterial,jt as VolumeMesh,ge as VolumeRenderStyle,re as computeHeatData3DForPoint,Qt as createColorFogPoints,kt as createGradientData3DTexture,te as createGradientFogPoints,se as createHeatData3D,Wt as createImageData3DTextureByExtrudeImage,Yt as createImageData3DTextureFromGradient,me as createLineData3D,W as createLinearGradientImageData,ht as data2DCoordToIndex,vt as data2DIndexToCoord,at as data3DCoordToIndex,ot as data3DIndexToCoord,Me as default,pt as extrudeImage,mt as extrudeImageData,ft as extrudeImageDataOnAxis,xt as getData2DItem,gt as getData2DItemSafe,wt as getData2DRow,yt as getData2DValue,_t as getData2DValueSafe,st as getData3DItem,rt as getData3DItemSafe,dt as getData3DSlice,ct as getData3DValue,lt as getData3DValueSafe,Q as getImageDateColor,Y as getImageDateOfImage,J as getImageDateRow,X as getNaturalSizeOfImageSource,qt as gradientData3DToImageData3D,ce as hollowGradient_Default,$ as imageDataToCanvas,tt as imageDataToUrl,et as isIImageData2,nt as isIImageData3,it as isOutOfSize,ue as lineValueGradient_Default,Gt as makeOriginOnBoundingBoxMinOfGeometry,ut as mergeData3Ds,de as numberValuesAccumulate_Default,he as optimizeGradientOptions,le as radiusGradient_Default,Z as reverseImageDateY,pe as transformGradientOptions,fe as translateScaleGradientOptions,ae as valueGradient_Default,oe as valuesAccumulate_Default};
1
+ import { TextureLoader as Nt, Texture as Pt, Vector4 as Ot, Vector3 as f, Vector2 as T, DepthStencilFormat as It, DepthFormat as Ft, LuminanceAlphaFormat as Tt, LuminanceFormat as Rt, RGBAIntegerFormat as Vt, RGBAFormat as Ye, RGIntegerFormat as Et, RGFormat as Gt, RedIntegerFormat as Lt, RedFormat as Xe, AlphaFormat as Bt, Matrix3 as _e, ShaderMaterial as te, UniformsUtils as Je, BackSide as Q, RawShaderMaterial as Ze, Color as Qe, GLSL3 as ie, ShaderLib as jt, Data3DTexture as et, FloatType as tt, LinearFilter as it, UnsignedByteType as at, DoubleSide as Oe, Mesh as rt, PlaneGeometry as kt, FrontSide as J, Matrix4 as ot, BoxGeometry as Ht, Points as nt, Box3 as xe, Line3 as $t, Quaternion as qt, BufferGeometry as st, Float32BufferAttribute as Z, Uint8ClampedBufferAttribute as Kt } from "three";
2
+ import Wt from "soonspacejs";
3
+ var S = /* @__PURE__ */ ((i) => (i[i.x = 0] = "x", i[i.y = 1] = "y", i[i.z = 2] = "z", i))(S || {});
4
+ ((i) => {
5
+ function e(r) {
6
+ return i[r];
7
+ }
8
+ i.toKey = e;
9
+ function t(r) {
10
+ return i[r];
11
+ }
12
+ i.toIndex = t;
13
+ function a(r) {
14
+ const o = (r + 1) % 3, n = (r + 2) % 3;
15
+ return [o, n];
16
+ }
17
+ i.getCrossAxiss = a;
18
+ })(S || (S = {}));
19
+ var Ae = /* @__PURE__ */ ((i) => (i[i.x = 0] = "x", i[i.y = 1] = "y", i[i.z = 2] = "z", i[i.w = 3] = "w", i))(Ae || {});
20
+ ((i) => {
21
+ function e(r) {
22
+ return i[r];
23
+ }
24
+ i.toKey = e;
25
+ function t(r) {
26
+ return i[r];
27
+ }
28
+ i.toIndex = t;
29
+ function a(r) {
30
+ const o = (r + 1) % 4, n = (r + 2) % 4;
31
+ return [o, n];
32
+ }
33
+ i.getCrossAxiss = a;
34
+ })(Ae || (Ae = {}));
35
+ var Yt = Object.defineProperty, Xt = (i, e, t) => e in i ? Yt(i, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : i[e] = t, F = (i, e, t) => (Xt(i, typeof e != "symbol" ? e + "" : e, t), t);
36
+ function lt(i, e, t, a = "srgb") {
37
+ const r = new OffscreenCanvas(e, t).getContext("2d"), o = r.createLinearGradient(0, 0, 256, 1);
38
+ for (const [n, s] of i)
39
+ o.addColorStop(Number(n), s);
40
+ return r.fillStyle = o, r.fillRect(0, 0, e, t), r.getImageData(0, 0, e, t, { colorSpace: a });
41
+ }
42
+ function ut(i, e) {
43
+ let { area: t, width: a, height: r, colorSpace: o } = e || {};
44
+ o = o ?? "srgb", t = t || {};
45
+ const n = t.x ?? 0, s = t.y ?? 0, l = Jt(i), u = t.width ?? l.width, c = t.height ?? l.height;
46
+ a = a ?? u, r = r ?? c;
47
+ const d = new OffscreenCanvas(a, r).getContext("2d");
48
+ return d.drawImage(i, n, s, u, c, 0, 0, a, r), d.getImageData(0, 0, a, r, { colorSpace: o });
49
+ }
50
+ function Jt(i) {
51
+ let e = 0, t = 0;
52
+ return i instanceof HTMLImageElement ? (e = i.naturalWidth, t = i.naturalHeight) : i instanceof HTMLVideoElement ? (e = i.videoWidth, t = i.videoHeight) : (e = i.width, t = i.height), { width: e, height: t };
53
+ }
54
+ function ct(i) {
55
+ const { data: e, width: t, height: a, colorSpace: r } = i, o = e.length, n = new Uint8ClampedArray(o);
56
+ for (let s = 0; s < a; s++) {
57
+ const l = s * t, u = -(l + t), c = u + t, d = e.slice(u * 4, c * 4);
58
+ n.set(d, l * 4);
59
+ }
60
+ return new ImageData(n, t, a, { colorSpace: r });
61
+ }
62
+ function ia(i, e) {
63
+ const { data: t, width: a } = i, r = e * a, o = r + a;
64
+ return t.slice(r * 4, o * 4);
65
+ }
66
+ function dt(i, e, t) {
67
+ const { data: a, width: r } = i, o = (e * r + t) * 4;
68
+ return a.slice(o, o + 4);
69
+ }
70
+ function Zt(i) {
71
+ const e = document.createElement("canvas"), t = e.getContext("2d");
72
+ return e.width = i.width, e.height = i.height, t.putImageData(i, 0, 0), e;
73
+ }
74
+ function aa(i) {
75
+ return Zt(i).toDataURL();
76
+ }
77
+ function Ie(i) {
78
+ return i && i.data != null && i.width != null && i.height != null;
79
+ }
80
+ function Ne(i) {
81
+ return Ie(i) && i.depth != null;
82
+ }
83
+ function ra(i, e) {
84
+ for (const [t, a] of Object.entries(i))
85
+ if (0 <= a && a <= e[t])
86
+ return !0;
87
+ return !1;
88
+ }
89
+ function Fe(i, e) {
90
+ const { x: t, y: a } = e;
91
+ return i.z * a * t + i.y * t + i.x;
92
+ }
93
+ function oa(i, e) {
94
+ const { x: t, y: a } = e, r = Math.trunc(i / t), o = i - r * t, n = Math.trunc(r / a), s = r - n * a;
95
+ return { x: o, y: s, z: n };
96
+ }
97
+ function Te(i, e, t = 1) {
98
+ let { x: a, y: r, z: o } = e;
99
+ const n = i.size;
100
+ return a = Math.max(0, Math.min(n.x - 1, a)), r = Math.max(0, Math.min(n.y - 1, r)), o = Math.max(0, Math.min(n.z - 1, o)), mt(i, { x: a, y: r, z: o }, t);
101
+ }
102
+ function mt(i, e, t = 1) {
103
+ const { data: a, size: r } = i, o = Fe(e, r);
104
+ let n = [];
105
+ if (t > 0) {
106
+ const s = o * t;
107
+ for (let l = 0; l < t; l++)
108
+ n.push(a[s + l]);
109
+ }
110
+ return { index: o, value: n };
111
+ }
112
+ function Qt(i, e) {
113
+ let { x: t, y: a, z: r } = e;
114
+ const o = i.size;
115
+ return t = Math.max(0, Math.min(o.x - 1, t)), a = Math.max(0, Math.min(o.y - 1, a)), r = Math.max(0, Math.min(o.z - 1, r)), pt(i, { x: t, y: a, z: r });
116
+ }
117
+ function pt(i, e) {
118
+ const { data: t, size: a } = i, r = Fe(e, a);
119
+ return { index: r, value: t[r] };
120
+ }
121
+ function na(i, e) {
122
+ const { voidValue: t, valuesAccumulate: a, verifyVoid: r = () => !1 } = e;
123
+ let { x: o, y: n, z: s } = i[0].size;
124
+ const l = i.length;
125
+ for (let m = 1; m < l; m++) {
126
+ const p = i[m].size;
127
+ o = Math.max(o, p.x), n = Math.max(n, p.y), s = Math.max(s, p.z);
128
+ }
129
+ const u = o * n * s, c = new Array(u), d = o * n;
130
+ for (let m = 0; m < s; m++) {
131
+ const p = m * d;
132
+ for (let h = 0; h < n; h++) {
133
+ const x = p + h * o;
134
+ for (let _ = 0; _ < o; _++) {
135
+ const w = x + _, D = { x: _, y: h, z: m }, z = [];
136
+ for (const v of i) {
137
+ const b = v.size;
138
+ if (_ < b.x && h < b.y && m < b.z)
139
+ continue;
140
+ const { index: C, value: U } = pt(v, D);
141
+ r(U, v, C) || z.push({ value: U, index: C, data3D: v, coord: D });
142
+ }
143
+ const y = z.length;
144
+ let M = t;
145
+ y > 1 ? M = a(z) : y === 1 && (M = z[0].value), c[w] = M;
146
+ }
147
+ }
148
+ }
149
+ return {
150
+ data: c,
151
+ size: { x: o, y: n, z: s }
152
+ };
153
+ }
154
+ function ye(i, e, t, a = 1) {
155
+ const { size: r } = i, o = S.toKey(e), [n, s] = S.getCrossAxiss(e), l = S.toKey(n), u = S.toKey(s), c = r[l], d = r[u], m = [], p = r[o];
156
+ t = Math.trunc(t), t = Math.max(0, Math.min(p - 1, t));
157
+ let h = { x: 0, y: 0, z: 0 };
158
+ h[o] = t;
159
+ for (let x = 0; x < d; x++) {
160
+ h[u] = x;
161
+ for (let _ = 0; _ < c; _++) {
162
+ h[l] = _;
163
+ const { value: w } = mt(i, h, a);
164
+ m.push(...w);
165
+ }
166
+ }
167
+ return { data: m, size: { x: c, y: d } };
168
+ }
169
+ function ei(i, e, t) {
170
+ e = Math.trunc(e);
171
+ const { data: a, width: r, height: o, colorSpace: n } = t ? ct(i) : i, s = a.length, l = s * e, u = new Uint8ClampedArray(l);
172
+ for (let c = 0; c < e; c++)
173
+ u.set(a, c * s);
174
+ return { data: u, width: r, height: o, depth: e, colorSpace: n };
175
+ }
176
+ function ti(i, e, t) {
177
+ const a = t || {}, r = a.reverseY, o = a.axis ?? "z", n = Ie(i) ? i : ut(i, a);
178
+ return o === "z" ? ei(n, e, r) : ii(n, o, e, r);
179
+ }
180
+ function ii(i, e, t, a) {
181
+ t = Math.trunc(t);
182
+ const { data: r, width: o, height: n, colorSpace: s } = a ? ct(i) : i, l = S.toKey(e), u = (e + 1) % 3, c = (e + 2) % 3, d = S.toKey(u), m = S.toKey(c), p = {
183
+ [d]: o,
184
+ [m]: n,
185
+ [l]: t
186
+ }, h = new Uint8ClampedArray(r.length * t), x = { x: 0, y: 0, z: 0 };
187
+ for (let _ = 0; _ < t; _++) {
188
+ x[l] = _;
189
+ for (let w = 0; w < n; w++) {
190
+ x[m] = w;
191
+ for (let D = 0; D < o; D++) {
192
+ x[d] = D;
193
+ const z = (w * o + D) * 4, y = z + 4, M = r.subarray(z, y), v = Fe(x, p) * 4;
194
+ h.set(M, v);
195
+ }
196
+ }
197
+ }
198
+ return { data: h, width: p.x, height: p.y, depth: p.z, colorSpace: s };
199
+ }
200
+ function ft(i, e) {
201
+ return i.y * e.x + i.x;
202
+ }
203
+ function sa(i, e) {
204
+ const { x: t } = e, a = Math.trunc(i / t);
205
+ return { x: i - a * t, y: a };
206
+ }
207
+ function la(i, e, t = 1) {
208
+ let { x: a, y: r } = e;
209
+ const o = i.size;
210
+ return a = Math.max(0, Math.min(o.x - 1, a)), r = Math.max(0, Math.min(o.y - 1, r)), ai(i, { x: a, y: r }, t);
211
+ }
212
+ function ai(i, e, t = 1) {
213
+ const { data: a, size: r } = i, o = ft(e, r);
214
+ let n = [];
215
+ if (t > 0) {
216
+ const s = o * t;
217
+ for (let l = 0; l < t; l++)
218
+ n.push(a[s + l]);
219
+ }
220
+ return { index: o, value: n };
221
+ }
222
+ function ua(i, e) {
223
+ let { x: t, y: a } = e;
224
+ const r = i.size;
225
+ return t = Math.max(0, Math.min(r.x - 1, t)), a = Math.max(0, Math.min(r.y - 1, a)), ri(i, { x: t, y: a });
226
+ }
227
+ function ri(i, e) {
228
+ const { data: t, size: a } = i, r = ft(e, a);
229
+ return { index: r, value: t[r] };
230
+ }
231
+ function ca(i, e, t = 1) {
232
+ const { data: a, size: r } = i, o = r.x, n = e * o, s = n + o;
233
+ return (typeof a.slice == "function" ? a : Array.from(a)).slice(n * t, s * t);
234
+ }
235
+ class oi {
236
+ constructor(e) {
237
+ F(this, "isImageData3DSlice", !0), F(this, "_image3D"), F(this, "_canvas"), F(this, "_context"), F(this, "_axis", S.z), F(this, "_depth", 0), F(this, "_sliceSize", null), F(this, "_slice"), this.image3D = e;
238
+ }
239
+ /**
240
+ * 3D图像数据
241
+ */
242
+ get image3D() {
243
+ return this._image3D;
244
+ }
245
+ set image3D(e) {
246
+ this._image3D = e, this.updateSize();
247
+ }
248
+ /**
249
+ * 呈现切片的 canvas 元素
250
+ * @remarks
251
+ * 当 {@link ImageData3DSlice.axis} 或 {@link ImageData3DSlice.depth} 变更时,它会自动更新切片
252
+ */
253
+ get canvas() {
254
+ let e = this._canvas;
255
+ return e || (e = this._canvas = document.createElement("canvas"), e.width = this.sliceSize.x, e.height = this.sliceSize.y), e;
256
+ }
257
+ /**
258
+ * canvas 的 2d 上下文对象
259
+ */
260
+ get context() {
261
+ return this._context ?? (this._context = this.canvas.getContext("2d"));
262
+ }
263
+ /**
264
+ * 轴
265
+ * @remarks
266
+ * 会沿该轴的垂直截面生成切片
267
+ *
268
+ * @defaultValue Axis.z
269
+ */
270
+ get axis() {
271
+ return this._axis;
272
+ }
273
+ set axis(e) {
274
+ this._axis = e, this.updateSize();
275
+ }
276
+ /**
277
+ * 轴上的坐标值
278
+ * @remarks
279
+ * 会在轴的该位置处获取切片
280
+ * @defaultValue 0
281
+ */
282
+ get depth() {
283
+ return this._depth;
284
+ }
285
+ set depth(e) {
286
+ this._depth = e, this.updateSlice();
287
+ }
288
+ /**
289
+ * 切片的尺寸
290
+ * @remarks
291
+ * 不同轴上的切片的尺寸一般不一样
292
+ */
293
+ get sliceSize() {
294
+ let e = this._sliceSize;
295
+ if (!e) {
296
+ const { axis: t, image3D: a } = this, { width: r, height: o, depth: n } = a, [s, l] = S.getCrossAxiss(t), u = [r, o, n];
297
+ this._sliceSize = e = {
298
+ x: u[s],
299
+ y: u[l]
300
+ };
301
+ }
302
+ return e;
303
+ }
304
+ /**
305
+ * 获取切片数据
306
+ * @remarks
307
+ * 总是获取当前轴和深度处的切片
308
+ */
309
+ get slice() {
310
+ return this._slice ?? (this._slice = this.getSlice(this.axis, this.depth));
311
+ }
312
+ /**
313
+ * 获取切片数据
314
+ * @remarks
315
+ * 可以指定轴和深度;该方法不会更新 {@link ImageData3DSlice.axis} 和 {@link ImageData3DSlice.depth} 属性
316
+ * @param axis - 轴
317
+ * @param depth - 深度
318
+ * @returns
319
+ */
320
+ getSlice(e, t) {
321
+ const { data: a, width: r, height: o, depth: n, colorSpace: s } = this.image3D, { data: l, size: u } = ye({ data: a, size: { x: r, y: o, z: n } }, e, t, 4), c = l instanceof Uint8ClampedArray ? l : Uint8ClampedArray.from(l);
322
+ return new ImageData(c, u.x, u.y, { colorSpace: s });
323
+ }
324
+ /**
325
+ * 获取切片图像的 url
326
+ * @returns
327
+ */
328
+ getDataURL() {
329
+ return this.canvas.toDataURL();
330
+ }
331
+ /**
332
+ * 获取切片上指定坐标处的颜色
333
+ * @param coord - 坐标
334
+ * @returns
335
+ */
336
+ getColor(e) {
337
+ const { x: t, y: a } = e;
338
+ return dt(this.slice, a, t);
339
+ }
340
+ /**
341
+ * 更新切片尺寸相关的信息
342
+ */
343
+ updateSize() {
344
+ this._sliceSize = null;
345
+ const e = this.canvas;
346
+ e.width = this.sliceSize.x, e.height = this.sliceSize.y, this.updateSlice();
347
+ }
348
+ /**
349
+ * 更新切片相关的信息
350
+ */
351
+ updateSlice() {
352
+ this._slice = null, this.context.putImageData(this.slice, 0, 0);
353
+ }
354
+ }
355
+ var ni = Object.defineProperty, si = (i, e, t) => e in i ? ni(i, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : i[e] = t, X = (i, e, t) => (si(i, typeof e != "symbol" ? e + "" : e, t), t);
356
+ function li(i) {
357
+ return i.w !== void 0 ? [Ot, 4] : i.z !== void 0 ? [f, 3] : [T, 2];
358
+ }
359
+ function ui(i) {
360
+ const e = i.length, t = [];
361
+ if (e === 0)
362
+ return t;
363
+ const [a, r] = li(i[0]);
364
+ for (let o = 0; o < e; o++) {
365
+ const n = i[o], s = new a().copy(n), l = n.radius, u = t[o] ?? (t[o] = []);
366
+ for (let c = o + 1; c < e; c++) {
367
+ const d = i[c];
368
+ s.distanceToSquared(d) <= (d.radius + l) ** 2 && (u.push(c), (t[c] = []).push(o));
369
+ }
370
+ }
371
+ return t;
372
+ }
373
+ let He;
374
+ function ee(i) {
375
+ if (typeof i == "string")
376
+ return (He || (He = new Nt())).load(i);
377
+ if (i.isTexture)
378
+ return i;
379
+ const e = Array.isArray(i) ? lt(i, 256, 1) : i, t = new Pt(e);
380
+ return e.colorSpace === "srgb" && (t.colorSpace = "srgb"), t.needsUpdate = !0, t;
381
+ }
382
+ function ci(i, e) {
383
+ const t = Math.sqrt(i.lengthSq() * e.lengthSq());
384
+ if (t === 0)
385
+ return 0;
386
+ let a = i.dot(e) / t;
387
+ return a = Math.max(-1, Math.min(1, a)), Math.acos(a);
388
+ }
389
+ function Se(i, e, t) {
390
+ let a = ci(i, e);
391
+ return a === 0 ? a : i.clone().cross(e).dot(t) < 0 ? -a : a;
392
+ }
393
+ function di(i, e, t) {
394
+ const a = e.clone().negate(), r = t.clone().projectOnPlane(e), o = i.clone().projectOnPlane(r), n = Se(e, o, r), s = e.clone().cross(r), l = i.clone().projectOnPlane(s), u = Se(e, l, s), c = i.clone().projectOnPlane(a), d = Se(r, c, a);
395
+ return { yaw: n, pitch: u, roll: d };
396
+ }
397
+ const be = 180 / Math.PI, Pe = {
398
+ yaw: [
399
+ { name: "前", range: [-15, 15] },
400
+ { name: "左", range: [15, 165] },
401
+ { name: "右", range: [-165, -15] },
402
+ { name: "后", range: [-180.1, -165] },
403
+ { name: "后", range: [165, 180.1] }
404
+ ],
405
+ pitch: [
406
+ { name: "前", range: [-15, 15] },
407
+ { name: "上", range: [15, 165] },
408
+ { name: "下", range: [-165, -15] },
409
+ { name: "后", range: [-180.1, -165] },
410
+ { name: "后", range: [165, 180.1] }
411
+ ],
412
+ roll: [
413
+ { name: "上", range: [-15, 15] },
414
+ { name: "左", range: [15, 165] },
415
+ { name: "右", range: [-165, -15] },
416
+ { name: "下", range: [-180.1, -165] },
417
+ { name: "下", range: [165, 180.1] }
418
+ ]
419
+ };
420
+ function mi(i) {
421
+ const e = {};
422
+ for (const [t, a] of Object.entries(i))
423
+ e[t] = Array.isArray(a) ? a : Object.entries(a).map(([r, o]) => ({ name: r, range: o }));
424
+ return e;
425
+ }
426
+ const Ce = {
427
+ degrees: !0,
428
+ map: Pe,
429
+ front: { x: 0, y: 0, z: 1 },
430
+ up: { x: 0, y: 1, z: 0 }
431
+ };
432
+ let ht = class {
433
+ constructor(e) {
434
+ X(this, "_options"), X(this, "_listMap"), X(this, "_front"), X(this, "_up"), e && (this.options = e);
435
+ }
436
+ static get options() {
437
+ return this._options ?? (this.options = Ce);
438
+ }
439
+ static set options(e) {
440
+ this._options = Object.assign({}, structuredClone(Pe), e);
441
+ }
442
+ /**
443
+ * 默认选项
444
+ */
445
+ get defaultOptions() {
446
+ return this.constructor.options;
447
+ }
448
+ get options() {
449
+ return this._options ?? (this.options = this.defaultOptions);
450
+ }
451
+ set options(e) {
452
+ this._options = Object.assign({}, structuredClone(this.defaultOptions), e), this._listMap = null, this._front = null, this._up = null;
453
+ }
454
+ /**
455
+ * 是否使用角度,而非弧度
456
+ */
457
+ get degrees() {
458
+ return this.options.degrees ?? (this.options.degrees = this.defaultOptions.degrees ?? !0);
459
+ }
460
+ set degrees(e) {
461
+ this.options.degrees = e;
462
+ }
463
+ get map() {
464
+ return this.options.map || (this.map = this.defaultOptions.map), this.options.map;
465
+ }
466
+ set map(e) {
467
+ const t = structuredClone(this.defaultOptions.map), a = structuredClone(Pe);
468
+ e = e ? {
469
+ yaw: e.yaw ?? t.yaw ?? a.yaw,
470
+ pitch: e.pitch ?? t.pitch ?? a.pitch,
471
+ roll: e.roll ?? t.roll ?? a.roll
472
+ } : t, this.options.map = e, this._listMap = null;
473
+ }
474
+ get listMap() {
475
+ return this._listMap ?? (this._listMap = mi(this.map ?? {}));
476
+ }
477
+ get front() {
478
+ return this._front || (this.front = this.options.front ?? this.defaultOptions.front ?? Ce.front), this._front;
479
+ }
480
+ set front(e) {
481
+ this._front = new f().copy(e);
482
+ }
483
+ get up() {
484
+ return this._up || (this.up = this.options.up ?? this.defaultOptions.up ?? Ce.up), this._up;
485
+ }
486
+ set up(e) {
487
+ this._up = new f().copy(e);
488
+ }
489
+ /**
490
+ * 计算方位
491
+ * @param target
492
+ * @param front
493
+ * @param up
494
+ */
495
+ computeAzimuth(e, t, a) {
496
+ const r = new f().copy(e), o = new f().copy(t ?? this.front), n = new f().copy(a ?? this.up);
497
+ let { yaw: s, pitch: l, roll: u } = di(r, o, n);
498
+ return this.degrees && (s *= be, l *= be, u *= be), {
499
+ yaw: {
500
+ angle: s,
501
+ name: this.findAzimuthNames("yaw", s)
502
+ },
503
+ pitch: {
504
+ angle: l,
505
+ name: this.findAzimuthNames("pitch", l)
506
+ },
507
+ roll: {
508
+ angle: u,
509
+ name: this.findAzimuthNames("roll", u)
510
+ }
511
+ };
512
+ }
513
+ /**
514
+ * 查找匹配的方位名字
515
+ * @param type - 类型
516
+ * @param angle - 角度
517
+ * @returns 匹配的名字列表
518
+ */
519
+ findAzimuthNames(e, t) {
520
+ const a = [], r = this.listMap[e];
521
+ if (!r)
522
+ return a;
523
+ for (const { name: o, range: [n, s] } of r)
524
+ (t >= n && t < s || t <= n && t > s) && a.push(o);
525
+ return a;
526
+ }
527
+ };
528
+ X(ht, "_options");
529
+ new ht();
530
+ const pi = {
531
+ [Bt]: 1,
532
+ [Xe]: 1,
533
+ [Lt]: 1,
534
+ [Gt]: 3,
535
+ [Et]: 2,
536
+ [Ye]: 4,
537
+ [Vt]: 4,
538
+ [Rt]: 1,
539
+ [Tt]: 2,
540
+ [Ft]: 1,
541
+ [It]: 2
542
+ };
543
+ function vt(i) {
544
+ return pi[i];
545
+ }
546
+ function fi(i, e, t) {
547
+ const { data: a, width: r, height: o, depth: n } = i.image, s = vt(i.format);
548
+ return ye({ data: a, size: { x: r, y: o, z: n } }, e, t, s);
549
+ }
550
+ function hi(i, e) {
551
+ const { data: t, width: a, height: r, depth: o } = i.image, n = vt(i.format);
552
+ return Te({ data: t, size: { x: a, y: r, z: o } }, e, n);
553
+ }
554
+ new _e();
555
+ var vi = Object.defineProperty, gi = (i, e, t) => e in i ? vi(i, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : i[e] = t, g = (i, e, t) => (gi(i, typeof e != "symbol" ? e + "" : e, t), t);
556
+ const xi = `precision highp sampler3D;
557
+
558
+ uniform sampler3D map;
559
+ uniform vec3 containerMin;
560
+ uniform vec3 containerMax;
561
+
562
+ // 0: 充满;1: 对齐;2: 原始
563
+ uniform int fit;
564
+
565
+
566
+ out vec3 cameraPos;
567
+ out vec3 lookDir;
568
+ out vec3 displayMin;
569
+ out vec3 displayMax;
570
+
571
+
572
+
573
+ void main() {
574
+ cameraPos = vec3( inverse( modelMatrix ) * vec4( cameraPosition, 1.0 ) ).xyz;
575
+ lookDir = position - cameraPos;
576
+
577
+ vec3 containerSize = containerMax - containerMin;
578
+ vec3 origin = containerMin;
579
+ vec3 textSize = vec3(textureSize(map,0));
580
+ displayMin = containerMin;
581
+ displayMax = containerMax;
582
+
583
+ switch (fit) {
584
+ case 1:
585
+ displayMax = displayMin + textSize;
586
+ break;
587
+ case 2:
588
+ origin = vec3(0.0);
589
+ break;
590
+ default:
591
+ textSize = containerSize;
592
+ }
593
+
594
+ vec3 scale = 1.0/textSize;
595
+ cameraPos = (cameraPos - origin)*scale;
596
+ lookDir *= scale;
597
+
598
+ displayMin = max((displayMin - origin)*scale,vec3(0.0));
599
+ displayMax = min((displayMax - origin)*scale,vec3(1.0));
600
+
601
+ gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
602
+ }`;
603
+ var gt = /* @__PURE__ */ ((i) => (i[i.Fill = 0] = "Fill", i[i.Align = 1] = "Align", i[i.Raw = 2] = "Raw", i))(gt || {});
604
+ class xt extends te {
605
+ constructor(e) {
606
+ const { map: t, opacity: a, accFactor: r, steps: o, alphaRange: n, fit: s, atomize: l, side: u, containerMin: c, containerMax: d, uniforms: m, ...p } = e ?? {}, h = a ?? 1, x = r ?? 1, _ = o ?? 100, w = new T().copy(n ?? { x: 0, y: 0.95 }), D = s ?? 0, z = l ?? !0, y = u ?? J, M = new f().copy(c ?? { x: 0, y: 0, z: 0 }), v = new f();
607
+ if (d)
608
+ v.copy(d);
609
+ else if (t) {
610
+ const { width: C, height: U, depth: E } = t.image, N = new f(C - 1, U - 1, E - 1);
611
+ v.addVectors(M, N);
612
+ }
613
+ const b = {
614
+ map: { value: t },
615
+ containerMin: { value: M },
616
+ containerMax: { value: v },
617
+ fit: { value: D },
618
+ opacity: { value: h },
619
+ alphaRange: { value: w },
620
+ accFactor: { value: x },
621
+ steps: { value: _ },
622
+ isDoubleSide: { value: !1 },
623
+ atomize: { value: z },
624
+ ...m
625
+ };
626
+ super({
627
+ glslVersion: ie,
628
+ // @ts-ignore
629
+ uniforms: b,
630
+ transparent: !0,
631
+ vertexShader: xi,
632
+ ...p
633
+ }), g(this, "isVolumeMaterial", !0), g(this, "_side", J), this.opacity = h, this.side = y;
634
+ }
635
+ /**
636
+ * 三维的纹理
637
+ */
638
+ get map() {
639
+ return this.uniforms.map.value;
640
+ }
641
+ set map(e) {
642
+ this.uniforms.map.value = e, this.uniformsNeedUpdate = !0;
643
+ }
644
+ /**
645
+ * 渲染体积材质的容器的最小点
646
+ * @remarks
647
+ * 容器的最小点和最大点一般是被设置成 geometry 的AABB包围盒;但也可以不是
648
+ * 总之,体积材质的渲染依托于 geometry 的形状,它不会超出 geometry 的尺寸;
649
+ * 但可以控制容器的最小点和最大点来控制体积材质的渲染尺寸;
650
+ */
651
+ get containerMin() {
652
+ return this.uniforms.containerMin.value;
653
+ }
654
+ set containerMin(e) {
655
+ this.uniforms.containerMin.value.copy(e), this.uniformsNeedUpdate = !0;
656
+ }
657
+ /**
658
+ * 渲染体积材质的容器的最大点
659
+ * @remarks
660
+ * 容器的最小点和最大点一般是被设置成 geometry 的AABB包围盒;但也可以不是
661
+ * 总之,体积材质的渲染依托于 geometry 的形状,它不会超出 geometry 的尺寸;
662
+ * 但可以控制容器的最小点和最大点来控制体积材质的渲染尺寸;
663
+ */
664
+ get containerMax() {
665
+ return this.uniforms.containerMax.value;
666
+ }
667
+ set containerMax(e) {
668
+ this.uniforms.containerMax.value.copy(e), this.uniformsNeedUpdate = !0;
669
+ }
670
+ /**
671
+ * 渲染体积材质容器的尺寸
672
+ * @remarks
673
+ * 每次调用都会重新计算
674
+ */
675
+ get containerSize() {
676
+ return this.containerMax.clone().sub(this.containerMin);
677
+ }
678
+ /**
679
+ * 体积材质在容器内的填充模式
680
+ * @defaultValue VolumeFit.Fill
681
+ */
682
+ get fit() {
683
+ return this.uniforms.fit.value;
684
+ }
685
+ set fit(e) {
686
+ this.uniforms.fit.value = e, this.uniformsNeedUpdate = !0;
687
+ }
688
+ /**
689
+ * 获取当前填模式下对 map 的应用的平移
690
+ * @returns
691
+ */
692
+ getFitTranslate() {
693
+ return this.fit === 2 ? new f() : this.containerMin.clone();
694
+ }
695
+ /**
696
+ * 获取当前填模式下对 map 的应用的缩放
697
+ * @returns
698
+ */
699
+ getFitScale() {
700
+ var e;
701
+ const t = new f(1, 1, 1), a = (e = this.map) == null ? void 0 : e.image, r = this.fit;
702
+ if (!a || r === 2 || r === 1)
703
+ return t;
704
+ const o = new f(a.width, a.height, a.depth);
705
+ return t.copy(this.containerSize).divide(o), t;
706
+ }
707
+ /**
708
+ * 获取当前填模式下对 map 的应用的变换矩阵
709
+ * @returns
710
+ */
711
+ getFitMatrix() {
712
+ var e;
713
+ const t = new ot(), a = (e = this.map) == null ? void 0 : e.image, r = this.fit;
714
+ if (!a || r === 2)
715
+ return t;
716
+ if (r === 0) {
717
+ const o = new f(a.width, a.height, a.depth), n = this.containerSize.divide(o);
718
+ t.makeScale(n.x, n.y, n.z);
719
+ }
720
+ return t.setPosition(this.containerMin), t;
721
+ }
722
+ /**
723
+ * 获取当前填模式下对 map 的应用的变换矩阵的逆矩阵
724
+ * @returns
725
+ */
726
+ getFitMatrixInvert() {
727
+ return this.getFitMatrix().invert();
728
+ }
729
+ /**
730
+ * Mesh三角形的渲染面
731
+ * @remarks
732
+ * 可设置为前面、后面、或者两面都渲染
733
+ * 如果只渲染前面,进入体积材质内部,体积材质就会消失
734
+ * 如果只渲染后面,体积初遮挡,就会消失
735
+ * 如果两面都渲染,则会隐藏看到容器的面
736
+ */
737
+ // @ts-ignore
738
+ get side() {
739
+ return this._side;
740
+ }
741
+ set side(e) {
742
+ this._side = e, this.uniforms && (this.uniforms.isDoubleSide.value = e === Oe, this.uniformsNeedUpdate = !0);
743
+ }
744
+ /**
745
+ * 透明度
746
+ * @remarks
747
+ * 决定整体的透明度
748
+ */
749
+ // @ts-ignore
750
+ get opacity() {
751
+ return this.uniforms.opacity.value;
752
+ }
753
+ set opacity(e) {
754
+ this.uniforms && (this.uniforms.opacity.value = e), this.uniformsNeedUpdate = !0;
755
+ }
756
+ /**
757
+ * 有效透明度的取值范围
758
+ * @remarks
759
+ * 如果最终颜色的透明度小于或等于 alphaRange.x ,则被认为是完全透明
760
+ * 如果最终颜色的透明度在于或等于 alphaRange.y ,则被认为是完全不透明
761
+ * 取值范围应当在 0 - 1
762
+ * @defaultValue {x:0,y:0.95}
763
+ */
764
+ get alphaRange() {
765
+ return this.uniforms.alphaRange.value;
766
+ }
767
+ set alphaRange(e) {
768
+ this.uniforms.alphaRange.value.copy(e), this.uniformsNeedUpdate = !0;
769
+ }
770
+ /**
771
+ * 是否开启雾化的效果
772
+ * @remarks
773
+ * 开启后的渲染效果会更像雾
774
+ * @defaultValue true
775
+ */
776
+ get atomize() {
777
+ return this.uniforms.atomize.value;
778
+ }
779
+ set atomize(e) {
780
+ this.uniforms.atomize.value = e, this.uniformsNeedUpdate = !0;
781
+ }
782
+ /**
783
+ * 体积材质渲染的采样数
784
+ * @remarks
785
+ * 采样数越高,占用的GPU资源就越大;所以该数据设置的适宜最好;
786
+ * @defaultValue 100
787
+ */
788
+ get steps() {
789
+ return this.uniforms.steps.value;
790
+ }
791
+ set steps(e) {
792
+ this.uniforms.steps.value = e, this.uniformsNeedUpdate = !0;
793
+ }
794
+ /**
795
+ * 颜色累积系数
796
+ * @remarks
797
+ * 它是对体积材质进行积分时使用的系数;只在开启雾化效果{@link VolumeMaterial.atomize}时才有效;
798
+ * 值越小,最终呈现出的效果就越雾化;
799
+ * @defaultValue 1
800
+ */
801
+ get accFactor() {
802
+ return this.uniforms.accFactor.value;
803
+ }
804
+ set accFactor(e) {
805
+ this.uniforms && (this.uniforms.accFactor.value = e), this.uniformsNeedUpdate = !0;
806
+ }
807
+ /**
808
+ * 将材质空间下的坐标转为 map 空间下的坐标
809
+ * @param coord - 材质空间下的坐标
810
+ * @returns
811
+ */
812
+ toMapPosition(e) {
813
+ const t = new f(e.x, e.y, e.z).applyMatrix4(this.getFitMatrixInvert());
814
+ return t.set(Math.trunc(t.x), Math.trunc(t.y), Math.trunc(t.z)), t;
815
+ }
816
+ /**
817
+ * 将材质空间下的深度转为 map 空间下的深度
818
+ * @param axis - map坐标系下的坐标轴
819
+ * @param depth - 材质空间下的深度
820
+ * @returns
821
+ */
822
+ toMapDepth(e, t) {
823
+ const a = S.toKey(e), r = new f();
824
+ r[a] = 1;
825
+ const o = new _e().setFromMatrix4(this.getFitMatrix());
826
+ return r.applyMatrix3(o), t /= r.length(), Math.trunc(t);
827
+ }
828
+ /**
829
+ * 获取3D数据的切片
830
+ * @remarks
831
+ * 切片就是指定轴的指定位置的垂直截面
832
+ * @param axis - map坐标系下的坐标轴
833
+ * @param depth - 材质空间下,在轴方向的坐标值
834
+ * @returns
835
+ */
836
+ getData3DSlice(e, t) {
837
+ const a = this.map;
838
+ return a != null && a.image ? (t = this.toMapDepth(e, t), fi(a, e, t)) : null;
839
+ }
840
+ /**
841
+ * 获取3D数据中指定坐标处的数据项目
842
+ * @param coord
843
+ * @returns
844
+ */
845
+ getItem(e) {
846
+ const t = this.map;
847
+ return t != null && t.image ? hi(t, this.toMapPosition(e)).value : null;
848
+ }
849
+ }
850
+ function _i(i) {
851
+ i.boundingBox || i.computeBoundingBox();
852
+ const { x: e, y: t, z: a } = i.boundingBox.min;
853
+ return i.translate(-e, -t, -a), i;
854
+ }
855
+ class $e extends rt {
856
+ constructor(e) {
857
+ var t;
858
+ const { width: a, height: r, depth: o } = ((t = e.map) == null ? void 0 : t.image) || {}, n = new Ht(a, r, o);
859
+ _i(n), super(n, e), g(this, "isVolumeMesh", !0), g(this, "_geometry"), g(this, "autoUpdateMaterial", !0), g(this, "_material"), g(this, "autoUpdateGeometry", !0), g(this, "autoNormalize", !1), Object.defineProperties(this, {
860
+ geometry: {
861
+ get: () => this._geometry,
862
+ set: (s) => {
863
+ this._geometry = s, this.autoNormalize ? this.normalize() : this.autoUpdateMaterial && this.updateMaterial();
864
+ }
865
+ },
866
+ material: {
867
+ get: () => this._material,
868
+ set: (s) => {
869
+ this._material = s, this.autoUpdateGeometry && this.updateGeometry();
870
+ }
871
+ }
872
+ }), this.geometry = n, this.material = e;
873
+ }
874
+ /**
875
+ * 更新材质
876
+ * @remarks
877
+ * 更新体积材质的相关选项以使其匹配 geometry
878
+ */
879
+ updateMaterial() {
880
+ const { geometry: e, material: t } = this;
881
+ if (!(t && e))
882
+ return !1;
883
+ e.boundingBox || e.computeBoundingBox();
884
+ const { min: a, max: r } = e.boundingBox;
885
+ t.containerMin = a, t.containerMax = r;
886
+ }
887
+ /**
888
+ * 更新几何体
889
+ * @remarks
890
+ * 更新 geometry 的相关选项以使其匹配体积材质
891
+ */
892
+ updateGeometry() {
893
+ var e;
894
+ const { geometry: t, material: a, autoUpdateMaterial: r } = this, o = (e = a.map) == null ? void 0 : e.image;
895
+ if (!o)
896
+ return !1;
897
+ t.boundingBox || t.computeBoundingBox();
898
+ const { width: n, height: s, depth: l } = o, u = t.boundingBox.getSize(new f());
899
+ t.scale(n / u.x, s / u.y, l / u.z), r && this.updateMaterial();
900
+ }
901
+ /**
902
+ * 规范化
903
+ * @remarks
904
+ * 将 geometry 的原点移动到包围盒的最小点处
905
+ */
906
+ normalize() {
907
+ const { geometry: e, autoUpdateMaterial: t } = this;
908
+ e.boundingBox || e.computeBoundingBox();
909
+ const { x: a, y: r, z: o } = e.boundingBox.min;
910
+ e.translate(-a, -r, -o), t && this.updateMaterial();
911
+ }
912
+ /**
913
+ * 将材质空间下的坐标转为 map 空间下的坐标
914
+ * @param coord - 材质空间下的坐标
915
+ * @returns
916
+ */
917
+ toMapPosition(e) {
918
+ const t = this.worldToLocal(new f(e.x, e.y, e.z));
919
+ return this.material.toMapPosition(t);
920
+ }
921
+ /**
922
+ * 将世界坐标系下的深度转为 material 空间下的深度
923
+ * @param axis - 材质空间下的坐标轴
924
+ * @param depth - 深度
925
+ * @returns
926
+ */
927
+ toMaterialDepth(e, t) {
928
+ const a = S.toKey(e), r = new f();
929
+ r[a] = 1;
930
+ const o = new _e().setFromMatrix4(this.matrixWorld);
931
+ return r.applyMatrix3(o), t /= r.length(), t;
932
+ }
933
+ /**
934
+ * 将世界坐标系下的深度转为 map 空间下的深度
935
+ * @param axis - map空间下的坐标轴
936
+ * @param depth - 深度
937
+ * @returns
938
+ */
939
+ toMapDepth(e, t) {
940
+ return t = this.toMaterialDepth(e, t), this.material.toMapDepth(e, t);
941
+ }
942
+ /**
943
+ * 获取3D数据的切片
944
+ * @remarks
945
+ * 切片就是指定轴的指定位置的垂直截面;
946
+ * 轴和深度都是局部坐标系下的
947
+ * @param axis - map空间下的坐标轴
948
+ * @param depth - 世界空间下在轴方向上的坐标值
949
+ * @returns
950
+ */
951
+ getData3DSlice(e, t) {
952
+ return t = this.toMaterialDepth(e, t), this.material.getData3DSlice(e, t);
953
+ }
954
+ /**
955
+ * 获取3D数据中指定坐标处的数据项目
956
+ * @param coord - 世界坐标系下的坐标
957
+ * @returns
958
+ */
959
+ getItem(e) {
960
+ const t = this.worldToLocal(new f(e.x, e.y, e.z));
961
+ return this.material.getItem(t);
962
+ }
963
+ }
964
+ const yi = `precision highp float;
965
+ precision highp sampler3D;
966
+
967
+ uniform sampler3D map;
968
+ uniform sampler2D gradient;
969
+
970
+ uniform bool atomize;
971
+ uniform float steps;
972
+ // 颜色累积系数
973
+ uniform float accFactor;
974
+ uniform vec2 range;
975
+ // 是否丢弃超出范围的像素
976
+ uniform bool discardOut;
977
+ // 空值范围
978
+ uniform vec2 voidRange;
979
+ uniform float opacity;
980
+ uniform vec2 alphaRange;
981
+ uniform bool isDoubleSide;
982
+
983
+ in vec3 cameraPos;
984
+ in vec3 lookDir;
985
+ in vec3 displayMin;
986
+ in vec3 displayMax;
987
+ out vec4 fragColor;
988
+
989
+ vec4 colorBlend(vec4 near,vec4 far){
990
+ float nA = near.a;
991
+ if (nA >= 1.0){
992
+ return near;
993
+ }
994
+ if (nA <= 0.0){
995
+ return far;
996
+ }
997
+
998
+ float fA = far.a;
999
+ float a = fA + nA - fA*nA;
1000
+ vec3 color = (far.rgb * fA * (1.0 - nA) + near.rgb*nA)/a;
1001
+ return vec4(color,a);
1002
+ }
1003
+
1004
+
1005
+
1006
+
1007
+ vec2 intersectBox( vec3 orig, vec3 dir ) {
1008
+ vec3 inv_dir = 1.0 / dir;
1009
+ vec3 tmin_tmp = (displayMin - orig ) * inv_dir;
1010
+ vec3 tmax_tmp = (displayMax - orig ) * inv_dir;
1011
+ vec3 tmin = min( tmin_tmp, tmax_tmp );
1012
+ vec3 tmax = max( tmin_tmp, tmax_tmp );
1013
+ float t0 = max( tmin.x, max( tmin.y, tmin.z ) );
1014
+ float t1 = min( tmax.x, min( tmax.y, tmax.z ) );
1015
+ return vec2( t0, t1 );
1016
+ }
1017
+
1018
+ float getValue( vec3 point ) {
1019
+ return texture( map, point ).r;
1020
+ }
1021
+
1022
+ // 获取梯度颜色
1023
+ vec4 getGradientColor(float val) {
1024
+ val = clamp( val, 0.0,1.0);
1025
+ return texture2D(gradient, vec2(val, 0.5));
1026
+ }
1027
+
1028
+
1029
+
1030
+
1031
+ void main(){
1032
+ vec3 rayDir = normalize( lookDir );
1033
+
1034
+ vec2 times = intersectBox( cameraPos, rayDir );
1035
+ float tMin = times.x;
1036
+ float tMax = times.y;
1037
+ if ( tMin > tMax || tMax < 0.0 ) discard;
1038
+ tMin = max( tMin, 0.0 );
1039
+
1040
+ vec3 point = cameraPos + tMin * rayDir;
1041
+
1042
+ float step = 1.0/steps;
1043
+ float opacityFactor = atomize ? step * accFactor : 1.0;
1044
+
1045
+
1046
+ float invRangeLen = 1.0/(range.y - range.x);
1047
+ vec3 stepDir = rayDir * step;
1048
+
1049
+ vec4 finalColor = vec4( 0,0,0,0);
1050
+ float alphaMax = alphaRange.y;
1051
+
1052
+ for ( float t = tMin; t <= tMax; t += step,point += stepDir ) {
1053
+ float val = getValue( point);
1054
+ if (voidRange.x <= val && val <= voidRange.y ) continue;
1055
+ val = (val - range.x) * invRangeLen;
1056
+ if (discardOut && (val < 0.0 || val > 1.0)) continue;
1057
+
1058
+ vec4 gradientColor = getGradientColor(val);
1059
+ gradientColor.a *= opacityFactor;
1060
+ finalColor = colorBlend(finalColor,gradientColor);
1061
+ if ( finalColor.a >= alphaMax ) break;
1062
+ }
1063
+
1064
+ finalColor.a *= opacity;
1065
+ if ( finalColor.a <= alphaRange.x ) discard;
1066
+ if (isDoubleSide){
1067
+ finalColor.a = 1.0 - sqrt(1.0 - finalColor.a);
1068
+ }
1069
+ fragColor = finalColor;
1070
+
1071
+ }`;
1072
+ class Ue extends xt {
1073
+ constructor(e) {
1074
+ const { gradient: t, range: a, discardOut: r, voidRange: o, ...n } = e ?? {}, s = new T().copy(a ?? { x: 0, y: 100 }), l = r ?? !0, u = new T().copy(o ?? { x: -100, y: -1 }), c = {
1075
+ gradient: { value: t == null ? t : ee(t) },
1076
+ range: { value: s },
1077
+ discardOut: { value: l },
1078
+ voidRange: { value: u }
1079
+ };
1080
+ super({ ...n, fragmentShader: yi, uniforms: c }), g(this, "isGradientVolumeMaterial", !0);
1081
+ }
1082
+ /**
1083
+ * 数值的梯度映射纹理
1084
+ */
1085
+ get gradient() {
1086
+ return this.uniforms.gradient.value;
1087
+ }
1088
+ set gradient(e) {
1089
+ this.uniforms.gradient.value = e, this.uniformsNeedUpdate = !0;
1090
+ }
1091
+ /**
1092
+ * 数值的映射区间
1093
+ * @remarks
1094
+ * x 为最小值,y 为最大值
1095
+ *
1096
+ * @defaultValue {x:0,y:100}
1097
+ */
1098
+ get range() {
1099
+ return this.uniforms.range.value;
1100
+ }
1101
+ set range(e) {
1102
+ this.uniforms.range.value.copy(e), this.uniformsNeedUpdate = !0;
1103
+ }
1104
+ /**
1105
+ * 是否丢弃超出映射范围的数值
1106
+ * @remarks
1107
+ * 当数值超出映射区间 {@link GradientVolumeMaterial.range} 时,是否丢弃;
1108
+ *
1109
+ * 包含左右边界值
1110
+ * @defaultValue true
1111
+ */
1112
+ get discardOut() {
1113
+ return this.uniforms.discardOut.value;
1114
+ }
1115
+ set discardOut(e) {
1116
+ this.uniforms.discardOut.value = e, this.uniformsNeedUpdate = !0;
1117
+ }
1118
+ /**
1119
+ * 空值的范围
1120
+ * @remarks
1121
+ * 当数值在此范围中时,会被认为是空的值,渲染时会被丢弃
1122
+ *
1123
+ * 包含左右边界值
1124
+ *
1125
+ * @defaultValue {x:-100,y:-1}
1126
+ */
1127
+ get voidRange() {
1128
+ return this.uniforms.voidRange.value;
1129
+ }
1130
+ set voidRange(e) {
1131
+ this.uniforms.voidRange.value.copy(e), this.uniformsNeedUpdate = !0;
1132
+ }
1133
+ }
1134
+ class Mi extends et {
1135
+ constructor(e, t, a, r, o) {
1136
+ super(e, t, a, r), g(this, "isGradientData3DTexture", !0), this.format = Xe, this.type = o ?? tt, this.minFilter = this.magFilter = it, this.unpackAlignment = 1, this.needsUpdate = !0;
1137
+ }
1138
+ /**
1139
+ * 获取3D数据的切片
1140
+ * @remarks
1141
+ * 切片就是指定轴的指定位置的垂直截面
1142
+ * @param axis - 轴
1143
+ * @param depth - 在轴上的坐标值
1144
+ * @returns
1145
+ */
1146
+ getData3DSlice(e, t) {
1147
+ const { data: a, width: r, height: o, depth: n } = this.image;
1148
+ return ye({ data: a, size: { x: r, y: o, z: n } }, e, t, 1);
1149
+ }
1150
+ /**
1151
+ * 获取3D数据中指定坐标处的数据项目
1152
+ * @remarks
1153
+ * 在 ImageData3DTexture 中,与 {@link ImageData3DTexture.getColor} 返回的值一样;
1154
+ * @param coord
1155
+ * @returns
1156
+ */
1157
+ getItem(e) {
1158
+ const { data: t, width: a, height: r, depth: o } = this.image;
1159
+ return Te({ data: t, size: { x: a, y: r, z: o } }, e).value;
1160
+ }
1161
+ /**
1162
+ * 获取3D数据中指定坐标处的值
1163
+ * @param coord - 坐标
1164
+ * @returns
1165
+ */
1166
+ getValue(e) {
1167
+ const { data: t, width: a, height: r, depth: o } = this.image;
1168
+ return Qt({ data: t, size: { x: a, y: r, z: o } }, e).value;
1169
+ }
1170
+ }
1171
+ function wi(i, e) {
1172
+ const { data: t, size: a } = i, { x: r, y: o, z: n } = a, s = r * o * n, { voidValue: l = 0, uint8: u } = e ?? {};
1173
+ let c;
1174
+ if (u) {
1175
+ c = new Uint8Array(s);
1176
+ for (let m = 0; m < s; m++) {
1177
+ const p = t[m] ?? l;
1178
+ c[m] = Math.trunc(p);
1179
+ }
1180
+ } else {
1181
+ c = new Float32Array(s);
1182
+ for (let m = 0; m < s; m++) {
1183
+ const p = t[m] ?? l;
1184
+ c[m] = p;
1185
+ }
1186
+ }
1187
+ const d = u ? at : tt;
1188
+ return new Mi(c, r, o, n, d);
1189
+ }
1190
+ const zi = `precision highp float;
1191
+ precision highp sampler3D;
1192
+
1193
+ uniform sampler3D map;
1194
+
1195
+
1196
+
1197
+ // 颜色累积系数
1198
+ uniform float accFactor;
1199
+ uniform bool isDoubleSide;
1200
+ uniform bool atomize;
1201
+
1202
+
1203
+ uniform float opacity;
1204
+ uniform vec2 alphaRange;
1205
+ uniform float steps;
1206
+
1207
+ in vec3 cameraPos;
1208
+ in vec3 lookDir;
1209
+ in vec3 displayMin;
1210
+ in vec3 displayMax;
1211
+ out vec4 fragColor;
1212
+
1213
+ // 混合颜色
1214
+ vec4 colorBlend(vec4 near,vec4 far){
1215
+ float nA = near.a;
1216
+ if (nA >= 1.0){
1217
+ return near;
1218
+ }
1219
+ if (nA <= 0.0){
1220
+ return far;
1221
+ }
1222
+
1223
+ float fA = far.a;
1224
+ float a = fA + nA - fA*nA;
1225
+ vec3 color = (far.rgb * fA * (1.0 - nA) + near.rgb*nA)/a;
1226
+ return vec4(color,a);
1227
+ }
1228
+
1229
+
1230
+
1231
+
1232
+ // 包围盒求交
1233
+ vec2 intersectBox( vec3 orig, vec3 dir ) {
1234
+ vec3 inv_dir = 1.0 / dir;
1235
+ vec3 tmin_tmp = (displayMin - orig ) * inv_dir;
1236
+ vec3 tmax_tmp = (displayMax - orig ) * inv_dir;
1237
+ vec3 tmin = min( tmin_tmp, tmax_tmp );
1238
+ vec3 tmax = max( tmin_tmp, tmax_tmp );
1239
+ float t0 = max( tmin.x, max( tmin.y, tmin.z ) );
1240
+ float t1 = min( tmax.x, min( tmax.y, tmax.z ) );
1241
+ return vec2( t0, t1 );
1242
+ }
1243
+
1244
+
1245
+
1246
+ void main(){
1247
+ vec3 rayDir = normalize( lookDir );
1248
+
1249
+ vec2 times = intersectBox( cameraPos, rayDir );
1250
+ float tMin = times.x;
1251
+ float tMax = times.y;
1252
+ if ( tMin > tMax || tMax < 0.0 ) discard;
1253
+ tMin = max( tMin, 0.0 );
1254
+
1255
+ vec3 point = cameraPos + tMin * rayDir;
1256
+
1257
+ float step = 1.0/steps;
1258
+ float opacityFactor = atomize ? step * accFactor : 1.0;
1259
+
1260
+ vec3 stepDir = rayDir * step;
1261
+
1262
+ vec4 finalColor = vec4( 0,0,0,0);
1263
+ float alphaMax = alphaRange.y;
1264
+
1265
+ for ( float t = tMin; t <= tMax; t += step,point += stepDir ) {
1266
+ vec4 textureColor = texture( map, point );
1267
+ textureColor.a *= opacityFactor;
1268
+ finalColor = colorBlend(finalColor,textureColor);
1269
+ if ( finalColor.a >= alphaMax ) break;
1270
+ }
1271
+
1272
+ finalColor.a *= opacity;
1273
+ if ( finalColor.a <= alphaRange.x ) discard;
1274
+ if (isDoubleSide){
1275
+ finalColor.a = 1.0 - sqrt(1.0 - finalColor.a);
1276
+ }
1277
+ fragColor = finalColor;
1278
+
1279
+ }`;
1280
+ class qe extends xt {
1281
+ constructor(e) {
1282
+ super({ ...e, fragmentShader: zi }), g(this, "isImageVolumeMaterial", !0);
1283
+ }
1284
+ }
1285
+ function Di(i, e, t) {
1286
+ const a = t ?? {}, { x: r, y: o } = a.range ?? { x: 0, y: 100 }, n = a.discardOut ?? !0, { x: s, y: l } = a.voidRange ?? { x: -100, y: -1 }, u = a.voidColor ?? [0, 0, 0, 0], { width: c, height: d } = e, m = Math.trunc(d / 2), p = c - 1;
1287
+ function h(y) {
1288
+ const M = Math.trunc(p * y);
1289
+ return dt(e, m, M);
1290
+ }
1291
+ const x = 1 / (o - r), { data: _, size: w } = i, D = _.length, z = [];
1292
+ for (let y = 0; y < D; y++) {
1293
+ let M = u, v = _[y];
1294
+ (v <= s || l <= v) && (v = (v - r) * x, n && (v < 0 || v > 1) || (v = Math.min(Math.max(v, 0), 1), M = h(v))), z.push(...M);
1295
+ }
1296
+ return { data: z, size: w };
1297
+ }
1298
+ class _t extends et {
1299
+ constructor(e, t, a, r) {
1300
+ super(e, t, a, r), g(this, "isImageData3DTexture", !0), this.format = Ye, this.type = at, this.minFilter = this.magFilter = it, this.unpackAlignment = 1, this.needsUpdate = !0;
1301
+ }
1302
+ /**
1303
+ * 获取3D数据的切片
1304
+ * @remarks
1305
+ * 切片就是指定轴的指定位置的垂直截面
1306
+ * @param axis - 轴
1307
+ * @param depth - 在轴上的坐标值
1308
+ * @returns
1309
+ */
1310
+ getData3DSlice(e, t) {
1311
+ const { data: a, width: r, height: o, depth: n } = this.image;
1312
+ return ye({ data: a, size: { x: r, y: o, z: n } }, e, t, 4);
1313
+ }
1314
+ /**
1315
+ * 获取3D数据中指定坐标处的数据项目
1316
+ * @remarks
1317
+ * 在 ImageData3DTexture 中,与 {@link ImageData3DTexture.getColor} 返回的值一样;
1318
+ * @param coord
1319
+ * @returns
1320
+ */
1321
+ getItem(e) {
1322
+ return this.getColor(e);
1323
+ }
1324
+ /**
1325
+ * 获取3D图像中指定坐标处的颜色
1326
+ * @param coord - 坐标
1327
+ * @returns
1328
+ */
1329
+ getColor(e) {
1330
+ const { data: t, width: a, height: r, depth: o } = this.image;
1331
+ return Te({ data: t, size: { x: a, y: r, z: o } }, e, 4).value;
1332
+ }
1333
+ }
1334
+ function Si(i, e, t) {
1335
+ const a = t?.reverseY ?? !0, { data: r, width: o, height: n, depth: s, colorSpace: l } = ti(i, e, { ...t, reverseY: a }), u = new _t(r, o, n, s);
1336
+ return l === "srgb" && (u.colorSpace = "srgb"), u;
1337
+ }
1338
+ function Ke(i, e) {
1339
+ const t = e.gradient, a = Array.isArray(t) ? lt(t, 256, 1) : Ie(t) ? t : ut(t);
1340
+ let r = i;
1341
+ Ne(i) && (r = {
1342
+ // @ts-ignore
1343
+ data: i.data,
1344
+ size: { x: i.width, y: i.height, z: i.depth }
1345
+ });
1346
+ const { data: o, size: n } = Di(r, a, e), s = Uint8ClampedArray.from(o);
1347
+ return new _t(s, n.x, n.y, n.z);
1348
+ }
1349
+ const bi = `out vec3 lookDir;
1350
+ out vec3 normalDir;
1351
+
1352
+ #if defined( USE_COLOR_ALPHA ) || defined( USE_COLOR )
1353
+ out vec4 verColor;
1354
+ #endif
1355
+
1356
+ void main() {
1357
+ vec3 cameraPos = vec3( inverse( modelMatrix ) * vec4( cameraPosition, 1.0 ) ).xyz;
1358
+ lookDir = position - cameraPos;
1359
+ normalDir = normal;
1360
+
1361
+ #if defined( USE_COLOR_ALPHA )
1362
+ verColor = color;
1363
+ #elif defined( USE_INSTANCING_COLOR )
1364
+ overColor = vec3(instanceColor,1.0);
1365
+ #elif defined( USE_COLOR )
1366
+ overColor = vec3(color,1.0);
1367
+ #endif
1368
+ gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
1369
+ }`, Ci = `uniform vec3 color;
1370
+ uniform float solid;
1371
+ uniform float exp;
1372
+
1373
+ uniform float opacity;
1374
+ uniform bool isDoubleSide;
1375
+
1376
+ in vec3 lookDir;
1377
+ in vec3 normalDir;
1378
+
1379
+ #if defined( USE_COLOR_ALPHA ) || defined( USE_COLOR )
1380
+ in vec4 verColor;
1381
+ #endif
1382
+
1383
+ out vec4 fragColor;
1384
+
1385
+
1386
+ void main(){
1387
+ #if defined( USE_COLOR_ALPHA ) || defined( USE_COLOR )
1388
+ fragColor = verColor;
1389
+ #else
1390
+ fragColor = vec4(color,1.0);
1391
+ #endif
1392
+
1393
+ vec3 dir = normalize(lookDir);
1394
+ vec3 nor = normalize(normalDir);
1395
+ float depth = abs(dot(nor,dir));
1396
+ float dist = sqrt(1.0 - pow(depth,2.0));
1397
+
1398
+ float finalAlpha = fragColor.a * depth;
1399
+ if (dist > solid) {
1400
+ float distAlpha = 1.0 - (dist - solid)/(1.0 - solid);
1401
+ finalAlpha *= pow(distAlpha,exp);
1402
+ }
1403
+
1404
+ finalAlpha *= opacity;
1405
+ if ( finalAlpha == 0.0 ) discard;
1406
+ if (isDoubleSide){
1407
+ finalAlpha = 1.0 - sqrt(1.0 - finalAlpha);
1408
+ }
1409
+ fragColor.a = finalAlpha;
1410
+ }`;
1411
+ class ma extends te {
1412
+ constructor(e) {
1413
+ const t = e ?? {}, a = t.color ?? new Qe(1, 1, 1), r = t.solid ?? 0, o = t.exp ?? 1, n = t.opacity ?? 1, s = t.side ?? J;
1414
+ super({
1415
+ glslVersion: ie,
1416
+ // @ts-ignore
1417
+ uniforms: {
1418
+ color: { value: a },
1419
+ solid: { value: r },
1420
+ exp: { value: o },
1421
+ opacity: { value: n },
1422
+ isDoubleSide: { value: !1 }
1423
+ },
1424
+ vertexShader: bi,
1425
+ fragmentShader: Ci,
1426
+ side: J,
1427
+ transparent: !0
1428
+ }), g(this, "isSphereFogMaterial", !0), g(this, "_side", J), this.opacity = n, this.side = s;
1429
+ }
1430
+ /**
1431
+ * Mesh三角形的渲染面
1432
+ * @remarks
1433
+ * 可设置为前面、后面、或者两面都渲染
1434
+ * 如果只渲染前面,进入体积材质内部,体积材质就会消失
1435
+ * 如果只渲染后面,体积初遮挡,就会消失
1436
+ * 如果两面都渲染,则会隐藏看到容器的面
1437
+ */
1438
+ // @ts-ignore
1439
+ get side() {
1440
+ return this._side;
1441
+ }
1442
+ set side(e) {
1443
+ this._side = e, this.uniforms && (this.uniforms.isDoubleSide.value = e === Oe, this.uniformsNeedUpdate = !0);
1444
+ }
1445
+ /**
1446
+ * 球形雾的颜色
1447
+ * @remarks
1448
+ * 当开启顶点颜色 {@link SphereFogMaterial.vertexColors} 时,此设置将无论;
1449
+ */
1450
+ get color() {
1451
+ return this.uniforms.color.value;
1452
+ }
1453
+ set color(e) {
1454
+ this.uniforms.color.value.copy(e), this.uniformsNeedUpdate = !0;
1455
+ }
1456
+ /**
1457
+ * 透明度
1458
+ * @remarks
1459
+ * 决定整体的透明度
1460
+ * @defaultValue 1
1461
+ */
1462
+ // @ts-ignore
1463
+ get opacity() {
1464
+ return this.uniforms.opacity.value;
1465
+ }
1466
+ set opacity(e) {
1467
+ this.uniforms && (this.uniforms.opacity.value = e), this.uniformsNeedUpdate = !0;
1468
+ }
1469
+ /**
1470
+ * 实心因子
1471
+ * @remarks
1472
+ * 在实心范围内,球形雾不会衰减
1473
+ * @defaultValue 0
1474
+ */
1475
+ get solid() {
1476
+ return this.uniforms.solid.value;
1477
+ }
1478
+ set solid(e) {
1479
+ this.uniforms && (this.uniforms.solid.value = e), this.uniformsNeedUpdate = !0;
1480
+ }
1481
+ /**
1482
+ * 雾的衰减指数
1483
+ * @defaultValue 1
1484
+ */
1485
+ get exp() {
1486
+ return this.uniforms.exp.value;
1487
+ }
1488
+ set exp(e) {
1489
+ this.uniforms && (this.uniforms.exp.value = e), this.uniformsNeedUpdate = !0;
1490
+ }
1491
+ }
1492
+ class yt extends te {
1493
+ constructor(e, t) {
1494
+ const { solid: a = 0, exp: r = 1, useRadius: o = !0, sizeAttenuation: n = !0, star: s = !1, ...l } = e ?? {}, { uniforms: u, ...c } = t || {}, d = {
1495
+ star: { value: s },
1496
+ solid: { value: a },
1497
+ exp: { value: r }
1498
+ };
1499
+ super({
1500
+ // glslVersion: GLSL3,
1501
+ // @ts-ignore
1502
+ uniforms: Je.merge([jt.points.uniforms, d, u]),
1503
+ transparent: !0,
1504
+ depthTest: !1,
1505
+ // depthWrite:false,
1506
+ defines: {
1507
+ useRadius: o
1508
+ },
1509
+ ...c
1510
+ }), g(this, "isFogPointsMaterial", !0), g(this, "sizeAttenuation", !0), Object.assign(this, { ...l, solid: a, exp: r, sizeAttenuation: n });
1511
+ }
1512
+ /**
1513
+ * 使用来自Texture的数据设置点的颜色
1514
+ * @remarks
1515
+ * 可以选择包括一个alpha通道,通常与 .transparent或.alphaTest。
1516
+ */
1517
+ get map() {
1518
+ return this.uniforms.map.value;
1519
+ }
1520
+ set map(e) {
1521
+ this.uniforms.map.value = e, this.uniformsNeedUpdate = !0;
1522
+ }
1523
+ /**
1524
+ * 是否渲染成星星的样式
1525
+ * @remarks
1526
+ * 否则,将被渲染成球形
1527
+ */
1528
+ get star() {
1529
+ return this.uniforms.star.value;
1530
+ }
1531
+ set star(e) {
1532
+ this.uniforms.star.value = e, this.uniformsNeedUpdate = !0;
1533
+ }
1534
+ /**
1535
+ * 点的大小
1536
+ * @defaultValue 1.0
1537
+ */
1538
+ get size() {
1539
+ return this.uniforms.size.value;
1540
+ }
1541
+ set size(e) {
1542
+ this.uniforms.size.value = e, this.uniformsNeedUpdate = !0;
1543
+ }
1544
+ /**
1545
+ * 透明度
1546
+ * @remarks
1547
+ * 决定整体的透明度
1548
+ * @defaultValue 1
1549
+ */
1550
+ // @ts-ignore
1551
+ get opacity() {
1552
+ return this.uniforms.opacity.value;
1553
+ }
1554
+ set opacity(e) {
1555
+ this.uniforms && (this.uniforms.opacity.value = e), this.uniformsNeedUpdate = !0;
1556
+ }
1557
+ /**
1558
+ * 实心因子
1559
+ * @remarks
1560
+ * 在实心范围内,雾点不会衰减
1561
+ * @defaultValue 0
1562
+ */
1563
+ get solid() {
1564
+ return this.uniforms.solid.value;
1565
+ }
1566
+ set solid(e) {
1567
+ this.uniforms && (this.uniforms.solid.value = e), this.uniformsNeedUpdate = !0;
1568
+ }
1569
+ /**
1570
+ * 雾的衰减指数
1571
+ * @defaultValue 1
1572
+ */
1573
+ get exp() {
1574
+ return this.uniforms.exp.value;
1575
+ }
1576
+ set exp(e) {
1577
+ this.uniforms && (this.uniforms.exp.value = e), this.uniformsNeedUpdate = !0;
1578
+ }
1579
+ get scale() {
1580
+ return this.uniforms.scale.value;
1581
+ }
1582
+ set scale(e) {
1583
+ this.uniforms && (this.uniforms.scale.value = e), this.uniformsNeedUpdate = !0;
1584
+ }
1585
+ get fogDensity() {
1586
+ return this.uniforms.fogDensity.value;
1587
+ }
1588
+ set fogDensity(e) {
1589
+ this.uniforms && (this.uniforms.fogDensity.value = e), this.uniformsNeedUpdate = !0;
1590
+ }
1591
+ get fogNear() {
1592
+ return this.uniforms.fogNear.value;
1593
+ }
1594
+ set fogNear(e) {
1595
+ this.uniforms && (this.uniforms.fogNear.value = e), this.uniformsNeedUpdate = !0;
1596
+ }
1597
+ get fogFar() {
1598
+ return this.uniforms.fogFar.value;
1599
+ }
1600
+ set fogFar(e) {
1601
+ this.uniforms && (this.uniforms.fogFar.value = e), this.uniformsNeedUpdate = !0;
1602
+ }
1603
+ get fogColor() {
1604
+ return this.uniforms.fogColor.value;
1605
+ }
1606
+ set fogColor(e) {
1607
+ this.uniforms.fogColor.value.copy(e), this.uniformsNeedUpdate = !0;
1608
+ }
1609
+ }
1610
+ const Ui = `#ifdef useRadius
1611
+ attribute float radius;
1612
+ #endif
1613
+
1614
+ uniform float size;
1615
+ uniform float scale;
1616
+
1617
+ #include <common>
1618
+ #include <color_pars_vertex>
1619
+ #include <fog_pars_vertex>
1620
+ #include <morphtarget_pars_vertex>
1621
+ #include <logdepthbuf_pars_vertex>
1622
+ #include <clipping_planes_pars_vertex>
1623
+
1624
+ #ifdef USE_POINTS_UV
1625
+
1626
+ varying vec2 vUv;
1627
+ uniform mat3 uvTransform;
1628
+
1629
+ #endif
1630
+
1631
+ void main() {
1632
+
1633
+ #ifdef USE_POINTS_UV
1634
+
1635
+ vUv = ( uvTransform * vec3( uv, 1 ) ).xy;
1636
+
1637
+ #endif
1638
+
1639
+ #include <color_vertex>
1640
+ #include <morphcolor_vertex>
1641
+ #include <begin_vertex>
1642
+ #include <morphtarget_vertex>
1643
+ #include <project_vertex>
1644
+
1645
+ #ifdef useRadius
1646
+ gl_PointSize = radius;
1647
+ #else
1648
+ gl_PointSize = size;
1649
+ #endif
1650
+
1651
+ #ifdef USE_SIZEATTENUATION
1652
+
1653
+ bool isPerspective = isPerspectiveMatrix( projectionMatrix );
1654
+
1655
+ if ( isPerspective ) gl_PointSize *= ( scale / - mvPosition.z );
1656
+
1657
+ #endif
1658
+
1659
+ #include <logdepthbuf_vertex>
1660
+ #include <clipping_planes_vertex>
1661
+ #include <worldpos_vertex>
1662
+ #include <fog_vertex>
1663
+
1664
+ }`, Ai = `uniform float solid;
1665
+ uniform float exp;
1666
+ uniform bool star;
1667
+
1668
+ uniform vec3 diffuse;
1669
+ uniform float opacity;
1670
+
1671
+ #include <common>
1672
+ #include <color_pars_fragment>
1673
+ #include <map_particle_pars_fragment>
1674
+ #include <alphatest_pars_fragment>
1675
+ #include <fog_pars_fragment>
1676
+ #include <logdepthbuf_pars_fragment>
1677
+ #include <clipping_planes_pars_fragment>
1678
+
1679
+
1680
+ vec4 getColor(vec4 originColor){
1681
+ float finalAlpha = originColor.a;
1682
+ float dist = 0.0;
1683
+ if (star){
1684
+ vec2 coord = abs(gl_PointCoord - vec2(0.5));
1685
+ dist = max(coord.x,coord.y);
1686
+ }else{
1687
+ dist = distance(gl_PointCoord,vec2(0.5));
1688
+ if (dist>0.5) discard;
1689
+ }
1690
+ dist /= 0.5;
1691
+ float depth = sqrt(1.0 - pow(dist,2.0));
1692
+ finalAlpha *= depth;
1693
+ if (dist > solid) {
1694
+ float distAlpha = 1.0 - (dist - solid)/(1.0 - solid);
1695
+ finalAlpha *= pow(distAlpha,exp);
1696
+ }
1697
+ originColor.a = finalAlpha;
1698
+ return originColor;
1699
+ }
1700
+
1701
+ void main() {
1702
+
1703
+ #include <clipping_planes_fragment>
1704
+
1705
+ vec3 outgoingLight = vec3( 0.0 );
1706
+ vec4 diffuseColor = vec4( diffuse, opacity );
1707
+
1708
+ #include <logdepthbuf_fragment>
1709
+ #include <map_particle_fragment>
1710
+ #include <color_fragment>
1711
+ #include <alphatest_fragment>
1712
+
1713
+ diffuseColor = getColor(diffuseColor);
1714
+ outgoingLight = diffuseColor.rgb;
1715
+
1716
+ #include <output_fragment>
1717
+ #include <tonemapping_fragment>
1718
+ #include <encodings_fragment>
1719
+ #include <fog_fragment>
1720
+ #include <premultiplied_alpha_fragment>
1721
+
1722
+ }`;
1723
+ class Ni extends yt {
1724
+ constructor(e) {
1725
+ super(e, { vertexShader: Ui, fragmentShader: Ai }), g(this, "isColorFogPointsMaterial", !0);
1726
+ }
1727
+ /**
1728
+ * 雾点的颜色
1729
+ * @remarks
1730
+ * 当开启顶点颜色 {@link SphereFogMaterial.vertexColors} 时,此设置将无论;
1731
+ */
1732
+ get color() {
1733
+ return this.uniforms.diffuse.value;
1734
+ }
1735
+ set color(e) {
1736
+ this.uniforms.diffuse.value.copy(e), this.uniformsNeedUpdate = !0;
1737
+ }
1738
+ get alphaMap() {
1739
+ return this.uniforms.alphaMap.value;
1740
+ }
1741
+ set alphaMap(e) {
1742
+ this.uniforms && (this.uniforms.alphaMap.value = e), this.uniformsNeedUpdate = !0;
1743
+ }
1744
+ get uvTransform() {
1745
+ return this.uniforms.uvTransform.value;
1746
+ }
1747
+ set uvTransform(e) {
1748
+ this.uniforms && this.uniforms.uvTransform.value.copy(e), this.uniformsNeedUpdate = !0;
1749
+ }
1750
+ }
1751
+ function Pi(i) {
1752
+ const { points: e, radius: t = 10, color: a = [0, 0, 0, 0] } = i, r = [], o = [], n = [];
1753
+ for (const { x: l, y: u, z: c, radius: d, color: m } of e) {
1754
+ r.push(l, u, c), o.push(d ?? t);
1755
+ const p = m ?? a, h = p[3];
1756
+ p[3] = Math.trunc(h * 255), n.push(...p);
1757
+ }
1758
+ const s = new st();
1759
+ return s.setAttribute("position", new Z(r, 3)), s.setAttribute("radius", new Z(o, 1)), s.setAttribute("color", new Kt(n, 4, !0)), s;
1760
+ }
1761
+ function pa(i) {
1762
+ const e = new Ni(i), t = Pi(i);
1763
+ return new nt(t, e);
1764
+ }
1765
+ const Oi = `attribute float value;
1766
+ uniform vec2 range;
1767
+ varying float vValue;
1768
+ #ifdef useRadius
1769
+ attribute float radius;
1770
+ #endif
1771
+
1772
+
1773
+ uniform float size;
1774
+ uniform float scale;
1775
+
1776
+ #include <common>
1777
+ // #include <color_pars_vertex>
1778
+ #include <fog_pars_vertex>
1779
+ #include <morphtarget_pars_vertex>
1780
+ #include <logdepthbuf_pars_vertex>
1781
+ #include <clipping_planes_pars_vertex>
1782
+
1783
+ #ifdef USE_POINTS_UV
1784
+
1785
+ varying vec2 vUv;
1786
+ uniform mat3 uvTransform;
1787
+
1788
+ #endif
1789
+
1790
+ void main() {
1791
+ vValue = (value - range.x)/(range.y - range.x);
1792
+
1793
+ #ifdef USE_POINTS_UV
1794
+
1795
+ vUv = ( uvTransform * vec3( uv, 1 ) ).xy;
1796
+
1797
+ #endif
1798
+
1799
+ // #include <color_vertex>
1800
+ // #include <morphcolor_vertex>
1801
+ #include <begin_vertex>
1802
+ #include <morphtarget_vertex>
1803
+ #include <project_vertex>
1804
+
1805
+ #ifdef useRadius
1806
+ gl_PointSize = radius;
1807
+ #else
1808
+ gl_PointSize = size;
1809
+ #endif
1810
+
1811
+ #ifdef USE_SIZEATTENUATION
1812
+
1813
+ bool isPerspective = isPerspectiveMatrix( projectionMatrix );
1814
+
1815
+ if ( isPerspective ) gl_PointSize *= ( scale / - mvPosition.z );
1816
+
1817
+ #endif
1818
+
1819
+ #include <logdepthbuf_vertex>
1820
+ #include <clipping_planes_vertex>
1821
+ #include <worldpos_vertex>
1822
+ #include <fog_vertex>
1823
+
1824
+ }`, Ii = `varying float vValue;
1825
+ uniform sampler2D map;
1826
+
1827
+
1828
+ uniform float solid;
1829
+ uniform float exp;
1830
+ uniform bool star;
1831
+
1832
+ // uniform vec3 diffuse;
1833
+ uniform float opacity;
1834
+
1835
+ #include <common>
1836
+ // #include <color_pars_fragment>
1837
+ // #include <map_particle_pars_fragment>
1838
+ #include <alphatest_pars_fragment>
1839
+ #include <fog_pars_fragment>
1840
+ #include <logdepthbuf_pars_fragment>
1841
+ #include <clipping_planes_pars_fragment>
1842
+
1843
+
1844
+ // 获取梯度颜色
1845
+ vec4 getGradientColor(float val) {
1846
+ val = clamp( val, 0.0,1.0);
1847
+ return texture2D(map, vec2(val, 0.5));
1848
+ }
1849
+
1850
+
1851
+ vec4 getColor(){
1852
+ float val = vValue;
1853
+ float dist = 0.0;
1854
+ if (star){
1855
+ vec2 coord = abs(gl_PointCoord - vec2(0.5));
1856
+ dist = max(coord.x,coord.y);
1857
+ }else{
1858
+ dist = distance(gl_PointCoord,vec2(0.5));
1859
+ if (dist>0.5) discard;
1860
+ }
1861
+ dist /= 0.5;
1862
+ float depth = sqrt(1.0 - pow(dist,2.0));
1863
+ if (dist > solid) {
1864
+ float solidDist = 1.0 - (dist - solid)/(1.0 - solid);
1865
+ val *= pow(solidDist,exp);
1866
+ }
1867
+ vec4 valColor = getGradientColor(val);
1868
+ valColor.a *= depth * opacity;
1869
+ return valColor;
1870
+ }
1871
+
1872
+ void main() {
1873
+
1874
+ #include <clipping_planes_fragment>
1875
+
1876
+ vec3 outgoingLight = vec3( 0.0 );
1877
+ vec4 diffuseColor = getColor();
1878
+
1879
+ #include <logdepthbuf_fragment>
1880
+ // #include <map_particle_fragment>
1881
+ // #include <color_fragment>
1882
+ #include <alphatest_fragment>
1883
+
1884
+ outgoingLight = diffuseColor.rgb;
1885
+
1886
+ #include <output_fragment>
1887
+ #include <tonemapping_fragment>
1888
+ #include <encodings_fragment>
1889
+ #include <fog_fragment>
1890
+ #include <premultiplied_alpha_fragment>
1891
+
1892
+ }`;
1893
+ class Fi extends yt {
1894
+ constructor(e) {
1895
+ const { range: t, ...a } = e || {}, r = {
1896
+ range: { value: new T().copy(t ?? { x: 0, y: 100 }) }
1897
+ };
1898
+ super(a, { vertexShader: Oi, fragmentShader: Ii, uniforms: r }), g(this, "isColorFogPointsMaterial", !0);
1899
+ }
1900
+ /**
1901
+ * 数值的映射区间
1902
+ * @remarks
1903
+ * x 为最小值,y 为最大值
1904
+ *
1905
+ * @defaultValue {x:0,y:100}
1906
+ */
1907
+ get range() {
1908
+ return this.uniforms.range.value;
1909
+ }
1910
+ set range(e) {
1911
+ this.uniforms.range.value.copy(e), this.uniformsNeedUpdate = !0;
1912
+ }
1913
+ }
1914
+ function Ti(i) {
1915
+ const { points: e, radius: t = 10, value: a = 100 } = i, r = [], o = [], n = [];
1916
+ for (const { x: l, y: u, z: c, radius: d, value: m } of e)
1917
+ r.push(l, u, c), o.push(d ?? t), n.push(m ?? a);
1918
+ const s = new st();
1919
+ return s.setAttribute("position", new Z(r, 3)), s.setAttribute("radius", new Z(o, 1)), s.setAttribute("value", new Z(n, 1)), s;
1920
+ }
1921
+ function fa(i) {
1922
+ const e = i.gradient, t = e == null ? e : ee(e), a = new Fi({ ...i, map: t }), r = Ti(i);
1923
+ return new nt(r, a);
1924
+ }
1925
+ const Ri = ` out vec2 vUv;
1926
+
1927
+ void main() {
1928
+ vUv = uv;
1929
+ gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
1930
+ }`, Vi = `precision highp float;
1931
+ precision highp sampler3D;
1932
+
1933
+ uniform sampler3D map;
1934
+
1935
+ uniform float opacity;
1936
+ uniform int axis;
1937
+ uniform float depth;
1938
+
1939
+ in vec2 vUv;
1940
+ out vec4 fragColor;
1941
+
1942
+ void main(){
1943
+ vec3 uv3 = vec3(0.0);
1944
+ int depthSize = textureSize(map,0)[axis];
1945
+ uv3[axis] = depth/float(depthSize);
1946
+ int xIndex = (axis + 1)%3;
1947
+ int yIndex = (axis + 2)%3;
1948
+ uv3[xIndex] = vUv.x;
1949
+ uv3[yIndex] = vUv.y;
1950
+
1951
+ fragColor = texture(map, uv3);
1952
+ fragColor.a *= opacity;
1953
+ }`;
1954
+ class Ei extends te {
1955
+ constructor(e) {
1956
+ const t = e ?? {};
1957
+ let { map: a, opacity: r, axis: o, depth: n, side: s, ...l } = t;
1958
+ r = r ?? 1, o = o ?? S.z, n = n ?? 0, s = s ?? Oe, super({
1959
+ ...l,
1960
+ glslVersion: ie,
1961
+ // @ts-ignore
1962
+ uniforms: {
1963
+ map: { value: a },
1964
+ opacity: { value: r },
1965
+ axis: { value: o },
1966
+ depth: { value: n }
1967
+ },
1968
+ transparent: !0,
1969
+ vertexShader: Ri,
1970
+ fragmentShader: Vi,
1971
+ side: s
1972
+ }), g(this, "isSliceMaterial", !0), g(this, "_sliceSize", null), this.opacity = r;
1973
+ }
1974
+ /**
1975
+ * 三维的纹理
1976
+ */
1977
+ get map() {
1978
+ return this.uniforms.map.value;
1979
+ }
1980
+ set map(e) {
1981
+ this.uniforms.map.value = e, this._sliceSize = null, this.uniformsNeedUpdate = !0;
1982
+ }
1983
+ /**
1984
+ * 透明度
1985
+ * @remarks
1986
+ * 决定整体的透明度
1987
+ * @defaultValue 1
1988
+ */
1989
+ // @ts-ignore
1990
+ get opacity() {
1991
+ return this.uniforms.opacity.value;
1992
+ }
1993
+ set opacity(e) {
1994
+ this.uniforms && (this.uniforms.opacity.value = e), this.uniformsNeedUpdate = !0;
1995
+ }
1996
+ /**
1997
+ * 轴
1998
+ * @remarks
1999
+ * 切片就是垂直于该轴的截面
2000
+ *
2001
+ * @defaultValue Axis.z
2002
+ */
2003
+ get axis() {
2004
+ return this.uniforms.axis.value;
2005
+ }
2006
+ set axis(e) {
2007
+ this.uniforms.axis.value = e, this._sliceSize = null, this.uniformsNeedUpdate = !0;
2008
+ }
2009
+ /**
2010
+ * 轴上的坐标值
2011
+ * @remarks
2012
+ * 会在轴的该位置处获取切片
2013
+ * @defaultValue 0
2014
+ */
2015
+ get depth() {
2016
+ return this.uniforms.depth.value;
2017
+ }
2018
+ set depth(e) {
2019
+ this.uniforms.depth.value = e, this.uniformsNeedUpdate = !0;
2020
+ }
2021
+ /**
2022
+ * 切片的尺寸
2023
+ * @remarks
2024
+ * 不同轴上的切片的尺寸一般不一样
2025
+ */
2026
+ get sliceSize() {
2027
+ let e = this._sliceSize;
2028
+ if (!e) {
2029
+ this._sliceSize = e = new T(1, 1);
2030
+ const { axis: t, map: a } = this;
2031
+ if (a) {
2032
+ const { width: r, height: o, depth: n } = a.image, [s, l] = S.getCrossAxiss(t), u = [r, o, n];
2033
+ e.set(u[s], u[l]);
2034
+ }
2035
+ }
2036
+ return e;
2037
+ }
2038
+ }
2039
+ class Gi extends rt {
2040
+ constructor(e) {
2041
+ const t = new Ei(e), a = new kt();
2042
+ super(a, t), g(this, "isSliceMesh", !0), g(this, "_geometry"), g(this, "_material"), g(this, "autoUpdateGeometry", !0), Object.defineProperties(this, {
2043
+ geometry: {
2044
+ get: () => this._geometry,
2045
+ set: (r) => {
2046
+ this._geometry = r, this.autoUpdateGeometry && this.updateGeometry();
2047
+ }
2048
+ },
2049
+ material: {
2050
+ get: () => this._material,
2051
+ set: (r) => {
2052
+ this._material = r, this.autoUpdateGeometry && this.updateGeometry();
2053
+ }
2054
+ }
2055
+ }), this.geometry = a, this.material = t;
2056
+ }
2057
+ /**
2058
+ * 更新几何体
2059
+ */
2060
+ updateGeometry() {
2061
+ var e;
2062
+ const { geometry: t, material: a } = this;
2063
+ if (!a || !((e = a.map) != null && e.image))
2064
+ return !1;
2065
+ t.boundingBox || t.computeBoundingBox();
2066
+ const r = a.sliceSize, o = t.boundingBox.getSize(new f());
2067
+ t.scale(r.x / o.x, r.y / o.y, 1);
2068
+ }
2069
+ /**
2070
+ * 三维的纹理
2071
+ */
2072
+ get map() {
2073
+ return this.material.map;
2074
+ }
2075
+ set map(e) {
2076
+ this.material.map = e, this.material = this.material;
2077
+ }
2078
+ /**
2079
+ * 轴
2080
+ * @remarks
2081
+ * 切片就是垂直于该轴的截面
2082
+ *
2083
+ * @defaultValue Axis.z
2084
+ */
2085
+ get axis() {
2086
+ return this.material.axis;
2087
+ }
2088
+ set axis(e) {
2089
+ this.material.axis = e, this.material = this.material;
2090
+ }
2091
+ /**
2092
+ * 轴上的坐标值
2093
+ * @remarks
2094
+ * 会在轴的该位置处获取切片
2095
+ * @defaultValue 0
2096
+ */
2097
+ get depth() {
2098
+ return this.material.depth;
2099
+ }
2100
+ set depth(e) {
2101
+ this.material.depth = e;
2102
+ }
2103
+ /**
2104
+ * 切片的尺寸
2105
+ * @remarks
2106
+ * 不同轴上的切片的尺寸一般不一样
2107
+ */
2108
+ get sliceSize() {
2109
+ return this.material.sliceSize;
2110
+ }
2111
+ }
2112
+ class Li extends oi {
2113
+ constructor(e) {
2114
+ const t = Ne(e) ? e : e.image;
2115
+ super(t), g(this, "isImageData3DTextureSlice", !0);
2116
+ }
2117
+ /**
2118
+ * 设置材质或 IImageData3 类数据
2119
+ */
2120
+ set texture(e) {
2121
+ this.image3D = Ne(e) ? e : e.image;
2122
+ }
2123
+ }
2124
+ function Mt({ ratio: i, value: e }) {
2125
+ return e - e * i;
2126
+ }
2127
+ function Bi(i, e) {
2128
+ const { x: t, y: a } = e;
2129
+ let r = 0;
2130
+ for (const { value: o, clim: { x: n, y: s } } of i)
2131
+ r += (o - n) / (s - n);
2132
+ return r * (a - t) + t;
2133
+ }
2134
+ function ji(i, e, t) {
2135
+ const { size: a, data3D: r, tags: o } = e, { clim: n, radius: s, value: l, hollow: u, valueGradient: c, valuesAccumulate: d } = i, m = new f().copy(i), p = [], h = [], x = {
2136
+ particles: p,
2137
+ values: h
2138
+ }, _ = s * u, w = m.clone().subScalar(s), D = m.clone().addScalar(s);
2139
+ w.max(new f(0, 0, 0));
2140
+ const z = new f().copy(a).subScalar(1);
2141
+ D.min(z);
2142
+ let { x: y, y: M, z: v } = w;
2143
+ y = Math.trunc(y), M = Math.trunc(M), v = Math.trunc(v);
2144
+ let { x: b, y: C, z: U } = D;
2145
+ if (b = Math.trunc(b), C = Math.trunc(C), U = Math.trunc(U), y > b || M > C || v > U)
2146
+ return x;
2147
+ const { x: E, y: N } = a, ae = E * N;
2148
+ for (let O = v; O <= U; O++) {
2149
+ const Me = O * ae;
2150
+ for (let R = M; R <= C; R++) {
2151
+ const re = Me + R * E;
2152
+ e:
2153
+ for (let P = y; P <= b; P++) {
2154
+ const j = re + P;
2155
+ if (o[j])
2156
+ continue;
2157
+ const I = new f(P, R, O), A = I.distanceTo(m);
2158
+ if (A > s || A < _)
2159
+ continue;
2160
+ o[j] = !0;
2161
+ const k = {
2162
+ radius: s,
2163
+ hollow: u,
2164
+ hollowRadius: _,
2165
+ distance: A,
2166
+ clim: n,
2167
+ value: l
2168
+ }, G = [], H = {
2169
+ ...k,
2170
+ ratio: A / s,
2171
+ distance: A,
2172
+ point: I
2173
+ }, $ = c(H);
2174
+ G.push({
2175
+ ...i,
2176
+ ...H,
2177
+ value: $
2178
+ });
2179
+ for (const L of t) {
2180
+ const B = I.distanceTo(L), { hollow: we, radius: K } = L;
2181
+ if (B <= K) {
2182
+ const W = K * we;
2183
+ if (B < W)
2184
+ continue e;
2185
+ const V = {
2186
+ ...L,
2187
+ ratio: B / K,
2188
+ distance: B,
2189
+ hollowRadius: W,
2190
+ point: I
2191
+ }, ze = c(V);
2192
+ G.push({ ...V, value: ze });
2193
+ }
2194
+ }
2195
+ const q = d(G, n);
2196
+ r[j] = q, p.push(I), h.push(q);
2197
+ }
2198
+ }
2199
+ }
2200
+ return x;
2201
+ }
2202
+ function ki(i) {
2203
+ const { points: e, clim: t = { x: 0, y: 100 }, radius: a = 10, value: r = 100, hollow: o = 0, valueGradient: n = Mt, valuesAccumulate: s = Bi, size: l } = i, u = { clim: t, radius: a, value: r, hollow: o, valueGradient: n, valuesAccumulate: s }, c = e.map((y) => ({ ...u, ...y }));
2204
+ let d = l;
2205
+ l || (d = new xe().setFromPoints(c).max.addScalar(1));
2206
+ const m = ui(c);
2207
+ let { x: p, y: h, z: x } = d;
2208
+ p = d.x = Math.trunc(p), h = d.y = Math.trunc(h), x = d.z = Math.trunc(x);
2209
+ const _ = new Array(p * h * x), w = new Array(p * h * x), D = { size: d, data3D: _, tags: w }, z = c.length;
2210
+ for (let y = 0; y < z; y++) {
2211
+ const M = c[y], v = m[y].map((b) => c[b]);
2212
+ ji(M, D, v);
2213
+ }
2214
+ return {
2215
+ data: _,
2216
+ size: d
2217
+ };
2218
+ }
2219
+ function Hi({ startRadius: i, addedRadius: e, ratio: t }) {
2220
+ return e * t + i;
2221
+ }
2222
+ function $i({ startHollow: i, addedHollow: e, ratio: t }) {
2223
+ return e * t + i;
2224
+ }
2225
+ function qi({ startValue: i, addedValue: e, ratio: t }) {
2226
+ return e * t + i;
2227
+ }
2228
+ function Ki(i, e) {
2229
+ const { x: t, y: a } = e;
2230
+ return i.reduce((r, o) => r + o - t, 0);
2231
+ }
2232
+ function Wi(i) {
2233
+ const { points: e, size: t, clim: a = { x: 0, y: 100 }, radius: r = 10, value: o = 100, hollow: n = 0, valueGradient: s = Mt, radiusGradient: l = Hi, hollowGradient: u = $i, lineValueGradient: c = qi, valuesAccumulate: d = Ki } = i, m = { radius: r, value: o, hollow: n }, p = e.map(function(N) {
2234
+ return Object.assign(new f(), m, N);
2235
+ }), h = t ? new f().copy(t).subScalar(1) : new xe().setFromPoints(p).max;
2236
+ h.x = Math.trunc(h.x), h.y = Math.trunc(h.y), h.z = Math.trunc(h.z);
2237
+ const x = h.clone().addScalar(1), { x: _, y: w, z: D } = x, z = _ * w, y = new Array(z * D), M = [], v = [], b = {
2238
+ particles: M,
2239
+ values: v,
2240
+ size: x,
2241
+ data: y
2242
+ }, C = new f(0, 0, 0), U = e.length, E = Math.trunc(U / 2);
2243
+ for (let N = 0; N < E; N++) {
2244
+ const ae = N * 2, O = p[ae], Me = ae + 1, R = p[Me], re = new $t(O, R), P = re.distance(), j = re.delta(new f()).normalize(), I = new qt();
2245
+ I.setFromUnitVectors(new f(0, 1, 0), j);
2246
+ const A = new ot().makeRotationFromQuaternion(I);
2247
+ A.setPosition(O);
2248
+ const { radius: k, value: G, hollow: H } = O, { radius: $, value: q, hollow: L } = R, B = $ - k, we = q - G, K = L - H, W = { length: P, startRadius: k, endRadius: $, addedRadius: B, defaultRadius: r, radius: r, startValue: G, endValue: q, addedValue: we, defaultValue: o, startHollow: H, endHollow: L, addedHollow: K, defaultHollow: n, clim: a }, V = Math.max(k, $), ze = new f(-V, 0, -V), zt = new f(V, P, V), Re = new xe(ze, zt);
2249
+ Re.applyMatrix4(A);
2250
+ const { min: Ve, max: Ee } = Re;
2251
+ Ve.max(C), Ee.min(h);
2252
+ let { x: oe, y: ne, z: se } = Ve;
2253
+ oe = Math.trunc(oe), ne = Math.trunc(ne), se = Math.trunc(se);
2254
+ let { x: le, y: ue, z: ce } = Ee;
2255
+ if (le = Math.trunc(le), ue = Math.trunc(ue), ce = Math.trunc(ce), oe > le || ne > ue || se > ce)
2256
+ return b;
2257
+ A.invert();
2258
+ for (let de = se; de <= ce; de++) {
2259
+ const Dt = de * z;
2260
+ for (let me = ne; me <= ue; me++) {
2261
+ const St = Dt + me * _;
2262
+ for (let pe = oe; pe <= le; pe++) {
2263
+ const Ge = St + pe, fe = new f(pe, me, de), Le = fe.clone();
2264
+ Le.applyMatrix4(A);
2265
+ const { x: bt, y: De, z: Ct } = Le;
2266
+ if (De < 0 || De > P)
2267
+ continue;
2268
+ const he = Math.hypot(bt, Ct), ve = {
2269
+ ...W,
2270
+ ratio: De / P,
2271
+ point: fe
2272
+ }, Y = l(ve);
2273
+ ve.radius = Y;
2274
+ const Be = u(ve), je = Y * Be;
2275
+ if (he > Y || he < je)
2276
+ continue;
2277
+ const Ut = c(ve), At = {
2278
+ ...W,
2279
+ value: Ut,
2280
+ ratio: he / Y,
2281
+ radius: Y,
2282
+ hollow: Be,
2283
+ hollowRadius: je,
2284
+ distance: he,
2285
+ point: fe
2286
+ };
2287
+ let ge = s(At);
2288
+ const ke = v[Ge];
2289
+ ke !== void 0 && (ge = d([ke, ge], a)), y[Ge] = ge, M.push(fe), v.push(ge);
2290
+ }
2291
+ }
2292
+ }
2293
+ }
2294
+ return b;
2295
+ }
2296
+ function ha(i, e) {
2297
+ const t = new f().setFromMatrixScale(e), a = Math.sqrt(t.lengthSq() / 3), r = new _e().setFromMatrix4(e);
2298
+ let { points: o, size: n, radius: s, ...l } = i;
2299
+ if (n && (n = new f().copy(n).applyMatrix3(r)), s && (s *= a), o) {
2300
+ const u = [];
2301
+ for (let { x: c, y: d, z: m, radius: p, ...h } of o) {
2302
+ p && (p *= a);
2303
+ const x = new f(c, d, m).applyMatrix4(e);
2304
+ Object.assign(x, h, { radius: p }), u.push(x);
2305
+ }
2306
+ o = u;
2307
+ }
2308
+ return { points: o, size: n, radius: s, ...l };
2309
+ }
2310
+ function Yi(i, e, t = 1) {
2311
+ let { points: a, size: r, radius: o, ...n } = i;
2312
+ if (o && (o *= t), a) {
2313
+ const s = [];
2314
+ for (let { x: l, y: u, z: c, radius: d, ...m } of a) {
2315
+ d && (d *= t);
2316
+ const p = new f(l, u, c).add(e).multiplyScalar(t);
2317
+ Object.assign(p, m, { radius: d }), s.push(p);
2318
+ }
2319
+ a = s;
2320
+ }
2321
+ return r && (r = new f().copy(r).add(e).multiplyScalar(t)), { points: a, size: r, radius: o, ...n };
2322
+ }
2323
+ function Xi(i, e) {
2324
+ const { points: t, radius: a } = i;
2325
+ if (!t)
2326
+ return { options: i, position: new f(), scale: 1 };
2327
+ const r = new xe();
2328
+ for (const d of t) {
2329
+ const m = new f().copy(d), p = d.radius ?? a;
2330
+ p ? (r.expandByPoint(m.clone().subScalar(p)), r.expandByPoint(m.addScalar(p))) : r.expandByPoint(m);
2331
+ }
2332
+ const o = new f().max(r.min), n = r.max.clone().sub(o).addScalar(1);
2333
+ i.size && n.min(i.size);
2334
+ let { scale: s, maxSize: l } = e || {};
2335
+ s || (l = l ?? 100, s = l / Math.max(n.x, n.y, n.z)), n.multiplyScalar(s);
2336
+ const u = o.clone().negate(), c = Yi(i, u, s);
2337
+ return c.size = n, { options: c, position: o, scale: 1 / s };
2338
+ }
2339
+ const We = {
2340
+ uniforms: {
2341
+ u_size: { value: new f(1, 1, 1) },
2342
+ u_renderstyle: { value: 0 },
2343
+ u_renderthreshold: { value: 0.5 },
2344
+ u_clim: { value: new T(1, 1) },
2345
+ u_data: { value: null },
2346
+ u_cmdata: { value: null }
2347
+ },
2348
+ vertexShader: (
2349
+ /* glsl */
2350
+ `
2351
+
2352
+ varying vec4 v_nearpos;
2353
+ varying vec4 v_farpos;
2354
+ varying vec3 v_position;
2355
+
2356
+ void main() {
2357
+ // Prepare transforms to map to "camera view". See also:
2358
+ // https://threejs.org/docs/#api/renderers/webgl/WebGLProgram
2359
+ mat4 viewtransformf = modelViewMatrix;
2360
+ mat4 viewtransformi = inverse(modelViewMatrix);
2361
+
2362
+ // Project local vertex coordinate to camera position. Then do a step
2363
+ // backward (in cam coords) to the near clipping plane, and project back. Do
2364
+ // the same for the far clipping plane. This gives us all the information we
2365
+ // need to calculate the ray and truncate it to the viewing cone.
2366
+ vec4 position4 = vec4(position, 1.0);
2367
+ vec4 pos_in_cam = viewtransformf * position4;
2368
+
2369
+ // Intersection of ray and near clipping plane (z = -1 in clip coords)
2370
+ pos_in_cam.z = -pos_in_cam.w;
2371
+ v_nearpos = viewtransformi * pos_in_cam;
2372
+
2373
+ // Intersection of ray and far clipping plane (z = +1 in clip coords)
2374
+ pos_in_cam.z = pos_in_cam.w;
2375
+ v_farpos = viewtransformi * pos_in_cam;
2376
+
2377
+ // Set varyings and output pos
2378
+ v_position = position;
2379
+ gl_Position = projectionMatrix * viewMatrix * modelMatrix * position4;
2380
+ }`
2381
+ ),
2382
+ fragmentShader: (
2383
+ /* glsl */
2384
+ `
2385
+
2386
+ precision highp float;
2387
+ precision mediump sampler3D;
2388
+
2389
+ uniform vec3 u_size;
2390
+ uniform int u_renderstyle;
2391
+ uniform float u_renderthreshold;
2392
+ uniform vec2 u_clim;
2393
+
2394
+ uniform sampler3D u_data;
2395
+ uniform sampler2D u_cmdata;
2396
+
2397
+ varying vec3 v_position;
2398
+ varying vec4 v_nearpos;
2399
+ varying vec4 v_farpos;
2400
+
2401
+ // The maximum distance through our rendering volume is sqrt(3).
2402
+ const int MAX_STEPS = 887; // 887 for 512^3, 1774 for 1024^3
2403
+ const int REFINEMENT_STEPS = 4;
2404
+ const float relative_step_size = 1.0;
2405
+ const vec4 ambient_color = vec4(0.2, 0.4, 0.2, 1.0);
2406
+ const vec4 diffuse_color = vec4(0.8, 0.2, 0.2, 1.0);
2407
+ const vec4 specular_color = vec4(1.0, 1.0, 1.0, 1.0);
2408
+ const float shininess = 40.0;
2409
+
2410
+ void cast_mip(vec3 start_loc, vec3 step, int nsteps, vec3 view_ray);
2411
+ void cast_iso(vec3 start_loc, vec3 step, int nsteps, vec3 view_ray);
2412
+
2413
+ float sample1(vec3 texcoords);
2414
+ vec4 apply_colormap(float val);
2415
+ vec4 add_lighting(float val, vec3 loc, vec3 step, vec3 view_ray);
2416
+
2417
+
2418
+ void main() {
2419
+ // Normalize clipping plane info
2420
+ vec3 farpos = v_farpos.xyz / v_farpos.w;
2421
+ vec3 nearpos = v_nearpos.xyz / v_nearpos.w;
2422
+
2423
+ // Calculate unit vector pointing in the view direction through this fragment.
2424
+ vec3 view_ray = normalize(nearpos.xyz - farpos.xyz);
2425
+
2426
+ // Compute the (negative) distance to the front surface or near clipping plane.
2427
+ // v_position is the back face of the cuboid, so the initial distance calculated in the dot
2428
+ // product below is the distance from near clip plane to the back of the cuboid
2429
+ float distance = dot(nearpos - v_position, view_ray);
2430
+ distance = max(distance, min((-0.5 - v_position.x) / view_ray.x,
2431
+ (u_size.x - 0.5 - v_position.x) / view_ray.x));
2432
+ distance = max(distance, min((-0.5 - v_position.y) / view_ray.y,
2433
+ (u_size.y - 0.5 - v_position.y) / view_ray.y));
2434
+ distance = max(distance, min((-0.5 - v_position.z) / view_ray.z,
2435
+ (u_size.z - 0.5 - v_position.z) / view_ray.z));
2436
+
2437
+ // Now we have the starting position on the front surface
2438
+ vec3 front = v_position + view_ray * distance;
2439
+
2440
+ // Decide how many steps to take
2441
+ int nsteps = int(-distance / relative_step_size + 0.5);
2442
+ if ( nsteps < 1 )
2443
+ discard;
2444
+
2445
+ // Get starting location and step vector in texture coordinates
2446
+ vec3 step = ((v_position - front) / u_size) / float(nsteps);
2447
+ vec3 start_loc = front / u_size;
2448
+
2449
+ // For testing: show the number of steps. This helps to establish
2450
+ // whether the rays are correctly oriented
2451
+ //'gl_FragColor = vec4(0.0, float(nsteps) / 1.0 / u_size.x, 1.0, 1.0);
2452
+ //'return;
2453
+
2454
+ if (u_renderstyle == 0)
2455
+ cast_mip(start_loc, step, nsteps, view_ray);
2456
+ else if (u_renderstyle == 1)
2457
+ cast_iso(start_loc, step, nsteps, view_ray);
2458
+
2459
+ if (gl_FragColor.a < 0.05)
2460
+ discard;
2461
+ }
2462
+
2463
+
2464
+ float sample1(vec3 texcoords) {
2465
+ /* Sample float value from a 3D texture. Assumes intensity data. */
2466
+ return texture(u_data, texcoords.xyz).r;
2467
+ }
2468
+
2469
+
2470
+ vec4 apply_colormap(float val) {
2471
+ val = (val - u_clim[0]) / (u_clim[1] - u_clim[0]);
2472
+ return texture2D(u_cmdata, vec2(val, 0.5));
2473
+ }
2474
+
2475
+
2476
+ void cast_mip(vec3 start_loc, vec3 step, int nsteps, vec3 view_ray) {
2477
+
2478
+ float max_val = -1e6;
2479
+ int max_i = 100;
2480
+ vec3 loc = start_loc;
2481
+
2482
+ // Enter the raycasting loop. In WebGL 1 the loop index cannot be compared with
2483
+ // non-constant expression. So we use a hard-coded max, and an additional condition
2484
+ // inside the loop.
2485
+ for (int iter=0; iter<MAX_STEPS; iter++) {
2486
+ if (iter >= nsteps)
2487
+ break;
2488
+ // Sample from the 3D texture
2489
+ float val = sample1(loc);
2490
+ // Apply MIP operation
2491
+ if (val > max_val) {
2492
+ max_val = val;
2493
+ max_i = iter;
2494
+ }
2495
+ // Advance location deeper into the volume
2496
+ loc += step;
2497
+ }
2498
+
2499
+ // Refine location, gives crispier images
2500
+ vec3 iloc = start_loc + step * (float(max_i) - 0.5);
2501
+ vec3 istep = step / float(REFINEMENT_STEPS);
2502
+ for (int i=0; i<REFINEMENT_STEPS; i++) {
2503
+ max_val = max(max_val, sample1(iloc));
2504
+ iloc += istep;
2505
+ }
2506
+
2507
+ // Resolve final color
2508
+ gl_FragColor = apply_colormap(max_val);
2509
+ }
2510
+
2511
+
2512
+ void cast_iso(vec3 start_loc, vec3 step, int nsteps, vec3 view_ray) {
2513
+
2514
+ gl_FragColor = vec4(0.0); // init transparent
2515
+ vec4 color3 = vec4(0.0); // final color
2516
+ vec3 dstep = 1.5 / u_size; // step to sample derivative
2517
+ vec3 loc = start_loc;
2518
+
2519
+ float low_threshold = u_renderthreshold - 0.02 * (u_clim[1] - u_clim[0]);
2520
+
2521
+ // Enter the raycasting loop. In WebGL 1 the loop index cannot be compared with
2522
+ // non-constant expression. So we use a hard-coded max, and an additional condition
2523
+ // inside the loop.
2524
+ for (int iter=0; iter<MAX_STEPS; iter++) {
2525
+ if (iter >= nsteps)
2526
+ break;
2527
+
2528
+ // Sample from the 3D texture
2529
+ float val = sample1(loc);
2530
+
2531
+ if (val > low_threshold) {
2532
+ // Take the last interval in smaller steps
2533
+ vec3 iloc = loc - 0.5 * step;
2534
+ vec3 istep = step / float(REFINEMENT_STEPS);
2535
+ for (int i=0; i<REFINEMENT_STEPS; i++) {
2536
+ val = sample1(iloc);
2537
+ if (val > u_renderthreshold) {
2538
+ gl_FragColor = add_lighting(val, iloc, dstep, view_ray);
2539
+ return;
2540
+ }
2541
+ iloc += istep;
2542
+ }
2543
+ }
2544
+
2545
+ // Advance location deeper into the volume
2546
+ loc += step;
2547
+ }
2548
+ }
2549
+
2550
+
2551
+ vec4 add_lighting(float val, vec3 loc, vec3 step, vec3 view_ray)
2552
+ {
2553
+ // Calculate color by incorporating lighting
2554
+
2555
+ // View direction
2556
+ vec3 V = normalize(view_ray);
2557
+
2558
+ // calculate normal vector from gradient
2559
+ vec3 N;
2560
+ float val1, val2;
2561
+ val1 = sample1(loc + vec3(-step[0], 0.0, 0.0));
2562
+ val2 = sample1(loc + vec3(+step[0], 0.0, 0.0));
2563
+ N[0] = val1 - val2;
2564
+ val = max(max(val1, val2), val);
2565
+ val1 = sample1(loc + vec3(0.0, -step[1], 0.0));
2566
+ val2 = sample1(loc + vec3(0.0, +step[1], 0.0));
2567
+ N[1] = val1 - val2;
2568
+ val = max(max(val1, val2), val);
2569
+ val1 = sample1(loc + vec3(0.0, 0.0, -step[2]));
2570
+ val2 = sample1(loc + vec3(0.0, 0.0, +step[2]));
2571
+ N[2] = val1 - val2;
2572
+ val = max(max(val1, val2), val);
2573
+
2574
+ float gm = length(N); // gradient magnitude
2575
+ N = normalize(N);
2576
+
2577
+ // Flip normal so it points towards viewer
2578
+ float Nselect = float(dot(N, V) > 0.0);
2579
+ N = (2.0 * Nselect - 1.0) * N; // == Nselect * N - (1.0-Nselect)*N;
2580
+
2581
+ // Init colors
2582
+ vec4 ambient_color = vec4(0.0, 0.0, 0.0, 0.0);
2583
+ vec4 diffuse_color = vec4(0.0, 0.0, 0.0, 0.0);
2584
+ vec4 specular_color = vec4(0.0, 0.0, 0.0, 0.0);
2585
+
2586
+ // note: could allow multiple lights
2587
+ for (int i=0; i<1; i++)
2588
+ {
2589
+ // Get light direction (make sure to prevent zero devision)
2590
+ vec3 L = normalize(view_ray); //lightDirs[i];
2591
+ float lightEnabled = float( length(L) > 0.0 );
2592
+ L = normalize(L + (1.0 - lightEnabled));
2593
+
2594
+ // Calculate lighting properties
2595
+ float lambertTerm = clamp(dot(N, L), 0.0, 1.0);
2596
+ vec3 H = normalize(L+V); // Halfway vector
2597
+ float specularTerm = pow(max(dot(H, N), 0.0), shininess);
2598
+
2599
+ // Calculate mask
2600
+ float mask1 = lightEnabled;
2601
+
2602
+ // Calculate colors
2603
+ ambient_color += mask1 * ambient_color; // * gl_LightSource[i].ambient;
2604
+ diffuse_color += mask1 * lambertTerm;
2605
+ specular_color += mask1 * specularTerm * specular_color;
2606
+ }
2607
+
2608
+ // Calculate final color by componing different components
2609
+ vec4 final_color;
2610
+ vec4 color = apply_colormap(val);
2611
+ final_color = color * (ambient_color + diffuse_color) + specular_color;
2612
+ final_color.a = color.a;
2613
+ return final_color;
2614
+ }`
2615
+ )
2616
+ };
2617
+ var Ji = /* @__PURE__ */ ((i) => (i[i.MIP = 0] = "MIP", i[i.ISO = 1] = "ISO", i))(Ji || {});
2618
+ class va extends te {
2619
+ constructor(e) {
2620
+ const { style: t, threshold: a, clim: r, map: o, gradient: n } = e ?? {}, s = new f(1, 1, 1);
2621
+ if (o) {
2622
+ const { width: c, height: d, depth: m } = o.image;
2623
+ s.set(c, d, m);
2624
+ }
2625
+ const l = n == null ? n : ee(n), u = Je.clone(We.uniforms);
2626
+ u.u_size.value.copy(s), u.u_clim.value.copy(r ?? new T(1, 1)), u.u_renderstyle.value = t ?? 1, u.u_renderthreshold.value = a ?? 0.5, u.u_data.value = o ?? null, u.u_cmdata.value = l ?? null, super({
2627
+ ...We,
2628
+ // @ts-ignore
2629
+ uniforms: u,
2630
+ side: Q
2631
+ }), g(this, "isExampleVolumeMaterial_1", !0), g(this, "_gradient");
2632
+ }
2633
+ /**
2634
+ * 三维纹理
2635
+ */
2636
+ get map() {
2637
+ return this.uniforms.u_data.value;
2638
+ }
2639
+ set map(e) {
2640
+ this.uniforms.u_data.value = e, this.uniformsNeedUpdate = !0;
2641
+ }
2642
+ /**
2643
+ * 颜色映射纹理
2644
+ * @remarks
2645
+ * 会将垂直居中的那条水平像素从左到右映射到 clim 表示的限制区间,
2646
+ * 即 clim.x 对应最左边的像素,clim.y 对应最右边的像素
2647
+ */
2648
+ get gradientMap() {
2649
+ return this.uniforms.u_cmdata.value;
2650
+ }
2651
+ /**
2652
+ * 颜色映射选项
2653
+ */
2654
+ get gradient() {
2655
+ return this._gradient;
2656
+ }
2657
+ set gradient(e) {
2658
+ this._gradient = e;
2659
+ const t = e == null ? e : ee(e);
2660
+ this.uniforms.u_cmdata.value = t ?? null, this.uniformsNeedUpdate = !0;
2661
+ }
2662
+ /**
2663
+ * 三维纹理的尺寸
2664
+ * @remarks
2665
+ * 三维纹理的尺寸 要 和 Geometry 的尺寸是一样的,不但比列一样,大小也是一样的
2666
+ * 但 mesh 本身可以进行几何变换;
2667
+ * Geometry 左下角的坐标要从 (0,0,0) 开始;
2668
+ */
2669
+ get size() {
2670
+ return this.uniforms.u_size.value;
2671
+ }
2672
+ set size(e) {
2673
+ this.uniforms.u_size.value.copy(e), this.uniformsNeedUpdate = !0;
2674
+ }
2675
+ /**
2676
+ * 渲染样式
2677
+ */
2678
+ get style() {
2679
+ return this.uniforms.u_renderstyle.value;
2680
+ }
2681
+ set style(e) {
2682
+ this.uniforms.u_renderstyle.value = e, this.uniformsNeedUpdate = !0;
2683
+ }
2684
+ /**
2685
+ * 映射区间
2686
+ * @remarks
2687
+ * x 为最小值,y 为最大值
2688
+ */
2689
+ get clim() {
2690
+ return this.uniforms.u_clim.value;
2691
+ }
2692
+ set clim(e) {
2693
+ this.uniforms.u_clim.value = e, this.uniformsNeedUpdate = !0;
2694
+ }
2695
+ /**
2696
+ * 渲染最低阈值
2697
+ * @remarks
2698
+ * 只对 ISO 样式有效;
2699
+ *
2700
+ * 当三维纹理中的值低于该值时,不会被渲染,即视为空
2701
+ */
2702
+ get threshold() {
2703
+ return this.uniforms.u_renderthreshold.value;
2704
+ }
2705
+ set threshold(e) {
2706
+ this.uniforms.u_renderthreshold.value = e, this.uniformsNeedUpdate = !0;
2707
+ }
2708
+ }
2709
+ const wt = `in vec3 position;
2710
+
2711
+ uniform mat4 modelMatrix;
2712
+ uniform mat4 modelViewMatrix;
2713
+ uniform mat4 projectionMatrix;
2714
+ uniform vec3 cameraPos;
2715
+
2716
+ out vec3 vOrigin;
2717
+ out vec3 vDirection;
2718
+
2719
+ void main() {
2720
+ vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );
2721
+ vOrigin = vec3( inverse( modelMatrix ) * vec4( cameraPos, 1.0 ) ).xyz;
2722
+ vDirection = position - vOrigin;
2723
+ gl_Position = projectionMatrix * mvPosition;
2724
+ }`, Zi = `precision highp float;
2725
+ precision highp sampler3D;
2726
+
2727
+ uniform mat4 modelViewMatrix;
2728
+ uniform mat4 projectionMatrix;
2729
+
2730
+ in vec3 vOrigin;
2731
+ in vec3 vDirection;
2732
+
2733
+ out vec4 color;
2734
+
2735
+ uniform vec3 base;
2736
+ uniform sampler3D map;
2737
+
2738
+ uniform float threshold;
2739
+ uniform float range;
2740
+ uniform float opacity;
2741
+ uniform float steps;
2742
+ uniform float frame;
2743
+
2744
+ uint wang_hash(uint seed)
2745
+ {
2746
+ seed = (seed ^ 61u) ^ (seed >> 16u);
2747
+ seed *= 9u;
2748
+ seed = seed ^ (seed >> 4u);
2749
+ seed *= 0x27d4eb2du;
2750
+ seed = seed ^ (seed >> 15u);
2751
+ return seed;
2752
+ }
2753
+
2754
+ float randomFloat(inout uint seed)
2755
+ {
2756
+ return float(wang_hash(seed)) / 4294967296.;
2757
+ }
2758
+
2759
+ vec2 hitBox( vec3 orig, vec3 dir ) {
2760
+ const vec3 box_min = vec3( - 0.5 );
2761
+ const vec3 box_max = vec3( 0.5 );
2762
+ vec3 inv_dir = 1.0 / dir;
2763
+ vec3 tmin_tmp = ( box_min - orig ) * inv_dir;
2764
+ vec3 tmax_tmp = ( box_max - orig ) * inv_dir;
2765
+ vec3 tmin = min( tmin_tmp, tmax_tmp );
2766
+ vec3 tmax = max( tmin_tmp, tmax_tmp );
2767
+ float t0 = max( tmin.x, max( tmin.y, tmin.z ) );
2768
+ float t1 = min( tmax.x, min( tmax.y, tmax.z ) );
2769
+ return vec2( t0, t1 );
2770
+ }
2771
+
2772
+ float sample1( vec3 p ) {
2773
+ return texture( map, p ).r;
2774
+ }
2775
+
2776
+ float shading( vec3 coord ) {
2777
+ float step = 0.01;
2778
+ return sample1( coord + vec3( - step ) ) - sample1( coord + vec3( step ) );
2779
+ }
2780
+
2781
+ void main(){
2782
+ vec3 rayDir = normalize( vDirection );
2783
+ vec2 bounds = hitBox( vOrigin, rayDir );
2784
+
2785
+ if ( bounds.x > bounds.y ) discard;
2786
+
2787
+ bounds.x = max( bounds.x, 0.0 );
2788
+
2789
+ vec3 p = vOrigin + bounds.x * rayDir;
2790
+ vec3 inc = 1.0 / abs( rayDir );
2791
+ float delta = min( inc.x, min( inc.y, inc.z ) );
2792
+ delta /= steps;
2793
+
2794
+ // Jitter
2795
+
2796
+ // Nice little seed from
2797
+ // https://blog.demofox.org/2020/05/25/casual-shadertoy-path-tracing-1-basic-camera-diffuse-emissive/
2798
+ uint seed = uint( gl_FragCoord.x ) * uint( 1973 ) + uint( gl_FragCoord.y ) * uint( 9277 ) + uint( frame ) * uint( 26699 );
2799
+ vec3 size = vec3( textureSize( map, 0 ) );
2800
+ float randNum = randomFloat( seed ) * 2.0 - 1.0;
2801
+ p += rayDir * randNum * ( 1.0 / size );
2802
+
2803
+ //
2804
+
2805
+ vec4 ac = vec4( base, 0.0 );
2806
+
2807
+ for ( float t = bounds.x; t < bounds.y; t += delta ) {
2808
+
2809
+ float d = sample1( p + 0.5 );
2810
+
2811
+ d = smoothstep( threshold - range, threshold + range, d ) * opacity;
2812
+
2813
+ float col = shading( p + 0.5 ) * 3.0 + ( ( p.x + p.y ) * 0.25 ) + 0.2;
2814
+
2815
+ ac.rgb += ( 1.0 - ac.a ) * d * col;
2816
+
2817
+ ac.a += ( 1.0 - ac.a ) * d;
2818
+
2819
+ if ( ac.a >= 0.95 ) break;
2820
+
2821
+ p += rayDir * delta;
2822
+
2823
+ }
2824
+
2825
+ color = ac;
2826
+
2827
+ if ( color.a == 0.0 ) discard;
2828
+
2829
+ }`;
2830
+ class ga extends Ze {
2831
+ constructor(e) {
2832
+ let { color: t, threshold: a, map: r, opacity: o, range: n, steps: s, frame: l, cameraPos: u } = e ?? {};
2833
+ t = t ?? new Qe(1, 1, 1), a = a ?? 0.25, o = o ?? 0.25, n = n ?? 0.1, s = s ?? 100, l = l ?? 100, u = u ?? new f(), super({
2834
+ glslVersion: ie,
2835
+ // @ts-ignore
2836
+ uniforms: {
2837
+ base: { value: t },
2838
+ map: { value: r },
2839
+ cameraPos: { value: u },
2840
+ threshold: { value: a },
2841
+ opacity: { value: o },
2842
+ range: { value: n },
2843
+ steps: { value: s },
2844
+ frame: { value: l }
2845
+ },
2846
+ vertexShader: wt,
2847
+ fragmentShader: Zi,
2848
+ side: Q,
2849
+ transparent: !0
2850
+ }), g(this, "isExampleVolumeMaterial_Cloud", !0), this.opacity = o;
2851
+ }
2852
+ /**
2853
+ * 三维纹理
2854
+ */
2855
+ get map() {
2856
+ return this.uniforms.map.value;
2857
+ }
2858
+ set map(e) {
2859
+ this.uniforms.map.value = e, this.uniformsNeedUpdate = !0;
2860
+ }
2861
+ /**
2862
+ * 颜色
2863
+ */
2864
+ get color() {
2865
+ return this.uniforms.base.value;
2866
+ }
2867
+ set color(e) {
2868
+ this.uniforms.base.value = e, this.uniformsNeedUpdate = !0;
2869
+ }
2870
+ /**
2871
+ * 透明度
2872
+ */
2873
+ // @ts-ignore
2874
+ get opacity() {
2875
+ return this.uniforms.opacity.value;
2876
+ }
2877
+ set opacity(e) {
2878
+ this.uniforms && (this.uniforms.opacity.value = e), this.uniformsNeedUpdate = !0;
2879
+ }
2880
+ /**
2881
+ * 渲染最低阈值
2882
+ */
2883
+ get threshold() {
2884
+ return this.uniforms.threshold.value;
2885
+ }
2886
+ set threshold(e) {
2887
+ this.uniforms.threshold.value = e, this.uniformsNeedUpdate = !0;
2888
+ }
2889
+ /**
2890
+ * 范围
2891
+ */
2892
+ get range() {
2893
+ return this.uniforms.range.value;
2894
+ }
2895
+ set range(e) {
2896
+ this.uniforms.range.value = e, this.uniformsNeedUpdate = !0;
2897
+ }
2898
+ /**
2899
+ * 体积材质渲染的采样数
2900
+ */
2901
+ get steps() {
2902
+ return this.uniforms.steps.value;
2903
+ }
2904
+ set steps(e) {
2905
+ this.uniforms.steps.value = e, this.uniformsNeedUpdate = !0;
2906
+ }
2907
+ /**
2908
+ * 渲染帧次
2909
+ */
2910
+ get frame() {
2911
+ return this.uniforms.frame.value;
2912
+ }
2913
+ set frame(e) {
2914
+ this.uniforms.frame.value = e, this.uniformsNeedUpdate = !0;
2915
+ }
2916
+ /**
2917
+ * 相机的位置
2918
+ */
2919
+ get cameraPos() {
2920
+ return this.uniforms.cameraPos.value;
2921
+ }
2922
+ set cameraPos(e) {
2923
+ this.uniforms.cameraPos.value.copy(e), this.uniformsNeedUpdate = !0;
2924
+ }
2925
+ }
2926
+ const Qi = `precision highp float;
2927
+ precision highp sampler3D;
2928
+
2929
+ uniform mat4 modelViewMatrix;
2930
+ uniform mat4 projectionMatrix;
2931
+
2932
+ in vec3 vOrigin;
2933
+ in vec3 vDirection;
2934
+
2935
+ out vec4 color;
2936
+
2937
+ uniform sampler3D map;
2938
+
2939
+ uniform float threshold;
2940
+ uniform float steps;
2941
+
2942
+ vec2 hitBox( vec3 orig, vec3 dir ) {
2943
+ const vec3 box_min = vec3( - 0.5 );
2944
+ const vec3 box_max = vec3( 0.5 );
2945
+ vec3 inv_dir = 1.0 / dir;
2946
+ vec3 tmin_tmp = ( box_min - orig ) * inv_dir;
2947
+ vec3 tmax_tmp = ( box_max - orig ) * inv_dir;
2948
+ vec3 tmin = min( tmin_tmp, tmax_tmp );
2949
+ vec3 tmax = max( tmin_tmp, tmax_tmp );
2950
+ float t0 = max( tmin.x, max( tmin.y, tmin.z ) );
2951
+ float t1 = min( tmax.x, min( tmax.y, tmax.z ) );
2952
+ return vec2( t0, t1 );
2953
+ }
2954
+
2955
+ float sample1( vec3 p ) {
2956
+ return texture( map, p ).r;
2957
+ }
2958
+
2959
+ #define epsilon .0001
2960
+
2961
+ vec3 normal( vec3 coord ) {
2962
+ if ( coord.x < epsilon ) return vec3( 1.0, 0.0, 0.0 );
2963
+ if ( coord.y < epsilon ) return vec3( 0.0, 1.0, 0.0 );
2964
+ if ( coord.z < epsilon ) return vec3( 0.0, 0.0, 1.0 );
2965
+ if ( coord.x > 1.0 - epsilon ) return vec3( - 1.0, 0.0, 0.0 );
2966
+ if ( coord.y > 1.0 - epsilon ) return vec3( 0.0, - 1.0, 0.0 );
2967
+ if ( coord.z > 1.0 - epsilon ) return vec3( 0.0, 0.0, - 1.0 );
2968
+
2969
+ float step = 0.01;
2970
+ float x = sample1( coord + vec3( - step, 0.0, 0.0 ) ) - sample1( coord + vec3( step, 0.0, 0.0 ) );
2971
+ float y = sample1( coord + vec3( 0.0, - step, 0.0 ) ) - sample1( coord + vec3( 0.0, step, 0.0 ) );
2972
+ float z = sample1( coord + vec3( 0.0, 0.0, - step ) ) - sample1( coord + vec3( 0.0, 0.0, step ) );
2973
+
2974
+ return normalize( vec3( x, y, z ) );
2975
+ }
2976
+
2977
+ void main(){
2978
+
2979
+ vec3 rayDir = normalize( vDirection );
2980
+ vec2 bounds = hitBox( vOrigin, rayDir );
2981
+
2982
+ if ( bounds.x > bounds.y ) discard;
2983
+
2984
+ bounds.x = max( bounds.x, 0.0 );
2985
+
2986
+ vec3 p = vOrigin + bounds.x * rayDir;
2987
+ vec3 inc = 1.0 / abs( rayDir );
2988
+ float delta = min( inc.x, min( inc.y, inc.z ) );
2989
+ delta /= steps;
2990
+
2991
+ for ( float t = bounds.x; t < bounds.y; t += delta ) {
2992
+
2993
+ float d = sample1( p + 0.5 );
2994
+
2995
+ if ( d > threshold ) {
2996
+
2997
+ color.rgb = normal( p + 0.5 ) * 0.5 + ( p * 1.5 + 0.25 );
2998
+ color.a = 1.;
2999
+ break;
3000
+
3001
+ }
3002
+
3003
+ p += rayDir * delta;
3004
+
3005
+ }
3006
+
3007
+ if ( color.a == 0.0 ) discard;
3008
+
3009
+ }`;
3010
+ class xa extends Ze {
3011
+ constructor(e) {
3012
+ let { threshold: t, map: a, steps: r, cameraPos: o } = e ?? {};
3013
+ t = t ?? 0.25, r = r ?? 100, o = o ?? new f(), super({
3014
+ glslVersion: ie,
3015
+ // @ts-ignore
3016
+ uniforms: {
3017
+ map: { value: a },
3018
+ cameraPos: { value: o },
3019
+ threshold: { value: t },
3020
+ steps: { value: r }
3021
+ },
3022
+ vertexShader: wt,
3023
+ fragmentShader: Qi,
3024
+ side: Q,
3025
+ transparent: !0
3026
+ }), g(this, "isExampleVolumeMaterial_Perlin", !0);
3027
+ }
3028
+ /**
3029
+ * 三维纹理
3030
+ */
3031
+ get map() {
3032
+ return this.uniforms.map.value;
3033
+ }
3034
+ set map(e) {
3035
+ this.uniforms.map.value = e, this.uniformsNeedUpdate = !0;
3036
+ }
3037
+ /**
3038
+ * 渲染最低阈值
3039
+ */
3040
+ get threshold() {
3041
+ return this.uniforms.threshold.value;
3042
+ }
3043
+ set threshold(e) {
3044
+ this.uniforms.threshold.value = e, this.uniformsNeedUpdate = !0;
3045
+ }
3046
+ /**
3047
+ * 体积材质渲染的采样数
3048
+ */
3049
+ get steps() {
3050
+ return this.uniforms.steps.value;
3051
+ }
3052
+ set steps(e) {
3053
+ this.uniforms.steps.value = e, this.uniformsNeedUpdate = !0;
3054
+ }
3055
+ /**
3056
+ * 相机的位置
3057
+ */
3058
+ get cameraPos() {
3059
+ return this.uniforms.cameraPos.value;
3060
+ }
3061
+ set cameraPos(e) {
3062
+ this.uniforms.cameraPos.value.copy(e), this.uniformsNeedUpdate = !0;
3063
+ }
3064
+ }
3065
+ class _a {
3066
+ constructor(e) {
3067
+ this.ssp = e;
3068
+ }
3069
+ defaultColorGradient = [
3070
+ [0, "rgba(0,255,0,0)"],
3071
+ [0.5, "rgba(64,255,255,0.5)"],
3072
+ [1, "rgba(255,64,255,1)"]
3073
+ ];
3074
+ defaultGradientVolumeMaterialOptions = {
3075
+ fit: gt.Raw,
3076
+ accFactor: 2,
3077
+ depthTest: !1,
3078
+ side: Q,
3079
+ discardOut: !1,
3080
+ // 数值的梯度映射纹理
3081
+ gradient: ee(this.defaultColorGradient)
3082
+ };
3083
+ _createTexture(e, t, a = !1) {
3084
+ const r = Xi({ points: e, ...t }, { maxSize: 60, ...t }), { options: o, position: n, scale: s } = r, l = a ? Wi(o) : ki(o), u = wi(l, {
3085
+ ...t
3086
+ }), c = new Ue({
3087
+ ...this.defaultGradientVolumeMaterialOptions,
3088
+ map: u,
3089
+ ...t
3090
+ }), d = new $e(c);
3091
+ return d.position.copy(n), d.scale.set(s, s, s), this.ssp.addObject(d), d;
3092
+ }
3093
+ /**
3094
+ * 创建热力云
3095
+ * return material
3096
+ */
3097
+ createHeatCloud(e, t) {
3098
+ return this._createTexture(e, t);
3099
+ }
3100
+ //创建线状热力
3101
+ createLineHeat(e, t) {
3102
+ return this._createTexture(e, t, !0);
3103
+ }
3104
+ //创建图片挤压
3105
+ async createImageExtrusion(e, t) {
3106
+ const a = new qe({ side: Q, depthTest: !1, ...t }), r = await Wt.utils.imageLoader.loadAsync(e), o = Si(r, t?.depth ?? 200, t);
3107
+ a.map = o;
3108
+ const n = new $e(a);
3109
+ return this.ssp.addObject(n), n;
3110
+ }
3111
+ //创建切片
3112
+ createSliceMesh(e, t) {
3113
+ let a = e.map;
3114
+ if (!a) return;
3115
+ if (e instanceof Ue) {
3116
+ const { gradient: o, range: n, discardOut: s, voidRange: l } = e;
3117
+ a = Ke(a.image, {
3118
+ gradient: o?.image,
3119
+ range: n,
3120
+ discardOut: s,
3121
+ voidRange: l,
3122
+ ...t
3123
+ // voidColor
3124
+ });
3125
+ }
3126
+ const r = new Gi({ map: a, ...t });
3127
+ return this.ssp.addObject(r), r;
3128
+ }
3129
+ //创建切片dom
3130
+ createImageSlice(e, t) {
3131
+ const a = e.map;
3132
+ if (!a) return;
3133
+ let r = null;
3134
+ if (e instanceof Ue) {
3135
+ const { gradient: n, range: s, discardOut: l, voidRange: u } = e;
3136
+ r = Ke(a.image, {
3137
+ gradient: n?.image,
3138
+ range: s,
3139
+ discardOut: l,
3140
+ voidRange: u,
3141
+ ...t
3142
+ // voidColor
3143
+ });
3144
+ }
3145
+ return e instanceof qe && (r = a), r ? new Li(r) : void 0;
3146
+ }
3147
+ }
3148
+ export {
3149
+ Ni as ColorFogPointsMaterial,
3150
+ va as ExampleVolumeMaterial_1,
3151
+ ga as ExampleVolumeMaterial_Cloud,
3152
+ xa as ExampleVolumeMaterial_Perlin,
3153
+ yt as FogPointsMaterial,
3154
+ Mi as GradientData3DTexture,
3155
+ Fi as GradientFogPointsMaterial,
3156
+ Ue as GradientVolumeMaterial,
3157
+ _a as HeatMapPlugin,
3158
+ oi as ImageData3DSlice,
3159
+ _t as ImageData3DTexture,
3160
+ Li as ImageData3DTextureSlice,
3161
+ qe as ImageVolumeMaterial,
3162
+ Ei as SliceMaterial,
3163
+ Gi as SliceMesh,
3164
+ ma as SphereFogMaterial,
3165
+ gt as VolumeFit,
3166
+ xt as VolumeMaterial,
3167
+ $e as VolumeMesh,
3168
+ Ji as VolumeRenderStyle,
3169
+ ji as computeHeatData3DForPoint,
3170
+ pa as createColorFogPoints,
3171
+ wi as createGradientData3DTexture,
3172
+ fa as createGradientFogPoints,
3173
+ ki as createHeatData3D,
3174
+ Si as createImageData3DTextureByExtrudeImage,
3175
+ Ke as createImageData3DTextureFromGradient,
3176
+ Wi as createLineData3D,
3177
+ lt as createLinearGradientImageData,
3178
+ ft as data2DCoordToIndex,
3179
+ sa as data2DIndexToCoord,
3180
+ Fe as data3DCoordToIndex,
3181
+ oa as data3DIndexToCoord,
3182
+ _a as default,
3183
+ ti as extrudeImage,
3184
+ ei as extrudeImageData,
3185
+ ii as extrudeImageDataOnAxis,
3186
+ ai as getData2DItem,
3187
+ la as getData2DItemSafe,
3188
+ ca as getData2DRow,
3189
+ ri as getData2DValue,
3190
+ ua as getData2DValueSafe,
3191
+ mt as getData3DItem,
3192
+ Te as getData3DItemSafe,
3193
+ ye as getData3DSlice,
3194
+ pt as getData3DValue,
3195
+ Qt as getData3DValueSafe,
3196
+ dt as getImageDateColor,
3197
+ ut as getImageDateOfImage,
3198
+ ia as getImageDateRow,
3199
+ Jt as getNaturalSizeOfImageSource,
3200
+ Di as gradientData3DToImageData3D,
3201
+ $i as hollowGradient_Default,
3202
+ Zt as imageDataToCanvas,
3203
+ aa as imageDataToUrl,
3204
+ Ie as isIImageData2,
3205
+ Ne as isIImageData3,
3206
+ ra as isOutOfSize,
3207
+ qi as lineValueGradient_Default,
3208
+ _i as makeOriginOnBoundingBoxMinOfGeometry,
3209
+ na as mergeData3Ds,
3210
+ Ki as numberValuesAccumulate_Default,
3211
+ Xi as optimizeGradientOptions,
3212
+ Hi as radiusGradient_Default,
3213
+ ct as reverseImageDateY,
3214
+ ha as transformGradientOptions,
3215
+ Yi as translateScaleGradientOptions,
3216
+ Mt as valueGradient_Default,
3217
+ Bi as valuesAccumulate_Default
3218
+ };