添加关照、全局等高线、修改图层问题
This commit is contained in:
288
static/sdk/three/jsm/shaders/FXAAShader.js
Normal file
288
static/sdk/three/jsm/shaders/FXAAShader.js
Normal file
@ -0,0 +1,288 @@
|
||||
import {
|
||||
Vector2
|
||||
} from 'three';
|
||||
|
||||
/**
|
||||
* NVIDIA FXAA by Timothy Lottes
|
||||
* https://developer.download.nvidia.com/assets/gamedev/files/sdk/11/FXAA_WhitePaper.pdf
|
||||
* - WebGL port by @supereggbert
|
||||
* http://www.glge.org/demos/fxaa/
|
||||
* Further improved by Daniel Sturk
|
||||
*/
|
||||
|
||||
const FXAAShader = {
|
||||
|
||||
name: 'FXAAShader',
|
||||
|
||||
uniforms: {
|
||||
|
||||
'tDiffuse': { value: null },
|
||||
'resolution': { value: new Vector2( 1 / 1024, 1 / 512 ) }
|
||||
|
||||
},
|
||||
|
||||
vertexShader: /* glsl */`
|
||||
|
||||
varying vec2 vUv;
|
||||
|
||||
void main() {
|
||||
|
||||
vUv = uv;
|
||||
gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
|
||||
|
||||
}`,
|
||||
|
||||
fragmentShader: /* glsl */`
|
||||
precision highp float;
|
||||
|
||||
uniform sampler2D tDiffuse;
|
||||
|
||||
uniform vec2 resolution;
|
||||
|
||||
varying vec2 vUv;
|
||||
|
||||
// FXAA 3.11 implementation by NVIDIA, ported to WebGL by Agost Biro (biro@archilogic.com)
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// File: es3-kepler\FXAA\assets\shaders/FXAA_DefaultES.frag
|
||||
// SDK Version: v3.00
|
||||
// Email: gameworks@nvidia.com
|
||||
// Site: http://developer.nvidia.com/
|
||||
//
|
||||
// Copyright (c) 2014-2015, NVIDIA CORPORATION. All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
#ifndef FXAA_DISCARD
|
||||
//
|
||||
// Only valid for PC OpenGL currently.
|
||||
// Probably will not work when FXAA_GREEN_AS_LUMA = 1.
|
||||
//
|
||||
// 1 = Use discard on pixels which don't need AA.
|
||||
// For APIs which enable concurrent TEX+ROP from same surface.
|
||||
// 0 = Return unchanged color on pixels which don't need AA.
|
||||
//
|
||||
#define FXAA_DISCARD 0
|
||||
#endif
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
#define FxaaTexTop(t, p) texture2D(t, p, -100.0)
|
||||
#define FxaaTexOff(t, p, o, r) texture2D(t, p + (o * r), -100.0)
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
#define NUM_SAMPLES 5
|
||||
|
||||
// assumes colors have premultipliedAlpha, so that the calculated color contrast is scaled by alpha
|
||||
float contrast( vec4 a, vec4 b ) {
|
||||
vec4 diff = abs( a - b );
|
||||
return max( max( max( diff.r, diff.g ), diff.b ), diff.a );
|
||||
}
|
||||
|
||||
/*============================================================================
|
||||
|
||||
FXAA3 QUALITY - PC
|
||||
|
||||
============================================================================*/
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
vec4 FxaaPixelShader(
|
||||
vec2 posM,
|
||||
sampler2D tex,
|
||||
vec2 fxaaQualityRcpFrame,
|
||||
float fxaaQualityEdgeThreshold,
|
||||
float fxaaQualityinvEdgeThreshold
|
||||
) {
|
||||
vec4 rgbaM = FxaaTexTop(tex, posM);
|
||||
vec4 rgbaS = FxaaTexOff(tex, posM, vec2( 0.0, 1.0), fxaaQualityRcpFrame.xy);
|
||||
vec4 rgbaE = FxaaTexOff(tex, posM, vec2( 1.0, 0.0), fxaaQualityRcpFrame.xy);
|
||||
vec4 rgbaN = FxaaTexOff(tex, posM, vec2( 0.0,-1.0), fxaaQualityRcpFrame.xy);
|
||||
vec4 rgbaW = FxaaTexOff(tex, posM, vec2(-1.0, 0.0), fxaaQualityRcpFrame.xy);
|
||||
// . S .
|
||||
// W M E
|
||||
// . N .
|
||||
|
||||
bool earlyExit = max( max( max(
|
||||
contrast( rgbaM, rgbaN ),
|
||||
contrast( rgbaM, rgbaS ) ),
|
||||
contrast( rgbaM, rgbaE ) ),
|
||||
contrast( rgbaM, rgbaW ) )
|
||||
< fxaaQualityEdgeThreshold;
|
||||
// . 0 .
|
||||
// 0 0 0
|
||||
// . 0 .
|
||||
|
||||
#if (FXAA_DISCARD == 1)
|
||||
if(earlyExit) FxaaDiscard;
|
||||
#else
|
||||
if(earlyExit) return rgbaM;
|
||||
#endif
|
||||
|
||||
float contrastN = contrast( rgbaM, rgbaN );
|
||||
float contrastS = contrast( rgbaM, rgbaS );
|
||||
float contrastE = contrast( rgbaM, rgbaE );
|
||||
float contrastW = contrast( rgbaM, rgbaW );
|
||||
|
||||
float relativeVContrast = ( contrastN + contrastS ) - ( contrastE + contrastW );
|
||||
relativeVContrast *= fxaaQualityinvEdgeThreshold;
|
||||
|
||||
bool horzSpan = relativeVContrast > 0.;
|
||||
// . 1 .
|
||||
// 0 0 0
|
||||
// . 1 .
|
||||
|
||||
// 45 deg edge detection and corners of objects, aka V/H contrast is too similar
|
||||
if( abs( relativeVContrast ) < .3 ) {
|
||||
// locate the edge
|
||||
vec2 dirToEdge;
|
||||
dirToEdge.x = contrastE > contrastW ? 1. : -1.;
|
||||
dirToEdge.y = contrastS > contrastN ? 1. : -1.;
|
||||
// . 2 . . 1 .
|
||||
// 1 0 2 ~= 0 0 1
|
||||
// . 1 . . 0 .
|
||||
|
||||
// tap 2 pixels and see which ones are "outside" the edge, to
|
||||
// determine if the edge is vertical or horizontal
|
||||
|
||||
vec4 rgbaAlongH = FxaaTexOff(tex, posM, vec2( dirToEdge.x, -dirToEdge.y ), fxaaQualityRcpFrame.xy);
|
||||
float matchAlongH = contrast( rgbaM, rgbaAlongH );
|
||||
// . 1 .
|
||||
// 0 0 1
|
||||
// . 0 H
|
||||
|
||||
vec4 rgbaAlongV = FxaaTexOff(tex, posM, vec2( -dirToEdge.x, dirToEdge.y ), fxaaQualityRcpFrame.xy);
|
||||
float matchAlongV = contrast( rgbaM, rgbaAlongV );
|
||||
// V 1 .
|
||||
// 0 0 1
|
||||
// . 0 .
|
||||
|
||||
relativeVContrast = matchAlongV - matchAlongH;
|
||||
relativeVContrast *= fxaaQualityinvEdgeThreshold;
|
||||
|
||||
if( abs( relativeVContrast ) < .3 ) { // 45 deg edge
|
||||
// 1 1 .
|
||||
// 0 0 1
|
||||
// . 0 1
|
||||
|
||||
// do a simple blur
|
||||
return mix(
|
||||
rgbaM,
|
||||
(rgbaN + rgbaS + rgbaE + rgbaW) * .25,
|
||||
.4
|
||||
);
|
||||
}
|
||||
|
||||
horzSpan = relativeVContrast > 0.;
|
||||
}
|
||||
|
||||
if(!horzSpan) rgbaN = rgbaW;
|
||||
if(!horzSpan) rgbaS = rgbaE;
|
||||
// . 0 . 1
|
||||
// 1 0 1 -> 0
|
||||
// . 0 . 1
|
||||
|
||||
bool pairN = contrast( rgbaM, rgbaN ) > contrast( rgbaM, rgbaS );
|
||||
if(!pairN) rgbaN = rgbaS;
|
||||
|
||||
vec2 offNP;
|
||||
offNP.x = (!horzSpan) ? 0.0 : fxaaQualityRcpFrame.x;
|
||||
offNP.y = ( horzSpan) ? 0.0 : fxaaQualityRcpFrame.y;
|
||||
|
||||
bool doneN = false;
|
||||
bool doneP = false;
|
||||
|
||||
float nDist = 0.;
|
||||
float pDist = 0.;
|
||||
|
||||
vec2 posN = posM;
|
||||
vec2 posP = posM;
|
||||
|
||||
int iterationsUsed = 0;
|
||||
int iterationsUsedN = 0;
|
||||
int iterationsUsedP = 0;
|
||||
for( int i = 0; i < NUM_SAMPLES; i++ ) {
|
||||
iterationsUsed = i;
|
||||
|
||||
float increment = float(i + 1);
|
||||
|
||||
if(!doneN) {
|
||||
nDist += increment;
|
||||
posN = posM + offNP * nDist;
|
||||
vec4 rgbaEndN = FxaaTexTop(tex, posN.xy);
|
||||
doneN = contrast( rgbaEndN, rgbaM ) > contrast( rgbaEndN, rgbaN );
|
||||
iterationsUsedN = i;
|
||||
}
|
||||
|
||||
if(!doneP) {
|
||||
pDist += increment;
|
||||
posP = posM - offNP * pDist;
|
||||
vec4 rgbaEndP = FxaaTexTop(tex, posP.xy);
|
||||
doneP = contrast( rgbaEndP, rgbaM ) > contrast( rgbaEndP, rgbaN );
|
||||
iterationsUsedP = i;
|
||||
}
|
||||
|
||||
if(doneN || doneP) break;
|
||||
}
|
||||
|
||||
|
||||
if ( !doneP && !doneN ) return rgbaM; // failed to find end of edge
|
||||
|
||||
float dist = min(
|
||||
doneN ? float( iterationsUsedN ) / float( NUM_SAMPLES - 1 ) : 1.,
|
||||
doneP ? float( iterationsUsedP ) / float( NUM_SAMPLES - 1 ) : 1.
|
||||
);
|
||||
|
||||
// hacky way of reduces blurriness of mostly diagonal edges
|
||||
// but reduces AA quality
|
||||
dist = pow(dist, .5);
|
||||
|
||||
dist = 1. - dist;
|
||||
|
||||
return mix(
|
||||
rgbaM,
|
||||
rgbaN,
|
||||
dist * .5
|
||||
);
|
||||
}
|
||||
|
||||
void main() {
|
||||
const float edgeDetectionQuality = .2;
|
||||
const float invEdgeDetectionQuality = 1. / edgeDetectionQuality;
|
||||
|
||||
gl_FragColor = FxaaPixelShader(
|
||||
vUv,
|
||||
tDiffuse,
|
||||
resolution,
|
||||
edgeDetectionQuality, // [0,1] contrast needed, otherwise early discard
|
||||
invEdgeDetectionQuality
|
||||
);
|
||||
|
||||
}
|
||||
`
|
||||
|
||||
};
|
||||
|
||||
export { FXAAShader };
|
Reference in New Issue
Block a user