roavatar-renderer 1.6.7 → 1.7.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.d.ts +7 -2
- package/dist/index.js +3438 -9
- package/package.json +2 -1
package/dist/index.js
CHANGED
|
@@ -16853,6 +16853,105 @@ function parseKeyframeTrack(json) {
|
|
|
16853
16853
|
return new trackType(json.name, json.times, json.values, json.interpolation);
|
|
16854
16854
|
}
|
|
16855
16855
|
}
|
|
16856
|
+
class LoadingManager {
|
|
16857
|
+
/**
|
|
16858
|
+
* Constructs a new loading manager.
|
|
16859
|
+
*
|
|
16860
|
+
* @param {Function} [onLoad] - Executes when all items have been loaded.
|
|
16861
|
+
* @param {Function} [onProgress] - Executes when single items have been loaded.
|
|
16862
|
+
* @param {Function} [onError] - Executes when an error occurs.
|
|
16863
|
+
*/
|
|
16864
|
+
constructor(onLoad, onProgress, onError) {
|
|
16865
|
+
const scope = this;
|
|
16866
|
+
let isLoading = false;
|
|
16867
|
+
let itemsLoaded = 0;
|
|
16868
|
+
let itemsTotal = 0;
|
|
16869
|
+
let urlModifier = void 0;
|
|
16870
|
+
const handlers = [];
|
|
16871
|
+
this.onStart = void 0;
|
|
16872
|
+
this.onLoad = onLoad;
|
|
16873
|
+
this.onProgress = onProgress;
|
|
16874
|
+
this.onError = onError;
|
|
16875
|
+
this._abortController = null;
|
|
16876
|
+
this.itemStart = function(url) {
|
|
16877
|
+
itemsTotal++;
|
|
16878
|
+
if (isLoading === false) {
|
|
16879
|
+
if (scope.onStart !== void 0) {
|
|
16880
|
+
scope.onStart(url, itemsLoaded, itemsTotal);
|
|
16881
|
+
}
|
|
16882
|
+
}
|
|
16883
|
+
isLoading = true;
|
|
16884
|
+
};
|
|
16885
|
+
this.itemEnd = function(url) {
|
|
16886
|
+
itemsLoaded++;
|
|
16887
|
+
if (scope.onProgress !== void 0) {
|
|
16888
|
+
scope.onProgress(url, itemsLoaded, itemsTotal);
|
|
16889
|
+
}
|
|
16890
|
+
if (itemsLoaded === itemsTotal) {
|
|
16891
|
+
isLoading = false;
|
|
16892
|
+
if (scope.onLoad !== void 0) {
|
|
16893
|
+
scope.onLoad();
|
|
16894
|
+
}
|
|
16895
|
+
}
|
|
16896
|
+
};
|
|
16897
|
+
this.itemError = function(url) {
|
|
16898
|
+
if (scope.onError !== void 0) {
|
|
16899
|
+
scope.onError(url);
|
|
16900
|
+
}
|
|
16901
|
+
};
|
|
16902
|
+
this.resolveURL = function(url) {
|
|
16903
|
+
url = url.normalize("NFC");
|
|
16904
|
+
if (urlModifier) {
|
|
16905
|
+
return urlModifier(url);
|
|
16906
|
+
}
|
|
16907
|
+
return url;
|
|
16908
|
+
};
|
|
16909
|
+
this.setURLModifier = function(transform) {
|
|
16910
|
+
urlModifier = transform;
|
|
16911
|
+
return this;
|
|
16912
|
+
};
|
|
16913
|
+
this.addHandler = function(regex, loader) {
|
|
16914
|
+
handlers.push(regex, loader);
|
|
16915
|
+
return this;
|
|
16916
|
+
};
|
|
16917
|
+
this.removeHandler = function(regex) {
|
|
16918
|
+
const index = handlers.indexOf(regex);
|
|
16919
|
+
if (index !== -1) {
|
|
16920
|
+
handlers.splice(index, 2);
|
|
16921
|
+
}
|
|
16922
|
+
return this;
|
|
16923
|
+
};
|
|
16924
|
+
this.getHandler = function(file) {
|
|
16925
|
+
for (let i = 0, l = handlers.length; i < l; i += 2) {
|
|
16926
|
+
const regex = handlers[i];
|
|
16927
|
+
const loader = handlers[i + 1];
|
|
16928
|
+
if (regex.global) regex.lastIndex = 0;
|
|
16929
|
+
if (regex.test(file)) {
|
|
16930
|
+
return loader;
|
|
16931
|
+
}
|
|
16932
|
+
}
|
|
16933
|
+
return null;
|
|
16934
|
+
};
|
|
16935
|
+
this.abort = function() {
|
|
16936
|
+
this.abortController.abort();
|
|
16937
|
+
this._abortController = null;
|
|
16938
|
+
return this;
|
|
16939
|
+
};
|
|
16940
|
+
}
|
|
16941
|
+
// TODO: Revert this back to a single member variable once this issue has been fixed
|
|
16942
|
+
// https://github.com/cloudflare/workerd/issues/3657
|
|
16943
|
+
/**
|
|
16944
|
+
* Used for aborting ongoing requests in loaders using this manager.
|
|
16945
|
+
*
|
|
16946
|
+
* @type {AbortController}
|
|
16947
|
+
*/
|
|
16948
|
+
get abortController() {
|
|
16949
|
+
if (!this._abortController) {
|
|
16950
|
+
this._abortController = new AbortController();
|
|
16951
|
+
}
|
|
16952
|
+
return this._abortController;
|
|
16953
|
+
}
|
|
16954
|
+
}
|
|
16856
16955
|
class Light extends Object3D {
|
|
16857
16956
|
/**
|
|
16858
16957
|
* Constructs a new light.
|
|
@@ -56539,6 +56638,57 @@ var BloomEffect = class extends Effect {
|
|
|
56539
56638
|
}
|
|
56540
56639
|
}
|
|
56541
56640
|
};
|
|
56641
|
+
var ShaderPass = class extends Pass {
|
|
56642
|
+
/**
|
|
56643
|
+
* Constructs a new shader pass.
|
|
56644
|
+
*
|
|
56645
|
+
* @param {ShaderMaterial} material - A shader material.
|
|
56646
|
+
* @param {String} [input="inputBuffer"] - The name of the input buffer uniform.
|
|
56647
|
+
*/
|
|
56648
|
+
constructor(material, input = "inputBuffer") {
|
|
56649
|
+
super("ShaderPass");
|
|
56650
|
+
this.fullscreenMaterial = material;
|
|
56651
|
+
this.input = input;
|
|
56652
|
+
}
|
|
56653
|
+
/**
|
|
56654
|
+
* Sets the name of the input buffer uniform.
|
|
56655
|
+
*
|
|
56656
|
+
* @param {String} input - The name of the input buffer uniform.
|
|
56657
|
+
* @deprecated Use input instead.
|
|
56658
|
+
*/
|
|
56659
|
+
setInput(input) {
|
|
56660
|
+
this.input = input;
|
|
56661
|
+
}
|
|
56662
|
+
/**
|
|
56663
|
+
* Renders the effect.
|
|
56664
|
+
*
|
|
56665
|
+
* @param {WebGLRenderer} renderer - The renderer.
|
|
56666
|
+
* @param {WebGLRenderTarget} inputBuffer - A frame buffer that contains the result of the previous pass.
|
|
56667
|
+
* @param {WebGLRenderTarget} outputBuffer - A frame buffer that serves as the output render target unless this pass renders to screen.
|
|
56668
|
+
* @param {Number} [deltaTime] - The time between the last frame and the current one in seconds.
|
|
56669
|
+
* @param {Boolean} [stencilTest] - Indicates whether a stencil mask is active.
|
|
56670
|
+
*/
|
|
56671
|
+
render(renderer, inputBuffer, outputBuffer, deltaTime, stencilTest) {
|
|
56672
|
+
const uniforms = this.fullscreenMaterial.uniforms;
|
|
56673
|
+
if (inputBuffer !== null && uniforms !== void 0 && uniforms[this.input] !== void 0) {
|
|
56674
|
+
uniforms[this.input].value = inputBuffer.texture;
|
|
56675
|
+
}
|
|
56676
|
+
renderer.setRenderTarget(this.renderToScreen ? null : outputBuffer);
|
|
56677
|
+
renderer.render(this.scene, this.camera);
|
|
56678
|
+
}
|
|
56679
|
+
/**
|
|
56680
|
+
* Performs initialization tasks.
|
|
56681
|
+
*
|
|
56682
|
+
* @param {WebGLRenderer} renderer - A renderer.
|
|
56683
|
+
* @param {Boolean} alpha - Whether the renderer uses the alpha channel.
|
|
56684
|
+
* @param {Number} frameBufferType - The type of the main frame buffers.
|
|
56685
|
+
*/
|
|
56686
|
+
initialize(renderer, alpha, frameBufferType) {
|
|
56687
|
+
if (frameBufferType !== void 0 && frameBufferType !== UnsignedByteType) {
|
|
56688
|
+
this.fullscreenMaterial.defines.FRAMEBUFFER_PRECISION_HIGH = "1";
|
|
56689
|
+
}
|
|
56690
|
+
}
|
|
56691
|
+
};
|
|
56542
56692
|
var RenderPass = class extends Pass {
|
|
56543
56693
|
/**
|
|
56544
56694
|
* Constructs a new render pass.
|
|
@@ -56725,6 +56875,957 @@ var RenderPass = class extends Pass {
|
|
|
56725
56875
|
renderer.shadowMap.autoUpdate = shadowMapAutoUpdate;
|
|
56726
56876
|
}
|
|
56727
56877
|
};
|
|
56878
|
+
var EdgeDetectionMode = {
|
|
56879
|
+
COLOR: 2
|
|
56880
|
+
};
|
|
56881
|
+
var PredicationMode = {
|
|
56882
|
+
DISABLED: 0
|
|
56883
|
+
};
|
|
56884
|
+
var SMAAPreset = {
|
|
56885
|
+
LOW: 0,
|
|
56886
|
+
MEDIUM: 1,
|
|
56887
|
+
HIGH: 2,
|
|
56888
|
+
ULTRA: 3
|
|
56889
|
+
};
|
|
56890
|
+
var edge_detection_default = `varying vec2 vUv;varying vec2 vUv0;varying vec2 vUv1;
|
|
56891
|
+
#if EDGE_DETECTION_MODE != 0
|
|
56892
|
+
varying vec2 vUv2;varying vec2 vUv3;varying vec2 vUv4;varying vec2 vUv5;
|
|
56893
|
+
#endif
|
|
56894
|
+
#if EDGE_DETECTION_MODE == 1
|
|
56895
|
+
#include <common>
|
|
56896
|
+
#endif
|
|
56897
|
+
#if EDGE_DETECTION_MODE == 0 || PREDICATION_MODE == 1
|
|
56898
|
+
#ifdef GL_FRAGMENT_PRECISION_HIGH
|
|
56899
|
+
uniform highp sampler2D depthBuffer;
|
|
56900
|
+
#else
|
|
56901
|
+
uniform mediump sampler2D depthBuffer;
|
|
56902
|
+
#endif
|
|
56903
|
+
float readDepth(const in vec2 uv){
|
|
56904
|
+
#if DEPTH_PACKING == 3201
|
|
56905
|
+
return unpackRGBAToDepth(texture2D(depthBuffer,uv));
|
|
56906
|
+
#else
|
|
56907
|
+
return texture2D(depthBuffer,uv).r;
|
|
56908
|
+
#endif
|
|
56909
|
+
}vec3 gatherNeighbors(){float p=readDepth(vUv);float pLeft=readDepth(vUv0);float pTop=readDepth(vUv1);return vec3(p,pLeft,pTop);}
|
|
56910
|
+
#elif PREDICATION_MODE == 2
|
|
56911
|
+
uniform sampler2D predicationBuffer;vec3 gatherNeighbors(){float p=texture2D(predicationBuffer,vUv).r;float pLeft=texture2D(predicationBuffer,vUv0).r;float pTop=texture2D(predicationBuffer,vUv1).r;return vec3(p,pLeft,pTop);}
|
|
56912
|
+
#endif
|
|
56913
|
+
#if PREDICATION_MODE != 0
|
|
56914
|
+
vec2 calculatePredicatedThreshold(){vec3 neighbours=gatherNeighbors();vec2 delta=abs(neighbours.xx-neighbours.yz);vec2 edges=step(PREDICATION_THRESHOLD,delta);return PREDICATION_SCALE*EDGE_THRESHOLD*(1.0-PREDICATION_STRENGTH*edges);}
|
|
56915
|
+
#endif
|
|
56916
|
+
#if EDGE_DETECTION_MODE != 0
|
|
56917
|
+
uniform sampler2D inputBuffer;
|
|
56918
|
+
#endif
|
|
56919
|
+
void main(){
|
|
56920
|
+
#if EDGE_DETECTION_MODE == 0
|
|
56921
|
+
const vec2 threshold=vec2(DEPTH_THRESHOLD);
|
|
56922
|
+
#elif PREDICATION_MODE != 0
|
|
56923
|
+
vec2 threshold=calculatePredicatedThreshold();
|
|
56924
|
+
#else
|
|
56925
|
+
const vec2 threshold=vec2(EDGE_THRESHOLD);
|
|
56926
|
+
#endif
|
|
56927
|
+
#if EDGE_DETECTION_MODE == 0
|
|
56928
|
+
vec3 neighbors=gatherNeighbors();vec2 delta=abs(neighbors.xx-vec2(neighbors.y,neighbors.z));vec2 edges=step(threshold,delta);if(dot(edges,vec2(1.0))==0.0){discard;}gl_FragColor=vec4(edges,0.0,1.0);
|
|
56929
|
+
#elif EDGE_DETECTION_MODE == 1
|
|
56930
|
+
float l=luminance(texture2D(inputBuffer,vUv).rgb);float lLeft=luminance(texture2D(inputBuffer,vUv0).rgb);float lTop=luminance(texture2D(inputBuffer,vUv1).rgb);vec4 delta;delta.xy=abs(l-vec2(lLeft,lTop));vec2 edges=step(threshold,delta.xy);if(dot(edges,vec2(1.0))==0.0){discard;}float lRight=luminance(texture2D(inputBuffer,vUv2).rgb);float lBottom=luminance(texture2D(inputBuffer,vUv3).rgb);delta.zw=abs(l-vec2(lRight,lBottom));vec2 maxDelta=max(delta.xy,delta.zw);float lLeftLeft=luminance(texture2D(inputBuffer,vUv4).rgb);float lTopTop=luminance(texture2D(inputBuffer,vUv5).rgb);delta.zw=abs(vec2(lLeft,lTop)-vec2(lLeftLeft,lTopTop));maxDelta=max(maxDelta.xy,delta.zw);float finalDelta=max(maxDelta.x,maxDelta.y);edges.xy*=step(finalDelta,LOCAL_CONTRAST_ADAPTATION_FACTOR*delta.xy);gl_FragColor=vec4(edges,0.0,1.0);
|
|
56931
|
+
#elif EDGE_DETECTION_MODE == 2
|
|
56932
|
+
vec4 delta;vec3 c=texture2D(inputBuffer,vUv).rgb;vec3 cLeft=texture2D(inputBuffer,vUv0).rgb;vec3 t=abs(c-cLeft);delta.x=max(max(t.r,t.g),t.b);vec3 cTop=texture2D(inputBuffer,vUv1).rgb;t=abs(c-cTop);delta.y=max(max(t.r,t.g),t.b);vec2 edges=step(threshold,delta.xy);if(dot(edges,vec2(1.0))==0.0){discard;}vec3 cRight=texture2D(inputBuffer,vUv2).rgb;t=abs(c-cRight);delta.z=max(max(t.r,t.g),t.b);vec3 cBottom=texture2D(inputBuffer,vUv3).rgb;t=abs(c-cBottom);delta.w=max(max(t.r,t.g),t.b);vec2 maxDelta=max(delta.xy,delta.zw);vec3 cLeftLeft=texture2D(inputBuffer,vUv4).rgb;t=abs(c-cLeftLeft);delta.z=max(max(t.r,t.g),t.b);vec3 cTopTop=texture2D(inputBuffer,vUv5).rgb;t=abs(c-cTopTop);delta.w=max(max(t.r,t.g),t.b);maxDelta=max(maxDelta.xy,delta.zw);float finalDelta=max(maxDelta.x,maxDelta.y);edges*=step(finalDelta,LOCAL_CONTRAST_ADAPTATION_FACTOR*delta.xy);gl_FragColor=vec4(edges,0.0,1.0);
|
|
56933
|
+
#endif
|
|
56934
|
+
}`;
|
|
56935
|
+
var edge_detection_default2 = `uniform vec2 texelSize;varying vec2 vUv;varying vec2 vUv0;varying vec2 vUv1;
|
|
56936
|
+
#if EDGE_DETECTION_MODE != 0
|
|
56937
|
+
varying vec2 vUv2;varying vec2 vUv3;varying vec2 vUv4;varying vec2 vUv5;
|
|
56938
|
+
#endif
|
|
56939
|
+
void main(){vUv=position.xy*0.5+0.5;vUv0=vUv+texelSize*vec2(-1.0,0.0);vUv1=vUv+texelSize*vec2(0.0,-1.0);
|
|
56940
|
+
#if EDGE_DETECTION_MODE != 0
|
|
56941
|
+
vUv2=vUv+texelSize*vec2(1.0,0.0);vUv3=vUv+texelSize*vec2(0.0,1.0);vUv4=vUv+texelSize*vec2(-2.0,0.0);vUv5=vUv+texelSize*vec2(0.0,-2.0);
|
|
56942
|
+
#endif
|
|
56943
|
+
gl_Position=vec4(position.xy,1.0,1.0);}`;
|
|
56944
|
+
var EdgeDetectionMaterial = class extends ShaderMaterial {
|
|
56945
|
+
/**
|
|
56946
|
+
* Constructs a new edge detection material.
|
|
56947
|
+
*
|
|
56948
|
+
* TODO Remove parameters.
|
|
56949
|
+
* @param {Vector2} [texelSize] - The screen texel size.
|
|
56950
|
+
* @param {EdgeDetectionMode} [mode=EdgeDetectionMode.COLOR] - The edge detection mode.
|
|
56951
|
+
*/
|
|
56952
|
+
constructor(texelSize = new Vector2$1(), mode = EdgeDetectionMode.COLOR) {
|
|
56953
|
+
super({
|
|
56954
|
+
name: "EdgeDetectionMaterial",
|
|
56955
|
+
defines: {
|
|
56956
|
+
THREE_REVISION: REVISION.replace(/\D+/g, ""),
|
|
56957
|
+
LOCAL_CONTRAST_ADAPTATION_FACTOR: "2.0",
|
|
56958
|
+
EDGE_THRESHOLD: "0.1",
|
|
56959
|
+
DEPTH_THRESHOLD: "0.01",
|
|
56960
|
+
PREDICATION_MODE: "0",
|
|
56961
|
+
PREDICATION_THRESHOLD: "0.01",
|
|
56962
|
+
PREDICATION_SCALE: "2.0",
|
|
56963
|
+
PREDICATION_STRENGTH: "1.0",
|
|
56964
|
+
DEPTH_PACKING: "0"
|
|
56965
|
+
},
|
|
56966
|
+
uniforms: {
|
|
56967
|
+
inputBuffer: new Uniform(null),
|
|
56968
|
+
depthBuffer: new Uniform(null),
|
|
56969
|
+
predicationBuffer: new Uniform(null),
|
|
56970
|
+
texelSize: new Uniform(texelSize)
|
|
56971
|
+
},
|
|
56972
|
+
blending: NoBlending,
|
|
56973
|
+
toneMapped: false,
|
|
56974
|
+
depthWrite: false,
|
|
56975
|
+
depthTest: false,
|
|
56976
|
+
fragmentShader: edge_detection_default,
|
|
56977
|
+
vertexShader: edge_detection_default2
|
|
56978
|
+
});
|
|
56979
|
+
this.edgeDetectionMode = mode;
|
|
56980
|
+
}
|
|
56981
|
+
/**
|
|
56982
|
+
* The depth buffer.
|
|
56983
|
+
*
|
|
56984
|
+
* @type {Texture}
|
|
56985
|
+
*/
|
|
56986
|
+
set depthBuffer(value) {
|
|
56987
|
+
this.uniforms.depthBuffer.value = value;
|
|
56988
|
+
}
|
|
56989
|
+
/**
|
|
56990
|
+
* The depth packing strategy.
|
|
56991
|
+
*
|
|
56992
|
+
* @type {DepthPackingStrategies}
|
|
56993
|
+
*/
|
|
56994
|
+
set depthPacking(value) {
|
|
56995
|
+
this.defines.DEPTH_PACKING = value.toFixed(0);
|
|
56996
|
+
this.needsUpdate = true;
|
|
56997
|
+
}
|
|
56998
|
+
/**
|
|
56999
|
+
* Sets the depth buffer.
|
|
57000
|
+
*
|
|
57001
|
+
* @deprecated Use depthBuffer and depthPacking instead.
|
|
57002
|
+
* @param {Texture} buffer - The depth texture.
|
|
57003
|
+
* @param {DepthPackingStrategies} [depthPacking=BasicDepthPacking] - The depth packing strategy.
|
|
57004
|
+
*/
|
|
57005
|
+
setDepthBuffer(buffer2, depthPacking = BasicDepthPacking) {
|
|
57006
|
+
this.depthBuffer = buffer2;
|
|
57007
|
+
this.depthPacking = depthPacking;
|
|
57008
|
+
}
|
|
57009
|
+
/**
|
|
57010
|
+
* The edge detection mode.
|
|
57011
|
+
*
|
|
57012
|
+
* @type {EdgeDetectionMode}
|
|
57013
|
+
*/
|
|
57014
|
+
get edgeDetectionMode() {
|
|
57015
|
+
return Number(this.defines.EDGE_DETECTION_MODE);
|
|
57016
|
+
}
|
|
57017
|
+
set edgeDetectionMode(value) {
|
|
57018
|
+
this.defines.EDGE_DETECTION_MODE = value.toFixed(0);
|
|
57019
|
+
this.needsUpdate = true;
|
|
57020
|
+
}
|
|
57021
|
+
/**
|
|
57022
|
+
* Returns the edge detection mode.
|
|
57023
|
+
*
|
|
57024
|
+
* @deprecated Use edgeDetectionMode instead.
|
|
57025
|
+
* @return {EdgeDetectionMode} The mode.
|
|
57026
|
+
*/
|
|
57027
|
+
getEdgeDetectionMode() {
|
|
57028
|
+
return this.edgeDetectionMode;
|
|
57029
|
+
}
|
|
57030
|
+
/**
|
|
57031
|
+
* Sets the edge detection mode.
|
|
57032
|
+
*
|
|
57033
|
+
* @deprecated Use edgeDetectionMode instead.
|
|
57034
|
+
* @param {EdgeDetectionMode} value - The edge detection mode.
|
|
57035
|
+
*/
|
|
57036
|
+
setEdgeDetectionMode(value) {
|
|
57037
|
+
this.edgeDetectionMode = value;
|
|
57038
|
+
}
|
|
57039
|
+
/**
|
|
57040
|
+
* The local contrast adaptation factor. Has no effect if the edge detection mode is set to DEPTH. Default is 2.0.
|
|
57041
|
+
*
|
|
57042
|
+
* If a neighbor edge has _factor_ times bigger contrast than the current edge, the edge will be discarded.
|
|
57043
|
+
*
|
|
57044
|
+
* This allows to eliminate spurious crossing edges and is based on the fact that if there is too much contrast in a
|
|
57045
|
+
* direction, the perceptual contrast in the other neighbors will be hidden.
|
|
57046
|
+
*
|
|
57047
|
+
* @type {Number}
|
|
57048
|
+
*/
|
|
57049
|
+
get localContrastAdaptationFactor() {
|
|
57050
|
+
return Number(this.defines.LOCAL_CONTRAST_ADAPTATION_FACTOR);
|
|
57051
|
+
}
|
|
57052
|
+
set localContrastAdaptationFactor(value) {
|
|
57053
|
+
this.defines.LOCAL_CONTRAST_ADAPTATION_FACTOR = value.toFixed("6");
|
|
57054
|
+
this.needsUpdate = true;
|
|
57055
|
+
}
|
|
57056
|
+
/**
|
|
57057
|
+
* Returns the local contrast adaptation factor.
|
|
57058
|
+
*
|
|
57059
|
+
* @deprecated Use localContrastAdaptationFactor instead.
|
|
57060
|
+
* @return {Number} The factor.
|
|
57061
|
+
*/
|
|
57062
|
+
getLocalContrastAdaptationFactor() {
|
|
57063
|
+
return this.localContrastAdaptationFactor;
|
|
57064
|
+
}
|
|
57065
|
+
/**
|
|
57066
|
+
* Sets the local contrast adaptation factor. Has no effect if the edge detection mode is set to DEPTH.
|
|
57067
|
+
*
|
|
57068
|
+
* @deprecated Use localContrastAdaptationFactor instead.
|
|
57069
|
+
* @param {Number} value - The local contrast adaptation factor. Default is 2.0.
|
|
57070
|
+
*/
|
|
57071
|
+
setLocalContrastAdaptationFactor(value) {
|
|
57072
|
+
this.localContrastAdaptationFactor = value;
|
|
57073
|
+
}
|
|
57074
|
+
/**
|
|
57075
|
+
* The edge detection threshold. Range: [0.0, 0.5].
|
|
57076
|
+
*
|
|
57077
|
+
* A lower value results in more edges being detected at the expense of performance.
|
|
57078
|
+
*
|
|
57079
|
+
* For luma- and chroma-based edge detection, 0.1 is a reasonable value and allows to catch most visible edges. 0.05
|
|
57080
|
+
* is a rather overkill value that allows to catch 'em all. Darker scenes may require an even lower threshold.
|
|
57081
|
+
*
|
|
57082
|
+
* If depth-based edge detection is used, the threshold will depend on the scene depth.
|
|
57083
|
+
*
|
|
57084
|
+
* @type {Number}
|
|
57085
|
+
*/
|
|
57086
|
+
get edgeDetectionThreshold() {
|
|
57087
|
+
return Number(this.defines.EDGE_THRESHOLD);
|
|
57088
|
+
}
|
|
57089
|
+
set edgeDetectionThreshold(value) {
|
|
57090
|
+
this.defines.EDGE_THRESHOLD = value.toFixed("6");
|
|
57091
|
+
this.defines.DEPTH_THRESHOLD = (value * 0.1).toFixed("6");
|
|
57092
|
+
this.needsUpdate = true;
|
|
57093
|
+
}
|
|
57094
|
+
/**
|
|
57095
|
+
* Returns the edge detection threshold.
|
|
57096
|
+
*
|
|
57097
|
+
* @deprecated Use edgeDetectionThreshold instead.
|
|
57098
|
+
* @return {Number} The threshold.
|
|
57099
|
+
*/
|
|
57100
|
+
getEdgeDetectionThreshold() {
|
|
57101
|
+
return this.edgeDetectionThreshold;
|
|
57102
|
+
}
|
|
57103
|
+
/**
|
|
57104
|
+
* Sets the edge detection threshold.
|
|
57105
|
+
*
|
|
57106
|
+
* @deprecated Use edgeDetectionThreshold instead.
|
|
57107
|
+
* @param {Number} value - The edge detection threshold. Range: [0.0, 0.5].
|
|
57108
|
+
*/
|
|
57109
|
+
setEdgeDetectionThreshold(value) {
|
|
57110
|
+
this.edgeDetectionThreshold = value;
|
|
57111
|
+
}
|
|
57112
|
+
/**
|
|
57113
|
+
* The predication mode.
|
|
57114
|
+
*
|
|
57115
|
+
* Predicated thresholding allows to better preserve texture details and to improve edge detection using an additional
|
|
57116
|
+
* buffer such as a light accumulation or depth buffer.
|
|
57117
|
+
*
|
|
57118
|
+
* @type {PredicationMode}
|
|
57119
|
+
*/
|
|
57120
|
+
get predicationMode() {
|
|
57121
|
+
return Number(this.defines.PREDICATION_MODE);
|
|
57122
|
+
}
|
|
57123
|
+
set predicationMode(value) {
|
|
57124
|
+
this.defines.PREDICATION_MODE = value.toFixed(0);
|
|
57125
|
+
this.needsUpdate = true;
|
|
57126
|
+
}
|
|
57127
|
+
/**
|
|
57128
|
+
* Returns the predication mode.
|
|
57129
|
+
*
|
|
57130
|
+
* @deprecated Use predicationMode instead.
|
|
57131
|
+
* @return {PredicationMode} The mode.
|
|
57132
|
+
*/
|
|
57133
|
+
getPredicationMode() {
|
|
57134
|
+
return this.predicationMode;
|
|
57135
|
+
}
|
|
57136
|
+
/**
|
|
57137
|
+
* Sets the predication mode.
|
|
57138
|
+
*
|
|
57139
|
+
* @deprecated Use predicationMode instead.
|
|
57140
|
+
* @param {PredicationMode} value - The predication mode.
|
|
57141
|
+
*/
|
|
57142
|
+
setPredicationMode(value) {
|
|
57143
|
+
this.predicationMode = value;
|
|
57144
|
+
}
|
|
57145
|
+
/**
|
|
57146
|
+
* The predication buffer.
|
|
57147
|
+
*
|
|
57148
|
+
* @type {Texture}
|
|
57149
|
+
*/
|
|
57150
|
+
set predicationBuffer(value) {
|
|
57151
|
+
this.uniforms.predicationBuffer.value = value;
|
|
57152
|
+
}
|
|
57153
|
+
/**
|
|
57154
|
+
* Sets a custom predication buffer.
|
|
57155
|
+
*
|
|
57156
|
+
* @deprecated Use predicationBuffer instead.
|
|
57157
|
+
* @param {Texture} value - The predication buffer.
|
|
57158
|
+
*/
|
|
57159
|
+
setPredicationBuffer(value) {
|
|
57160
|
+
this.uniforms.predicationBuffer.value = value;
|
|
57161
|
+
}
|
|
57162
|
+
/**
|
|
57163
|
+
* The predication threshold.
|
|
57164
|
+
*
|
|
57165
|
+
* @type {Number}
|
|
57166
|
+
*/
|
|
57167
|
+
get predicationThreshold() {
|
|
57168
|
+
return Number(this.defines.PREDICATION_THRESHOLD);
|
|
57169
|
+
}
|
|
57170
|
+
set predicationThreshold(value) {
|
|
57171
|
+
this.defines.PREDICATION_THRESHOLD = value.toFixed("6");
|
|
57172
|
+
this.needsUpdate = true;
|
|
57173
|
+
}
|
|
57174
|
+
/**
|
|
57175
|
+
* Returns the predication threshold.
|
|
57176
|
+
*
|
|
57177
|
+
* @deprecated Use predicationThreshold instead.
|
|
57178
|
+
* @return {Number} The threshold.
|
|
57179
|
+
*/
|
|
57180
|
+
getPredicationThreshold() {
|
|
57181
|
+
return this.predicationThreshold;
|
|
57182
|
+
}
|
|
57183
|
+
/**
|
|
57184
|
+
* Sets the predication threshold.
|
|
57185
|
+
*
|
|
57186
|
+
* @deprecated Use predicationThreshold instead.
|
|
57187
|
+
* @param {Number} value - The threshold.
|
|
57188
|
+
*/
|
|
57189
|
+
setPredicationThreshold(value) {
|
|
57190
|
+
this.predicationThreshold = value;
|
|
57191
|
+
}
|
|
57192
|
+
/**
|
|
57193
|
+
* The predication scale. Range: [1.0, 5.0].
|
|
57194
|
+
*
|
|
57195
|
+
* Determines how much the edge detection threshold should be scaled when using predication.
|
|
57196
|
+
*
|
|
57197
|
+
* @type {Boolean|Texture|Number}
|
|
57198
|
+
*/
|
|
57199
|
+
get predicationScale() {
|
|
57200
|
+
return Number(this.defines.PREDICATION_SCALE);
|
|
57201
|
+
}
|
|
57202
|
+
set predicationScale(value) {
|
|
57203
|
+
this.defines.PREDICATION_SCALE = value.toFixed("6");
|
|
57204
|
+
this.needsUpdate = true;
|
|
57205
|
+
}
|
|
57206
|
+
/**
|
|
57207
|
+
* Returns the predication scale.
|
|
57208
|
+
*
|
|
57209
|
+
* @deprecated Use predicationScale instead.
|
|
57210
|
+
* @return {Number} The scale.
|
|
57211
|
+
*/
|
|
57212
|
+
getPredicationScale() {
|
|
57213
|
+
return this.predicationScale;
|
|
57214
|
+
}
|
|
57215
|
+
/**
|
|
57216
|
+
* Sets the predication scale.
|
|
57217
|
+
*
|
|
57218
|
+
* @deprecated Use predicationScale instead.
|
|
57219
|
+
* @param {Number} value - The scale. Range: [1.0, 5.0].
|
|
57220
|
+
*/
|
|
57221
|
+
setPredicationScale(value) {
|
|
57222
|
+
this.predicationScale = value;
|
|
57223
|
+
}
|
|
57224
|
+
/**
|
|
57225
|
+
* The predication strength. Range: [0.0, 1.0].
|
|
57226
|
+
*
|
|
57227
|
+
* Determines how much the edge detection threshold should be decreased locally when using predication.
|
|
57228
|
+
*
|
|
57229
|
+
* @type {Number}
|
|
57230
|
+
*/
|
|
57231
|
+
get predicationStrength() {
|
|
57232
|
+
return Number(this.defines.PREDICATION_STRENGTH);
|
|
57233
|
+
}
|
|
57234
|
+
set predicationStrength(value) {
|
|
57235
|
+
this.defines.PREDICATION_STRENGTH = value.toFixed("6");
|
|
57236
|
+
this.needsUpdate = true;
|
|
57237
|
+
}
|
|
57238
|
+
/**
|
|
57239
|
+
* Returns the predication strength.
|
|
57240
|
+
*
|
|
57241
|
+
* @deprecated Use predicationStrength instead.
|
|
57242
|
+
* @return {Number} The strength.
|
|
57243
|
+
*/
|
|
57244
|
+
getPredicationStrength() {
|
|
57245
|
+
return this.predicationStrength;
|
|
57246
|
+
}
|
|
57247
|
+
/**
|
|
57248
|
+
* Sets the predication strength.
|
|
57249
|
+
*
|
|
57250
|
+
* @deprecated Use predicationStrength instead.
|
|
57251
|
+
* @param {Number} value - The strength. Range: [0.0, 1.0].
|
|
57252
|
+
*/
|
|
57253
|
+
setPredicationStrength(value) {
|
|
57254
|
+
this.predicationStrength = value;
|
|
57255
|
+
}
|
|
57256
|
+
/**
|
|
57257
|
+
* Sets the size of this object.
|
|
57258
|
+
*
|
|
57259
|
+
* @param {Number} width - The width.
|
|
57260
|
+
* @param {Number} height - The height.
|
|
57261
|
+
*/
|
|
57262
|
+
setSize(width, height) {
|
|
57263
|
+
this.uniforms.texelSize.value.set(1 / width, 1 / height);
|
|
57264
|
+
}
|
|
57265
|
+
};
|
|
57266
|
+
var smaa_weights_default = `#define sampleLevelZeroOffset(t, coord, offset) texture2D(t, coord + offset * texelSize)
|
|
57267
|
+
#if __VERSION__ < 300
|
|
57268
|
+
#define round(v) floor(v + 0.5)
|
|
57269
|
+
#endif
|
|
57270
|
+
#ifdef FRAMEBUFFER_PRECISION_HIGH
|
|
57271
|
+
uniform mediump sampler2D inputBuffer;
|
|
57272
|
+
#else
|
|
57273
|
+
uniform lowp sampler2D inputBuffer;
|
|
57274
|
+
#endif
|
|
57275
|
+
uniform lowp sampler2D areaTexture;uniform lowp sampler2D searchTexture;uniform vec2 texelSize;uniform vec2 resolution;varying vec2 vUv;varying vec4 vOffset[3];varying vec2 vPixCoord;void movec(const in bvec2 c,inout vec2 variable,const in vec2 value){if(c.x){variable.x=value.x;}if(c.y){variable.y=value.y;}}void movec(const in bvec4 c,inout vec4 variable,const in vec4 value){movec(c.xy,variable.xy,value.xy);movec(c.zw,variable.zw,value.zw);}vec2 decodeDiagBilinearAccess(in vec2 e){e.r=e.r*abs(5.0*e.r-5.0*0.75);return round(e);}vec4 decodeDiagBilinearAccess(in vec4 e){e.rb=e.rb*abs(5.0*e.rb-5.0*0.75);return round(e);}vec2 searchDiag1(const in vec2 texCoord,const in vec2 dir,out vec2 e){vec4 coord=vec4(texCoord,-1.0,1.0);vec3 t=vec3(texelSize,1.0);for(int i=0;i<MAX_SEARCH_STEPS_INT;++i){if(!(coord.z<float(MAX_SEARCH_STEPS_DIAG_INT-1)&&coord.w>0.9)){break;}coord.xyz=t*vec3(dir,1.0)+coord.xyz;e=texture2D(inputBuffer,coord.xy).rg;coord.w=dot(e,vec2(0.5));}return coord.zw;}vec2 searchDiag2(const in vec2 texCoord,const in vec2 dir,out vec2 e){vec4 coord=vec4(texCoord,-1.0,1.0);coord.x+=0.25*texelSize.x;vec3 t=vec3(texelSize,1.0);for(int i=0;i<MAX_SEARCH_STEPS_INT;++i){if(!(coord.z<float(MAX_SEARCH_STEPS_DIAG_INT-1)&&coord.w>0.9)){break;}coord.xyz=t*vec3(dir,1.0)+coord.xyz;e=texture2D(inputBuffer,coord.xy).rg;e=decodeDiagBilinearAccess(e);coord.w=dot(e,vec2(0.5));}return coord.zw;}vec2 areaDiag(const in vec2 dist,const in vec2 e,const in float offset){vec2 texCoord=vec2(AREATEX_MAX_DISTANCE_DIAG,AREATEX_MAX_DISTANCE_DIAG)*e+dist;texCoord=AREATEX_PIXEL_SIZE*texCoord+0.5*AREATEX_PIXEL_SIZE;texCoord.x+=0.5;texCoord.y+=AREATEX_SUBTEX_SIZE*offset;return texture2D(areaTexture,texCoord).rg;}vec2 calculateDiagWeights(const in vec2 texCoord,const in vec2 e,const in vec4 subsampleIndices){vec2 weights=vec2(0.0);vec4 d;vec2 end;if(e.r>0.0){d.xz=searchDiag1(texCoord,vec2(-1.0,1.0),end);d.x+=float(end.y>0.9);}else{d.xz=vec2(0.0);}d.yw=searchDiag1(texCoord,vec2(1.0,-1.0),end);if(d.x+d.y>2.0){vec4 coords=vec4(-d.x+0.25,d.x,d.y,-d.y-0.25)*texelSize.xyxy+texCoord.xyxy;vec4 c;c.xy=sampleLevelZeroOffset(inputBuffer,coords.xy,vec2(-1,0)).rg;c.zw=sampleLevelZeroOffset(inputBuffer,coords.zw,vec2(1,0)).rg;c.yxwz=decodeDiagBilinearAccess(c.xyzw);vec2 cc=vec2(2.0)*c.xz+c.yw;movec(bvec2(step(0.9,d.zw)),cc,vec2(0.0));weights+=areaDiag(d.xy,cc,subsampleIndices.z);}d.xz=searchDiag2(texCoord,vec2(-1.0,-1.0),end);if(sampleLevelZeroOffset(inputBuffer,texCoord,vec2(1,0)).r>0.0){d.yw=searchDiag2(texCoord,vec2(1.0),end);d.y+=float(end.y>0.9);}else{d.yw=vec2(0.0);}if(d.x+d.y>2.0){vec4 coords=vec4(-d.x,-d.x,d.y,d.y)*texelSize.xyxy+texCoord.xyxy;vec4 c;c.x=sampleLevelZeroOffset(inputBuffer,coords.xy,vec2(-1,0)).g;c.y=sampleLevelZeroOffset(inputBuffer,coords.xy,vec2(0,-1)).r;c.zw=sampleLevelZeroOffset(inputBuffer,coords.zw,vec2(1,0)).gr;vec2 cc=vec2(2.0)*c.xz+c.yw;movec(bvec2(step(0.9,d.zw)),cc,vec2(0.0));weights+=areaDiag(d.xy,cc,subsampleIndices.w).gr;}return weights;}float searchLength(const in vec2 e,const in float offset){vec2 scale=SEARCHTEX_SIZE*vec2(0.5,-1.0);vec2 bias=SEARCHTEX_SIZE*vec2(offset,1.0);scale+=vec2(-1.0,1.0);bias+=vec2(0.5,-0.5);scale*=1.0/SEARCHTEX_PACKED_SIZE;bias*=1.0/SEARCHTEX_PACKED_SIZE;return texture2D(searchTexture,scale*e+bias).r;}float searchXLeft(in vec2 texCoord,const in float end){vec2 e=vec2(0.0,1.0);for(int i=0;i<MAX_SEARCH_STEPS_INT;++i){if(!(texCoord.x>end&&e.g>0.8281&&e.r==0.0)){break;}e=texture2D(inputBuffer,texCoord).rg;texCoord=vec2(-2.0,0.0)*texelSize+texCoord;}float offset=-(255.0/127.0)*searchLength(e,0.0)+3.25;return texelSize.x*offset+texCoord.x;}float searchXRight(vec2 texCoord,const in float end){vec2 e=vec2(0.0,1.0);for(int i=0;i<MAX_SEARCH_STEPS_INT;++i){if(!(texCoord.x<end&&e.g>0.8281&&e.r==0.0)){break;}e=texture2D(inputBuffer,texCoord).rg;texCoord=vec2(2.0,0.0)*texelSize.xy+texCoord;}float offset=-(255.0/127.0)*searchLength(e,0.5)+3.25;return-texelSize.x*offset+texCoord.x;}float searchYUp(vec2 texCoord,const in float end){vec2 e=vec2(1.0,0.0);for(int i=0;i<MAX_SEARCH_STEPS_INT;++i){if(!(texCoord.y>end&&e.r>0.8281&&e.g==0.0)){break;}e=texture2D(inputBuffer,texCoord).rg;texCoord=-vec2(0.0,2.0)*texelSize.xy+texCoord;}float offset=-(255.0/127.0)*searchLength(e.gr,0.0)+3.25;return texelSize.y*offset+texCoord.y;}float searchYDown(vec2 texCoord,const in float end){vec2 e=vec2(1.0,0.0);for(int i=0;i<MAX_SEARCH_STEPS_INT;i++){if(!(texCoord.y<end&&e.r>0.8281&&e.g==0.0)){break;}e=texture2D(inputBuffer,texCoord).rg;texCoord=vec2(0.0,2.0)*texelSize.xy+texCoord;}float offset=-(255.0/127.0)*searchLength(e.gr,0.5)+3.25;return-texelSize.y*offset+texCoord.y;}vec2 area(const in vec2 dist,const in float e1,const in float e2,const in float offset){vec2 texCoord=vec2(AREATEX_MAX_DISTANCE)*round(4.0*vec2(e1,e2))+dist;texCoord=AREATEX_PIXEL_SIZE*texCoord+0.5*AREATEX_PIXEL_SIZE;texCoord.y=AREATEX_SUBTEX_SIZE*offset+texCoord.y;return texture2D(areaTexture,texCoord).rg;}void detectHorizontalCornerPattern(inout vec2 weights,const in vec4 texCoord,const in vec2 d){
|
|
57276
|
+
#if !defined(DISABLE_CORNER_DETECTION)
|
|
57277
|
+
vec2 leftRight=step(d.xy,d.yx);vec2 rounding=(1.0-CORNER_ROUNDING_NORM)*leftRight;rounding/=leftRight.x+leftRight.y;vec2 factor=vec2(1.0);factor.x-=rounding.x*sampleLevelZeroOffset(inputBuffer,texCoord.xy,vec2(0,1)).r;factor.x-=rounding.y*sampleLevelZeroOffset(inputBuffer,texCoord.zw,vec2(1,1)).r;factor.y-=rounding.x*sampleLevelZeroOffset(inputBuffer,texCoord.xy,vec2(0,-2)).r;factor.y-=rounding.y*sampleLevelZeroOffset(inputBuffer,texCoord.zw,vec2(1,-2)).r;weights*=clamp(factor,0.0,1.0);
|
|
57278
|
+
#endif
|
|
57279
|
+
}void detectVerticalCornerPattern(inout vec2 weights,const in vec4 texCoord,const in vec2 d){
|
|
57280
|
+
#if !defined(DISABLE_CORNER_DETECTION)
|
|
57281
|
+
vec2 leftRight=step(d.xy,d.yx);vec2 rounding=(1.0-CORNER_ROUNDING_NORM)*leftRight;rounding/=leftRight.x+leftRight.y;vec2 factor=vec2(1.0);factor.x-=rounding.x*sampleLevelZeroOffset(inputBuffer,texCoord.xy,vec2(1,0)).g;factor.x-=rounding.y*sampleLevelZeroOffset(inputBuffer,texCoord.zw,vec2(1,1)).g;factor.y-=rounding.x*sampleLevelZeroOffset(inputBuffer,texCoord.xy,vec2(-2,0)).g;factor.y-=rounding.y*sampleLevelZeroOffset(inputBuffer,texCoord.zw,vec2(-2,1)).g;weights*=clamp(factor,0.0,1.0);
|
|
57282
|
+
#endif
|
|
57283
|
+
}void main(){vec4 weights=vec4(0.0);vec4 subsampleIndices=vec4(0.0);vec2 e=texture2D(inputBuffer,vUv).rg;if(e.g>0.0){
|
|
57284
|
+
#if !defined(DISABLE_DIAG_DETECTION)
|
|
57285
|
+
weights.rg=calculateDiagWeights(vUv,e,subsampleIndices);if(weights.r==-weights.g){
|
|
57286
|
+
#endif
|
|
57287
|
+
vec2 d;vec3 coords;coords.x=searchXLeft(vOffset[0].xy,vOffset[2].x);coords.y=vOffset[1].y;d.x=coords.x;float e1=texture2D(inputBuffer,coords.xy).r;coords.z=searchXRight(vOffset[0].zw,vOffset[2].y);d.y=coords.z;d=round(resolution.xx*d+-vPixCoord.xx);vec2 sqrtD=sqrt(abs(d));float e2=sampleLevelZeroOffset(inputBuffer,coords.zy,vec2(1,0)).r;weights.rg=area(sqrtD,e1,e2,subsampleIndices.y);coords.y=vUv.y;detectHorizontalCornerPattern(weights.rg,coords.xyzy,d);
|
|
57288
|
+
#if !defined(DISABLE_DIAG_DETECTION)
|
|
57289
|
+
}else{e.r=0.0;}
|
|
57290
|
+
#endif
|
|
57291
|
+
}if(e.r>0.0){vec2 d;vec3 coords;coords.y=searchYUp(vOffset[1].xy,vOffset[2].z);coords.x=vOffset[0].x;d.x=coords.y;float e1=texture2D(inputBuffer,coords.xy).g;coords.z=searchYDown(vOffset[1].zw,vOffset[2].w);d.y=coords.z;d=round(resolution.yy*d-vPixCoord.yy);vec2 sqrtD=sqrt(abs(d));float e2=sampleLevelZeroOffset(inputBuffer,coords.xz,vec2(0,1)).g;weights.ba=area(sqrtD,e1,e2,subsampleIndices.x);coords.x=vUv.x;detectVerticalCornerPattern(weights.ba,coords.xyxz,d);}gl_FragColor=weights;}`;
|
|
57292
|
+
var smaa_weights_default2 = `uniform vec2 texelSize;uniform vec2 resolution;varying vec2 vUv;varying vec4 vOffset[3];varying vec2 vPixCoord;void main(){vUv=position.xy*0.5+0.5;vPixCoord=vUv*resolution;vOffset[0]=vUv.xyxy+texelSize.xyxy*vec4(-0.25,-0.125,1.25,-0.125);vOffset[1]=vUv.xyxy+texelSize.xyxy*vec4(-0.125,-0.25,-0.125,1.25);vOffset[2]=vec4(vOffset[0].xz,vOffset[1].yw)+vec4(-2.0,2.0,-2.0,2.0)*texelSize.xxyy*MAX_SEARCH_STEPS_FLOAT;gl_Position=vec4(position.xy,1.0,1.0);}`;
|
|
57293
|
+
var SMAAWeightsMaterial = class extends ShaderMaterial {
|
|
57294
|
+
/**
|
|
57295
|
+
* Constructs a new SMAA weights material.
|
|
57296
|
+
*
|
|
57297
|
+
* @param {Vector2} [texelSize] - The absolute screen texel size.
|
|
57298
|
+
* @param {Vector2} [resolution] - The resolution.
|
|
57299
|
+
*/
|
|
57300
|
+
constructor(texelSize = new Vector2$1(), resolution = new Vector2$1()) {
|
|
57301
|
+
super({
|
|
57302
|
+
name: "SMAAWeightsMaterial",
|
|
57303
|
+
defines: {
|
|
57304
|
+
// Configurable settings:
|
|
57305
|
+
MAX_SEARCH_STEPS_INT: "16",
|
|
57306
|
+
MAX_SEARCH_STEPS_FLOAT: "16.0",
|
|
57307
|
+
MAX_SEARCH_STEPS_DIAG_INT: "8",
|
|
57308
|
+
MAX_SEARCH_STEPS_DIAG_FLOAT: "8.0",
|
|
57309
|
+
CORNER_ROUNDING: "25",
|
|
57310
|
+
CORNER_ROUNDING_NORM: "0.25",
|
|
57311
|
+
// Non-configurable settings:
|
|
57312
|
+
AREATEX_MAX_DISTANCE: "16.0",
|
|
57313
|
+
AREATEX_MAX_DISTANCE_DIAG: "20.0",
|
|
57314
|
+
AREATEX_PIXEL_SIZE: "(1.0 / vec2(160.0, 560.0))",
|
|
57315
|
+
AREATEX_SUBTEX_SIZE: "(1.0 / 7.0)",
|
|
57316
|
+
SEARCHTEX_SIZE: "vec2(66.0, 33.0)",
|
|
57317
|
+
SEARCHTEX_PACKED_SIZE: "vec2(64.0, 16.0)"
|
|
57318
|
+
},
|
|
57319
|
+
uniforms: {
|
|
57320
|
+
inputBuffer: new Uniform(null),
|
|
57321
|
+
searchTexture: new Uniform(null),
|
|
57322
|
+
areaTexture: new Uniform(null),
|
|
57323
|
+
resolution: new Uniform(resolution),
|
|
57324
|
+
texelSize: new Uniform(texelSize)
|
|
57325
|
+
},
|
|
57326
|
+
blending: NoBlending,
|
|
57327
|
+
toneMapped: false,
|
|
57328
|
+
depthWrite: false,
|
|
57329
|
+
depthTest: false,
|
|
57330
|
+
fragmentShader: smaa_weights_default,
|
|
57331
|
+
vertexShader: smaa_weights_default2
|
|
57332
|
+
});
|
|
57333
|
+
}
|
|
57334
|
+
/**
|
|
57335
|
+
* The input buffer.
|
|
57336
|
+
*
|
|
57337
|
+
* @type {Texture}
|
|
57338
|
+
*/
|
|
57339
|
+
set inputBuffer(value) {
|
|
57340
|
+
this.uniforms.inputBuffer.value = value;
|
|
57341
|
+
}
|
|
57342
|
+
/**
|
|
57343
|
+
* Sets the input buffer.
|
|
57344
|
+
*
|
|
57345
|
+
* @deprecated Use inputBuffer instead.
|
|
57346
|
+
* @param {Texture} value - The input buffer.
|
|
57347
|
+
*/
|
|
57348
|
+
setInputBuffer(value) {
|
|
57349
|
+
this.uniforms.inputBuffer.value = value;
|
|
57350
|
+
}
|
|
57351
|
+
/**
|
|
57352
|
+
* The search lookup texture.
|
|
57353
|
+
*
|
|
57354
|
+
* @type {Texture}
|
|
57355
|
+
*/
|
|
57356
|
+
get searchTexture() {
|
|
57357
|
+
return this.uniforms.searchTexture.value;
|
|
57358
|
+
}
|
|
57359
|
+
set searchTexture(value) {
|
|
57360
|
+
this.uniforms.searchTexture.value = value;
|
|
57361
|
+
}
|
|
57362
|
+
/**
|
|
57363
|
+
* The area lookup texture.
|
|
57364
|
+
*
|
|
57365
|
+
* @type {Texture}
|
|
57366
|
+
*/
|
|
57367
|
+
get areaTexture() {
|
|
57368
|
+
return this.uniforms.areaTexture.value;
|
|
57369
|
+
}
|
|
57370
|
+
set areaTexture(value) {
|
|
57371
|
+
this.uniforms.areaTexture.value = value;
|
|
57372
|
+
}
|
|
57373
|
+
/**
|
|
57374
|
+
* Sets the search and area lookup textures.
|
|
57375
|
+
*
|
|
57376
|
+
* @deprecated Use searchTexture and areaTexture instead.
|
|
57377
|
+
* @param {Texture} search - The search lookup texture.
|
|
57378
|
+
* @param {Texture} area - The area lookup texture.
|
|
57379
|
+
*/
|
|
57380
|
+
setLookupTextures(search, area2) {
|
|
57381
|
+
this.searchTexture = search;
|
|
57382
|
+
this.areaTexture = area2;
|
|
57383
|
+
}
|
|
57384
|
+
/**
|
|
57385
|
+
* The maximum amount of steps performed in the horizontal/vertical pattern searches, at each side of the pixel.
|
|
57386
|
+
* Range: [0, 112].
|
|
57387
|
+
*
|
|
57388
|
+
* In number of pixels, it's actually the double. So the maximum line length perfectly handled by, for example 16, is
|
|
57389
|
+
* 64 (perfectly means that longer lines won't look as good, but are still antialiased).
|
|
57390
|
+
*
|
|
57391
|
+
* @type {Number}
|
|
57392
|
+
*/
|
|
57393
|
+
get orthogonalSearchSteps() {
|
|
57394
|
+
return Number(this.defines.MAX_SEARCH_STEPS_INT);
|
|
57395
|
+
}
|
|
57396
|
+
set orthogonalSearchSteps(value) {
|
|
57397
|
+
const s = Math.min(Math.max(value, 0), 112);
|
|
57398
|
+
this.defines.MAX_SEARCH_STEPS_INT = s.toFixed("0");
|
|
57399
|
+
this.defines.MAX_SEARCH_STEPS_FLOAT = s.toFixed("1");
|
|
57400
|
+
this.needsUpdate = true;
|
|
57401
|
+
}
|
|
57402
|
+
/**
|
|
57403
|
+
* Sets the maximum amount of steps performed in the horizontal/vertical pattern searches, at each side of the pixel.
|
|
57404
|
+
*
|
|
57405
|
+
* @deprecated Use orthogonalSearchSteps instead.
|
|
57406
|
+
* @param {Number} value - The search steps. Range: [0, 112].
|
|
57407
|
+
*/
|
|
57408
|
+
setOrthogonalSearchSteps(value) {
|
|
57409
|
+
this.orthogonalSearchSteps = value;
|
|
57410
|
+
}
|
|
57411
|
+
/**
|
|
57412
|
+
* The maximum steps performed in the diagonal pattern searches, at each side of the pixel. This search
|
|
57413
|
+
* jumps one pixel at a time. Range: [0, 20].
|
|
57414
|
+
*
|
|
57415
|
+
* On high-end machines this search is cheap (between 0.8x and 0.9x slower for 16 steps), but it can have a
|
|
57416
|
+
* significant impact on older machines.
|
|
57417
|
+
*
|
|
57418
|
+
* @type {Number}
|
|
57419
|
+
*/
|
|
57420
|
+
get diagonalSearchSteps() {
|
|
57421
|
+
return Number(this.defines.MAX_SEARCH_STEPS_DIAG_INT);
|
|
57422
|
+
}
|
|
57423
|
+
set diagonalSearchSteps(value) {
|
|
57424
|
+
const s = Math.min(Math.max(value, 0), 20);
|
|
57425
|
+
this.defines.MAX_SEARCH_STEPS_DIAG_INT = s.toFixed("0");
|
|
57426
|
+
this.defines.MAX_SEARCH_STEPS_DIAG_FLOAT = s.toFixed("1");
|
|
57427
|
+
this.needsUpdate = true;
|
|
57428
|
+
}
|
|
57429
|
+
/**
|
|
57430
|
+
* Specifies the maximum steps performed in the diagonal pattern searches, at each side of the pixel.
|
|
57431
|
+
*
|
|
57432
|
+
* @deprecated Use diagonalSearchSteps instead.
|
|
57433
|
+
* @param {Number} value - The search steps. Range: [0, 20].
|
|
57434
|
+
*/
|
|
57435
|
+
setDiagonalSearchSteps(value) {
|
|
57436
|
+
this.diagonalSearchSteps = value;
|
|
57437
|
+
}
|
|
57438
|
+
/**
|
|
57439
|
+
* Indicates whether diagonal pattern detection is enabled.
|
|
57440
|
+
*
|
|
57441
|
+
* @type {Boolean}
|
|
57442
|
+
*/
|
|
57443
|
+
get diagonalDetection() {
|
|
57444
|
+
return this.defines.DISABLE_DIAG_DETECTION === void 0;
|
|
57445
|
+
}
|
|
57446
|
+
set diagonalDetection(value) {
|
|
57447
|
+
if (value) {
|
|
57448
|
+
delete this.defines.DISABLE_DIAG_DETECTION;
|
|
57449
|
+
} else {
|
|
57450
|
+
this.defines.DISABLE_DIAG_DETECTION = "1";
|
|
57451
|
+
}
|
|
57452
|
+
this.needsUpdate = true;
|
|
57453
|
+
}
|
|
57454
|
+
/**
|
|
57455
|
+
* Indicates whether diagonal pattern detection is enabled.
|
|
57456
|
+
*
|
|
57457
|
+
* @deprecated Use diagonalDetection instead.
|
|
57458
|
+
* @return {Boolean} Whether diagonal pattern detection is enabled.
|
|
57459
|
+
*/
|
|
57460
|
+
isDiagonalDetectionEnabled() {
|
|
57461
|
+
return this.diagonalDetection;
|
|
57462
|
+
}
|
|
57463
|
+
/**
|
|
57464
|
+
* Enables or disables diagonal pattern detection.
|
|
57465
|
+
*
|
|
57466
|
+
* @deprecated Use diagonalDetection instead.
|
|
57467
|
+
* @param {Boolean} value - Whether diagonal pattern detection should be enabled.
|
|
57468
|
+
*/
|
|
57469
|
+
setDiagonalDetectionEnabled(value) {
|
|
57470
|
+
this.diagonalDetection = value;
|
|
57471
|
+
}
|
|
57472
|
+
/**
|
|
57473
|
+
* Specifies how much sharp corners will be rounded. Range: [0, 100].
|
|
57474
|
+
*
|
|
57475
|
+
* @type {Number}
|
|
57476
|
+
*/
|
|
57477
|
+
get cornerRounding() {
|
|
57478
|
+
return Number(this.defines.CORNER_ROUNDING);
|
|
57479
|
+
}
|
|
57480
|
+
set cornerRounding(value) {
|
|
57481
|
+
const r = Math.min(Math.max(value, 0), 100);
|
|
57482
|
+
this.defines.CORNER_ROUNDING = r.toFixed("4");
|
|
57483
|
+
this.defines.CORNER_ROUNDING_NORM = (r / 100).toFixed("4");
|
|
57484
|
+
this.needsUpdate = true;
|
|
57485
|
+
}
|
|
57486
|
+
/**
|
|
57487
|
+
* Specifies how much sharp corners will be rounded.
|
|
57488
|
+
*
|
|
57489
|
+
* @deprecated Use cornerRounding instead.
|
|
57490
|
+
* @param {Number} value - The corner rounding amount. Range: [0, 100].
|
|
57491
|
+
*/
|
|
57492
|
+
setCornerRounding(value) {
|
|
57493
|
+
this.cornerRounding = value;
|
|
57494
|
+
}
|
|
57495
|
+
/**
|
|
57496
|
+
* Indicates whether corner detection is enabled.
|
|
57497
|
+
*
|
|
57498
|
+
* @type {Number}
|
|
57499
|
+
*/
|
|
57500
|
+
get cornerDetection() {
|
|
57501
|
+
return this.defines.DISABLE_CORNER_DETECTION === void 0;
|
|
57502
|
+
}
|
|
57503
|
+
set cornerDetection(value) {
|
|
57504
|
+
if (value) {
|
|
57505
|
+
delete this.defines.DISABLE_CORNER_DETECTION;
|
|
57506
|
+
} else {
|
|
57507
|
+
this.defines.DISABLE_CORNER_DETECTION = "1";
|
|
57508
|
+
}
|
|
57509
|
+
this.needsUpdate = true;
|
|
57510
|
+
}
|
|
57511
|
+
/**
|
|
57512
|
+
* Indicates whether corner rounding is enabled.
|
|
57513
|
+
*
|
|
57514
|
+
* @deprecated Use cornerDetection instead.
|
|
57515
|
+
* @return {Boolean} Whether corner rounding is enabled.
|
|
57516
|
+
*/
|
|
57517
|
+
isCornerRoundingEnabled() {
|
|
57518
|
+
return this.cornerDetection;
|
|
57519
|
+
}
|
|
57520
|
+
/**
|
|
57521
|
+
* Enables or disables corner rounding.
|
|
57522
|
+
*
|
|
57523
|
+
* @deprecated Use cornerDetection instead.
|
|
57524
|
+
* @param {Boolean} value - Whether corner rounding should be enabled.
|
|
57525
|
+
*/
|
|
57526
|
+
setCornerRoundingEnabled(value) {
|
|
57527
|
+
this.cornerDetection = value;
|
|
57528
|
+
}
|
|
57529
|
+
/**
|
|
57530
|
+
* Sets the size of this object.
|
|
57531
|
+
*
|
|
57532
|
+
* @param {Number} width - The width.
|
|
57533
|
+
* @param {Number} height - The height.
|
|
57534
|
+
*/
|
|
57535
|
+
setSize(width, height) {
|
|
57536
|
+
const uniforms = this.uniforms;
|
|
57537
|
+
uniforms.texelSize.value.set(1 / width, 1 / height);
|
|
57538
|
+
uniforms.resolution.value.set(width, height);
|
|
57539
|
+
}
|
|
57540
|
+
};
|
|
57541
|
+
var searchImageDataURL_default = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAAAQCAYAAACm53kpAAAAeElEQVRYR+2XSwqAMAxEJ168ePEqwRSKhIIiuHjJqiU0gWE+1CQdApcVAMUAuARaMGCX1MIL/Ow13++9lW2s3mW9MWvsnWc/2fvGygwPAN4E8QzAA4CXAB6AHjG4JTHYI1ey3pcx6FHnEfhLDOIBKAmUBK6/ANUDTlROXAHd9EC1AAAAAElFTkSuQmCC";
|
|
57542
|
+
var areaImageDataURL_default = "data:image/png;base64,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";
|
|
57543
|
+
var smaa_default = `uniform sampler2D weightMap;varying vec2 vOffset0;varying vec2 vOffset1;void movec(const in bvec2 c,inout vec2 variable,const in vec2 value){if(c.x){variable.x=value.x;}if(c.y){variable.y=value.y;}}void movec(const in bvec4 c,inout vec4 variable,const in vec4 value){movec(c.xy,variable.xy,value.xy);movec(c.zw,variable.zw,value.zw);}void mainImage(const in vec4 inputColor,const in vec2 uv,out vec4 outputColor){vec4 a;a.x=texture2D(weightMap,vOffset0).a;a.y=texture2D(weightMap,vOffset1).g;a.wz=texture2D(weightMap,uv).rb;vec4 color=inputColor;if(dot(a,vec4(1.0))>=1e-5){bool h=max(a.x,a.z)>max(a.y,a.w);vec4 blendingOffset=vec4(0.0,a.y,0.0,a.w);vec2 blendingWeight=a.yw;movec(bvec4(h),blendingOffset,vec4(a.x,0.0,a.z,0.0));movec(bvec2(h),blendingWeight,a.xz);blendingWeight/=dot(blendingWeight,vec2(1.0));vec4 blendingCoord=blendingOffset*vec4(texelSize,-texelSize)+uv.xyxy;color=blendingWeight.x*texture2D(inputBuffer,blendingCoord.xy);color+=blendingWeight.y*texture2D(inputBuffer,blendingCoord.zw);}outputColor=color;}`;
|
|
57544
|
+
var smaa_default2 = `varying vec2 vOffset0;varying vec2 vOffset1;void mainSupport(const in vec2 uv){vOffset0=uv+texelSize*vec2(1.0,0.0);vOffset1=uv+texelSize*vec2(0.0,1.0);}`;
|
|
57545
|
+
var SMAAEffect = class extends Effect {
|
|
57546
|
+
/**
|
|
57547
|
+
* Constructs a new SMAA effect.
|
|
57548
|
+
*
|
|
57549
|
+
* @param {Object} [options] - The options.
|
|
57550
|
+
* @param {BlendFunction} [options.blendFunction=BlendFunction.SRC] - The blend function of this effect.
|
|
57551
|
+
* @param {SMAAPreset} [options.preset=SMAAPreset.MEDIUM] - The quality preset.
|
|
57552
|
+
* @param {EdgeDetectionMode} [options.edgeDetectionMode=EdgeDetectionMode.COLOR] - The edge detection mode.
|
|
57553
|
+
* @param {PredicationMode} [options.predicationMode=PredicationMode.DISABLED] - The predication mode.
|
|
57554
|
+
*/
|
|
57555
|
+
constructor({
|
|
57556
|
+
blendFunction = BlendFunction.SRC,
|
|
57557
|
+
preset = SMAAPreset.MEDIUM,
|
|
57558
|
+
edgeDetectionMode = EdgeDetectionMode.COLOR,
|
|
57559
|
+
predicationMode = PredicationMode.DISABLED
|
|
57560
|
+
} = {}) {
|
|
57561
|
+
super("SMAAEffect", smaa_default, {
|
|
57562
|
+
vertexShader: smaa_default2,
|
|
57563
|
+
blendFunction,
|
|
57564
|
+
attributes: EffectAttribute.CONVOLUTION | EffectAttribute.DEPTH,
|
|
57565
|
+
uniforms: /* @__PURE__ */ new Map([
|
|
57566
|
+
["weightMap", new Uniform(null)]
|
|
57567
|
+
])
|
|
57568
|
+
});
|
|
57569
|
+
let searchImage, areaImage;
|
|
57570
|
+
if (arguments.length > 1) {
|
|
57571
|
+
searchImage = arguments[0];
|
|
57572
|
+
areaImage = arguments[1];
|
|
57573
|
+
if (arguments.length > 2) {
|
|
57574
|
+
preset = arguments[2];
|
|
57575
|
+
}
|
|
57576
|
+
if (arguments.length > 3) {
|
|
57577
|
+
edgeDetectionMode = arguments[3];
|
|
57578
|
+
}
|
|
57579
|
+
}
|
|
57580
|
+
this.renderTargetEdges = new WebGLRenderTarget(1, 1, { depthBuffer: false });
|
|
57581
|
+
this.renderTargetEdges.texture.name = "SMAA.Edges";
|
|
57582
|
+
this.renderTargetWeights = this.renderTargetEdges.clone();
|
|
57583
|
+
this.renderTargetWeights.texture.name = "SMAA.Weights";
|
|
57584
|
+
this.uniforms.get("weightMap").value = this.renderTargetWeights.texture;
|
|
57585
|
+
this.clearPass = new ClearPass(true, false, false);
|
|
57586
|
+
this.clearPass.overrideClearColor = new Color(0);
|
|
57587
|
+
this.clearPass.overrideClearAlpha = 1;
|
|
57588
|
+
this.edgeDetectionPass = new ShaderPass(new EdgeDetectionMaterial());
|
|
57589
|
+
this.edgeDetectionMaterial.edgeDetectionMode = edgeDetectionMode;
|
|
57590
|
+
this.edgeDetectionMaterial.predicationMode = predicationMode;
|
|
57591
|
+
this.weightsPass = new ShaderPass(new SMAAWeightsMaterial());
|
|
57592
|
+
const loadingManager = new LoadingManager();
|
|
57593
|
+
loadingManager.onLoad = () => {
|
|
57594
|
+
const searchTexture = new Texture(searchImage);
|
|
57595
|
+
searchTexture.name = "SMAA.Search";
|
|
57596
|
+
searchTexture.magFilter = NearestFilter;
|
|
57597
|
+
searchTexture.minFilter = NearestFilter;
|
|
57598
|
+
searchTexture.generateMipmaps = false;
|
|
57599
|
+
searchTexture.needsUpdate = true;
|
|
57600
|
+
searchTexture.flipY = true;
|
|
57601
|
+
this.weightsMaterial.searchTexture = searchTexture;
|
|
57602
|
+
const areaTexture = new Texture(areaImage);
|
|
57603
|
+
areaTexture.name = "SMAA.Area";
|
|
57604
|
+
areaTexture.magFilter = LinearFilter;
|
|
57605
|
+
areaTexture.minFilter = LinearFilter;
|
|
57606
|
+
areaTexture.generateMipmaps = false;
|
|
57607
|
+
areaTexture.needsUpdate = true;
|
|
57608
|
+
areaTexture.flipY = false;
|
|
57609
|
+
this.weightsMaterial.areaTexture = areaTexture;
|
|
57610
|
+
this.dispatchEvent({ type: "load" });
|
|
57611
|
+
};
|
|
57612
|
+
loadingManager.itemStart("search");
|
|
57613
|
+
loadingManager.itemStart("area");
|
|
57614
|
+
if (searchImage !== void 0 && areaImage !== void 0) {
|
|
57615
|
+
loadingManager.itemEnd("search");
|
|
57616
|
+
loadingManager.itemEnd("area");
|
|
57617
|
+
} else if (typeof Image !== "undefined") {
|
|
57618
|
+
searchImage = new Image();
|
|
57619
|
+
areaImage = new Image();
|
|
57620
|
+
searchImage.addEventListener("load", () => loadingManager.itemEnd("search"));
|
|
57621
|
+
areaImage.addEventListener("load", () => loadingManager.itemEnd("area"));
|
|
57622
|
+
searchImage.src = searchImageDataURL_default;
|
|
57623
|
+
areaImage.src = areaImageDataURL_default;
|
|
57624
|
+
}
|
|
57625
|
+
this.applyPreset(preset);
|
|
57626
|
+
}
|
|
57627
|
+
/**
|
|
57628
|
+
* The edges texture.
|
|
57629
|
+
*
|
|
57630
|
+
* @type {Texture}
|
|
57631
|
+
*/
|
|
57632
|
+
get edgesTexture() {
|
|
57633
|
+
return this.renderTargetEdges.texture;
|
|
57634
|
+
}
|
|
57635
|
+
/**
|
|
57636
|
+
* Returns the edges texture.
|
|
57637
|
+
*
|
|
57638
|
+
* @deprecated Use edgesTexture instead.
|
|
57639
|
+
* @return {Texture} The texture.
|
|
57640
|
+
*/
|
|
57641
|
+
getEdgesTexture() {
|
|
57642
|
+
return this.edgesTexture;
|
|
57643
|
+
}
|
|
57644
|
+
/**
|
|
57645
|
+
* The edge weights texture.
|
|
57646
|
+
*
|
|
57647
|
+
* @type {Texture}
|
|
57648
|
+
*/
|
|
57649
|
+
get weightsTexture() {
|
|
57650
|
+
return this.renderTargetWeights.texture;
|
|
57651
|
+
}
|
|
57652
|
+
/**
|
|
57653
|
+
* Returns the edge weights texture.
|
|
57654
|
+
*
|
|
57655
|
+
* @deprecated Use weightsTexture instead.
|
|
57656
|
+
* @return {Texture} The texture.
|
|
57657
|
+
*/
|
|
57658
|
+
getWeightsTexture() {
|
|
57659
|
+
return this.weightsTexture;
|
|
57660
|
+
}
|
|
57661
|
+
/**
|
|
57662
|
+
* The edge detection material.
|
|
57663
|
+
*
|
|
57664
|
+
* @type {EdgeDetectionMaterial}
|
|
57665
|
+
*/
|
|
57666
|
+
get edgeDetectionMaterial() {
|
|
57667
|
+
return this.edgeDetectionPass.fullscreenMaterial;
|
|
57668
|
+
}
|
|
57669
|
+
/**
|
|
57670
|
+
* The edge detection material.
|
|
57671
|
+
*
|
|
57672
|
+
* @type {EdgeDetectionMaterial}
|
|
57673
|
+
* @deprecated Use edgeDetectionMaterial instead.
|
|
57674
|
+
*/
|
|
57675
|
+
get colorEdgesMaterial() {
|
|
57676
|
+
return this.edgeDetectionMaterial;
|
|
57677
|
+
}
|
|
57678
|
+
/**
|
|
57679
|
+
* Returns the edge detection material.
|
|
57680
|
+
*
|
|
57681
|
+
* @deprecated Use edgeDetectionMaterial instead.
|
|
57682
|
+
* @return {EdgeDetectionMaterial} The material.
|
|
57683
|
+
*/
|
|
57684
|
+
getEdgeDetectionMaterial() {
|
|
57685
|
+
return this.edgeDetectionMaterial;
|
|
57686
|
+
}
|
|
57687
|
+
/**
|
|
57688
|
+
* The edge weights material.
|
|
57689
|
+
*
|
|
57690
|
+
* @type {SMAAWeightsMaterial}
|
|
57691
|
+
*/
|
|
57692
|
+
get weightsMaterial() {
|
|
57693
|
+
return this.weightsPass.fullscreenMaterial;
|
|
57694
|
+
}
|
|
57695
|
+
/**
|
|
57696
|
+
* Returns the edge weights material.
|
|
57697
|
+
*
|
|
57698
|
+
* @deprecated Use weightsMaterial instead.
|
|
57699
|
+
* @return {SMAAWeightsMaterial} The material.
|
|
57700
|
+
*/
|
|
57701
|
+
getWeightsMaterial() {
|
|
57702
|
+
return this.weightsMaterial;
|
|
57703
|
+
}
|
|
57704
|
+
/**
|
|
57705
|
+
* Sets the edge detection sensitivity.
|
|
57706
|
+
*
|
|
57707
|
+
* See {@link EdgeDetectionMaterial#setEdgeDetectionThreshold} for more details.
|
|
57708
|
+
*
|
|
57709
|
+
* @deprecated Use edgeDetectionMaterial instead.
|
|
57710
|
+
* @param {Number} threshold - The edge detection sensitivity. Range: [0.05, 0.5].
|
|
57711
|
+
*/
|
|
57712
|
+
setEdgeDetectionThreshold(threshold) {
|
|
57713
|
+
this.edgeDetectionMaterial.edgeDetectionThreshold = threshold;
|
|
57714
|
+
}
|
|
57715
|
+
/**
|
|
57716
|
+
* Sets the maximum amount of horizontal/vertical search steps.
|
|
57717
|
+
*
|
|
57718
|
+
* See {@link SMAAWeightsMaterial#setOrthogonalSearchSteps} for more details.
|
|
57719
|
+
*
|
|
57720
|
+
* @deprecated Use weightsMaterial instead.
|
|
57721
|
+
* @param {Number} steps - The search steps. Range: [0, 112].
|
|
57722
|
+
*/
|
|
57723
|
+
setOrthogonalSearchSteps(steps) {
|
|
57724
|
+
this.weightsMaterial.orthogonalSearchSteps = steps;
|
|
57725
|
+
}
|
|
57726
|
+
/**
|
|
57727
|
+
* Applies the given quality preset.
|
|
57728
|
+
*
|
|
57729
|
+
* @param {SMAAPreset} preset - The preset.
|
|
57730
|
+
*/
|
|
57731
|
+
applyPreset(preset) {
|
|
57732
|
+
const edgeDetectionMaterial = this.edgeDetectionMaterial;
|
|
57733
|
+
const weightsMaterial = this.weightsMaterial;
|
|
57734
|
+
switch (preset) {
|
|
57735
|
+
case SMAAPreset.LOW:
|
|
57736
|
+
edgeDetectionMaterial.edgeDetectionThreshold = 0.15;
|
|
57737
|
+
weightsMaterial.orthogonalSearchSteps = 4;
|
|
57738
|
+
weightsMaterial.diagonalDetection = false;
|
|
57739
|
+
weightsMaterial.cornerDetection = false;
|
|
57740
|
+
break;
|
|
57741
|
+
case SMAAPreset.MEDIUM:
|
|
57742
|
+
edgeDetectionMaterial.edgeDetectionThreshold = 0.1;
|
|
57743
|
+
weightsMaterial.orthogonalSearchSteps = 8;
|
|
57744
|
+
weightsMaterial.diagonalDetection = false;
|
|
57745
|
+
weightsMaterial.cornerDetection = false;
|
|
57746
|
+
break;
|
|
57747
|
+
case SMAAPreset.HIGH:
|
|
57748
|
+
edgeDetectionMaterial.edgeDetectionThreshold = 0.1;
|
|
57749
|
+
weightsMaterial.orthogonalSearchSteps = 16;
|
|
57750
|
+
weightsMaterial.diagonalSearchSteps = 8;
|
|
57751
|
+
weightsMaterial.cornerRounding = 25;
|
|
57752
|
+
weightsMaterial.diagonalDetection = true;
|
|
57753
|
+
weightsMaterial.cornerDetection = true;
|
|
57754
|
+
break;
|
|
57755
|
+
case SMAAPreset.ULTRA:
|
|
57756
|
+
edgeDetectionMaterial.edgeDetectionThreshold = 0.05;
|
|
57757
|
+
weightsMaterial.orthogonalSearchSteps = 32;
|
|
57758
|
+
weightsMaterial.diagonalSearchSteps = 16;
|
|
57759
|
+
weightsMaterial.cornerRounding = 25;
|
|
57760
|
+
weightsMaterial.diagonalDetection = true;
|
|
57761
|
+
weightsMaterial.cornerDetection = true;
|
|
57762
|
+
break;
|
|
57763
|
+
}
|
|
57764
|
+
}
|
|
57765
|
+
/**
|
|
57766
|
+
* Sets the depth texture.
|
|
57767
|
+
*
|
|
57768
|
+
* @param {Texture} depthTexture - A depth texture.
|
|
57769
|
+
* @param {DepthPackingStrategies} [depthPacking=BasicDepthPacking] - The depth packing.
|
|
57770
|
+
*/
|
|
57771
|
+
setDepthTexture(depthTexture, depthPacking = BasicDepthPacking) {
|
|
57772
|
+
this.edgeDetectionMaterial.depthBuffer = depthTexture;
|
|
57773
|
+
this.edgeDetectionMaterial.depthPacking = depthPacking;
|
|
57774
|
+
}
|
|
57775
|
+
/**
|
|
57776
|
+
* Updates this effect.
|
|
57777
|
+
*
|
|
57778
|
+
* @param {WebGLRenderer} renderer - The renderer.
|
|
57779
|
+
* @param {WebGLRenderTarget} inputBuffer - A frame buffer that contains the result of the previous pass.
|
|
57780
|
+
* @param {Number} [deltaTime] - The time between the last frame and the current one in seconds.
|
|
57781
|
+
*/
|
|
57782
|
+
update(renderer, inputBuffer, deltaTime) {
|
|
57783
|
+
this.clearPass.render(renderer, this.renderTargetEdges);
|
|
57784
|
+
this.edgeDetectionPass.render(renderer, inputBuffer, this.renderTargetEdges);
|
|
57785
|
+
this.weightsPass.render(renderer, this.renderTargetEdges, this.renderTargetWeights);
|
|
57786
|
+
}
|
|
57787
|
+
/**
|
|
57788
|
+
* Updates the size of internal render targets.
|
|
57789
|
+
*
|
|
57790
|
+
* @param {Number} width - The width.
|
|
57791
|
+
* @param {Number} height - The height.
|
|
57792
|
+
*/
|
|
57793
|
+
setSize(width, height) {
|
|
57794
|
+
this.edgeDetectionMaterial.setSize(width, height);
|
|
57795
|
+
this.weightsMaterial.setSize(width, height);
|
|
57796
|
+
this.renderTargetEdges.setSize(width, height);
|
|
57797
|
+
this.renderTargetWeights.setSize(width, height);
|
|
57798
|
+
}
|
|
57799
|
+
/**
|
|
57800
|
+
* Deletes internal render targets and textures.
|
|
57801
|
+
*/
|
|
57802
|
+
dispose() {
|
|
57803
|
+
const { searchTexture, areaTexture } = this.weightsMaterial;
|
|
57804
|
+
if (searchTexture !== null && areaTexture !== null) {
|
|
57805
|
+
searchTexture.dispose();
|
|
57806
|
+
areaTexture.dispose();
|
|
57807
|
+
}
|
|
57808
|
+
super.dispose();
|
|
57809
|
+
}
|
|
57810
|
+
/**
|
|
57811
|
+
* The SMAA search image, encoded as a base64 data URL.
|
|
57812
|
+
*
|
|
57813
|
+
* @type {String}
|
|
57814
|
+
* @deprecated
|
|
57815
|
+
*/
|
|
57816
|
+
static get searchImageDataURL() {
|
|
57817
|
+
return searchImageDataURL_default;
|
|
57818
|
+
}
|
|
57819
|
+
/**
|
|
57820
|
+
* The SMAA area image, encoded as a base64 data URL.
|
|
57821
|
+
*
|
|
57822
|
+
* @type {String}
|
|
57823
|
+
* @deprecated
|
|
57824
|
+
*/
|
|
57825
|
+
static get areaImageDataURL() {
|
|
57826
|
+
return areaImageDataURL_default;
|
|
57827
|
+
}
|
|
57828
|
+
};
|
|
56728
57829
|
var effect_default = `#include <common>
|
|
56729
57830
|
#include <packing>
|
|
56730
57831
|
#include <dithering_pars_fragment>
|
|
@@ -57369,6 +58470,2282 @@ var EffectPass = class extends Pass {
|
|
|
57369
58470
|
}
|
|
57370
58471
|
}
|
|
57371
58472
|
};
|
|
58473
|
+
function $parcel$interopDefault(a) {
|
|
58474
|
+
return a && a.__esModule ? a.default : a;
|
|
58475
|
+
}
|
|
58476
|
+
class $e4ca8dcb0218f846$var$FullScreenTriangleGeometry extends BufferGeometry {
|
|
58477
|
+
boundingSphere = new Sphere();
|
|
58478
|
+
constructor() {
|
|
58479
|
+
super();
|
|
58480
|
+
this.setAttribute("position", new BufferAttribute(new Float32Array([
|
|
58481
|
+
-1,
|
|
58482
|
+
-1,
|
|
58483
|
+
3,
|
|
58484
|
+
-1,
|
|
58485
|
+
-1,
|
|
58486
|
+
3
|
|
58487
|
+
]), 2));
|
|
58488
|
+
this.setAttribute("uv", new BufferAttribute(new Float32Array([
|
|
58489
|
+
0,
|
|
58490
|
+
0,
|
|
58491
|
+
2,
|
|
58492
|
+
0,
|
|
58493
|
+
0,
|
|
58494
|
+
2
|
|
58495
|
+
]), 2));
|
|
58496
|
+
}
|
|
58497
|
+
computeBoundingSphere() {
|
|
58498
|
+
}
|
|
58499
|
+
}
|
|
58500
|
+
const $e4ca8dcb0218f846$var$_geometry = /* @__PURE__ */ new $e4ca8dcb0218f846$var$FullScreenTriangleGeometry();
|
|
58501
|
+
const $e4ca8dcb0218f846$var$_camera = /* @__PURE__ */ new OrthographicCamera();
|
|
58502
|
+
class $e4ca8dcb0218f846$export$dcd670d73db751f5 {
|
|
58503
|
+
constructor(material) {
|
|
58504
|
+
this._mesh = new Mesh($e4ca8dcb0218f846$var$_geometry, material);
|
|
58505
|
+
this._mesh.frustumCulled = false;
|
|
58506
|
+
}
|
|
58507
|
+
render(renderer) {
|
|
58508
|
+
renderer.render(this._mesh, $e4ca8dcb0218f846$var$_camera);
|
|
58509
|
+
}
|
|
58510
|
+
get material() {
|
|
58511
|
+
return this._mesh.material;
|
|
58512
|
+
}
|
|
58513
|
+
set material(value) {
|
|
58514
|
+
this._mesh.material = value;
|
|
58515
|
+
}
|
|
58516
|
+
dispose() {
|
|
58517
|
+
this._mesh.material.dispose();
|
|
58518
|
+
this._mesh.geometry.dispose();
|
|
58519
|
+
}
|
|
58520
|
+
}
|
|
58521
|
+
const $1ed45968c1160c3c$export$c9b263b9a17dffd7 = {
|
|
58522
|
+
uniforms: {
|
|
58523
|
+
"sceneDiffuse": {
|
|
58524
|
+
value: null
|
|
58525
|
+
},
|
|
58526
|
+
"sceneDepth": {
|
|
58527
|
+
value: null
|
|
58528
|
+
},
|
|
58529
|
+
"sceneNormal": {
|
|
58530
|
+
value: null
|
|
58531
|
+
},
|
|
58532
|
+
"projMat": {
|
|
58533
|
+
value: /* @__PURE__ */ new Matrix4()
|
|
58534
|
+
},
|
|
58535
|
+
"viewMat": {
|
|
58536
|
+
value: /* @__PURE__ */ new Matrix4()
|
|
58537
|
+
},
|
|
58538
|
+
"projViewMat": {
|
|
58539
|
+
value: /* @__PURE__ */ new Matrix4()
|
|
58540
|
+
},
|
|
58541
|
+
"projectionMatrixInv": {
|
|
58542
|
+
value: /* @__PURE__ */ new Matrix4()
|
|
58543
|
+
},
|
|
58544
|
+
"viewMatrixInv": {
|
|
58545
|
+
value: /* @__PURE__ */ new Matrix4()
|
|
58546
|
+
},
|
|
58547
|
+
"cameraPos": {
|
|
58548
|
+
value: /* @__PURE__ */ new Vector3$1()
|
|
58549
|
+
},
|
|
58550
|
+
"resolution": {
|
|
58551
|
+
value: /* @__PURE__ */ new Vector2$1()
|
|
58552
|
+
},
|
|
58553
|
+
"biasAdjustment": {
|
|
58554
|
+
value: /* @__PURE__ */ new Vector2$1()
|
|
58555
|
+
},
|
|
58556
|
+
"time": {
|
|
58557
|
+
value: 0
|
|
58558
|
+
},
|
|
58559
|
+
"samples": {
|
|
58560
|
+
value: []
|
|
58561
|
+
},
|
|
58562
|
+
"bluenoise": {
|
|
58563
|
+
value: null
|
|
58564
|
+
},
|
|
58565
|
+
"distanceFalloff": {
|
|
58566
|
+
value: 1
|
|
58567
|
+
},
|
|
58568
|
+
"radius": {
|
|
58569
|
+
value: 5
|
|
58570
|
+
},
|
|
58571
|
+
"near": {
|
|
58572
|
+
value: 0.1
|
|
58573
|
+
},
|
|
58574
|
+
"far": {
|
|
58575
|
+
value: 1e3
|
|
58576
|
+
},
|
|
58577
|
+
"ortho": {
|
|
58578
|
+
value: false
|
|
58579
|
+
},
|
|
58580
|
+
"screenSpaceRadius": {
|
|
58581
|
+
value: false
|
|
58582
|
+
},
|
|
58583
|
+
"frame": {
|
|
58584
|
+
value: 0
|
|
58585
|
+
}
|
|
58586
|
+
},
|
|
58587
|
+
depthWrite: false,
|
|
58588
|
+
depthTest: false,
|
|
58589
|
+
vertexShader: (
|
|
58590
|
+
/* glsl */
|
|
58591
|
+
`
|
|
58592
|
+
varying vec2 vUv;
|
|
58593
|
+
void main() {
|
|
58594
|
+
vUv = uv;
|
|
58595
|
+
gl_Position = vec4(position, 1);
|
|
58596
|
+
}`
|
|
58597
|
+
),
|
|
58598
|
+
fragmentShader: (
|
|
58599
|
+
/* glsl */
|
|
58600
|
+
`
|
|
58601
|
+
#define SAMPLES 16
|
|
58602
|
+
#define FSAMPLES 16.0
|
|
58603
|
+
uniform sampler2D sceneDiffuse;
|
|
58604
|
+
uniform highp sampler2D sceneNormal;
|
|
58605
|
+
uniform highp sampler2D sceneDepth;
|
|
58606
|
+
uniform mat4 projectionMatrixInv;
|
|
58607
|
+
uniform mat4 viewMatrixInv;
|
|
58608
|
+
uniform mat4 projMat;
|
|
58609
|
+
uniform mat4 viewMat;
|
|
58610
|
+
uniform mat4 projViewMat;
|
|
58611
|
+
uniform vec3 cameraPos;
|
|
58612
|
+
uniform vec2 resolution;
|
|
58613
|
+
uniform vec2 biasAdjustment;
|
|
58614
|
+
uniform float time;
|
|
58615
|
+
uniform vec3[SAMPLES] samples;
|
|
58616
|
+
uniform float radius;
|
|
58617
|
+
uniform float distanceFalloff;
|
|
58618
|
+
uniform float near;
|
|
58619
|
+
uniform float far;
|
|
58620
|
+
uniform float frame;
|
|
58621
|
+
uniform bool ortho;
|
|
58622
|
+
uniform bool screenSpaceRadius;
|
|
58623
|
+
uniform sampler2D bluenoise;
|
|
58624
|
+
varying vec2 vUv;
|
|
58625
|
+
highp float linearize_depth(highp float d, highp float zNear,highp float zFar)
|
|
58626
|
+
{
|
|
58627
|
+
return (zFar * zNear) / (zFar - d * (zFar - zNear));
|
|
58628
|
+
}
|
|
58629
|
+
highp float linearize_depth_ortho(highp float d, highp float nearZ, highp float farZ) {
|
|
58630
|
+
return nearZ + (farZ - nearZ) * d;
|
|
58631
|
+
}
|
|
58632
|
+
highp float linearize_depth_log(highp float d, highp float nearZ,highp float farZ) {
|
|
58633
|
+
float depth = pow(2.0, d * log2(farZ + 1.0)) - 1.0;
|
|
58634
|
+
float a = farZ / (farZ - nearZ);
|
|
58635
|
+
float b = farZ * nearZ / (nearZ - farZ);
|
|
58636
|
+
float linDepth = a + b / depth;
|
|
58637
|
+
/*return ortho ? linearize_depth_ortho(
|
|
58638
|
+
linDepth,
|
|
58639
|
+
nearZ,
|
|
58640
|
+
farZ
|
|
58641
|
+
) :linearize_depth(linDepth, nearZ, farZ);*/
|
|
58642
|
+
#ifdef ORTHO
|
|
58643
|
+
|
|
58644
|
+
return linearize_depth_ortho(d, nearZ, farZ);
|
|
58645
|
+
|
|
58646
|
+
#else
|
|
58647
|
+
return linearize_depth(linDepth, nearZ, farZ);
|
|
58648
|
+
#endif
|
|
58649
|
+
}
|
|
58650
|
+
|
|
58651
|
+
vec3 getWorldPosLog(vec3 posS) {
|
|
58652
|
+
vec2 uv = posS.xy;
|
|
58653
|
+
float z = posS.z;
|
|
58654
|
+
float nearZ =near;
|
|
58655
|
+
float farZ = far;
|
|
58656
|
+
float depth = pow(2.0, z * log2(farZ + 1.0)) - 1.0;
|
|
58657
|
+
float a = farZ / (farZ - nearZ);
|
|
58658
|
+
float b = farZ * nearZ / (nearZ - farZ);
|
|
58659
|
+
float linDepth = a + b / depth;
|
|
58660
|
+
vec4 clipVec = vec4(uv, linDepth, 1.0) * 2.0 - 1.0;
|
|
58661
|
+
vec4 wpos = projectionMatrixInv * clipVec;
|
|
58662
|
+
return wpos.xyz / wpos.w;
|
|
58663
|
+
}
|
|
58664
|
+
float depthToClipZ(float depth) {
|
|
58665
|
+
#ifdef REVERSEDEPTH
|
|
58666
|
+
return depth;
|
|
58667
|
+
#else
|
|
58668
|
+
return depth * 2.0 - 1.0;
|
|
58669
|
+
#endif
|
|
58670
|
+
}
|
|
58671
|
+
bool isBackgroundDepth(float depth) {
|
|
58672
|
+
#ifdef REVERSEDEPTH
|
|
58673
|
+
return depth == 0.0;
|
|
58674
|
+
#else
|
|
58675
|
+
return depth == 1.0;
|
|
58676
|
+
#endif
|
|
58677
|
+
}
|
|
58678
|
+
vec3 getWorldPos(float depth, vec2 coord) {
|
|
58679
|
+
#ifdef LOGDEPTH
|
|
58680
|
+
#ifndef ORTHO
|
|
58681
|
+
return getWorldPosLog(vec3(coord, depth));
|
|
58682
|
+
#endif
|
|
58683
|
+
#endif
|
|
58684
|
+
#ifdef ORTHO
|
|
58685
|
+
float z = depthToClipZ(depth);
|
|
58686
|
+
vec4 clipSpacePosition = vec4(coord * 2. - 1., z, 1.);
|
|
58687
|
+
vec4 viewSpacePosition = projectionMatrixInv * clipSpacePosition;
|
|
58688
|
+
viewSpacePosition.xyz /= viewSpacePosition.w;
|
|
58689
|
+
return viewSpacePosition.xyz;
|
|
58690
|
+
#else
|
|
58691
|
+
vec2 ndc = coord * 2. - 1.;
|
|
58692
|
+
float ndcZ = depthToClipZ(depth);
|
|
58693
|
+
mat4 Q = projectionMatrixInv;
|
|
58694
|
+
vec3 view = vec3(Q[0][0] * ndc.x + Q[3][0], Q[1][1] * ndc.y + Q[3][1], Q[3][2]);
|
|
58695
|
+
float invW = 1. / (Q[2][3] * ndcZ + Q[3][3]);
|
|
58696
|
+
return view * invW;
|
|
58697
|
+
#endif
|
|
58698
|
+
}
|
|
58699
|
+
|
|
58700
|
+
vec3 computeNormal(vec3 worldPos, vec2 vUv) {
|
|
58701
|
+
ivec2 p = ivec2(vUv * resolution);
|
|
58702
|
+
float c0 = texelFetch(sceneDepth, p, 0).x;
|
|
58703
|
+
float l2 = texelFetch(sceneDepth, p - ivec2(2, 0), 0).x;
|
|
58704
|
+
float l1 = texelFetch(sceneDepth, p - ivec2(1, 0), 0).x;
|
|
58705
|
+
float r1 = texelFetch(sceneDepth, p + ivec2(1, 0), 0).x;
|
|
58706
|
+
float r2 = texelFetch(sceneDepth, p + ivec2(2, 0), 0).x;
|
|
58707
|
+
float b2 = texelFetch(sceneDepth, p - ivec2(0, 2), 0).x;
|
|
58708
|
+
float b1 = texelFetch(sceneDepth, p - ivec2(0, 1), 0).x;
|
|
58709
|
+
float t1 = texelFetch(sceneDepth, p + ivec2(0, 1), 0).x;
|
|
58710
|
+
float t2 = texelFetch(sceneDepth, p + ivec2(0, 2), 0).x;
|
|
58711
|
+
|
|
58712
|
+
float dl = abs((2.0 * l1 - l2) - c0);
|
|
58713
|
+
float dr = abs((2.0 * r1 - r2) - c0);
|
|
58714
|
+
float db = abs((2.0 * b1 - b2) - c0);
|
|
58715
|
+
float dt = abs((2.0 * t1 - t2) - c0);
|
|
58716
|
+
|
|
58717
|
+
vec3 ce = getWorldPos(c0, vUv).xyz;
|
|
58718
|
+
|
|
58719
|
+
vec3 dpdx = (dl < dr) ? ce - getWorldPos(l1, (vUv - vec2(1.0 / resolution.x, 0.0))).xyz
|
|
58720
|
+
: -ce + getWorldPos(r1, (vUv + vec2(1.0 / resolution.x, 0.0))).xyz;
|
|
58721
|
+
vec3 dpdy = (db < dt) ? ce - getWorldPos(b1, (vUv - vec2(0.0, 1.0 / resolution.y))).xyz
|
|
58722
|
+
: -ce + getWorldPos(t1, (vUv + vec2(0.0, 1.0 / resolution.y))).xyz;
|
|
58723
|
+
|
|
58724
|
+
return normalize(cross(dpdx, dpdy));
|
|
58725
|
+
}
|
|
58726
|
+
|
|
58727
|
+
mat3 makeRotationZ(float theta) {
|
|
58728
|
+
float c = cos(theta);
|
|
58729
|
+
float s = sin(theta);
|
|
58730
|
+
return mat3(c, - s, 0,
|
|
58731
|
+
s, c, 0,
|
|
58732
|
+
0, 0, 1);
|
|
58733
|
+
}
|
|
58734
|
+
|
|
58735
|
+
void main() {
|
|
58736
|
+
vec4 diffuse = texture2D(sceneDiffuse, vUv);
|
|
58737
|
+
float depth = texture2D(sceneDepth, vUv).x;
|
|
58738
|
+
if (isBackgroundDepth(depth)) {
|
|
58739
|
+
gl_FragColor = vec4(vec3(1.0), 1.0);
|
|
58740
|
+
return;
|
|
58741
|
+
}
|
|
58742
|
+
vec3 worldPos = getWorldPos(depth, vUv);
|
|
58743
|
+
#ifdef HALFRES
|
|
58744
|
+
vec3 normal = texture2D(sceneNormal, vUv).rgb;
|
|
58745
|
+
#else
|
|
58746
|
+
vec3 normal = computeNormal(worldPos, vUv);
|
|
58747
|
+
#endif
|
|
58748
|
+
vec4 noise = texture2D(bluenoise, gl_FragCoord.xy / 128.0);
|
|
58749
|
+
vec2 harmoniousNumbers = vec2(
|
|
58750
|
+
1.618033988749895,
|
|
58751
|
+
1.324717957244746
|
|
58752
|
+
);
|
|
58753
|
+
noise.rg += harmoniousNumbers * frame;
|
|
58754
|
+
noise.rg = fract(noise.rg);
|
|
58755
|
+
vec3 helperVec = vec3(0.0, 1.0, 0.0);
|
|
58756
|
+
if (dot(helperVec, normal) > 0.99) {
|
|
58757
|
+
helperVec = vec3(1.0, 0.0, 0.0);
|
|
58758
|
+
}
|
|
58759
|
+
vec3 tangent = normalize(cross(helperVec, normal));
|
|
58760
|
+
vec3 bitangent = cross(normal, tangent);
|
|
58761
|
+
mediump mat3 tbn = mat3(tangent, bitangent, normal) * makeRotationZ( noise.r * 3.1415962 * 2.0) ;
|
|
58762
|
+
|
|
58763
|
+
mediump float occluded = 0.0;
|
|
58764
|
+
mediump float totalWeight = 0.0;
|
|
58765
|
+
float radiusToUse = screenSpaceRadius ? distance(
|
|
58766
|
+
worldPos,
|
|
58767
|
+
getWorldPos(depth, vUv +
|
|
58768
|
+
vec2(radius, 0.0) / resolution)
|
|
58769
|
+
) : radius;
|
|
58770
|
+
float distanceFalloffToUse =screenSpaceRadius ?
|
|
58771
|
+
radiusToUse * distanceFalloff
|
|
58772
|
+
: radiusToUse * distanceFalloff * 0.2;
|
|
58773
|
+
float bias = (min(
|
|
58774
|
+
0.1,
|
|
58775
|
+
distanceFalloffToUse * 0.1
|
|
58776
|
+
) / near) * fwidth(distance(worldPos, cameraPos)) / radiusToUse;
|
|
58777
|
+
bias = biasAdjustment.x + biasAdjustment.y * bias;
|
|
58778
|
+
mediump float offsetMove = noise.g;
|
|
58779
|
+
mediump float offsetMoveInv = 1.0 / FSAMPLES;
|
|
58780
|
+
float farTimesNear = far * near;
|
|
58781
|
+
float farMinusNear = far - near;
|
|
58782
|
+
|
|
58783
|
+
for(int i = 0; i < SAMPLES; i++) {
|
|
58784
|
+
mediump vec3 sampleDirection = tbn * samples[i];
|
|
58785
|
+
|
|
58786
|
+
float moveAmt = fract(offsetMove);
|
|
58787
|
+
offsetMove += offsetMoveInv;
|
|
58788
|
+
vec3 samplePos = worldPos + radiusToUse * moveAmt * sampleDirection;
|
|
58789
|
+
vec4 offset = projMat * vec4(samplePos, 1.0);
|
|
58790
|
+
offset.xyz /= offset.w;
|
|
58791
|
+
offset.xy = offset.xy * 0.5 + 0.5;
|
|
58792
|
+
#ifndef REVERSEDEPTH
|
|
58793
|
+
offset.z = offset.z * 0.5 + 0.5;
|
|
58794
|
+
#endif
|
|
58795
|
+
|
|
58796
|
+
if (all(greaterThan(offset.xyz * (1.0 - offset.xyz), vec3(0.0)))) {
|
|
58797
|
+
float sampleDepth = textureLod(sceneDepth, offset.xy, 0.0).x;
|
|
58798
|
+
|
|
58799
|
+
/*#ifdef LOGDEPTH
|
|
58800
|
+
float distSample = linearize_depth_log(sampleDepth, near, far);
|
|
58801
|
+
#else
|
|
58802
|
+
#ifdef ORTHO
|
|
58803
|
+
float distSample = near + farMinusNear * sampleDepth;
|
|
58804
|
+
#else
|
|
58805
|
+
float distSample = (farTimesNear) / (far - sampleDepth * farMinusNear);
|
|
58806
|
+
#endif
|
|
58807
|
+
#endif*/
|
|
58808
|
+
#ifdef REVERSEDEPTH
|
|
58809
|
+
float distSample = -getWorldPos(sampleDepth, offset.xy).z;
|
|
58810
|
+
#else
|
|
58811
|
+
#ifdef ORTHO
|
|
58812
|
+
float distSample = near + sampleDepth * farMinusNear;
|
|
58813
|
+
#else
|
|
58814
|
+
#ifdef LOGDEPTH
|
|
58815
|
+
float distSample = linearize_depth_log(sampleDepth, near, far);
|
|
58816
|
+
#else
|
|
58817
|
+
float distSample = (farTimesNear) / (far - sampleDepth * farMinusNear);
|
|
58818
|
+
#endif
|
|
58819
|
+
#endif
|
|
58820
|
+
#endif
|
|
58821
|
+
|
|
58822
|
+
#ifdef REVERSEDEPTH
|
|
58823
|
+
float distWorld = -samplePos.z;
|
|
58824
|
+
#else
|
|
58825
|
+
#ifdef ORTHO
|
|
58826
|
+
float distWorld = near + offset.z * farMinusNear;
|
|
58827
|
+
#else
|
|
58828
|
+
float distWorld = (farTimesNear) / (far - offset.z * farMinusNear);
|
|
58829
|
+
#endif
|
|
58830
|
+
#endif
|
|
58831
|
+
|
|
58832
|
+
mediump float rangeCheck = smoothstep(0.0, 1.0, distanceFalloffToUse / (abs(distSample - distWorld)));
|
|
58833
|
+
vec2 diff = gl_FragCoord.xy - floor(offset.xy * resolution);
|
|
58834
|
+
occluded += rangeCheck * float(distSample != distWorld) * float(sampleDepth != depth) * step(distSample + bias, distWorld) * step(
|
|
58835
|
+
1.0,
|
|
58836
|
+
dot(diff, diff)
|
|
58837
|
+
);
|
|
58838
|
+
|
|
58839
|
+
totalWeight ++;
|
|
58840
|
+
}
|
|
58841
|
+
}
|
|
58842
|
+
float occ = clamp(1.0 - occluded / (totalWeight == 0.0 ? 1.0 : totalWeight), 0.0, 1.0);
|
|
58843
|
+
gl_FragColor = vec4(occ, 0.5 + 0.5 * normal);
|
|
58844
|
+
}`
|
|
58845
|
+
)
|
|
58846
|
+
};
|
|
58847
|
+
const $12b21d24d1192a04$export$a815acccbd2c9a49 = {
|
|
58848
|
+
uniforms: {
|
|
58849
|
+
"sceneDiffuse": {
|
|
58850
|
+
value: null
|
|
58851
|
+
},
|
|
58852
|
+
"sceneDepth": {
|
|
58853
|
+
value: null
|
|
58854
|
+
},
|
|
58855
|
+
"tDiffuse": {
|
|
58856
|
+
value: null
|
|
58857
|
+
},
|
|
58858
|
+
"transparencyDWFalse": {
|
|
58859
|
+
value: null
|
|
58860
|
+
},
|
|
58861
|
+
"transparencyDWTrue": {
|
|
58862
|
+
value: null
|
|
58863
|
+
},
|
|
58864
|
+
"transparencyDWTrueDepth": {
|
|
58865
|
+
value: null
|
|
58866
|
+
},
|
|
58867
|
+
"transparencyAware": {
|
|
58868
|
+
value: false
|
|
58869
|
+
},
|
|
58870
|
+
"projMat": {
|
|
58871
|
+
value: /* @__PURE__ */ new Matrix4()
|
|
58872
|
+
},
|
|
58873
|
+
"viewMat": {
|
|
58874
|
+
value: /* @__PURE__ */ new Matrix4()
|
|
58875
|
+
},
|
|
58876
|
+
"projectionMatrixInv": {
|
|
58877
|
+
value: /* @__PURE__ */ new Matrix4()
|
|
58878
|
+
},
|
|
58879
|
+
"resolution": {
|
|
58880
|
+
value: /* @__PURE__ */ new Vector2$1()
|
|
58881
|
+
},
|
|
58882
|
+
"color": {
|
|
58883
|
+
value: /* @__PURE__ */ new Vector3$1(0, 0, 0)
|
|
58884
|
+
},
|
|
58885
|
+
"blueNoise": {
|
|
58886
|
+
value: null
|
|
58887
|
+
},
|
|
58888
|
+
"downsampledDepth": {
|
|
58889
|
+
value: null
|
|
58890
|
+
},
|
|
58891
|
+
"time": {
|
|
58892
|
+
value: 0
|
|
58893
|
+
},
|
|
58894
|
+
"intensity": {
|
|
58895
|
+
value: 10
|
|
58896
|
+
},
|
|
58897
|
+
"renderMode": {
|
|
58898
|
+
value: 0
|
|
58899
|
+
},
|
|
58900
|
+
"gammaCorrection": {
|
|
58901
|
+
value: false
|
|
58902
|
+
},
|
|
58903
|
+
"ortho": {
|
|
58904
|
+
value: false
|
|
58905
|
+
},
|
|
58906
|
+
"near": {
|
|
58907
|
+
value: 0.1
|
|
58908
|
+
},
|
|
58909
|
+
"far": {
|
|
58910
|
+
value: 1e3
|
|
58911
|
+
},
|
|
58912
|
+
"screenSpaceRadius": {
|
|
58913
|
+
value: false
|
|
58914
|
+
},
|
|
58915
|
+
"radius": {
|
|
58916
|
+
value: 0
|
|
58917
|
+
},
|
|
58918
|
+
"distanceFalloff": {
|
|
58919
|
+
value: 1
|
|
58920
|
+
},
|
|
58921
|
+
"fog": {
|
|
58922
|
+
value: false
|
|
58923
|
+
},
|
|
58924
|
+
"fogExp": {
|
|
58925
|
+
value: false
|
|
58926
|
+
},
|
|
58927
|
+
"fogDensity": {
|
|
58928
|
+
value: 0
|
|
58929
|
+
},
|
|
58930
|
+
"fogNear": {
|
|
58931
|
+
value: Infinity
|
|
58932
|
+
},
|
|
58933
|
+
"fogFar": {
|
|
58934
|
+
value: Infinity
|
|
58935
|
+
},
|
|
58936
|
+
"colorMultiply": {
|
|
58937
|
+
value: true
|
|
58938
|
+
},
|
|
58939
|
+
"aoTones": {
|
|
58940
|
+
value: 0
|
|
58941
|
+
}
|
|
58942
|
+
},
|
|
58943
|
+
depthWrite: false,
|
|
58944
|
+
depthTest: false,
|
|
58945
|
+
vertexShader: (
|
|
58946
|
+
/* glsl */
|
|
58947
|
+
`
|
|
58948
|
+
varying vec2 vUv;
|
|
58949
|
+
void main() {
|
|
58950
|
+
vUv = uv;
|
|
58951
|
+
gl_Position = vec4(position, 1);
|
|
58952
|
+
}`
|
|
58953
|
+
),
|
|
58954
|
+
fragmentShader: (
|
|
58955
|
+
/* glsl */
|
|
58956
|
+
`
|
|
58957
|
+
uniform sampler2D sceneDiffuse;
|
|
58958
|
+
uniform highp sampler2D sceneDepth;
|
|
58959
|
+
uniform highp sampler2D downsampledDepth;
|
|
58960
|
+
uniform highp sampler2D transparencyDWFalse;
|
|
58961
|
+
uniform highp sampler2D transparencyDWTrue;
|
|
58962
|
+
uniform highp sampler2D transparencyDWTrueDepth;
|
|
58963
|
+
uniform sampler2D tDiffuse;
|
|
58964
|
+
uniform sampler2D blueNoise;
|
|
58965
|
+
uniform vec2 resolution;
|
|
58966
|
+
uniform vec3 color;
|
|
58967
|
+
uniform mat4 projectionMatrixInv;
|
|
58968
|
+
uniform float intensity;
|
|
58969
|
+
uniform float renderMode;
|
|
58970
|
+
uniform float near;
|
|
58971
|
+
uniform float far;
|
|
58972
|
+
uniform float aoTones;
|
|
58973
|
+
uniform bool gammaCorrection;
|
|
58974
|
+
uniform bool ortho;
|
|
58975
|
+
uniform bool screenSpaceRadius;
|
|
58976
|
+
uniform bool fog;
|
|
58977
|
+
uniform bool fogExp;
|
|
58978
|
+
uniform bool colorMultiply;
|
|
58979
|
+
uniform bool transparencyAware;
|
|
58980
|
+
uniform float fogDensity;
|
|
58981
|
+
uniform float fogNear;
|
|
58982
|
+
uniform float fogFar;
|
|
58983
|
+
uniform float radius;
|
|
58984
|
+
uniform float distanceFalloff;
|
|
58985
|
+
varying vec2 vUv;
|
|
58986
|
+
highp float linearize_depth(highp float d, highp float zNear,highp float zFar)
|
|
58987
|
+
{
|
|
58988
|
+
return (zFar * zNear) / (zFar - d * (zFar - zNear));
|
|
58989
|
+
}
|
|
58990
|
+
highp float linearize_depth_ortho(highp float d, highp float nearZ, highp float farZ) {
|
|
58991
|
+
return nearZ + (farZ - nearZ) * d;
|
|
58992
|
+
}
|
|
58993
|
+
highp float linearize_depth_log(highp float d, highp float nearZ,highp float farZ) {
|
|
58994
|
+
float depth = pow(2.0, d * log2(farZ + 1.0)) - 1.0;
|
|
58995
|
+
float a = farZ / (farZ - nearZ);
|
|
58996
|
+
float b = farZ * nearZ / (nearZ - farZ);
|
|
58997
|
+
float linDepth = a + b / depth;
|
|
58998
|
+
return ortho ? linearize_depth_ortho(
|
|
58999
|
+
linDepth,
|
|
59000
|
+
nearZ,
|
|
59001
|
+
farZ
|
|
59002
|
+
) :linearize_depth(linDepth, nearZ, farZ);
|
|
59003
|
+
}
|
|
59004
|
+
vec3 getWorldPosLog(vec3 posS) {
|
|
59005
|
+
vec2 uv = posS.xy;
|
|
59006
|
+
float z = posS.z;
|
|
59007
|
+
float nearZ =near;
|
|
59008
|
+
float farZ = far;
|
|
59009
|
+
float depth = pow(2.0, z * log2(farZ + 1.0)) - 1.0;
|
|
59010
|
+
float a = farZ / (farZ - nearZ);
|
|
59011
|
+
float b = farZ * nearZ / (nearZ - farZ);
|
|
59012
|
+
float linDepth = a + b / depth;
|
|
59013
|
+
vec4 clipVec = vec4(uv, linDepth, 1.0) * 2.0 - 1.0;
|
|
59014
|
+
vec4 wpos = projectionMatrixInv * clipVec;
|
|
59015
|
+
return wpos.xyz / wpos.w;
|
|
59016
|
+
}
|
|
59017
|
+
float depthToClipZ(float depth) {
|
|
59018
|
+
#ifdef REVERSEDEPTH
|
|
59019
|
+
return depth;
|
|
59020
|
+
#else
|
|
59021
|
+
return depth * 2.0 - 1.0;
|
|
59022
|
+
#endif
|
|
59023
|
+
}
|
|
59024
|
+
bool isBackgroundDepth(float depth) {
|
|
59025
|
+
#ifdef REVERSEDEPTH
|
|
59026
|
+
return depth == 0.0;
|
|
59027
|
+
#else
|
|
59028
|
+
return depth == 1.0;
|
|
59029
|
+
#endif
|
|
59030
|
+
}
|
|
59031
|
+
vec3 getWorldPos(float depth, vec2 coord) {
|
|
59032
|
+
#ifdef LOGDEPTH
|
|
59033
|
+
#ifndef ORTHO
|
|
59034
|
+
return getWorldPosLog(vec3(coord, depth));
|
|
59035
|
+
#endif
|
|
59036
|
+
#endif
|
|
59037
|
+
// }
|
|
59038
|
+
#ifdef ORTHO
|
|
59039
|
+
float z = depthToClipZ(depth);
|
|
59040
|
+
vec4 clipSpacePosition = vec4(coord * 2. - 1., z, 1.);
|
|
59041
|
+
vec4 viewSpacePosition = projectionMatrixInv * clipSpacePosition;
|
|
59042
|
+
viewSpacePosition.xyz /= viewSpacePosition.w;
|
|
59043
|
+
return viewSpacePosition.xyz;
|
|
59044
|
+
#else
|
|
59045
|
+
vec2 ndc = coord * 2. - 1.;
|
|
59046
|
+
float ndcZ = depthToClipZ(depth);
|
|
59047
|
+
mat4 Q = projectionMatrixInv;
|
|
59048
|
+
vec3 view = vec3(Q[0][0] * ndc.x + Q[3][0], Q[1][1] * ndc.y + Q[3][1], Q[3][2]);
|
|
59049
|
+
float invW = 1. / (Q[2][3] * ndcZ + Q[3][3]);
|
|
59050
|
+
return view * invW;
|
|
59051
|
+
#endif
|
|
59052
|
+
}
|
|
59053
|
+
|
|
59054
|
+
vec3 computeNormal(vec3 worldPos, vec2 vUv) {
|
|
59055
|
+
ivec2 p = ivec2(vUv * resolution);
|
|
59056
|
+
float c0 = texelFetch(sceneDepth, p, 0).x;
|
|
59057
|
+
float l2 = texelFetch(sceneDepth, p - ivec2(2, 0), 0).x;
|
|
59058
|
+
float l1 = texelFetch(sceneDepth, p - ivec2(1, 0), 0).x;
|
|
59059
|
+
float r1 = texelFetch(sceneDepth, p + ivec2(1, 0), 0).x;
|
|
59060
|
+
float r2 = texelFetch(sceneDepth, p + ivec2(2, 0), 0).x;
|
|
59061
|
+
float b2 = texelFetch(sceneDepth, p - ivec2(0, 2), 0).x;
|
|
59062
|
+
float b1 = texelFetch(sceneDepth, p - ivec2(0, 1), 0).x;
|
|
59063
|
+
float t1 = texelFetch(sceneDepth, p + ivec2(0, 1), 0).x;
|
|
59064
|
+
float t2 = texelFetch(sceneDepth, p + ivec2(0, 2), 0).x;
|
|
59065
|
+
|
|
59066
|
+
float dl = abs((2.0 * l1 - l2) - c0);
|
|
59067
|
+
float dr = abs((2.0 * r1 - r2) - c0);
|
|
59068
|
+
float db = abs((2.0 * b1 - b2) - c0);
|
|
59069
|
+
float dt = abs((2.0 * t1 - t2) - c0);
|
|
59070
|
+
|
|
59071
|
+
vec3 ce = getWorldPos(c0, vUv).xyz;
|
|
59072
|
+
|
|
59073
|
+
vec3 dpdx = (dl < dr) ? ce - getWorldPos(l1, (vUv - vec2(1.0 / resolution.x, 0.0))).xyz
|
|
59074
|
+
: -ce + getWorldPos(r1, (vUv + vec2(1.0 / resolution.x, 0.0))).xyz;
|
|
59075
|
+
vec3 dpdy = (db < dt) ? ce - getWorldPos(b1, (vUv - vec2(0.0, 1.0 / resolution.y))).xyz
|
|
59076
|
+
: -ce + getWorldPos(t1, (vUv + vec2(0.0, 1.0 / resolution.y))).xyz;
|
|
59077
|
+
|
|
59078
|
+
return normalize(cross(dpdx, dpdy));
|
|
59079
|
+
}
|
|
59080
|
+
|
|
59081
|
+
#include <common>
|
|
59082
|
+
#include <dithering_pars_fragment>
|
|
59083
|
+
void main() {
|
|
59084
|
+
//vec4 texel = texture2D(tDiffuse, vUv);//vec3(0.0);
|
|
59085
|
+
vec4 sceneTexel = texture2D(sceneDiffuse, vUv);
|
|
59086
|
+
float depth = texture2D(sceneDepth, vUv).x;
|
|
59087
|
+
#ifdef HALFRES
|
|
59088
|
+
vec4 texel = vec4(0.0);
|
|
59089
|
+
if (isBackgroundDepth(depth)) {
|
|
59090
|
+
texel = vec4(1.0, 0.0, 0.0, 1.0);
|
|
59091
|
+
} else {
|
|
59092
|
+
vec3 worldPos = getWorldPos(depth, vUv);
|
|
59093
|
+
vec3 normal = computeNormal(getWorldPos(depth, vUv), vUv);
|
|
59094
|
+
// vec4 texel = texture2D(tDiffuse, vUv);
|
|
59095
|
+
// Find closest depth;
|
|
59096
|
+
float totalWeight = 0.0;
|
|
59097
|
+
float radiusToUse = screenSpaceRadius ? distance(
|
|
59098
|
+
worldPos,
|
|
59099
|
+
getWorldPos(depth, vUv +
|
|
59100
|
+
vec2(radius, 0.0) / resolution)
|
|
59101
|
+
) : radius;
|
|
59102
|
+
float distanceFalloffToUse =screenSpaceRadius ?
|
|
59103
|
+
radiusToUse * distanceFalloff
|
|
59104
|
+
: distanceFalloff;
|
|
59105
|
+
for(float x = -1.0; x <= 1.0; x++) {
|
|
59106
|
+
for(float y = -1.0; y <= 1.0; y++) {
|
|
59107
|
+
vec2 offset = vec2(x, y);
|
|
59108
|
+
ivec2 p = ivec2(
|
|
59109
|
+
(vUv * resolution * 0.5) + offset
|
|
59110
|
+
);
|
|
59111
|
+
vec2 pUv = vec2(p) / (resolution * 0.5);
|
|
59112
|
+
float sampleDepth = texelFetch(downsampledDepth,p, 0).x;
|
|
59113
|
+
vec4 sampleInfo = texelFetch(tDiffuse, p, 0);
|
|
59114
|
+
vec3 normalSample = sampleInfo.gba * 2.0 - 1.0;
|
|
59115
|
+
vec3 worldPosSample = getWorldPos(sampleDepth, pUv);
|
|
59116
|
+
float tangentPlaneDist = abs(dot(worldPosSample - worldPos, normal));
|
|
59117
|
+
float rangeCheck = exp(-1.0 * tangentPlaneDist * (1.0 / distanceFalloffToUse)) * max(dot(normal, normalSample), 0.0);
|
|
59118
|
+
float weight = rangeCheck;
|
|
59119
|
+
totalWeight += weight;
|
|
59120
|
+
texel += sampleInfo * weight;
|
|
59121
|
+
}
|
|
59122
|
+
}
|
|
59123
|
+
if (totalWeight == 0.0) {
|
|
59124
|
+
texel = texture2D(tDiffuse, vUv);
|
|
59125
|
+
} else {
|
|
59126
|
+
texel /= totalWeight;
|
|
59127
|
+
}
|
|
59128
|
+
}
|
|
59129
|
+
#else
|
|
59130
|
+
vec4 texel = texture2D(tDiffuse, vUv);
|
|
59131
|
+
#endif
|
|
59132
|
+
|
|
59133
|
+
#ifdef LOGDEPTH
|
|
59134
|
+
texel.r = clamp(texel.r, 0.0, 1.0);
|
|
59135
|
+
if (texel.r == 0.0) {
|
|
59136
|
+
texel.r = 1.0;
|
|
59137
|
+
}
|
|
59138
|
+
#endif
|
|
59139
|
+
|
|
59140
|
+
float finalAo = pow(texel.r, intensity);
|
|
59141
|
+
if (aoTones > 0.0) {
|
|
59142
|
+
finalAo = ceil(finalAo * aoTones) / aoTones;
|
|
59143
|
+
}
|
|
59144
|
+
float fogFactor = 0.0;
|
|
59145
|
+
if (fog) {
|
|
59146
|
+
float fogDepth = -getWorldPos(depth, vUv).z;
|
|
59147
|
+
if (fogExp) {
|
|
59148
|
+
fogFactor = 1.0 - exp( - fogDensity * fogDensity * fogDepth * fogDepth );
|
|
59149
|
+
} else {
|
|
59150
|
+
fogFactor = smoothstep( fogNear, fogFar, fogDepth );
|
|
59151
|
+
}
|
|
59152
|
+
}
|
|
59153
|
+
if (transparencyAware) {
|
|
59154
|
+
float transparencyDWOff = texture2D(transparencyDWFalse, vUv).a;
|
|
59155
|
+
float transparencyDWOn = texture2D(transparencyDWTrue, vUv).a;
|
|
59156
|
+
float adjustmentFactorOff = transparencyDWOff;
|
|
59157
|
+
float depthSample = texture2D(sceneDepth, vUv).r;
|
|
59158
|
+
float trueDepthSample = texture2D(transparencyDWTrueDepth, vUv).r;
|
|
59159
|
+
float adjustmentFactorOn = (1.0 - transparencyDWOn) * (
|
|
59160
|
+
trueDepthSample == depthSample ? 1.0 : 0.0
|
|
59161
|
+
);
|
|
59162
|
+
float adjustmentFactor = max(adjustmentFactorOff, adjustmentFactorOn);
|
|
59163
|
+
finalAo = mix(finalAo, 1.0, adjustmentFactor);
|
|
59164
|
+
}
|
|
59165
|
+
finalAo = mix(finalAo, 1.0, fogFactor);
|
|
59166
|
+
vec3 aoApplied = color * mix(vec3(1.0), sceneTexel.rgb, float(colorMultiply));
|
|
59167
|
+
if (renderMode == 0.0) {
|
|
59168
|
+
gl_FragColor = vec4( mix(sceneTexel.rgb, aoApplied, 1.0 - finalAo), sceneTexel.a);
|
|
59169
|
+
} else if (renderMode == 1.0) {
|
|
59170
|
+
gl_FragColor = vec4( mix(vec3(1.0), aoApplied, 1.0 - finalAo), sceneTexel.a);
|
|
59171
|
+
} else if (renderMode == 2.0) {
|
|
59172
|
+
gl_FragColor = vec4( sceneTexel.rgb, sceneTexel.a);
|
|
59173
|
+
} else if (renderMode == 3.0) {
|
|
59174
|
+
if (vUv.x < 0.5) {
|
|
59175
|
+
gl_FragColor = vec4( sceneTexel.rgb, sceneTexel.a);
|
|
59176
|
+
} else if (abs(vUv.x - 0.5) < 1.0 / resolution.x) {
|
|
59177
|
+
gl_FragColor = vec4(1.0);
|
|
59178
|
+
} else {
|
|
59179
|
+
gl_FragColor = vec4( mix(sceneTexel.rgb, aoApplied, 1.0 - finalAo), sceneTexel.a);
|
|
59180
|
+
}
|
|
59181
|
+
} else if (renderMode == 4.0) {
|
|
59182
|
+
if (vUv.x < 0.5) {
|
|
59183
|
+
gl_FragColor = vec4( sceneTexel.rgb, sceneTexel.a);
|
|
59184
|
+
} else if (abs(vUv.x - 0.5) < 1.0 / resolution.x) {
|
|
59185
|
+
gl_FragColor = vec4(1.0);
|
|
59186
|
+
} else {
|
|
59187
|
+
gl_FragColor = vec4( mix(vec3(1.0), aoApplied, 1.0 - finalAo), sceneTexel.a);
|
|
59188
|
+
}
|
|
59189
|
+
}
|
|
59190
|
+
#include <dithering_fragment>
|
|
59191
|
+
if (gammaCorrection) {
|
|
59192
|
+
gl_FragColor = sRGBTransferOETF(gl_FragColor);
|
|
59193
|
+
}
|
|
59194
|
+
}
|
|
59195
|
+
`
|
|
59196
|
+
)
|
|
59197
|
+
};
|
|
59198
|
+
var $62561e92e160ec9a$exports = {};
|
|
59199
|
+
$62561e92e160ec9a$exports = JSON.parse('{"architecture":"attention-v3-int8","formatVersion":3,"globalBias":[-0.32877659797668457,0.4370867609977722,-0.05251404270529747,1.3072023391723633,0.0477047860622406,0.24477416276931763,0.009111796505749226,-0.17459993064403534],"globalFeatureInverseStandardDeviation":[10.771836280822754,1.9548665285110474,1.612365484237671],"globalFeatureMean":[0.9198138117790222,-0.49808526039123535,0.03374629095196724],"globalWeights":[101,-4,7,-127,6,-11,3,1,0,-16,-7,8,-8,-1,7,-4,0,0,-12,-3,-13,1,0,2],"headBias":[-0.15895532071590424,0.007501596584916115,-0.47742825746536255,0.01632097363471985,-0.48355796933174133,-0.1052703931927681,-0.8414919376373291,-0.21046382188796997],"headWeights":[-45,-7,-45,-20,7,-13,120,-24,-15,-26,-19,1,27,-48,-4,-10,1,-5,-24,64,91,-1,-68,39,54,39,101,-40,-127,64,-41,-17,-23,-19,3,35,-2,33,3,9,-64,-32,30,42,-112,12,28,-11,15,2,-4,-7,7,-3,-5,1,76,48,-34,-67,103,-40,-26,1,58,-11,46,-41,5,-6,-17,-8,13,17,-35,45,27,-17,-28,7,-53,12,-51,6,-32,-5,58,-9,-28,-21,37,-12,1,20,2,2,11,7,-4,-9,2,-15,-1,-8,16,12,-27,-1,61,-5,-1,4,-7,-2,7,4,1,4,-2,4,-18,-16,28,6,-65,16,3,-3,-5,-2,0,-40,-21,-22,14,30,-21,49,15,-64,43,19,23,18,5,-15,21,21,30,17,-11,-6,22,-38,-20,97,-46,-5,-13,-59,26,-13,11,-2,-10,-8,2,-15,-17,-27,-9,26,7,-7,6,9,-32,5,-9,12,49,17,-1,24,20,35,14,-33,-50,-1,-4,-26,11,11,9,-80,30,9,36,6,-12,-4,-7,39,-10,-30,-49,1,-43,-20,-34,76,-36,-10,15,-8,43,31,38,-42,39,37,-7,7,8,16,28,-83,32,9,23,-13,39,119,23,-127,-24,8,-48,-29,-7,-33,-12,58,-24,-29,-19,12,-55,-90,0,126,26,42,54,22],"keyProjectionWeights":[0,-1,-1,1,1,1,1,1,-64,32,49,23,-25,4,27,-22,0,1,-1,-1,-1,1,1,0,-34,38,64,88,13,-53,-41,58,-7,-4,79,-41,27,26,14,2,-2,1,1,1,-1,-1,1,1,1,-1,-1,-1,-1,-1,1,1,4,-3,126,42,-40,-116,35,20],"name":"residual-attention-v3-50m-qat-int8-epoch-25-zo-278w","outputBias":-0.0005526235327124596,"outputWeights":[11,11,14,-27,9,-22,127,6],"quantization":{"scales":{"globalWeight":0.021090541950849095,"headWeight":0.04935851140909355,"keyWeight":0.1733924937791441,"outputWeight":0.0030087142047955295,"tapInputWeight":0.1096231754049479,"tapOutputWeight":0.017949438644286102,"valueWeight":0.013986751242596301},"scheme":"symmetric-int8-per-tensor","zeroPoint":0},"summaryQueries":[0.0038647791370749474,0.09565000981092453,0.002756686182692647,-0.08183622360229492,-0.15209506452083588,-0.0006105066277086735,0.0010439646430313587,-0.03020688332617283,0.005065929610282183,0.14488759636878967,0.003160916268825531,-0.0855727270245552,-0.3123375475406647,0.00039022407145239413,0.0037786494940519333,0.1451321840286255,-0.002009483054280281,0.0597594790160656,0.0045239729806780815,-0.08765853196382523,-0.13884992897510529,-0.0021647117100656033,0.003985927440226078,0.09727758169174194,0.007170629221946001,0.0786278173327446,0.004103775601834059,-0.1198369711637497,-0.2925199568271637,-0.002055276418104768,0.0030450925696641207,0.14401987195014954],"supportedDenoiseSamples":[4,8,16],"tapFeatureInverseStandardDeviation":[2.283243417739868,0.8810898065567017,0.8210930228233337,3.752316474914551,3.6375720500946045,2.670454978942871,10.249449729919434,0.12639354169368744,100],"tapFeatureMean":[0.010318092070519924,0.01364430133253336,0.13411010801792145,-0.004725644364953041,0.10053129494190216,0.8384788632392883,0.9203217625617981,1.7139031887054443,1],"tapInputBias":[0.4780646860599518,-0.45214661955833435,0.289407879114151,0.34804567694664,-0.1320028454065323,0.17722633481025696,0.011480014771223068,-0.26692497730255127],"tapInputWeights":[0,1,7,0,-1,-7,0,31,-2,-1,14,-126,0,0,-1,2,26,-2,0,66,-73,0,0,0,-12,22,-3,0,-76,-90,0,-1,-7,-3,58,-1,0,2,6,0,0,3,4,-40,0,0,3,-13,0,0,1,-7,-13,0,0,-7,10,0,-2,-7,0,-39,-2,0,-13,-19,0,-2,20,-1,3,-1],"tapOutputBias":[-0.3867710530757904,0.1349504142999649,0.35706064105033875,-0.5938405394554138,-0.031154220923781395,1.4079623222351074,-1.9221038818359375,0.6029739379882812],"tapOutputWeights":[18,-4,47,19,74,-94,-21,-9,73,-59,88,-10,-3,71,-7,24,20,74,24,-31,-12,-10,-15,-45,-126,2,-4,27,-5,24,35,-11,-4,9,-8,26,-10,27,26,-20,17,-50,5,-35,0,-5,12,-71,89,-58,22,-83,-115,7,-16,-89,89,22,1,-20,-22,-25,-26,44],"valueProjectionWeights":[-16,-6,40,-17,84,-76,59,51,-10,-2,-10,-1,-23,74,-70,23,-5,4,4,-7,-77,127,20,-48,-36,4,-17,-12,-4,10,29,-27,-2,11,-47,-50,-54,-3,14,11,-23,-1,109,31,4,-100,-33,-36,-19,0,-8,20,-35,-24,79,2,44,2,5,7,22,-70,-67,-35]}');
|
|
59200
|
+
const $1193f60a44983e43$var$MATRIX_LAYOUTS = [
|
|
59201
|
+
[
|
|
59202
|
+
"tapInputWeight",
|
|
59203
|
+
"tapInputWeights",
|
|
59204
|
+
8,
|
|
59205
|
+
9
|
|
59206
|
+
],
|
|
59207
|
+
[
|
|
59208
|
+
"tapOutputWeight",
|
|
59209
|
+
"tapOutputWeights",
|
|
59210
|
+
8,
|
|
59211
|
+
8
|
|
59212
|
+
],
|
|
59213
|
+
[
|
|
59214
|
+
"globalWeight",
|
|
59215
|
+
"globalWeights",
|
|
59216
|
+
8,
|
|
59217
|
+
3
|
|
59218
|
+
],
|
|
59219
|
+
[
|
|
59220
|
+
"keyWeight",
|
|
59221
|
+
"keyProjectionWeights",
|
|
59222
|
+
8,
|
|
59223
|
+
8
|
|
59224
|
+
],
|
|
59225
|
+
[
|
|
59226
|
+
"valueWeight",
|
|
59227
|
+
"valueProjectionWeights",
|
|
59228
|
+
8,
|
|
59229
|
+
8
|
|
59230
|
+
],
|
|
59231
|
+
[
|
|
59232
|
+
"headWeight",
|
|
59233
|
+
"headWeights",
|
|
59234
|
+
8,
|
|
59235
|
+
32
|
|
59236
|
+
],
|
|
59237
|
+
[
|
|
59238
|
+
"outputWeight",
|
|
59239
|
+
"outputWeights",
|
|
59240
|
+
1,
|
|
59241
|
+
8
|
|
59242
|
+
]
|
|
59243
|
+
];
|
|
59244
|
+
const $1193f60a44983e43$var$scale = (name) => {
|
|
59245
|
+
const value = (/* @__PURE__ */ $parcel$interopDefault($62561e92e160ec9a$exports)).quantization?.scales?.[name];
|
|
59246
|
+
if (!(value > 0) || !Number.isFinite(value)) throw new Error(`The bundled N8AO neural model has no valid ${name} scale.`);
|
|
59247
|
+
return value;
|
|
59248
|
+
};
|
|
59249
|
+
if ((/* @__PURE__ */ $parcel$interopDefault($62561e92e160ec9a$exports)).architecture !== "attention-v3-int8" || (/* @__PURE__ */ $parcel$interopDefault($62561e92e160ec9a$exports)).formatVersion !== 3 || (/* @__PURE__ */ $parcel$interopDefault($62561e92e160ec9a$exports)).quantization?.scheme !== "symmetric-int8-per-tensor" || (/* @__PURE__ */ $parcel$interopDefault($62561e92e160ec9a$exports)).quantization?.zeroPoint !== 0 || (/* @__PURE__ */ $parcel$interopDefault($62561e92e160ec9a$exports)).supportedDenoiseSamples?.join(",") !== "4,8,16" || $1193f60a44983e43$var$MATRIX_LAYOUTS.some(([, field, rows, columns]) => (/* @__PURE__ */ $parcel$interopDefault($62561e92e160ec9a$exports))[field]?.length !== rows * columns || (/* @__PURE__ */ $parcel$interopDefault($62561e92e160ec9a$exports))[field].some((value) => !Number.isInteger(value) || value < -127 || value > 127))) throw new Error("The bundled N8AO neural denoise model has an unsupported layout.");
|
|
59250
|
+
const $1193f60a44983e43$var$glslFloat = (value) => {
|
|
59251
|
+
if (!Number.isFinite(value)) throw new Error("The bundled N8AO neural model contains a non-finite value.");
|
|
59252
|
+
if (Object.is(value, -0)) return "0.0";
|
|
59253
|
+
const text = Number(value).toString();
|
|
59254
|
+
return /[.eE]/.test(text) ? text : `${text}.0`;
|
|
59255
|
+
};
|
|
59256
|
+
const $1193f60a44983e43$var$COMPONENTS = [
|
|
59257
|
+
"x",
|
|
59258
|
+
"y",
|
|
59259
|
+
"z",
|
|
59260
|
+
"w"
|
|
59261
|
+
];
|
|
59262
|
+
const $1193f60a44983e43$var$tokenAccessors = (name) => [
|
|
59263
|
+
...$1193f60a44983e43$var$COMPONENTS.map((component) => `${name}.lo.${component}`),
|
|
59264
|
+
...$1193f60a44983e43$var$COMPONENTS.map((component) => `${name}.hi.${component}`)
|
|
59265
|
+
];
|
|
59266
|
+
const $1193f60a44983e43$var$weightedTerm = (coefficient, input) => {
|
|
59267
|
+
if (coefficient === 0) return null;
|
|
59268
|
+
if (coefficient === 1) return input;
|
|
59269
|
+
if (coefficient === -1) return `(-${input})`;
|
|
59270
|
+
if (coefficient < 0) return `(-${$1193f60a44983e43$var$glslFloat(-coefficient)} * ${input})`;
|
|
59271
|
+
return `${$1193f60a44983e43$var$glslFloat(coefficient)} * ${input}`;
|
|
59272
|
+
};
|
|
59273
|
+
const $1193f60a44983e43$var$floatWeightedTerm = (coefficient, input) => {
|
|
59274
|
+
if (coefficient === 0) return null;
|
|
59275
|
+
return `${$1193f60a44983e43$var$glslFloat(coefficient)} * ${input}`;
|
|
59276
|
+
};
|
|
59277
|
+
const $1193f60a44983e43$var$sumTerms = (terms) => terms.filter(Boolean).join(" + ") || "0.0";
|
|
59278
|
+
const $1193f60a44983e43$var$quantizedRow = (weights, row, width, inputs, tensorScale, bias) => {
|
|
59279
|
+
const terms = inputs.map((input, column) => $1193f60a44983e43$var$weightedTerm(weights[row * width + column], input));
|
|
59280
|
+
return `${$1193f60a44983e43$var$glslFloat(tensorScale)} * (${$1193f60a44983e43$var$sumTerms(terms)}) + ${$1193f60a44983e43$var$glslFloat(bias[row])}`;
|
|
59281
|
+
};
|
|
59282
|
+
const $1193f60a44983e43$var$vec4 = (values, indent = " ") => `vec4(
|
|
59283
|
+
${values.map((value) => `${indent} ${value}`).join(",\n")}
|
|
59284
|
+
${indent})`;
|
|
59285
|
+
const $1193f60a44983e43$var$tokenLayer = ({ functionName, scaleName, weights, bias, width = 8, relu = false }) => {
|
|
59286
|
+
const inputs = $1193f60a44983e43$var$tokenAccessors("inputToken");
|
|
59287
|
+
const tensorScale = $1193f60a44983e43$var$scale(scaleName);
|
|
59288
|
+
const rows = Array.from({
|
|
59289
|
+
length: 8
|
|
59290
|
+
}, (_, row) => $1193f60a44983e43$var$quantizedRow(weights, row, width, inputs, tensorScale, bias));
|
|
59291
|
+
const low = $1193f60a44983e43$var$vec4(rows.slice(0, 4));
|
|
59292
|
+
const high = $1193f60a44983e43$var$vec4(rows.slice(4));
|
|
59293
|
+
const wrap = (value) => relu ? `max(${value}, vec4(0.0))` : value;
|
|
59294
|
+
return `
|
|
59295
|
+
NeuralToken neural${functionName[0].toUpperCase()}${functionName.slice(1)}(NeuralToken inputToken) {
|
|
59296
|
+
return NeuralToken(
|
|
59297
|
+
${wrap(low)},
|
|
59298
|
+
${wrap(high)}
|
|
59299
|
+
);
|
|
59300
|
+
}
|
|
59301
|
+
`;
|
|
59302
|
+
};
|
|
59303
|
+
const $1193f60a44983e43$var$foldedBias = (weights, bias, means, inverseStandardDeviations, rows, width, tensorScale, constantInputs = {}) => Array.from({
|
|
59304
|
+
length: rows
|
|
59305
|
+
}, (_, row) => {
|
|
59306
|
+
let value = bias[row];
|
|
59307
|
+
for (let column = 0; column < width; column++) {
|
|
59308
|
+
const weight = weights[row * width + column] * tensorScale;
|
|
59309
|
+
value -= weight * inverseStandardDeviations[column] * means[column];
|
|
59310
|
+
if (Object.hasOwn(constantInputs, column)) value += weight * inverseStandardDeviations[column] * constantInputs[column];
|
|
59311
|
+
}
|
|
59312
|
+
return value;
|
|
59313
|
+
});
|
|
59314
|
+
const $1193f60a44983e43$var$tapInputScale = $1193f60a44983e43$var$scale("tapInputWeight");
|
|
59315
|
+
const $1193f60a44983e43$var$tapInputBias = $1193f60a44983e43$var$foldedBias((/* @__PURE__ */ $parcel$interopDefault($62561e92e160ec9a$exports)).tapInputWeights, (/* @__PURE__ */ $parcel$interopDefault($62561e92e160ec9a$exports)).tapInputBias, (/* @__PURE__ */ $parcel$interopDefault($62561e92e160ec9a$exports)).tapFeatureMean, (/* @__PURE__ */ $parcel$interopDefault($62561e92e160ec9a$exports)).tapFeatureInverseStandardDeviation, 8, 9, $1193f60a44983e43$var$tapInputScale, {
|
|
59316
|
+
8: 1
|
|
59317
|
+
});
|
|
59318
|
+
const $1193f60a44983e43$var$tapScaledAccessors = $1193f60a44983e43$var$tokenAccessors("scaledInput");
|
|
59319
|
+
const $1193f60a44983e43$var$tapInputRows = Array.from({
|
|
59320
|
+
length: 8
|
|
59321
|
+
}, (_, row) => $1193f60a44983e43$var$quantizedRow((/* @__PURE__ */ $parcel$interopDefault($62561e92e160ec9a$exports)).tapInputWeights, row, 9, $1193f60a44983e43$var$tapScaledAccessors, $1193f60a44983e43$var$tapInputScale, $1193f60a44983e43$var$tapInputBias));
|
|
59322
|
+
const $1193f60a44983e43$var$tapInputShader = `
|
|
59323
|
+
NeuralToken neuralTapInput(NeuralToken raw) {
|
|
59324
|
+
NeuralToken scaledInput = NeuralToken(
|
|
59325
|
+
raw.lo * ${$1193f60a44983e43$var$vec4((/* @__PURE__ */ $parcel$interopDefault($62561e92e160ec9a$exports)).tapFeatureInverseStandardDeviation.slice(0, 4), " ")},
|
|
59326
|
+
raw.hi * ${$1193f60a44983e43$var$vec4((/* @__PURE__ */ $parcel$interopDefault($62561e92e160ec9a$exports)).tapFeatureInverseStandardDeviation.slice(4, 8), " ")}
|
|
59327
|
+
);
|
|
59328
|
+
return NeuralToken(
|
|
59329
|
+
max(${$1193f60a44983e43$var$vec4($1193f60a44983e43$var$tapInputRows.slice(0, 4))}, vec4(0.0)),
|
|
59330
|
+
max(${$1193f60a44983e43$var$vec4($1193f60a44983e43$var$tapInputRows.slice(4))}, vec4(0.0))
|
|
59331
|
+
);
|
|
59332
|
+
}
|
|
59333
|
+
`;
|
|
59334
|
+
const $1193f60a44983e43$var$globalScale = $1193f60a44983e43$var$scale("globalWeight");
|
|
59335
|
+
const $1193f60a44983e43$var$globalBias = $1193f60a44983e43$var$foldedBias((/* @__PURE__ */ $parcel$interopDefault($62561e92e160ec9a$exports)).globalWeights, (/* @__PURE__ */ $parcel$interopDefault($62561e92e160ec9a$exports)).globalBias, (/* @__PURE__ */ $parcel$interopDefault($62561e92e160ec9a$exports)).globalFeatureMean, (/* @__PURE__ */ $parcel$interopDefault($62561e92e160ec9a$exports)).globalFeatureInverseStandardDeviation, 8, 3, $1193f60a44983e43$var$globalScale);
|
|
59336
|
+
const $1193f60a44983e43$var$globalInputs = $1193f60a44983e43$var$COMPONENTS.slice(0, 3).map((component) => `scaledInput.${component}`);
|
|
59337
|
+
const $1193f60a44983e43$var$globalRows = Array.from({
|
|
59338
|
+
length: 8
|
|
59339
|
+
}, (_, row) => $1193f60a44983e43$var$quantizedRow((/* @__PURE__ */ $parcel$interopDefault($62561e92e160ec9a$exports)).globalWeights, row, 3, $1193f60a44983e43$var$globalInputs, $1193f60a44983e43$var$globalScale, $1193f60a44983e43$var$globalBias));
|
|
59340
|
+
const $1193f60a44983e43$var$globalInputShader = `
|
|
59341
|
+
NeuralToken neuralEncodeGlobal(vec4 raw) {
|
|
59342
|
+
vec3 scaledInput = raw.xyz * vec3(
|
|
59343
|
+
${(/* @__PURE__ */ $parcel$interopDefault($62561e92e160ec9a$exports)).globalFeatureInverseStandardDeviation.map($1193f60a44983e43$var$glslFloat).join(", ")}
|
|
59344
|
+
);
|
|
59345
|
+
return NeuralToken(
|
|
59346
|
+
max(${$1193f60a44983e43$var$vec4($1193f60a44983e43$var$globalRows.slice(0, 4))}, vec4(0.0)),
|
|
59347
|
+
max(${$1193f60a44983e43$var$vec4($1193f60a44983e43$var$globalRows.slice(4))}, vec4(0.0))
|
|
59348
|
+
);
|
|
59349
|
+
}
|
|
59350
|
+
`;
|
|
59351
|
+
const $1193f60a44983e43$var$queryInputs = $1193f60a44983e43$var$tokenAccessors("key");
|
|
59352
|
+
const $1193f60a44983e43$var$queryRows = Array.from({
|
|
59353
|
+
length: 4
|
|
59354
|
+
}, (_, query) => $1193f60a44983e43$var$sumTerms($1193f60a44983e43$var$queryInputs.map((input, column) => $1193f60a44983e43$var$floatWeightedTerm((/* @__PURE__ */ $parcel$interopDefault($62561e92e160ec9a$exports)).summaryQueries[query * 8 + column], input))));
|
|
59355
|
+
const $1193f60a44983e43$var$queryShader = `
|
|
59356
|
+
vec4 neuralQueryScores(NeuralToken key) {
|
|
59357
|
+
return ${$1193f60a44983e43$var$vec4($1193f60a44983e43$var$queryRows)};
|
|
59358
|
+
}
|
|
59359
|
+
`;
|
|
59360
|
+
const $1193f60a44983e43$var$summaryInputs = [];
|
|
59361
|
+
for (let query = 0; query < 4; query++) $1193f60a44983e43$var$summaryInputs.push(...$1193f60a44983e43$var$COMPONENTS.map((component) => `runningSummaryLo[${query}].${component}`), ...$1193f60a44983e43$var$COMPONENTS.map((component) => `runningSummaryHi[${query}].${component}`));
|
|
59362
|
+
const $1193f60a44983e43$var$headScale = $1193f60a44983e43$var$scale("headWeight");
|
|
59363
|
+
const $1193f60a44983e43$var$headRows = Array.from({
|
|
59364
|
+
length: 8
|
|
59365
|
+
}, (_, row) => $1193f60a44983e43$var$quantizedRow((/* @__PURE__ */ $parcel$interopDefault($62561e92e160ec9a$exports)).headWeights, row, 32, $1193f60a44983e43$var$summaryInputs, $1193f60a44983e43$var$headScale, (/* @__PURE__ */ $parcel$interopDefault($62561e92e160ec9a$exports)).headBias));
|
|
59366
|
+
const $1193f60a44983e43$var$headShader = `
|
|
59367
|
+
NeuralToken neuralHead(
|
|
59368
|
+
vec4 runningSummaryLo[4],
|
|
59369
|
+
vec4 runningSummaryHi[4]
|
|
59370
|
+
) {
|
|
59371
|
+
return NeuralToken(
|
|
59372
|
+
max(${$1193f60a44983e43$var$vec4($1193f60a44983e43$var$headRows.slice(0, 4))}, vec4(0.0)),
|
|
59373
|
+
max(${$1193f60a44983e43$var$vec4($1193f60a44983e43$var$headRows.slice(4))}, vec4(0.0))
|
|
59374
|
+
);
|
|
59375
|
+
}
|
|
59376
|
+
`;
|
|
59377
|
+
const $1193f60a44983e43$var$outputExpression = $1193f60a44983e43$var$quantizedRow((/* @__PURE__ */ $parcel$interopDefault($62561e92e160ec9a$exports)).outputWeights, 0, 8, $1193f60a44983e43$var$tokenAccessors("head"), $1193f60a44983e43$var$scale("outputWeight"), [
|
|
59378
|
+
(/* @__PURE__ */ $parcel$interopDefault($62561e92e160ec9a$exports)).outputBias
|
|
59379
|
+
]);
|
|
59380
|
+
const $1193f60a44983e43$var$outputShader = `
|
|
59381
|
+
float neuralOutput(NeuralToken head) {
|
|
59382
|
+
return ${$1193f60a44983e43$var$outputExpression};
|
|
59383
|
+
}
|
|
59384
|
+
`;
|
|
59385
|
+
const $1193f60a44983e43$export$d75ad64dd346ec0e = [
|
|
59386
|
+
$1193f60a44983e43$var$tapInputShader,
|
|
59387
|
+
$1193f60a44983e43$var$tokenLayer({
|
|
59388
|
+
functionName: "tapOutput",
|
|
59389
|
+
scaleName: "tapOutputWeight",
|
|
59390
|
+
weights: (/* @__PURE__ */ $parcel$interopDefault($62561e92e160ec9a$exports)).tapOutputWeights,
|
|
59391
|
+
bias: (/* @__PURE__ */ $parcel$interopDefault($62561e92e160ec9a$exports)).tapOutputBias,
|
|
59392
|
+
relu: true
|
|
59393
|
+
}),
|
|
59394
|
+
$1193f60a44983e43$var$globalInputShader,
|
|
59395
|
+
$1193f60a44983e43$var$tokenLayer({
|
|
59396
|
+
functionName: "keyProject",
|
|
59397
|
+
scaleName: "keyWeight",
|
|
59398
|
+
weights: (/* @__PURE__ */ $parcel$interopDefault($62561e92e160ec9a$exports)).keyProjectionWeights,
|
|
59399
|
+
bias: new Array(8).fill(0)
|
|
59400
|
+
}),
|
|
59401
|
+
$1193f60a44983e43$var$tokenLayer({
|
|
59402
|
+
functionName: "valueProject",
|
|
59403
|
+
scaleName: "valueWeight",
|
|
59404
|
+
weights: (/* @__PURE__ */ $parcel$interopDefault($62561e92e160ec9a$exports)).valueProjectionWeights,
|
|
59405
|
+
bias: new Array(8).fill(0)
|
|
59406
|
+
}),
|
|
59407
|
+
$1193f60a44983e43$var$queryShader,
|
|
59408
|
+
$1193f60a44983e43$var$headShader,
|
|
59409
|
+
$1193f60a44983e43$var$outputShader
|
|
59410
|
+
].join("\n");
|
|
59411
|
+
$1193f60a44983e43$var$MATRIX_LAYOUTS.reduce((sum, [, field]) => sum + (/* @__PURE__ */ $parcel$interopDefault($62561e92e160ec9a$exports))[field].length, 0);
|
|
59412
|
+
$1193f60a44983e43$var$MATRIX_LAYOUTS.reduce((sum, [, field]) => sum + (/* @__PURE__ */ $parcel$interopDefault($62561e92e160ec9a$exports))[field].filter((value) => value !== 0).length, 0);
|
|
59413
|
+
const $e52378cd0f5a973d$export$57856b59f317262e = {
|
|
59414
|
+
uniforms: {
|
|
59415
|
+
"sceneDiffuse": {
|
|
59416
|
+
value: null
|
|
59417
|
+
},
|
|
59418
|
+
"sceneDepth": {
|
|
59419
|
+
value: null
|
|
59420
|
+
},
|
|
59421
|
+
"tDiffuse": {
|
|
59422
|
+
value: null
|
|
59423
|
+
},
|
|
59424
|
+
"projMat": {
|
|
59425
|
+
value: /* @__PURE__ */ new Matrix4()
|
|
59426
|
+
},
|
|
59427
|
+
"viewMat": {
|
|
59428
|
+
value: /* @__PURE__ */ new Matrix4()
|
|
59429
|
+
},
|
|
59430
|
+
"projectionMatrixInv": {
|
|
59431
|
+
value: /* @__PURE__ */ new Matrix4()
|
|
59432
|
+
},
|
|
59433
|
+
"viewMatrixInv": {
|
|
59434
|
+
value: /* @__PURE__ */ new Matrix4()
|
|
59435
|
+
},
|
|
59436
|
+
"cameraPos": {
|
|
59437
|
+
value: /* @__PURE__ */ new Vector3$1()
|
|
59438
|
+
},
|
|
59439
|
+
"resolution": {
|
|
59440
|
+
value: /* @__PURE__ */ new Vector2$1()
|
|
59441
|
+
},
|
|
59442
|
+
"time": {
|
|
59443
|
+
value: 0
|
|
59444
|
+
},
|
|
59445
|
+
"r": {
|
|
59446
|
+
value: 5
|
|
59447
|
+
},
|
|
59448
|
+
"blueNoise": {
|
|
59449
|
+
value: null
|
|
59450
|
+
},
|
|
59451
|
+
"radius": {
|
|
59452
|
+
value: 12
|
|
59453
|
+
},
|
|
59454
|
+
"worldRadius": {
|
|
59455
|
+
value: 5
|
|
59456
|
+
},
|
|
59457
|
+
"index": {
|
|
59458
|
+
value: 0
|
|
59459
|
+
},
|
|
59460
|
+
"poissonDisk": {
|
|
59461
|
+
value: []
|
|
59462
|
+
},
|
|
59463
|
+
"distanceFalloff": {
|
|
59464
|
+
value: 1
|
|
59465
|
+
},
|
|
59466
|
+
"near": {
|
|
59467
|
+
value: 0.1
|
|
59468
|
+
},
|
|
59469
|
+
"far": {
|
|
59470
|
+
value: 1e3
|
|
59471
|
+
},
|
|
59472
|
+
"screenSpaceRadius": {
|
|
59473
|
+
value: false
|
|
59474
|
+
}
|
|
59475
|
+
},
|
|
59476
|
+
depthWrite: false,
|
|
59477
|
+
depthTest: false,
|
|
59478
|
+
vertexShader: (
|
|
59479
|
+
/* glsl */
|
|
59480
|
+
`
|
|
59481
|
+
varying vec2 vUv;
|
|
59482
|
+
void main() {
|
|
59483
|
+
vUv = uv;
|
|
59484
|
+
gl_Position = vec4(position, 1.0);
|
|
59485
|
+
}`
|
|
59486
|
+
),
|
|
59487
|
+
fragmentShader: (
|
|
59488
|
+
/* glsl */
|
|
59489
|
+
`
|
|
59490
|
+
uniform sampler2D sceneDiffuse;
|
|
59491
|
+
uniform highp sampler2D sceneDepth;
|
|
59492
|
+
uniform sampler2D tDiffuse;
|
|
59493
|
+
uniform sampler2D blueNoise;
|
|
59494
|
+
uniform mat4 projectionMatrixInv;
|
|
59495
|
+
uniform mat4 viewMatrixInv;
|
|
59496
|
+
uniform vec2 resolution;
|
|
59497
|
+
uniform float r;
|
|
59498
|
+
uniform float radius;
|
|
59499
|
+
uniform float worldRadius;
|
|
59500
|
+
uniform float index;
|
|
59501
|
+
uniform float near;
|
|
59502
|
+
uniform float far;
|
|
59503
|
+
uniform float distanceFalloff;
|
|
59504
|
+
uniform bool screenSpaceRadius;
|
|
59505
|
+
varying vec2 vUv;
|
|
59506
|
+
|
|
59507
|
+
highp float linearize_depth(highp float d, highp float zNear,highp float zFar)
|
|
59508
|
+
{
|
|
59509
|
+
highp float z_n = 2.0 * d - 1.0;
|
|
59510
|
+
return 2.0 * zNear * zFar / (zFar + zNear - z_n * (zFar - zNear));
|
|
59511
|
+
}
|
|
59512
|
+
highp float linearize_depth_log(highp float d, highp float nearZ,highp float farZ) {
|
|
59513
|
+
float depth = pow(2.0, d * log2(farZ + 1.0)) - 1.0;
|
|
59514
|
+
float a = farZ / (farZ - nearZ);
|
|
59515
|
+
float b = farZ * nearZ / (nearZ - farZ);
|
|
59516
|
+
float linDepth = a + b / depth;
|
|
59517
|
+
return linearize_depth(linDepth, nearZ, farZ);
|
|
59518
|
+
}
|
|
59519
|
+
highp float linearize_depth_ortho(highp float d, highp float nearZ, highp float farZ) {
|
|
59520
|
+
return nearZ + (farZ - nearZ) * d;
|
|
59521
|
+
}
|
|
59522
|
+
float depthToClipZ(float depth) {
|
|
59523
|
+
#ifdef REVERSEDEPTH
|
|
59524
|
+
return depth;
|
|
59525
|
+
#else
|
|
59526
|
+
return depth * 2.0 - 1.0;
|
|
59527
|
+
#endif
|
|
59528
|
+
}
|
|
59529
|
+
bool isBackgroundDepth(float depth) {
|
|
59530
|
+
#ifdef REVERSEDEPTH
|
|
59531
|
+
return depth == 0.0;
|
|
59532
|
+
#else
|
|
59533
|
+
return depth == 1.0;
|
|
59534
|
+
#endif
|
|
59535
|
+
}
|
|
59536
|
+
vec3 getWorldPosLog(vec3 posS) {
|
|
59537
|
+
vec2 uv = posS.xy;
|
|
59538
|
+
float z = posS.z;
|
|
59539
|
+
float nearZ =near;
|
|
59540
|
+
float farZ = far;
|
|
59541
|
+
float depth = pow(2.0, z * log2(farZ + 1.0)) - 1.0;
|
|
59542
|
+
float a = farZ / (farZ - nearZ);
|
|
59543
|
+
float b = farZ * nearZ / (nearZ - farZ);
|
|
59544
|
+
float linDepth = a + b / depth;
|
|
59545
|
+
vec4 clipVec = vec4(uv, linDepth, 1.0) * 2.0 - 1.0;
|
|
59546
|
+
vec4 wpos = projectionMatrixInv * clipVec;
|
|
59547
|
+
return wpos.xyz / wpos.w;
|
|
59548
|
+
}
|
|
59549
|
+
vec3 getWorldPos(float depth, vec2 coord) {
|
|
59550
|
+
#ifdef LOGDEPTH
|
|
59551
|
+
#ifndef ORTHO
|
|
59552
|
+
return getWorldPosLog(vec3(coord, depth));
|
|
59553
|
+
#endif
|
|
59554
|
+
#endif
|
|
59555
|
+
|
|
59556
|
+
#ifdef ORTHO
|
|
59557
|
+
float z = depthToClipZ(depth);
|
|
59558
|
+
vec4 clipSpacePosition = vec4(coord * 2. - 1., z, 1.);
|
|
59559
|
+
vec4 viewSpacePosition = projectionMatrixInv * clipSpacePosition;
|
|
59560
|
+
viewSpacePosition.xyz /= viewSpacePosition.w;
|
|
59561
|
+
return viewSpacePosition.xyz;
|
|
59562
|
+
#else
|
|
59563
|
+
vec2 ndc = coord * 2. - 1.;
|
|
59564
|
+
float ndcZ = depthToClipZ(depth);
|
|
59565
|
+
mat4 Q = projectionMatrixInv;
|
|
59566
|
+
vec3 view = vec3(Q[0][0] * ndc.x + Q[3][0], Q[1][1] * ndc.y + Q[3][1], Q[3][2]);
|
|
59567
|
+
float invW = 1.0 / (Q[2][3] * ndcZ + Q[3][3]);
|
|
59568
|
+
return view * invW;
|
|
59569
|
+
#endif
|
|
59570
|
+
}
|
|
59571
|
+
|
|
59572
|
+
#ifdef NEURAL_DENOISE
|
|
59573
|
+
struct NeuralToken {
|
|
59574
|
+
highp vec4 lo;
|
|
59575
|
+
highp vec4 hi;
|
|
59576
|
+
};
|
|
59577
|
+
|
|
59578
|
+
${$1193f60a44983e43$export$d75ad64dd346ec0e}
|
|
59579
|
+
|
|
59580
|
+
vec3 neuralSafeNormalize(vec3 value, vec3 fallback) {
|
|
59581
|
+
float lengthSquared = dot(value, value);
|
|
59582
|
+
return lengthSquared > 1e-12 ? value * inversesqrt(lengthSquared) : fallback;
|
|
59583
|
+
}
|
|
59584
|
+
|
|
59585
|
+
mat3 neuralLocalFrame(vec3 inputNormal) {
|
|
59586
|
+
vec3 frameNormal = neuralSafeNormalize(inputNormal, vec3(0.0, 0.0, 1.0));
|
|
59587
|
+
vec3 helper = abs(frameNormal.z) < 0.999
|
|
59588
|
+
? vec3(0.0, 0.0, 1.0)
|
|
59589
|
+
: vec3(0.0, 1.0, 0.0);
|
|
59590
|
+
vec3 tangent = neuralSafeNormalize(
|
|
59591
|
+
cross(helper, frameNormal),
|
|
59592
|
+
vec3(1.0, 0.0, 0.0)
|
|
59593
|
+
);
|
|
59594
|
+
vec3 bitangent = cross(frameNormal, tangent);
|
|
59595
|
+
return transpose(mat3(tangent, bitangent, frameNormal));
|
|
59596
|
+
}
|
|
59597
|
+
|
|
59598
|
+
void neuralConsumeToken(
|
|
59599
|
+
NeuralToken token,
|
|
59600
|
+
inout vec4 runningMaximum,
|
|
59601
|
+
inout vec4 runningDenominator,
|
|
59602
|
+
inout vec4 runningSummaryLo[4],
|
|
59603
|
+
inout vec4 runningSummaryHi[4]
|
|
59604
|
+
) {
|
|
59605
|
+
NeuralToken key = neuralKeyProject(token);
|
|
59606
|
+
NeuralToken value = neuralValueProject(token);
|
|
59607
|
+
vec4 score = neuralQueryScores(key) * 0.3535533905932738;
|
|
59608
|
+
vec4 newMaximum = max(runningMaximum, score);
|
|
59609
|
+
vec4 oldScale = exp(runningMaximum - newMaximum);
|
|
59610
|
+
vec4 newScale = exp(score - newMaximum);
|
|
59611
|
+
|
|
59612
|
+
runningSummaryLo[0] = runningSummaryLo[0] * oldScale.x + value.lo * newScale.x;
|
|
59613
|
+
runningSummaryHi[0] = runningSummaryHi[0] * oldScale.x + value.hi * newScale.x;
|
|
59614
|
+
runningSummaryLo[1] = runningSummaryLo[1] * oldScale.y + value.lo * newScale.y;
|
|
59615
|
+
runningSummaryHi[1] = runningSummaryHi[1] * oldScale.y + value.hi * newScale.y;
|
|
59616
|
+
runningSummaryLo[2] = runningSummaryLo[2] * oldScale.z + value.lo * newScale.z;
|
|
59617
|
+
runningSummaryHi[2] = runningSummaryHi[2] * oldScale.z + value.hi * newScale.z;
|
|
59618
|
+
runningSummaryLo[3] = runningSummaryLo[3] * oldScale.w + value.lo * newScale.w;
|
|
59619
|
+
runningSummaryHi[3] = runningSummaryHi[3] * oldScale.w + value.hi * newScale.w;
|
|
59620
|
+
runningDenominator = runningDenominator * oldScale + newScale;
|
|
59621
|
+
runningMaximum = newMaximum;
|
|
59622
|
+
}
|
|
59623
|
+
|
|
59624
|
+
void neuralEncodeTap(
|
|
59625
|
+
NeuralToken raw,
|
|
59626
|
+
inout vec4 runningMaximum,
|
|
59627
|
+
inout vec4 runningDenominator,
|
|
59628
|
+
inout vec4 runningSummaryLo[4],
|
|
59629
|
+
inout vec4 runningSummaryHi[4]
|
|
59630
|
+
) {
|
|
59631
|
+
NeuralToken first = neuralTapInput(raw);
|
|
59632
|
+
NeuralToken token = neuralTapOutput(first);
|
|
59633
|
+
neuralConsumeToken(
|
|
59634
|
+
token,
|
|
59635
|
+
runningMaximum,
|
|
59636
|
+
runningDenominator,
|
|
59637
|
+
runningSummaryLo,
|
|
59638
|
+
runningSummaryHi
|
|
59639
|
+
);
|
|
59640
|
+
}
|
|
59641
|
+
|
|
59642
|
+
float neuralFinish(
|
|
59643
|
+
float baselineAO,
|
|
59644
|
+
inout vec4 runningMaximum,
|
|
59645
|
+
inout vec4 runningDenominator,
|
|
59646
|
+
inout vec4 runningSummaryLo[4],
|
|
59647
|
+
inout vec4 runningSummaryHi[4]
|
|
59648
|
+
) {
|
|
59649
|
+
vec4 raw = vec4(
|
|
59650
|
+
baselineAO,
|
|
59651
|
+
log(max(worldRadius, 1e-6)),
|
|
59652
|
+
log(max(distanceFalloff, 1e-6)),
|
|
59653
|
+
0.0
|
|
59654
|
+
);
|
|
59655
|
+
NeuralToken token = neuralEncodeGlobal(raw);
|
|
59656
|
+
neuralConsumeToken(
|
|
59657
|
+
token,
|
|
59658
|
+
runningMaximum,
|
|
59659
|
+
runningDenominator,
|
|
59660
|
+
runningSummaryLo,
|
|
59661
|
+
runningSummaryHi
|
|
59662
|
+
);
|
|
59663
|
+
|
|
59664
|
+
vec4 inverseDenominator = 1.0 / max(runningDenominator, vec4(1e-12));
|
|
59665
|
+
runningSummaryLo[0] *= inverseDenominator.x;
|
|
59666
|
+
runningSummaryHi[0] *= inverseDenominator.x;
|
|
59667
|
+
runningSummaryLo[1] *= inverseDenominator.y;
|
|
59668
|
+
runningSummaryHi[1] *= inverseDenominator.y;
|
|
59669
|
+
runningSummaryLo[2] *= inverseDenominator.z;
|
|
59670
|
+
runningSummaryHi[2] *= inverseDenominator.z;
|
|
59671
|
+
runningSummaryLo[3] *= inverseDenominator.w;
|
|
59672
|
+
runningSummaryHi[3] *= inverseDenominator.w;
|
|
59673
|
+
|
|
59674
|
+
NeuralToken head = neuralHead(runningSummaryLo, runningSummaryHi);
|
|
59675
|
+
return neuralOutput(head);
|
|
59676
|
+
}
|
|
59677
|
+
#endif
|
|
59678
|
+
|
|
59679
|
+
#include <common>
|
|
59680
|
+
#define NUM_SAMPLES __N8AO_DENOISE_SAMPLES__
|
|
59681
|
+
uniform vec2 poissonDisk[NUM_SAMPLES];
|
|
59682
|
+
void main() {
|
|
59683
|
+
const float pi = 3.14159;
|
|
59684
|
+
vec2 texelSize = vec2(1.0 / resolution.x, 1.0 / resolution.y);
|
|
59685
|
+
vec2 uv = vUv;
|
|
59686
|
+
vec4 data = texture2D(tDiffuse, vUv);
|
|
59687
|
+
float occlusion = data.r;
|
|
59688
|
+
float baseOcc = data.r;
|
|
59689
|
+
vec3 normal = data.gba * 2.0 - 1.0;
|
|
59690
|
+
float count = 1.0;
|
|
59691
|
+
float d = texture2D(sceneDepth, vUv).x;
|
|
59692
|
+
if (isBackgroundDepth(d)) {
|
|
59693
|
+
gl_FragColor = data;
|
|
59694
|
+
return;
|
|
59695
|
+
}
|
|
59696
|
+
vec3 worldPos = getWorldPos(d, vUv);
|
|
59697
|
+
float size = radius;
|
|
59698
|
+
float angle;
|
|
59699
|
+
#ifdef NEURAL_DENOISE
|
|
59700
|
+
// The neural material is only bound for denoise iteration two.
|
|
59701
|
+
angle = texture2D(blueNoise, gl_FragCoord.xy / 128.0).z * PI2;
|
|
59702
|
+
#else
|
|
59703
|
+
if (index == 0.0) {
|
|
59704
|
+
angle = texture2D(blueNoise, gl_FragCoord.xy / 128.0).w * PI2;
|
|
59705
|
+
} else if (index == 1.0) {
|
|
59706
|
+
angle = texture2D(blueNoise, gl_FragCoord.xy / 128.0).z * PI2;
|
|
59707
|
+
} else if (index == 2.0) {
|
|
59708
|
+
angle = texture2D(blueNoise, gl_FragCoord.xy / 128.0).y * PI2;
|
|
59709
|
+
} else {
|
|
59710
|
+
angle = texture2D(blueNoise, gl_FragCoord.xy / 128.0).x * PI2;
|
|
59711
|
+
}
|
|
59712
|
+
#endif
|
|
59713
|
+
|
|
59714
|
+
mat2 rotationMatrix = mat2(cos(angle), -sin(angle), sin(angle), cos(angle));
|
|
59715
|
+
float radiusToUse = screenSpaceRadius ? distance(
|
|
59716
|
+
worldPos,
|
|
59717
|
+
getWorldPos(d, vUv +
|
|
59718
|
+
vec2(worldRadius, 0.0) / resolution)
|
|
59719
|
+
) : worldRadius;
|
|
59720
|
+
float distanceFalloffToUse =screenSpaceRadius ?
|
|
59721
|
+
radiusToUse * distanceFalloff
|
|
59722
|
+
: radiusToUse * distanceFalloff * 0.2;
|
|
59723
|
+
|
|
59724
|
+
float invDistance = (1.0 / distanceFalloffToUse);
|
|
59725
|
+
#ifdef NEURAL_DENOISE
|
|
59726
|
+
mat3 neuralWorldToLocal = neuralLocalFrame(normal);
|
|
59727
|
+
float neuralInverseRadius = 1.0 / max(radiusToUse, 1e-6);
|
|
59728
|
+
float neuralInverseDistance = 1.0 / max(distanceFalloffToUse, 1e-6);
|
|
59729
|
+
vec4 neuralMaximum = vec4(-1e30);
|
|
59730
|
+
vec4 neuralDenominator = vec4(0.0);
|
|
59731
|
+
vec4 neuralSummaryLo[4];
|
|
59732
|
+
vec4 neuralSummaryHi[4];
|
|
59733
|
+
for (int query = 0; query < 4; query++) {
|
|
59734
|
+
neuralSummaryLo[query] = vec4(0.0);
|
|
59735
|
+
neuralSummaryHi[query] = vec4(0.0);
|
|
59736
|
+
}
|
|
59737
|
+
#endif
|
|
59738
|
+
for(int i = 0; i < NUM_SAMPLES; i++) {
|
|
59739
|
+
vec2 offset = (rotationMatrix * poissonDisk[i]) * texelSize * size;
|
|
59740
|
+
vec4 dataSample = texture2D(tDiffuse, uv + offset);
|
|
59741
|
+
float occSample = dataSample.r;
|
|
59742
|
+
vec3 normalSample = dataSample.gba * 2.0 - 1.0;
|
|
59743
|
+
float dSample = texture2D(sceneDepth, uv + offset).x;
|
|
59744
|
+
vec3 worldPosSample = getWorldPos(dSample, uv + offset);
|
|
59745
|
+
float tangentPlaneDist = abs(dot(worldPosSample - worldPos, normal));
|
|
59746
|
+
float rangeCheck = float(!isBackgroundDepth(dSample)) * exp(-1.0 * tangentPlaneDist * invDistance ) * max(dot(normal, normalSample), 0.0);
|
|
59747
|
+
occlusion += occSample * rangeCheck;
|
|
59748
|
+
count += rangeCheck;
|
|
59749
|
+
#ifdef NEURAL_DENOISE
|
|
59750
|
+
if (!isBackgroundDepth(dSample)) {
|
|
59751
|
+
vec3 localDelta = (neuralWorldToLocal * (worldPosSample - worldPos))
|
|
59752
|
+
* neuralInverseRadius;
|
|
59753
|
+
vec3 localNormal = neuralWorldToLocal
|
|
59754
|
+
* neuralSafeNormalize(normalSample, vec3(0.0, 0.0, 1.0));
|
|
59755
|
+
NeuralToken rawTap = NeuralToken(
|
|
59756
|
+
vec4(localDelta, localNormal.x),
|
|
59757
|
+
vec4(
|
|
59758
|
+
localNormal.y,
|
|
59759
|
+
localNormal.z,
|
|
59760
|
+
occSample,
|
|
59761
|
+
tangentPlaneDist * neuralInverseDistance
|
|
59762
|
+
)
|
|
59763
|
+
);
|
|
59764
|
+
neuralEncodeTap(
|
|
59765
|
+
rawTap,
|
|
59766
|
+
neuralMaximum,
|
|
59767
|
+
neuralDenominator,
|
|
59768
|
+
neuralSummaryLo,
|
|
59769
|
+
neuralSummaryHi
|
|
59770
|
+
);
|
|
59771
|
+
}
|
|
59772
|
+
#endif
|
|
59773
|
+
}
|
|
59774
|
+
if (count > 0.0) {
|
|
59775
|
+
occlusion /= count;
|
|
59776
|
+
}
|
|
59777
|
+
occlusion = clamp(occlusion, 0.0, 1.0);
|
|
59778
|
+
if (occlusion == 0.0) {
|
|
59779
|
+
occlusion = 1.0;
|
|
59780
|
+
}
|
|
59781
|
+
#ifdef NEURAL_DENOISE
|
|
59782
|
+
occlusion = clamp(
|
|
59783
|
+
occlusion + neuralFinish(
|
|
59784
|
+
occlusion,
|
|
59785
|
+
neuralMaximum,
|
|
59786
|
+
neuralDenominator,
|
|
59787
|
+
neuralSummaryLo,
|
|
59788
|
+
neuralSummaryHi
|
|
59789
|
+
),
|
|
59790
|
+
0.0,
|
|
59791
|
+
1.0
|
|
59792
|
+
);
|
|
59793
|
+
#endif
|
|
59794
|
+
gl_FragColor = vec4(occlusion, 0.5 + 0.5 * normal);
|
|
59795
|
+
}
|
|
59796
|
+
`
|
|
59797
|
+
)
|
|
59798
|
+
};
|
|
59799
|
+
const $26aca173e0984d99$export$1efdf491687cd442 = {
|
|
59800
|
+
uniforms: {
|
|
59801
|
+
"sceneDepth": {
|
|
59802
|
+
value: null
|
|
59803
|
+
},
|
|
59804
|
+
"resolution": {
|
|
59805
|
+
value: /* @__PURE__ */ new Vector2$1()
|
|
59806
|
+
},
|
|
59807
|
+
"near": {
|
|
59808
|
+
value: 0.1
|
|
59809
|
+
},
|
|
59810
|
+
"far": {
|
|
59811
|
+
value: 1e3
|
|
59812
|
+
},
|
|
59813
|
+
"viewMatrixInv": {
|
|
59814
|
+
value: /* @__PURE__ */ new Matrix4()
|
|
59815
|
+
},
|
|
59816
|
+
"projectionMatrixInv": {
|
|
59817
|
+
value: /* @__PURE__ */ new Matrix4()
|
|
59818
|
+
},
|
|
59819
|
+
"logDepth": {
|
|
59820
|
+
value: false
|
|
59821
|
+
},
|
|
59822
|
+
"ortho": {
|
|
59823
|
+
value: false
|
|
59824
|
+
}
|
|
59825
|
+
},
|
|
59826
|
+
depthWrite: false,
|
|
59827
|
+
depthTest: false,
|
|
59828
|
+
vertexShader: (
|
|
59829
|
+
/* glsl */
|
|
59830
|
+
`
|
|
59831
|
+
varying vec2 vUv;
|
|
59832
|
+
void main() {
|
|
59833
|
+
vUv = uv;
|
|
59834
|
+
gl_Position = vec4(position, 1);
|
|
59835
|
+
}`
|
|
59836
|
+
),
|
|
59837
|
+
fragmentShader: (
|
|
59838
|
+
/* glsl */
|
|
59839
|
+
`
|
|
59840
|
+
uniform highp sampler2D sceneDepth;
|
|
59841
|
+
uniform vec2 resolution;
|
|
59842
|
+
uniform float near;
|
|
59843
|
+
uniform float far;
|
|
59844
|
+
uniform bool logDepth;
|
|
59845
|
+
uniform bool ortho;
|
|
59846
|
+
uniform mat4 viewMatrixInv;
|
|
59847
|
+
uniform mat4 projectionMatrixInv;
|
|
59848
|
+
varying vec2 vUv;
|
|
59849
|
+
layout(location = 1) out vec4 gNormal;
|
|
59850
|
+
vec3 getWorldPosLog(vec3 posS) {
|
|
59851
|
+
vec2 uv = posS.xy;
|
|
59852
|
+
float z = posS.z;
|
|
59853
|
+
float nearZ =near;
|
|
59854
|
+
float farZ = far;
|
|
59855
|
+
float depth = pow(2.0, z * log2(farZ + 1.0)) - 1.0;
|
|
59856
|
+
float a = farZ / (farZ - nearZ);
|
|
59857
|
+
float b = farZ * nearZ / (nearZ - farZ);
|
|
59858
|
+
float linDepth = a + b / depth;
|
|
59859
|
+
vec4 clipVec = vec4(uv, linDepth, 1.0) * 2.0 - 1.0;
|
|
59860
|
+
vec4 wpos = projectionMatrixInv * clipVec;
|
|
59861
|
+
return wpos.xyz / wpos.w;
|
|
59862
|
+
}
|
|
59863
|
+
vec3 getWorldPos(float depth, vec2 coord) {
|
|
59864
|
+
if (logDepth && !ortho) {
|
|
59865
|
+
return getWorldPosLog(vec3(coord, depth));
|
|
59866
|
+
}
|
|
59867
|
+
if (ortho) {
|
|
59868
|
+
#ifdef REVERSEDEPTH
|
|
59869
|
+
float z = depth;
|
|
59870
|
+
#else
|
|
59871
|
+
float z = depth * 2. - 1.;
|
|
59872
|
+
#endif
|
|
59873
|
+
vec4 clipSpacePosition = vec4(coord * 2. - 1., z, 1.);
|
|
59874
|
+
vec4 viewSpacePosition = projectionMatrixInv * clipSpacePosition;
|
|
59875
|
+
viewSpacePosition.xyz /= viewSpacePosition.w;
|
|
59876
|
+
return viewSpacePosition.xyz;
|
|
59877
|
+
}
|
|
59878
|
+
vec2 ndc = coord * 2. - 1.;
|
|
59879
|
+
#ifdef REVERSEDEPTH
|
|
59880
|
+
float ndcZ = depth;
|
|
59881
|
+
#else
|
|
59882
|
+
float ndcZ = depth * 2. - 1.;
|
|
59883
|
+
#endif
|
|
59884
|
+
mat4 Q = projectionMatrixInv;
|
|
59885
|
+
vec3 view = vec3(Q[0][0] * ndc.x + Q[3][0], Q[1][1] * ndc.y + Q[3][1], Q[3][2]);
|
|
59886
|
+
float invW = 1. / (Q[2][3] * ndcZ + Q[3][3]);
|
|
59887
|
+
return view * invW;
|
|
59888
|
+
}
|
|
59889
|
+
|
|
59890
|
+
vec3 computeNormal(vec3 worldPos, vec2 vUv) {
|
|
59891
|
+
ivec2 p = ivec2(vUv * resolution);
|
|
59892
|
+
float c0 = texelFetch(sceneDepth, p, 0).x;
|
|
59893
|
+
float l2 = texelFetch(sceneDepth, p - ivec2(2, 0), 0).x;
|
|
59894
|
+
float l1 = texelFetch(sceneDepth, p - ivec2(1, 0), 0).x;
|
|
59895
|
+
float r1 = texelFetch(sceneDepth, p + ivec2(1, 0), 0).x;
|
|
59896
|
+
float r2 = texelFetch(sceneDepth, p + ivec2(2, 0), 0).x;
|
|
59897
|
+
float b2 = texelFetch(sceneDepth, p - ivec2(0, 2), 0).x;
|
|
59898
|
+
float b1 = texelFetch(sceneDepth, p - ivec2(0, 1), 0).x;
|
|
59899
|
+
float t1 = texelFetch(sceneDepth, p + ivec2(0, 1), 0).x;
|
|
59900
|
+
float t2 = texelFetch(sceneDepth, p + ivec2(0, 2), 0).x;
|
|
59901
|
+
|
|
59902
|
+
float dl = abs((2.0 * l1 - l2) - c0);
|
|
59903
|
+
float dr = abs((2.0 * r1 - r2) - c0);
|
|
59904
|
+
float db = abs((2.0 * b1 - b2) - c0);
|
|
59905
|
+
float dt = abs((2.0 * t1 - t2) - c0);
|
|
59906
|
+
|
|
59907
|
+
vec3 ce = getWorldPos(c0, vUv).xyz;
|
|
59908
|
+
|
|
59909
|
+
vec3 dpdx = (dl < dr) ? ce - getWorldPos(l1, (vUv - vec2(1.0 / resolution.x, 0.0))).xyz
|
|
59910
|
+
: -ce + getWorldPos(r1, (vUv + vec2(1.0 / resolution.x, 0.0))).xyz;
|
|
59911
|
+
vec3 dpdy = (db < dt) ? ce - getWorldPos(b1, (vUv - vec2(0.0, 1.0 / resolution.y))).xyz
|
|
59912
|
+
: -ce + getWorldPos(t1, (vUv + vec2(0.0, 1.0 / resolution.y))).xyz;
|
|
59913
|
+
|
|
59914
|
+
return normalize(cross(dpdx, dpdy));
|
|
59915
|
+
}
|
|
59916
|
+
void main() {
|
|
59917
|
+
vec2 uv = vUv - vec2(0.5) / resolution;
|
|
59918
|
+
vec2 pixelSize = vec2(1.0) / resolution;
|
|
59919
|
+
highp vec2[4] uvSamples;
|
|
59920
|
+
uvSamples[0] = uv;
|
|
59921
|
+
uvSamples[1] = uv + vec2(pixelSize.x, 0.0);
|
|
59922
|
+
uvSamples[2] = uv + vec2(0.0, pixelSize.y);
|
|
59923
|
+
uvSamples[3] = uv + pixelSize;
|
|
59924
|
+
float depth00 = texture2D(sceneDepth, uvSamples[0]).r;
|
|
59925
|
+
float depth10 = texture2D(sceneDepth, uvSamples[1]).r;
|
|
59926
|
+
float depth01 = texture2D(sceneDepth, uvSamples[2]).r;
|
|
59927
|
+
float depth11 = texture2D(sceneDepth, uvSamples[3]).r;
|
|
59928
|
+
float minDepth = min(min(depth00, depth10), min(depth01, depth11));
|
|
59929
|
+
float maxDepth = max(max(depth00, depth10), max(depth01, depth11));
|
|
59930
|
+
float targetDepth = minDepth;
|
|
59931
|
+
// Checkerboard pattern to avoid artifacts
|
|
59932
|
+
if (mod(gl_FragCoord.x + gl_FragCoord.y, 2.0) > 0.5) {
|
|
59933
|
+
targetDepth = maxDepth;
|
|
59934
|
+
}
|
|
59935
|
+
int chosenIndex = 0;
|
|
59936
|
+
float[4] samples;
|
|
59937
|
+
samples[0] = depth00;
|
|
59938
|
+
samples[1] = depth10;
|
|
59939
|
+
samples[2] = depth01;
|
|
59940
|
+
samples[3] = depth11;
|
|
59941
|
+
for(int i = 0; i < 4; ++i) {
|
|
59942
|
+
if (samples[i] == targetDepth) {
|
|
59943
|
+
chosenIndex = i;
|
|
59944
|
+
break;
|
|
59945
|
+
}
|
|
59946
|
+
}
|
|
59947
|
+
gl_FragColor = vec4(samples[chosenIndex], 0.0, 0.0, 1.0);
|
|
59948
|
+
gNormal = vec4(computeNormal(
|
|
59949
|
+
getWorldPos(samples[chosenIndex], uvSamples[chosenIndex]), uvSamples[chosenIndex]
|
|
59950
|
+
), 0.0);
|
|
59951
|
+
}`
|
|
59952
|
+
)
|
|
59953
|
+
};
|
|
59954
|
+
const $06269ad78f3c5fdf$var$BlueNoise = `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`;
|
|
59955
|
+
const $06269ad78f3c5fdf$var$bluenoiseBits = /* @__PURE__ */ (() => Uint8Array.from(atob($06269ad78f3c5fdf$var$BlueNoise), (c) => c.charCodeAt(0)))();
|
|
59956
|
+
var $06269ad78f3c5fdf$export$2e2bcd8739ae039 = $06269ad78f3c5fdf$var$bluenoiseBits;
|
|
59957
|
+
const $ff9437d9c7577f11$var$version = /* @__PURE__ */ (() => parseInt(REVISION.replace(/\D+/g, "")))();
|
|
59958
|
+
const $ff9437d9c7577f11$export$156f6a58f569aa09 = $ff9437d9c7577f11$var$version >= 162 ? class extends WebGLRenderTarget {
|
|
59959
|
+
constructor(width = 1, height = 1, count = 1, options = {}) {
|
|
59960
|
+
super(width, height, {
|
|
59961
|
+
...options,
|
|
59962
|
+
count
|
|
59963
|
+
});
|
|
59964
|
+
this.isWebGLMultipleRenderTargets = true;
|
|
59965
|
+
}
|
|
59966
|
+
get texture() {
|
|
59967
|
+
return this.textures;
|
|
59968
|
+
}
|
|
59969
|
+
} : class extends WebGLRenderTarget {
|
|
59970
|
+
constructor(width = 1, height = 1, count = 1, options = {}) {
|
|
59971
|
+
super(width, height, options);
|
|
59972
|
+
this.isWebGLMultipleRenderTargets = true;
|
|
59973
|
+
const texture = this.texture;
|
|
59974
|
+
this.texture = [];
|
|
59975
|
+
for (let i = 0; i < count; i++) {
|
|
59976
|
+
this.texture[i] = texture.clone();
|
|
59977
|
+
this.texture[i].isRenderTargetTexture = true;
|
|
59978
|
+
}
|
|
59979
|
+
}
|
|
59980
|
+
setSize(width, height, depth = 1) {
|
|
59981
|
+
if (this.width !== width || this.height !== height || this.depth !== depth) {
|
|
59982
|
+
this.width = width;
|
|
59983
|
+
this.height = height;
|
|
59984
|
+
this.depth = depth;
|
|
59985
|
+
for (let i = 0, il = this.texture.length; i < il; i++) {
|
|
59986
|
+
this.texture[i].image.width = width;
|
|
59987
|
+
this.texture[i].image.height = height;
|
|
59988
|
+
this.texture[i].image.depth = depth;
|
|
59989
|
+
}
|
|
59990
|
+
this.dispose();
|
|
59991
|
+
}
|
|
59992
|
+
this.viewport.set(0, 0, width, height);
|
|
59993
|
+
this.scissor.set(0, 0, width, height);
|
|
59994
|
+
}
|
|
59995
|
+
copy(source) {
|
|
59996
|
+
this.dispose();
|
|
59997
|
+
this.width = source.width;
|
|
59998
|
+
this.height = source.height;
|
|
59999
|
+
this.depth = source.depth;
|
|
60000
|
+
this.scissor.copy(source.scissor);
|
|
60001
|
+
this.scissorTest = source.scissorTest;
|
|
60002
|
+
this.viewport.copy(source.viewport);
|
|
60003
|
+
this.depthBuffer = source.depthBuffer;
|
|
60004
|
+
this.stencilBuffer = source.stencilBuffer;
|
|
60005
|
+
if (source.depthTexture !== null) this.depthTexture = source.depthTexture.clone();
|
|
60006
|
+
this.texture.length = 0;
|
|
60007
|
+
for (let i = 0, il = source.texture.length; i < il; i++) {
|
|
60008
|
+
this.texture[i] = source.texture[i].clone();
|
|
60009
|
+
this.texture[i].isRenderTargetTexture = true;
|
|
60010
|
+
}
|
|
60011
|
+
return this;
|
|
60012
|
+
}
|
|
60013
|
+
};
|
|
60014
|
+
function $87431ee93b037844$var$checkTimerQuery(timerQuery, gl, pass) {
|
|
60015
|
+
const available = gl.getQueryParameter(timerQuery, gl.QUERY_RESULT_AVAILABLE);
|
|
60016
|
+
if (available) {
|
|
60017
|
+
const elapsedTimeInNs = gl.getQueryParameter(timerQuery, gl.QUERY_RESULT);
|
|
60018
|
+
const elapsedTimeInMs = elapsedTimeInNs / 1e6;
|
|
60019
|
+
pass.lastTime = pass.lastTime === 0 ? elapsedTimeInMs : pass.timeRollingAverage * pass.lastTime + (1 - pass.timeRollingAverage) * elapsedTimeInMs;
|
|
60020
|
+
} else
|
|
60021
|
+
setTimeout(() => {
|
|
60022
|
+
$87431ee93b037844$var$checkTimerQuery(timerQuery, gl, pass);
|
|
60023
|
+
}, 1);
|
|
60024
|
+
}
|
|
60025
|
+
class $87431ee93b037844$export$2489f9981ab0fa82 extends Pass {
|
|
60026
|
+
/**
|
|
60027
|
+
*
|
|
60028
|
+
* @param {THREE.Scene} scene
|
|
60029
|
+
* @param {THREE.Camera} camera
|
|
60030
|
+
* @param {number} width
|
|
60031
|
+
* @param {number} height
|
|
60032
|
+
*
|
|
60033
|
+
* @property {THREE.Scene} scene
|
|
60034
|
+
* @property {THREE.Camera} camera
|
|
60035
|
+
* @property {number} width
|
|
60036
|
+
* @property {number} height
|
|
60037
|
+
*/
|
|
60038
|
+
constructor(scene, camera, width = 512, height = 512) {
|
|
60039
|
+
super();
|
|
60040
|
+
this.width = Math.floor(width);
|
|
60041
|
+
this.height = Math.floor(height);
|
|
60042
|
+
this.clear = true;
|
|
60043
|
+
this._neuralDenoiseWarningKey = null;
|
|
60044
|
+
this.camera = camera;
|
|
60045
|
+
this.scene = scene;
|
|
60046
|
+
this.autosetGamma = true;
|
|
60047
|
+
this.configuration = new Proxy({
|
|
60048
|
+
aoSamples: 16,
|
|
60049
|
+
aoRadius: 5,
|
|
60050
|
+
aoTones: 0,
|
|
60051
|
+
denoiseSamples: 8,
|
|
60052
|
+
denoiseRadius: 12,
|
|
60053
|
+
distanceFalloff: 1,
|
|
60054
|
+
intensity: 5,
|
|
60055
|
+
denoiseIterations: 2,
|
|
60056
|
+
renderMode: 0,
|
|
60057
|
+
biasOffset: 0,
|
|
60058
|
+
biasMultiplier: 0,
|
|
60059
|
+
color: new Color(0, 0, 0),
|
|
60060
|
+
gammaCorrection: true,
|
|
60061
|
+
depthBufferType: $05f6997e4b65da14$export$ed4ee5d1e55474a5.Default,
|
|
60062
|
+
screenSpaceRadius: false,
|
|
60063
|
+
halfRes: false,
|
|
60064
|
+
depthAwareUpsampling: true,
|
|
60065
|
+
colorMultiply: true,
|
|
60066
|
+
transparencyAware: false,
|
|
60067
|
+
accumulate: false,
|
|
60068
|
+
neuralDenoise: false
|
|
60069
|
+
}, {
|
|
60070
|
+
set: (target, propName, value) => {
|
|
60071
|
+
const oldProp = target[propName];
|
|
60072
|
+
target[propName] = value;
|
|
60073
|
+
if (value.equals) {
|
|
60074
|
+
if (!value.equals(oldProp)) this.firstFrame();
|
|
60075
|
+
} else if (oldProp !== value) this.firstFrame();
|
|
60076
|
+
if (propName === "aoSamples" && oldProp !== value) this.configureAOPass(this.configuration.depthBufferType, this.camera.isOrthographicCamera);
|
|
60077
|
+
if (propName === "denoiseSamples" && oldProp !== value) this.configureDenoisePass(this.configuration.depthBufferType, this.camera.isOrthographicCamera);
|
|
60078
|
+
if (propName === "neuralDenoise" && oldProp !== value) {
|
|
60079
|
+
const reconfigureAO = value && (target.aoSamples !== 16 || target.halfRes);
|
|
60080
|
+
const disableHalfRes = value && target.halfRes;
|
|
60081
|
+
if (value) {
|
|
60082
|
+
target.aoSamples = 16;
|
|
60083
|
+
if (![
|
|
60084
|
+
4,
|
|
60085
|
+
8,
|
|
60086
|
+
16
|
|
60087
|
+
].includes(target.denoiseSamples)) target.denoiseSamples = 8;
|
|
60088
|
+
target.denoiseRadius = 12;
|
|
60089
|
+
target.denoiseIterations = 2;
|
|
60090
|
+
target.halfRes = false;
|
|
60091
|
+
}
|
|
60092
|
+
if (reconfigureAO) this.configureAOPass(this.configuration.depthBufferType, this.camera.isOrthographicCamera);
|
|
60093
|
+
if (disableHalfRes) {
|
|
60094
|
+
this.configureHalfResTargets();
|
|
60095
|
+
this.configureEffectCompositer(this.configuration.depthBufferType, this.camera.isOrthographicCamera);
|
|
60096
|
+
this.setSize(this.width, this.height);
|
|
60097
|
+
}
|
|
60098
|
+
this.configureDenoisePass(this.configuration.depthBufferType, this.camera.isOrthographicCamera);
|
|
60099
|
+
}
|
|
60100
|
+
if (propName === "halfRes" && oldProp !== value) {
|
|
60101
|
+
this.configureAOPass(this.configuration.depthBufferType, this.camera.isOrthographicCamera);
|
|
60102
|
+
this.configureHalfResTargets();
|
|
60103
|
+
this.configureEffectCompositer(this.configuration.depthBufferType, this.camera.isOrthographicCamera);
|
|
60104
|
+
this.setSize(this.width, this.height);
|
|
60105
|
+
}
|
|
60106
|
+
if (propName === "depthAwareUpsampling" && oldProp !== value) this.configureEffectCompositer(this.configuration.depthBufferType, this.camera.isOrthographicCamera);
|
|
60107
|
+
if (propName === "gammaCorrection") this.autosetGamma = false;
|
|
60108
|
+
if (propName === "transparencyAware" && oldProp !== value) {
|
|
60109
|
+
this.autoDetectTransparency = false;
|
|
60110
|
+
this.configureTransparencyTarget();
|
|
60111
|
+
}
|
|
60112
|
+
return true;
|
|
60113
|
+
}
|
|
60114
|
+
});
|
|
60115
|
+
this.samples = [];
|
|
60116
|
+
this.samplesDenoise = [];
|
|
60117
|
+
this.autoDetectTransparency = true;
|
|
60118
|
+
this.frames = 0;
|
|
60119
|
+
this.lastViewMatrix = new Matrix4();
|
|
60120
|
+
this.lastProjectionMatrix = new Matrix4();
|
|
60121
|
+
this.configureEffectCompositer(this.configuration.depthBufferType);
|
|
60122
|
+
this.configureSampleDependentPasses();
|
|
60123
|
+
this.configureHalfResTargets();
|
|
60124
|
+
this.detectTransparency();
|
|
60125
|
+
this.configureTransparencyTarget();
|
|
60126
|
+
this.copyQuad = new $e4ca8dcb0218f846$export$dcd670d73db751f5(new ShaderMaterial({
|
|
60127
|
+
uniforms: {
|
|
60128
|
+
tDiffuse: {
|
|
60129
|
+
value: null
|
|
60130
|
+
}
|
|
60131
|
+
},
|
|
60132
|
+
depthWrite: false,
|
|
60133
|
+
vertexShader: `
|
|
60134
|
+
varying vec2 vUv;
|
|
60135
|
+
void main() {
|
|
60136
|
+
vUv = uv;
|
|
60137
|
+
gl_Position = vec4(position, 1);
|
|
60138
|
+
}
|
|
60139
|
+
`,
|
|
60140
|
+
fragmentShader: `
|
|
60141
|
+
uniform sampler2D tDiffuse;
|
|
60142
|
+
varying vec2 vUv;
|
|
60143
|
+
void main() {
|
|
60144
|
+
gl_FragColor = texture2D(tDiffuse, vUv);
|
|
60145
|
+
}
|
|
60146
|
+
`
|
|
60147
|
+
}));
|
|
60148
|
+
this.writeTargetInternal = new WebGLRenderTarget(this.width, this.height, {
|
|
60149
|
+
minFilter: LinearFilter,
|
|
60150
|
+
magFilter: LinearFilter,
|
|
60151
|
+
depthBuffer: false,
|
|
60152
|
+
format: RGBAFormat
|
|
60153
|
+
});
|
|
60154
|
+
this.readTargetInternal = new WebGLRenderTarget(this.width, this.height, {
|
|
60155
|
+
minFilter: LinearFilter,
|
|
60156
|
+
magFilter: LinearFilter,
|
|
60157
|
+
depthBuffer: false,
|
|
60158
|
+
format: RGBAFormat
|
|
60159
|
+
});
|
|
60160
|
+
this.outputTargetInternal = new WebGLRenderTarget(this.width, this.height, {
|
|
60161
|
+
minFilter: LinearFilter,
|
|
60162
|
+
magFilter: LinearFilter,
|
|
60163
|
+
depthBuffer: false
|
|
60164
|
+
});
|
|
60165
|
+
this.accumulationRenderTarget = new WebGLRenderTarget(this.width, this.height, {
|
|
60166
|
+
minFilter: LinearFilter,
|
|
60167
|
+
magFilter: LinearFilter,
|
|
60168
|
+
depthBuffer: false,
|
|
60169
|
+
format: RGBAFormat,
|
|
60170
|
+
type: HalfFloatType,
|
|
60171
|
+
stencilBuffer: false,
|
|
60172
|
+
depthBuffer: false,
|
|
60173
|
+
alpha: true
|
|
60174
|
+
});
|
|
60175
|
+
this.accumulationQuad = new $e4ca8dcb0218f846$export$dcd670d73db751f5(new ShaderMaterial({
|
|
60176
|
+
uniforms: {
|
|
60177
|
+
frame: {
|
|
60178
|
+
value: 0
|
|
60179
|
+
},
|
|
60180
|
+
tDiffuse: {
|
|
60181
|
+
value: null
|
|
60182
|
+
}
|
|
60183
|
+
},
|
|
60184
|
+
transparent: true,
|
|
60185
|
+
opacity: 1,
|
|
60186
|
+
vertexShader: `
|
|
60187
|
+
varying vec2 vUv;
|
|
60188
|
+
void main() {
|
|
60189
|
+
vUv = uv;
|
|
60190
|
+
gl_Position = vec4(position, 1);
|
|
60191
|
+
}`,
|
|
60192
|
+
fragmentShader: `
|
|
60193
|
+
uniform sampler2D tDiffuse;
|
|
60194
|
+
uniform float frame;
|
|
60195
|
+
varying vec2 vUv;
|
|
60196
|
+
void main() {
|
|
60197
|
+
vec4 color = texture2D(tDiffuse, vUv);
|
|
60198
|
+
gl_FragColor = vec4(color.rgb, 1.0 / (frame + 1.0));
|
|
60199
|
+
}
|
|
60200
|
+
`
|
|
60201
|
+
}));
|
|
60202
|
+
this.bluenoise = new DataTexture($06269ad78f3c5fdf$export$2e2bcd8739ae039, 128, 128);
|
|
60203
|
+
this.bluenoise.colorSpace = NoColorSpace;
|
|
60204
|
+
this.bluenoise.wrapS = RepeatWrapping;
|
|
60205
|
+
this.bluenoise.wrapT = RepeatWrapping;
|
|
60206
|
+
this.bluenoise.minFilter = NearestFilter;
|
|
60207
|
+
this.bluenoise.magFilter = NearestFilter;
|
|
60208
|
+
this.bluenoise.needsUpdate = true;
|
|
60209
|
+
this.lastTime = 0;
|
|
60210
|
+
this.timeRollingAverage = 0.99;
|
|
60211
|
+
this.needsDepthTexture = true;
|
|
60212
|
+
this.needsSwap = true;
|
|
60213
|
+
this._r = new Vector2$1();
|
|
60214
|
+
this._c = new Color();
|
|
60215
|
+
}
|
|
60216
|
+
configureHalfResTargets() {
|
|
60217
|
+
this.firstFrame();
|
|
60218
|
+
if (this.configuration.halfRes) {
|
|
60219
|
+
this.depthDownsampleTarget = new $ff9437d9c7577f11$export$156f6a58f569aa09(Math.floor(this.width / 2), Math.floor(this.height / 2), 2);
|
|
60220
|
+
this.depthDownsampleTarget.textures[0].format = RedFormat;
|
|
60221
|
+
this.depthDownsampleTarget.textures[0].type = FloatType;
|
|
60222
|
+
this.depthDownsampleTarget.textures[0].minFilter = NearestFilter;
|
|
60223
|
+
this.depthDownsampleTarget.textures[0].magFilter = NearestFilter;
|
|
60224
|
+
this.depthDownsampleTarget.textures[0].depthBuffer = false;
|
|
60225
|
+
this.depthDownsampleTarget.textures[1].format = RGBAFormat;
|
|
60226
|
+
this.depthDownsampleTarget.textures[1].type = HalfFloatType;
|
|
60227
|
+
this.depthDownsampleTarget.textures[1].minFilter = NearestFilter;
|
|
60228
|
+
this.depthDownsampleTarget.textures[1].magFilter = NearestFilter;
|
|
60229
|
+
this.depthDownsampleTarget.textures[1].depthBuffer = false;
|
|
60230
|
+
this.depthDownsampleQuad = new $e4ca8dcb0218f846$export$dcd670d73db751f5(new ShaderMaterial($26aca173e0984d99$export$1efdf491687cd442));
|
|
60231
|
+
} else {
|
|
60232
|
+
if (this.depthDownsampleTarget) {
|
|
60233
|
+
this.depthDownsampleTarget.dispose();
|
|
60234
|
+
this.depthDownsampleTarget = null;
|
|
60235
|
+
}
|
|
60236
|
+
if (this.depthDownsampleQuad) {
|
|
60237
|
+
this.depthDownsampleQuad.dispose();
|
|
60238
|
+
this.depthDownsampleQuad = null;
|
|
60239
|
+
}
|
|
60240
|
+
}
|
|
60241
|
+
}
|
|
60242
|
+
detectTransparency() {
|
|
60243
|
+
if (this.autoDetectTransparency) {
|
|
60244
|
+
let isTransparency = false;
|
|
60245
|
+
this.scene.traverse((obj) => {
|
|
60246
|
+
if (obj.material && obj.material.transparent) isTransparency = true;
|
|
60247
|
+
});
|
|
60248
|
+
if (isTransparency) this.configuration.transparencyAware = true;
|
|
60249
|
+
}
|
|
60250
|
+
}
|
|
60251
|
+
configureTransparencyTarget() {
|
|
60252
|
+
if (this.configuration.transparencyAware) {
|
|
60253
|
+
this.transparencyRenderTargetDWFalse = new WebGLRenderTarget(this.width, this.height, {
|
|
60254
|
+
minFilter: LinearFilter,
|
|
60255
|
+
magFilter: NearestFilter,
|
|
60256
|
+
type: HalfFloatType,
|
|
60257
|
+
format: RGBAFormat
|
|
60258
|
+
});
|
|
60259
|
+
this.transparencyRenderTargetDWTrue = new WebGLRenderTarget(this.width, this.height, {
|
|
60260
|
+
minFilter: LinearFilter,
|
|
60261
|
+
magFilter: NearestFilter,
|
|
60262
|
+
type: HalfFloatType,
|
|
60263
|
+
format: RGBAFormat
|
|
60264
|
+
});
|
|
60265
|
+
this.transparencyRenderTargetDWTrue.depthTexture = new DepthTexture(this.width, this.height, UnsignedIntType);
|
|
60266
|
+
this.depthCopyPass = new $e4ca8dcb0218f846$export$dcd670d73db751f5(new ShaderMaterial({
|
|
60267
|
+
uniforms: {
|
|
60268
|
+
depthTexture: {
|
|
60269
|
+
value: this.depthTexture
|
|
60270
|
+
},
|
|
60271
|
+
reverseDepthBuffer: {
|
|
60272
|
+
value: this.configuration.depthBufferType === $05f6997e4b65da14$export$ed4ee5d1e55474a5.Reverse
|
|
60273
|
+
}
|
|
60274
|
+
},
|
|
60275
|
+
vertexShader: (
|
|
60276
|
+
/* glsl */
|
|
60277
|
+
`
|
|
60278
|
+
varying vec2 vUv;
|
|
60279
|
+
void main() {
|
|
60280
|
+
vUv = uv;
|
|
60281
|
+
gl_Position = vec4(position, 1);
|
|
60282
|
+
}`
|
|
60283
|
+
),
|
|
60284
|
+
fragmentShader: (
|
|
60285
|
+
/* glsl */
|
|
60286
|
+
`
|
|
60287
|
+
uniform sampler2D depthTexture;
|
|
60288
|
+
uniform bool reverseDepthBuffer;
|
|
60289
|
+
varying vec2 vUv;
|
|
60290
|
+
void main() {
|
|
60291
|
+
if (reverseDepthBuffer) {
|
|
60292
|
+
float d = 1.0 - texture2D(depthTexture, vUv).r;
|
|
60293
|
+
|
|
60294
|
+
d += 0.00001;
|
|
60295
|
+
gl_FragDepth = 1.0 - d;
|
|
60296
|
+
} else {
|
|
60297
|
+
float d = texture2D(depthTexture, vUv).r;
|
|
60298
|
+
d += 0.00001;
|
|
60299
|
+
gl_FragDepth = d;
|
|
60300
|
+
}
|
|
60301
|
+
gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0);
|
|
60302
|
+
}
|
|
60303
|
+
`
|
|
60304
|
+
)
|
|
60305
|
+
}));
|
|
60306
|
+
} else {
|
|
60307
|
+
if (this.transparencyRenderTargetDWFalse) {
|
|
60308
|
+
this.transparencyRenderTargetDWFalse.dispose();
|
|
60309
|
+
this.transparencyRenderTargetDWFalse = null;
|
|
60310
|
+
}
|
|
60311
|
+
if (this.transparencyRenderTargetDWTrue) {
|
|
60312
|
+
this.transparencyRenderTargetDWTrue.dispose();
|
|
60313
|
+
this.transparencyRenderTargetDWTrue = null;
|
|
60314
|
+
}
|
|
60315
|
+
if (this.depthCopyPass) {
|
|
60316
|
+
this.depthCopyPass.dispose();
|
|
60317
|
+
this.depthCopyPass = null;
|
|
60318
|
+
}
|
|
60319
|
+
}
|
|
60320
|
+
}
|
|
60321
|
+
renderTransparency(renderer) {
|
|
60322
|
+
const oldBackground = this.scene.background;
|
|
60323
|
+
const oldClearColor = renderer.getClearColor(new Color());
|
|
60324
|
+
const oldClearAlpha = renderer.getClearAlpha();
|
|
60325
|
+
const oldVisibility = /* @__PURE__ */ new Map();
|
|
60326
|
+
const oldAutoClearDepth = renderer.autoClearDepth;
|
|
60327
|
+
this.scene.traverse((obj) => {
|
|
60328
|
+
oldVisibility.set(obj, obj.visible);
|
|
60329
|
+
});
|
|
60330
|
+
this.scene.background = null;
|
|
60331
|
+
renderer.autoClearDepth = false;
|
|
60332
|
+
renderer.setClearColor(new Color(0, 0, 0), 0);
|
|
60333
|
+
this.depthCopyPass.material.uniforms.depthTexture.value = this.depthTexture;
|
|
60334
|
+
this.depthCopyPass.material.uniforms.reverseDepthBuffer.value = this.configuration.depthBufferType === $05f6997e4b65da14$export$ed4ee5d1e55474a5.Reverse;
|
|
60335
|
+
renderer.setRenderTarget(this.transparencyRenderTargetDWFalse);
|
|
60336
|
+
this.scene.traverse((obj) => {
|
|
60337
|
+
if (obj.material) obj.visible = oldVisibility.get(obj) && (obj.material.transparent && !obj.material.depthWrite && !obj.userData.treatAsOpaque || !!obj.userData.cannotReceiveAO);
|
|
60338
|
+
});
|
|
60339
|
+
renderer.clear(true, true, true);
|
|
60340
|
+
this.depthCopyPass.render(renderer);
|
|
60341
|
+
renderer.render(this.scene, this.camera);
|
|
60342
|
+
renderer.setRenderTarget(this.transparencyRenderTargetDWTrue);
|
|
60343
|
+
this.scene.traverse((obj) => {
|
|
60344
|
+
if (obj.material) obj.visible = oldVisibility.get(obj) && obj.material.transparent && obj.material.depthWrite && !obj.userData.treatAsOpaque;
|
|
60345
|
+
});
|
|
60346
|
+
renderer.clear(true, true, true);
|
|
60347
|
+
this.depthCopyPass.render(renderer);
|
|
60348
|
+
renderer.render(this.scene, this.camera);
|
|
60349
|
+
this.scene.traverse((obj) => {
|
|
60350
|
+
obj.visible = oldVisibility.get(obj);
|
|
60351
|
+
});
|
|
60352
|
+
renderer.setClearColor(oldClearColor, oldClearAlpha);
|
|
60353
|
+
this.scene.background = oldBackground;
|
|
60354
|
+
renderer.autoClearDepth = oldAutoClearDepth;
|
|
60355
|
+
}
|
|
60356
|
+
configureSampleDependentPasses() {
|
|
60357
|
+
this.configureAOPass(this.configuration.depthBufferType, this.camera.isOrthographicCamera);
|
|
60358
|
+
this.configureDenoisePass(this.configuration.depthBufferType, this.camera.isOrthographicCamera);
|
|
60359
|
+
}
|
|
60360
|
+
configureAOPass(depthBufferType = $05f6997e4b65da14$export$ed4ee5d1e55474a5.Default, ortho = false) {
|
|
60361
|
+
this.firstFrame();
|
|
60362
|
+
this.samples = this.generateHemisphereSamples(this.configuration.aoSamples);
|
|
60363
|
+
const e = {
|
|
60364
|
+
...$1ed45968c1160c3c$export$c9b263b9a17dffd7
|
|
60365
|
+
};
|
|
60366
|
+
e.fragmentShader = e.fragmentShader.replace("16", this.configuration.aoSamples).replace("16.0", this.configuration.aoSamples + ".0");
|
|
60367
|
+
if (depthBufferType === $05f6997e4b65da14$export$ed4ee5d1e55474a5.Log) e.fragmentShader = "#define LOGDEPTH\n" + e.fragmentShader;
|
|
60368
|
+
else if (depthBufferType === $05f6997e4b65da14$export$ed4ee5d1e55474a5.Reverse) e.fragmentShader = "#define REVERSEDEPTH\n" + e.fragmentShader;
|
|
60369
|
+
if (ortho) e.fragmentShader = "#define ORTHO\n" + e.fragmentShader;
|
|
60370
|
+
if (this.configuration.halfRes) e.fragmentShader = "#define HALFRES\n" + e.fragmentShader;
|
|
60371
|
+
if (this.effectShaderQuad) {
|
|
60372
|
+
this.effectShaderQuad.material.dispose();
|
|
60373
|
+
this.effectShaderQuad.material = new ShaderMaterial(e);
|
|
60374
|
+
} else this.effectShaderQuad = new $e4ca8dcb0218f846$export$dcd670d73db751f5(new ShaderMaterial(e));
|
|
60375
|
+
}
|
|
60376
|
+
configureDenoisePass(depthBufferType = $05f6997e4b65da14$export$ed4ee5d1e55474a5.Default, ortho = false) {
|
|
60377
|
+
this.firstFrame();
|
|
60378
|
+
this.samplesDenoise = this.generateDenoiseSamples(this.configuration.denoiseSamples, 11);
|
|
60379
|
+
const p2 = {
|
|
60380
|
+
...$e52378cd0f5a973d$export$57856b59f317262e
|
|
60381
|
+
};
|
|
60382
|
+
p2.fragmentShader = p2.fragmentShader.replace("__N8AO_DENOISE_SAMPLES__", this.configuration.denoiseSamples);
|
|
60383
|
+
if (depthBufferType === $05f6997e4b65da14$export$ed4ee5d1e55474a5.Log) p2.fragmentShader = "#define LOGDEPTH\n" + p2.fragmentShader;
|
|
60384
|
+
else if (depthBufferType === $05f6997e4b65da14$export$ed4ee5d1e55474a5.Reverse) p2.fragmentShader = "#define REVERSEDEPTH\n" + p2.fragmentShader;
|
|
60385
|
+
if (ortho) p2.fragmentShader = "#define ORTHO\n" + p2.fragmentShader;
|
|
60386
|
+
if (this.standardDenoiseMaterial) this.standardDenoiseMaterial.dispose();
|
|
60387
|
+
if (this.neuralDenoiseMaterial) this.neuralDenoiseMaterial.dispose();
|
|
60388
|
+
this.standardDenoiseMaterial = new ShaderMaterial(p2);
|
|
60389
|
+
this.neuralDenoiseMaterial = this.configuration.neuralDenoise && [
|
|
60390
|
+
4,
|
|
60391
|
+
8,
|
|
60392
|
+
16
|
|
60393
|
+
].includes(this.configuration.denoiseSamples) ? new ShaderMaterial({
|
|
60394
|
+
...p2,
|
|
60395
|
+
glslVersion: GLSL3,
|
|
60396
|
+
fragmentShader: "#define NEURAL_DENOISE\nlayout(location = 0) out highp vec4 neuralFragColor;\n#define gl_FragColor neuralFragColor\n" + p2.fragmentShader
|
|
60397
|
+
}) : null;
|
|
60398
|
+
if (this.poissonBlurQuad) this.poissonBlurQuad.material = this.standardDenoiseMaterial;
|
|
60399
|
+
else this.poissonBlurQuad = new $e4ca8dcb0218f846$export$dcd670d73db751f5(this.standardDenoiseMaterial);
|
|
60400
|
+
}
|
|
60401
|
+
shouldUseNeuralDenoise() {
|
|
60402
|
+
if (!this.configuration.neuralDenoise) {
|
|
60403
|
+
this._neuralDenoiseWarningKey = null;
|
|
60404
|
+
return false;
|
|
60405
|
+
}
|
|
60406
|
+
const incompatibilities = [];
|
|
60407
|
+
if (this.configuration.aoSamples !== 16) incompatibilities.push(`aoSamples is ${this.configuration.aoSamples} (expected 16)`);
|
|
60408
|
+
if (![
|
|
60409
|
+
4,
|
|
60410
|
+
8,
|
|
60411
|
+
16
|
|
60412
|
+
].includes(this.configuration.denoiseSamples)) incompatibilities.push(`denoiseSamples is ${this.configuration.denoiseSamples} (expected 4, 8, or 16)`);
|
|
60413
|
+
if (this.configuration.denoiseRadius !== 12) incompatibilities.push(`denoiseRadius is ${this.configuration.denoiseRadius} (expected 12)`);
|
|
60414
|
+
if (this.configuration.denoiseIterations !== 2) incompatibilities.push(`denoiseIterations is ${this.configuration.denoiseIterations} (expected 2)`);
|
|
60415
|
+
if (this.configuration.halfRes) incompatibilities.push("halfRes is enabled (expected full resolution)");
|
|
60416
|
+
if (incompatibilities.length > 0) {
|
|
60417
|
+
const warningKey = incompatibilities.join("; ");
|
|
60418
|
+
if (warningKey !== this._neuralDenoiseWarningKey) {
|
|
60419
|
+
console.warn(`[N8AO] neuralDenoise is enabled but cannot run: ${warningKey}. Neural denoising has been disabled; standard denoising will be used.`);
|
|
60420
|
+
this._neuralDenoiseWarningKey = warningKey;
|
|
60421
|
+
}
|
|
60422
|
+
return false;
|
|
60423
|
+
}
|
|
60424
|
+
this._neuralDenoiseWarningKey = null;
|
|
60425
|
+
return this.neuralDenoiseMaterial !== null;
|
|
60426
|
+
}
|
|
60427
|
+
configureEffectCompositer(depthBufferType = $05f6997e4b65da14$export$ed4ee5d1e55474a5.Default, ortho = false) {
|
|
60428
|
+
this.firstFrame();
|
|
60429
|
+
const e = {
|
|
60430
|
+
...$12b21d24d1192a04$export$a815acccbd2c9a49
|
|
60431
|
+
};
|
|
60432
|
+
if (depthBufferType === $05f6997e4b65da14$export$ed4ee5d1e55474a5.Log) e.fragmentShader = "#define LOGDEPTH\n" + e.fragmentShader;
|
|
60433
|
+
else if (depthBufferType === $05f6997e4b65da14$export$ed4ee5d1e55474a5.Reverse) e.fragmentShader = "#define REVERSEDEPTH\n" + e.fragmentShader;
|
|
60434
|
+
if (ortho) e.fragmentShader = "#define ORTHO\n" + e.fragmentShader;
|
|
60435
|
+
if (this.configuration.halfRes && this.configuration.depthAwareUpsampling) e.fragmentShader = "#define HALFRES\n" + e.fragmentShader;
|
|
60436
|
+
if (this.effectCompositerQuad) {
|
|
60437
|
+
this.effectCompositerQuad.material.dispose();
|
|
60438
|
+
this.effectCompositerQuad.material = new ShaderMaterial(e);
|
|
60439
|
+
} else this.effectCompositerQuad = new $e4ca8dcb0218f846$export$dcd670d73db751f5(new ShaderMaterial(e));
|
|
60440
|
+
}
|
|
60441
|
+
/**
|
|
60442
|
+
*
|
|
60443
|
+
* @param {Number} n
|
|
60444
|
+
* @returns {THREE.Vector3[]}
|
|
60445
|
+
*/
|
|
60446
|
+
generateHemisphereSamples(n) {
|
|
60447
|
+
const points = [];
|
|
60448
|
+
for (let k = 0; k < n; k++) {
|
|
60449
|
+
const theta = 2.399963 * k;
|
|
60450
|
+
const r = Math.sqrt(k + 0.5) / Math.sqrt(n);
|
|
60451
|
+
const x = r * Math.cos(theta);
|
|
60452
|
+
const y = r * Math.sin(theta);
|
|
60453
|
+
const z = Math.sqrt(1 - (x * x + y * y));
|
|
60454
|
+
points.push(new Vector3$1(x, y, z));
|
|
60455
|
+
}
|
|
60456
|
+
return points;
|
|
60457
|
+
}
|
|
60458
|
+
/**
|
|
60459
|
+
*
|
|
60460
|
+
* @param {number} numSamples
|
|
60461
|
+
* @param {number} numRings
|
|
60462
|
+
* @returns {THREE.Vector2[]}
|
|
60463
|
+
*/
|
|
60464
|
+
generateDenoiseSamples(numSamples, numRings) {
|
|
60465
|
+
const angleStep = 2 * Math.PI * numRings / numSamples;
|
|
60466
|
+
const invNumSamples = 1 / numSamples;
|
|
60467
|
+
const radiusStep = invNumSamples;
|
|
60468
|
+
const samples = [];
|
|
60469
|
+
let radius = invNumSamples;
|
|
60470
|
+
let angle = 0;
|
|
60471
|
+
for (let i = 0; i < numSamples; i++) {
|
|
60472
|
+
samples.push(new Vector2$1(Math.cos(angle), Math.sin(angle)).multiplyScalar(Math.pow(radius, 0.75)));
|
|
60473
|
+
radius += radiusStep;
|
|
60474
|
+
angle += angleStep;
|
|
60475
|
+
}
|
|
60476
|
+
return samples;
|
|
60477
|
+
}
|
|
60478
|
+
setSize(width, height) {
|
|
60479
|
+
this.firstFrame();
|
|
60480
|
+
this.width = Math.floor(width);
|
|
60481
|
+
this.height = Math.floor(height);
|
|
60482
|
+
const internalWidth = this.configuration.halfRes ? Math.floor(this.width / 2) : this.width;
|
|
60483
|
+
const internalHeight = this.configuration.halfRes ? Math.floor(this.height / 2) : this.height;
|
|
60484
|
+
this.writeTargetInternal.setSize(internalWidth, internalHeight);
|
|
60485
|
+
this.readTargetInternal.setSize(internalWidth, internalHeight);
|
|
60486
|
+
this.accumulationRenderTarget.setSize(internalWidth, internalHeight);
|
|
60487
|
+
if (this.configuration.halfRes) this.depthDownsampleTarget.setSize(internalWidth, internalHeight);
|
|
60488
|
+
if (this.configuration.transparencyAware) {
|
|
60489
|
+
this.transparencyRenderTargetDWFalse.setSize(this.width, this.height);
|
|
60490
|
+
this.transparencyRenderTargetDWTrue.setSize(this.width, this.height);
|
|
60491
|
+
}
|
|
60492
|
+
this.outputTargetInternal.setSize(this.width, this.height);
|
|
60493
|
+
}
|
|
60494
|
+
setDepthTexture(depthTexture) {
|
|
60495
|
+
this.depthTexture = depthTexture;
|
|
60496
|
+
}
|
|
60497
|
+
firstFrame() {
|
|
60498
|
+
this.needsFrame = true;
|
|
60499
|
+
}
|
|
60500
|
+
render(renderer, inputBuffer, outputBuffer) {
|
|
60501
|
+
const xrEnabled = renderer.xr.enabled;
|
|
60502
|
+
renderer.xr.enabled = false;
|
|
60503
|
+
const rendererUsesReverseDepth = renderer.capabilities.reversedDepthBuffer === true || renderer.capabilities.reverseDepthBuffer === true;
|
|
60504
|
+
const rendererDepthType = rendererUsesReverseDepth ? $05f6997e4b65da14$export$ed4ee5d1e55474a5.Reverse : renderer.capabilities.logarithmicDepthBuffer ? $05f6997e4b65da14$export$ed4ee5d1e55474a5.Log : $05f6997e4b65da14$export$ed4ee5d1e55474a5.Default;
|
|
60505
|
+
if (this.configuration.depthBufferType !== rendererDepthType) {
|
|
60506
|
+
this.configuration.depthBufferType = rendererDepthType;
|
|
60507
|
+
this.configureAOPass(this.configuration.depthBufferType, this.camera.isOrthographicCamera);
|
|
60508
|
+
this.configureDenoisePass(this.configuration.depthBufferType, this.camera.isOrthographicCamera);
|
|
60509
|
+
this.configureEffectCompositer(this.configuration.depthBufferType, this.camera.isOrthographicCamera);
|
|
60510
|
+
}
|
|
60511
|
+
this.detectTransparency();
|
|
60512
|
+
if (inputBuffer.texture.type !== this.outputTargetInternal.texture.type || inputBuffer.texture.format !== this.outputTargetInternal.texture.format) {
|
|
60513
|
+
this.outputTargetInternal.texture.type = inputBuffer.texture.type;
|
|
60514
|
+
this.outputTargetInternal.texture.format = inputBuffer.texture.format;
|
|
60515
|
+
this.outputTargetInternal.texture.needsUpdate = true;
|
|
60516
|
+
}
|
|
60517
|
+
this.camera.updateMatrixWorld();
|
|
60518
|
+
if (this.lastViewMatrix.equals(this.camera.matrixWorldInverse) && this.lastProjectionMatrix.equals(this.camera.projectionMatrix) && this.configuration.accumulate && !this.needsFrame) this.frame++;
|
|
60519
|
+
else {
|
|
60520
|
+
if (this.configuration.accumulate) {
|
|
60521
|
+
renderer.setRenderTarget(this.accumulationRenderTarget);
|
|
60522
|
+
renderer.clear(true, true, true);
|
|
60523
|
+
}
|
|
60524
|
+
this.frame = 0;
|
|
60525
|
+
this.needsFrame = false;
|
|
60526
|
+
}
|
|
60527
|
+
this.lastViewMatrix.copy(this.camera.matrixWorldInverse);
|
|
60528
|
+
this.lastProjectionMatrix.copy(this.camera.projectionMatrix);
|
|
60529
|
+
let gl;
|
|
60530
|
+
let ext;
|
|
60531
|
+
let timerQuery;
|
|
60532
|
+
if (this.debugMode) {
|
|
60533
|
+
gl = renderer.getContext();
|
|
60534
|
+
ext = gl.getExtension("EXT_disjoint_timer_query_webgl2");
|
|
60535
|
+
if (ext === null) {
|
|
60536
|
+
console.error("EXT_disjoint_timer_query_webgl2 not available, disabling debug mode.");
|
|
60537
|
+
this.debugMode = false;
|
|
60538
|
+
}
|
|
60539
|
+
}
|
|
60540
|
+
if (this.debugMode) {
|
|
60541
|
+
timerQuery = gl.createQuery();
|
|
60542
|
+
gl.beginQuery(ext.TIME_ELAPSED_EXT, timerQuery);
|
|
60543
|
+
}
|
|
60544
|
+
if (this.configuration.transparencyAware) this.renderTransparency(renderer);
|
|
60545
|
+
this._r.set(this.width, this.height);
|
|
60546
|
+
let trueRadius = this.configuration.aoRadius;
|
|
60547
|
+
if (this.configuration.halfRes && this.configuration.screenSpaceRadius) trueRadius *= 0.5;
|
|
60548
|
+
if (this.frame < 1024 / this.configuration.aoSamples) {
|
|
60549
|
+
if (this.configuration.halfRes) {
|
|
60550
|
+
renderer.setRenderTarget(this.depthDownsampleTarget);
|
|
60551
|
+
this.depthDownsampleQuad.material.uniforms.sceneDepth.value = this.depthTexture;
|
|
60552
|
+
this.depthDownsampleQuad.material.uniforms.resolution.value = this._r;
|
|
60553
|
+
this.depthDownsampleQuad.material.uniforms["near"].value = this.camera.near;
|
|
60554
|
+
this.depthDownsampleQuad.material.uniforms["far"].value = this.camera.far;
|
|
60555
|
+
this.depthDownsampleQuad.material.uniforms["projectionMatrixInv"].value = this.camera.projectionMatrixInverse;
|
|
60556
|
+
this.depthDownsampleQuad.material.uniforms["viewMatrixInv"].value = this.camera.matrixWorld;
|
|
60557
|
+
this.depthDownsampleQuad.material.uniforms["logDepth"].value = this.configuration.depthBufferType === $05f6997e4b65da14$export$ed4ee5d1e55474a5.Log;
|
|
60558
|
+
this.depthDownsampleQuad.material.uniforms["ortho"].value = this.camera.isOrthographicCamera;
|
|
60559
|
+
this.depthDownsampleQuad.render(renderer);
|
|
60560
|
+
}
|
|
60561
|
+
this.effectShaderQuad.material.uniforms["sceneDiffuse"].value = inputBuffer.texture;
|
|
60562
|
+
this.effectShaderQuad.material.uniforms["sceneDepth"].value = this.configuration.halfRes ? this.depthDownsampleTarget.textures[0] : this.depthTexture;
|
|
60563
|
+
this.effectShaderQuad.material.uniforms["sceneNormal"].value = this.configuration.halfRes ? this.depthDownsampleTarget.textures[1] : null;
|
|
60564
|
+
this.effectShaderQuad.material.uniforms["projMat"].value = this.camera.projectionMatrix;
|
|
60565
|
+
this.effectShaderQuad.material.uniforms["viewMat"].value = this.camera.matrixWorldInverse;
|
|
60566
|
+
this.effectShaderQuad.material.uniforms["projViewMat"].value = this.camera.projectionMatrix.clone().multiply(this.camera.matrixWorldInverse.clone());
|
|
60567
|
+
this.effectShaderQuad.material.uniforms["projectionMatrixInv"].value = this.camera.projectionMatrixInverse;
|
|
60568
|
+
this.effectShaderQuad.material.uniforms["viewMatrixInv"].value = this.camera.matrixWorld;
|
|
60569
|
+
this.effectShaderQuad.material.uniforms["cameraPos"].value = this.camera.getWorldPosition(new Vector3$1());
|
|
60570
|
+
this.effectShaderQuad.material.uniforms["biasAdjustment"].value = new Vector2$1(this.configuration.biasOffset, this.configuration.biasMultiplier);
|
|
60571
|
+
this.effectShaderQuad.material.uniforms["resolution"].value = this.configuration.halfRes ? this._r.clone().multiplyScalar(0.5).floor() : this._r;
|
|
60572
|
+
this.effectShaderQuad.material.uniforms["time"].value = performance.now() / 1e3;
|
|
60573
|
+
this.effectShaderQuad.material.uniforms["samples"].value = this.samples;
|
|
60574
|
+
this.effectShaderQuad.material.uniforms["bluenoise"].value = this.bluenoise;
|
|
60575
|
+
this.effectShaderQuad.material.uniforms["radius"].value = trueRadius;
|
|
60576
|
+
this.effectShaderQuad.material.uniforms["distanceFalloff"].value = this.configuration.distanceFalloff;
|
|
60577
|
+
this.effectShaderQuad.material.uniforms["near"].value = this.camera.near;
|
|
60578
|
+
this.effectShaderQuad.material.uniforms["far"].value = this.camera.far;
|
|
60579
|
+
this.effectShaderQuad.material.uniforms["ortho"].value = this.camera.isOrthographicCamera;
|
|
60580
|
+
this.effectShaderQuad.material.uniforms["screenSpaceRadius"].value = this.configuration.screenSpaceRadius;
|
|
60581
|
+
this.effectShaderQuad.material.uniforms["frame"].value = this.frame;
|
|
60582
|
+
renderer.setRenderTarget(this.writeTargetInternal);
|
|
60583
|
+
this.effectShaderQuad.render(renderer);
|
|
60584
|
+
const useNeuralDenoise = this.shouldUseNeuralDenoise();
|
|
60585
|
+
for (let i = 0; i < this.configuration.denoiseIterations; i++) {
|
|
60586
|
+
[this.writeTargetInternal, this.readTargetInternal] = [
|
|
60587
|
+
this.readTargetInternal,
|
|
60588
|
+
this.writeTargetInternal
|
|
60589
|
+
];
|
|
60590
|
+
this.poissonBlurQuad.material = useNeuralDenoise && i === 1 ? this.neuralDenoiseMaterial : this.standardDenoiseMaterial;
|
|
60591
|
+
this.poissonBlurQuad.material.uniforms["tDiffuse"].value = this.readTargetInternal.texture;
|
|
60592
|
+
this.poissonBlurQuad.material.uniforms["sceneDepth"].value = this.configuration.halfRes ? this.depthDownsampleTarget.textures[0] : this.depthTexture;
|
|
60593
|
+
this.poissonBlurQuad.material.uniforms["projMat"].value = this.camera.projectionMatrix;
|
|
60594
|
+
this.poissonBlurQuad.material.uniforms["viewMat"].value = this.camera.matrixWorldInverse;
|
|
60595
|
+
this.poissonBlurQuad.material.uniforms["projectionMatrixInv"].value = this.camera.projectionMatrixInverse;
|
|
60596
|
+
this.poissonBlurQuad.material.uniforms["viewMatrixInv"].value = this.camera.matrixWorld;
|
|
60597
|
+
this.poissonBlurQuad.material.uniforms["cameraPos"].value = this.camera.getWorldPosition(new Vector3$1());
|
|
60598
|
+
this.poissonBlurQuad.material.uniforms["resolution"].value = this.configuration.halfRes ? this._r.clone().multiplyScalar(0.5).floor() : this._r;
|
|
60599
|
+
this.poissonBlurQuad.material.uniforms["time"].value = performance.now() / 1e3;
|
|
60600
|
+
this.poissonBlurQuad.material.uniforms["blueNoise"].value = this.bluenoise;
|
|
60601
|
+
this.poissonBlurQuad.material.uniforms["radius"].value = this.configuration.denoiseRadius * (this.configuration.halfRes ? 0.5 : 1);
|
|
60602
|
+
this.poissonBlurQuad.material.uniforms["worldRadius"].value = trueRadius;
|
|
60603
|
+
this.poissonBlurQuad.material.uniforms["distanceFalloff"].value = this.configuration.distanceFalloff;
|
|
60604
|
+
this.poissonBlurQuad.material.uniforms["index"].value = i;
|
|
60605
|
+
this.poissonBlurQuad.material.uniforms["poissonDisk"].value = this.samplesDenoise;
|
|
60606
|
+
this.poissonBlurQuad.material.uniforms["near"].value = this.camera.near;
|
|
60607
|
+
this.poissonBlurQuad.material.uniforms["far"].value = this.camera.far;
|
|
60608
|
+
this.poissonBlurQuad.material.uniforms["screenSpaceRadius"].value = this.configuration.screenSpaceRadius;
|
|
60609
|
+
renderer.setRenderTarget(this.writeTargetInternal);
|
|
60610
|
+
this.poissonBlurQuad.render(renderer);
|
|
60611
|
+
}
|
|
60612
|
+
renderer.setRenderTarget(this.accumulationRenderTarget);
|
|
60613
|
+
const oldAutoClear = renderer.autoClear;
|
|
60614
|
+
renderer.autoClear = false;
|
|
60615
|
+
this.accumulationQuad.material.uniforms["tDiffuse"].value = this.writeTargetInternal.texture;
|
|
60616
|
+
this.accumulationQuad.material.uniforms["frame"].value = this.frame;
|
|
60617
|
+
this.accumulationQuad.render(renderer);
|
|
60618
|
+
renderer.autoClear = oldAutoClear;
|
|
60619
|
+
}
|
|
60620
|
+
if (this.configuration.transparencyAware) {
|
|
60621
|
+
this.effectCompositerQuad.material.uniforms["transparencyDWFalse"].value = this.transparencyRenderTargetDWFalse.texture;
|
|
60622
|
+
this.effectCompositerQuad.material.uniforms["transparencyDWTrue"].value = this.transparencyRenderTargetDWTrue.texture;
|
|
60623
|
+
this.effectCompositerQuad.material.uniforms["transparencyDWTrueDepth"].value = this.transparencyRenderTargetDWTrue.depthTexture;
|
|
60624
|
+
this.effectCompositerQuad.material.uniforms["transparencyAware"].value = true;
|
|
60625
|
+
}
|
|
60626
|
+
this.effectCompositerQuad.material.uniforms["sceneDiffuse"].value = inputBuffer.texture;
|
|
60627
|
+
this.effectCompositerQuad.material.uniforms["sceneDepth"].value = this.depthTexture;
|
|
60628
|
+
this.effectCompositerQuad.material.uniforms["aoTones"].value = this.configuration.aoTones;
|
|
60629
|
+
this.effectCompositerQuad.material.uniforms["near"].value = this.camera.near;
|
|
60630
|
+
this.effectCompositerQuad.material.uniforms["far"].value = this.camera.far;
|
|
60631
|
+
this.effectCompositerQuad.material.uniforms["projectionMatrixInv"].value = this.camera.projectionMatrixInverse;
|
|
60632
|
+
this.effectCompositerQuad.material.uniforms["ortho"].value = this.camera.isOrthographicCamera;
|
|
60633
|
+
this.effectCompositerQuad.material.uniforms["downsampledDepth"].value = this.configuration.halfRes ? this.depthDownsampleTarget.textures[0] : this.depthTexture;
|
|
60634
|
+
this.effectCompositerQuad.material.uniforms["resolution"].value = this._r;
|
|
60635
|
+
this.effectCompositerQuad.material.uniforms["blueNoise"].value = this.bluenoise;
|
|
60636
|
+
this.effectCompositerQuad.material.uniforms["intensity"].value = this.configuration.intensity;
|
|
60637
|
+
this.effectCompositerQuad.material.uniforms["renderMode"].value = this.configuration.renderMode;
|
|
60638
|
+
this.effectCompositerQuad.material.uniforms["screenSpaceRadius"].value = this.configuration.screenSpaceRadius;
|
|
60639
|
+
this.effectCompositerQuad.material.uniforms["radius"].value = trueRadius;
|
|
60640
|
+
this.effectCompositerQuad.material.uniforms["distanceFalloff"].value = this.configuration.distanceFalloff;
|
|
60641
|
+
this.effectCompositerQuad.material.uniforms["gammaCorrection"].value = this.autosetGamma ? this.renderToScreen : this.configuration.gammaCorrection;
|
|
60642
|
+
this.effectCompositerQuad.material.uniforms["tDiffuse"].value = this.accumulationRenderTarget.texture;
|
|
60643
|
+
this.effectCompositerQuad.material.uniforms["color"].value = this._c.copy(this.configuration.color).convertSRGBToLinear();
|
|
60644
|
+
this.effectCompositerQuad.material.uniforms["colorMultiply"].value = this.configuration.colorMultiply;
|
|
60645
|
+
this.effectCompositerQuad.material.uniforms["fog"].value = !!this.scene.fog;
|
|
60646
|
+
if (this.scene.fog) {
|
|
60647
|
+
if (this.scene.fog.isFog) {
|
|
60648
|
+
this.effectCompositerQuad.material.uniforms["fogExp"].value = false;
|
|
60649
|
+
this.effectCompositerQuad.material.uniforms["fogNear"].value = this.scene.fog.near;
|
|
60650
|
+
this.effectCompositerQuad.material.uniforms["fogFar"].value = this.scene.fog.far;
|
|
60651
|
+
} else if (this.scene.fog.isFogExp2) {
|
|
60652
|
+
this.effectCompositerQuad.material.uniforms["fogExp"].value = true;
|
|
60653
|
+
this.effectCompositerQuad.material.uniforms["fogDensity"].value = this.scene.fog.density;
|
|
60654
|
+
} else console.error(`Unsupported fog type ${this.scene.fog.constructor.name} in SSAOPass.`);
|
|
60655
|
+
}
|
|
60656
|
+
renderer.setRenderTarget(
|
|
60657
|
+
/* this.renderToScreen ? null :
|
|
60658
|
+
outputBuffer*/
|
|
60659
|
+
this.outputTargetInternal
|
|
60660
|
+
);
|
|
60661
|
+
this.effectCompositerQuad.render(renderer);
|
|
60662
|
+
renderer.setRenderTarget(this.renderToScreen ? null : outputBuffer);
|
|
60663
|
+
this.copyQuad.material.uniforms["tDiffuse"].value = this.outputTargetInternal.texture;
|
|
60664
|
+
this.copyQuad.render(renderer);
|
|
60665
|
+
if (this.debugMode) {
|
|
60666
|
+
gl.endQuery(ext.TIME_ELAPSED_EXT);
|
|
60667
|
+
$87431ee93b037844$var$checkTimerQuery(timerQuery, gl, this);
|
|
60668
|
+
}
|
|
60669
|
+
renderer.xr.enabled = xrEnabled;
|
|
60670
|
+
}
|
|
60671
|
+
/**
|
|
60672
|
+
* Enables the debug mode of the AO, meaning the lastTime value will be updated.
|
|
60673
|
+
*/
|
|
60674
|
+
enableDebugMode() {
|
|
60675
|
+
this.debugMode = true;
|
|
60676
|
+
}
|
|
60677
|
+
/**
|
|
60678
|
+
* Disables the debug mode of the AO, meaning the lastTime value will not be updated.
|
|
60679
|
+
*/
|
|
60680
|
+
disableDebugMode() {
|
|
60681
|
+
this.debugMode = false;
|
|
60682
|
+
}
|
|
60683
|
+
/**
|
|
60684
|
+
* Sets the display mode of the AO
|
|
60685
|
+
* @param {"Combined" | "AO" | "No AO" | "Split" | "Split AO"} mode - The display mode.
|
|
60686
|
+
*/
|
|
60687
|
+
setDisplayMode(mode) {
|
|
60688
|
+
this.configuration.renderMode = [
|
|
60689
|
+
"Combined",
|
|
60690
|
+
"AO",
|
|
60691
|
+
"No AO",
|
|
60692
|
+
"Split",
|
|
60693
|
+
"Split AO"
|
|
60694
|
+
].indexOf(mode);
|
|
60695
|
+
}
|
|
60696
|
+
/**
|
|
60697
|
+
*
|
|
60698
|
+
* @param {"Performance" | "Low" | "Medium" | "High" | "Ultra" | "Neural-Low" | "Neural-Medium" | "Neural-High"} mode
|
|
60699
|
+
*/
|
|
60700
|
+
setQualityMode(mode) {
|
|
60701
|
+
if (mode === "Performance") {
|
|
60702
|
+
this.configuration.neuralDenoise = false;
|
|
60703
|
+
this.configuration.aoSamples = 8;
|
|
60704
|
+
this.configuration.denoiseSamples = 4;
|
|
60705
|
+
this.configuration.denoiseRadius = 12;
|
|
60706
|
+
} else if (mode === "Low") {
|
|
60707
|
+
this.configuration.neuralDenoise = false;
|
|
60708
|
+
this.configuration.aoSamples = 16;
|
|
60709
|
+
this.configuration.denoiseSamples = 4;
|
|
60710
|
+
this.configuration.denoiseRadius = 12;
|
|
60711
|
+
} else if (mode === "Medium") {
|
|
60712
|
+
this.configuration.neuralDenoise = false;
|
|
60713
|
+
this.configuration.aoSamples = 16;
|
|
60714
|
+
this.configuration.denoiseSamples = 8;
|
|
60715
|
+
this.configuration.denoiseRadius = 12;
|
|
60716
|
+
} else if (mode === "High") {
|
|
60717
|
+
this.configuration.neuralDenoise = false;
|
|
60718
|
+
this.configuration.aoSamples = 64;
|
|
60719
|
+
this.configuration.denoiseSamples = 8;
|
|
60720
|
+
this.configuration.denoiseRadius = 6;
|
|
60721
|
+
} else if (mode === "Ultra") {
|
|
60722
|
+
this.configuration.neuralDenoise = false;
|
|
60723
|
+
this.configuration.aoSamples = 64;
|
|
60724
|
+
this.configuration.denoiseSamples = 16;
|
|
60725
|
+
this.configuration.denoiseRadius = 6;
|
|
60726
|
+
} else if ([
|
|
60727
|
+
"Neural-Low",
|
|
60728
|
+
"Neural-Medium",
|
|
60729
|
+
"Neural-High"
|
|
60730
|
+
].includes(mode)) {
|
|
60731
|
+
this.configuration.aoSamples = 16;
|
|
60732
|
+
this.configuration.denoiseSamples = {
|
|
60733
|
+
"Neural-Low": 4,
|
|
60734
|
+
"Neural-Medium": 8,
|
|
60735
|
+
"Neural-High": 16
|
|
60736
|
+
}[mode];
|
|
60737
|
+
this.configuration.denoiseRadius = 12;
|
|
60738
|
+
this.configuration.denoiseIterations = 2;
|
|
60739
|
+
this.configuration.halfRes = false;
|
|
60740
|
+
this.configuration.neuralDenoise = true;
|
|
60741
|
+
}
|
|
60742
|
+
}
|
|
60743
|
+
}
|
|
60744
|
+
const $05f6997e4b65da14$export$ed4ee5d1e55474a5 = {
|
|
60745
|
+
Default: 1,
|
|
60746
|
+
Log: 2,
|
|
60747
|
+
Reverse: 3
|
|
60748
|
+
};
|
|
57372
60749
|
function disposeMesh(scene, mesh) {
|
|
57373
60750
|
if (mesh.material) {
|
|
57374
60751
|
const materials = Array.isArray(mesh.material) ? mesh.material : [mesh.material];
|
|
@@ -57651,6 +61028,8 @@ class RBXRenderer {
|
|
|
57651
61028
|
return RBXRenderer.firstScene.controls;
|
|
57652
61029
|
}
|
|
57653
61030
|
static renderer;
|
|
61031
|
+
static usePostProcessing = true;
|
|
61032
|
+
static n8aoPass = void 0;
|
|
57654
61033
|
static resolution = [420, 420];
|
|
57655
61034
|
static backgroundColor = 2829619;
|
|
57656
61035
|
/**@deprecated Use backgroundColor instead */
|
|
@@ -57834,9 +61213,6 @@ class RBXRenderer {
|
|
|
57834
61213
|
RBXRenderer.renderer.shadowMap.type = PCFShadowMap;
|
|
57835
61214
|
RBXRenderer.renderer.setPixelRatio(globalThis.devicePixelRatio * 1 || 1);
|
|
57836
61215
|
RBXRenderer.renderer.setSize(...RBXRenderer.resolution);
|
|
57837
|
-
if (FLAGS.USE_POST_PROCESSING && FLAGS.POST_PROCESSING_IS_DOUBLE_SIZE) {
|
|
57838
|
-
RBXRenderer.renderer.setSize(RBXRenderer.resolution[0] * 2, RBXRenderer.resolution[1] * 2);
|
|
57839
|
-
}
|
|
57840
61216
|
RBXRenderer.renderer.domElement.setAttribute("id", "OutfitInfo-outfit-image-3d");
|
|
57841
61217
|
RBXRenderer.canvasContainer.appendChild(RBXRenderer.renderer.domElement);
|
|
57842
61218
|
if (RBXRenderer.createLoadingIcon && !RBXRenderer.loadingIcon) {
|
|
@@ -58042,7 +61418,7 @@ class RBXRenderer {
|
|
|
58042
61418
|
if (!autoClear) {
|
|
58043
61419
|
RBXRenderer.renderer.clearDepth();
|
|
58044
61420
|
}
|
|
58045
|
-
RBXRenderer.renderer.setRenderTarget(null);
|
|
61421
|
+
if (!(renderScene.effectComposer && this.usePostProcessing)) RBXRenderer.renderer.setRenderTarget(null);
|
|
58046
61422
|
let [x, y] = [0, 0];
|
|
58047
61423
|
let [width, height] = RBXRenderer.resolution;
|
|
58048
61424
|
if (renderScene.viewport) {
|
|
@@ -58051,6 +61427,10 @@ class RBXRenderer {
|
|
|
58051
61427
|
width = renderScene.viewport[2];
|
|
58052
61428
|
height = renderScene.viewport[3];
|
|
58053
61429
|
}
|
|
61430
|
+
if (FLAGS.POST_PROCESSING_IS_DOUBLE_SIZE) {
|
|
61431
|
+
width *= 2;
|
|
61432
|
+
height *= 2;
|
|
61433
|
+
}
|
|
58054
61434
|
RBXRenderer.renderer.setViewport(x, y, width, height);
|
|
58055
61435
|
if (renderScene.scissor) {
|
|
58056
61436
|
RBXRenderer.renderer.setScissorTest(true);
|
|
@@ -58061,7 +61441,7 @@ class RBXRenderer {
|
|
|
58061
61441
|
renderScene.camera.aspect = width / height;
|
|
58062
61442
|
renderScene.camera.updateProjectionMatrix();
|
|
58063
61443
|
if (width > 0 && height > 0) {
|
|
58064
|
-
if (renderScene.effectComposer) {
|
|
61444
|
+
if (renderScene.effectComposer && this.usePostProcessing) {
|
|
58065
61445
|
renderScene.effectComposer.render();
|
|
58066
61446
|
} else {
|
|
58067
61447
|
RBXRenderer.renderer.render(renderScene.scene, renderScene.camera);
|
|
@@ -58071,9 +61451,28 @@ class RBXRenderer {
|
|
|
58071
61451
|
}
|
|
58072
61452
|
static _createEffectComposer(renderScene = RBXRenderer.firstScene) {
|
|
58073
61453
|
if (!RBXRenderer.renderer) return;
|
|
58074
|
-
renderScene.effectComposer
|
|
61454
|
+
if (renderScene.effectComposer) {
|
|
61455
|
+
renderScene.effectComposer.dispose();
|
|
61456
|
+
}
|
|
61457
|
+
renderScene.effectComposer = new EffectComposer(RBXRenderer.renderer, {
|
|
61458
|
+
frameBufferType: HalfFloatType,
|
|
61459
|
+
multisampling: 0
|
|
61460
|
+
});
|
|
58075
61461
|
renderScene.effectComposer.addPass(new RenderPass(renderScene.scene, renderScene.camera));
|
|
58076
|
-
|
|
61462
|
+
const n8aoPass = new $87431ee93b037844$export$2489f9981ab0fa82(renderScene.scene, renderScene.camera, FLAGS.POST_PROCESSING_IS_DOUBLE_SIZE ? 840 : 420, FLAGS.POST_PROCESSING_IS_DOUBLE_SIZE ? 840 : 420);
|
|
61463
|
+
n8aoPass.configuration.aoRadius = 0.2;
|
|
61464
|
+
RBXRenderer.n8aoPass = n8aoPass;
|
|
61465
|
+
renderScene.effectComposer.addPass(n8aoPass);
|
|
61466
|
+
renderScene.effectComposer.addPass(new EffectPass(renderScene.camera, new SMAAEffect({
|
|
61467
|
+
preset: SMAAPreset.ULTRA
|
|
61468
|
+
})));
|
|
61469
|
+
renderScene.effectComposer.addPass(new EffectPass(renderScene.camera, new BloomEffect({
|
|
61470
|
+
blendFunction: BlendFunction.ADD,
|
|
61471
|
+
mipmapBlur: true,
|
|
61472
|
+
luminanceThreshold: 0.95,
|
|
61473
|
+
luminanceSmoothing: 0.2,
|
|
61474
|
+
intensity: 0.22
|
|
61475
|
+
})));
|
|
58077
61476
|
}
|
|
58078
61477
|
/**Removes an instance from the renderer */
|
|
58079
61478
|
static removeInstance(instance, renderScene = RBXRenderer.firstScene) {
|
|
@@ -58188,8 +61587,21 @@ class RBXRenderer {
|
|
|
58188
61587
|
RBXRenderer.canvasContainer.style.width = `${RBXRenderer.resolution[0]}px`;
|
|
58189
61588
|
RBXRenderer.canvasContainer.style.height = `${RBXRenderer.resolution[1]}px`;
|
|
58190
61589
|
RBXRenderer.renderer.setSize(width, height);
|
|
58191
|
-
if (
|
|
58192
|
-
|
|
61590
|
+
if (RBXRenderer.n8aoPass) {
|
|
61591
|
+
if (FLAGS.POST_PROCESSING_IS_DOUBLE_SIZE) {
|
|
61592
|
+
RBXRenderer.n8aoPass.setSize(width * 2, height * 2);
|
|
61593
|
+
} else {
|
|
61594
|
+
RBXRenderer.n8aoPass.setSize(width, height);
|
|
61595
|
+
}
|
|
61596
|
+
}
|
|
61597
|
+
for (const renderScene of this.scenes) {
|
|
61598
|
+
if (renderScene.effectComposer) {
|
|
61599
|
+
if (FLAGS.POST_PROCESSING_IS_DOUBLE_SIZE) {
|
|
61600
|
+
renderScene.effectComposer.setSize(width * 2, height * 2, false);
|
|
61601
|
+
} else {
|
|
61602
|
+
renderScene.effectComposer.setSize(width, height, false);
|
|
61603
|
+
}
|
|
61604
|
+
}
|
|
58193
61605
|
}
|
|
58194
61606
|
}
|
|
58195
61607
|
/**
|
|
@@ -58947,6 +62359,7 @@ class BackgroundRenderer {
|
|
|
58947
62359
|
currentlyUpdating = false;
|
|
58948
62360
|
hasNewUpdate = false;
|
|
58949
62361
|
affectSceneAppearance = true;
|
|
62362
|
+
affectSceneLighting = true;
|
|
58950
62363
|
cameraAffectsTransparency = true;
|
|
58951
62364
|
cameraAffectsRotation = false;
|
|
58952
62365
|
lastFrameTime = Date.now() / 1e3;
|
|
@@ -58956,6 +62369,7 @@ class BackgroundRenderer {
|
|
|
58956
62369
|
renderScene = RBXRenderer.firstScene;
|
|
58957
62370
|
_renderSceneCompiledConnection;
|
|
58958
62371
|
_renderSceneFailedConnection;
|
|
62372
|
+
ambientLight = new AmbientLight();
|
|
58959
62373
|
hasFiredFullyRendered = false;
|
|
58960
62374
|
/**Event is fired if a new outfit failed to load (specifically the Instance tree, not the rendering part)
|
|
58961
62375
|
*
|
|
@@ -59076,6 +62490,11 @@ class BackgroundRenderer {
|
|
|
59076
62490
|
const imageId = imageIdValue.Prop("Value");
|
|
59077
62491
|
cyclorama.Child("color_mesh").setProperty("Color", color2.toColor3uint8());
|
|
59078
62492
|
cyclorama.Child("texture_mesh").setProperty("TextureID", `rbxassetid://${imageId}`);
|
|
62493
|
+
if (this.affectSceneLighting) {
|
|
62494
|
+
this.ambientLight.color = new Color().setRGB(...color2.toArray(), SRGBColorSpace);
|
|
62495
|
+
this.ambientLight.intensity = 1 * (1 - targetTransparency);
|
|
62496
|
+
this.renderScene.scene.add(this.ambientLight);
|
|
62497
|
+
}
|
|
59079
62498
|
}
|
|
59080
62499
|
} else {
|
|
59081
62500
|
cyclorama.Child("color_mesh").setProperty("Transparency", 1);
|
|
@@ -59083,7 +62502,16 @@ class BackgroundRenderer {
|
|
|
59083
62502
|
}
|
|
59084
62503
|
cyclorama.preRender();
|
|
59085
62504
|
RBXRenderer.addInstance(cyclorama, this.auth, this.renderScene);
|
|
62505
|
+
const colorDesc = this.renderScene.renderDescs.get(cyclorama.Child("color_mesh"));
|
|
62506
|
+
const textureDesc = this.renderScene.renderDescs.get(cyclorama.Child("texture_mesh"));
|
|
62507
|
+
if (colorDesc && colorDesc.results && colorDesc.results[0]) {
|
|
62508
|
+
colorDesc.results[0].renderOrder = -2;
|
|
62509
|
+
}
|
|
62510
|
+
if (textureDesc && textureDesc.results && textureDesc.results[0]) {
|
|
62511
|
+
textureDesc.results[0].renderOrder = -1;
|
|
62512
|
+
}
|
|
59086
62513
|
} else if (this.avatarCyclorama) {
|
|
62514
|
+
this.renderScene.scene.remove(this.ambientLight);
|
|
59087
62515
|
RBXRenderer.removeInstance(this.avatarCyclorama, this.renderScene);
|
|
59088
62516
|
}
|
|
59089
62517
|
this.fireFullyRenderedIfNeeded();
|
|
@@ -59145,6 +62573,7 @@ class BackgroundRenderer {
|
|
|
59145
62573
|
/**Calls destroy on the background, stops animating and disconnects connections. The OutfitRenderer should not be interacted with after this */
|
|
59146
62574
|
destroy() {
|
|
59147
62575
|
this.stopAnimating();
|
|
62576
|
+
this.renderScene.scene.remove(this.ambientLight);
|
|
59148
62577
|
if (this.avatarCyclorama) RBXRenderer.removeInstance(this.avatarCyclorama, this.renderScene);
|
|
59149
62578
|
this.avatarCyclorama?.Destroy();
|
|
59150
62579
|
this.avatarCyclorama = void 0;
|