边缘检测算法

发布于:2024-09-18 ⋅ 阅读:(143) ⋅ 点赞:(0)
#version 300 es
#define varying in
layout(location = 0) out highp vec4 pc_fragColor;
#define gl_FragColor pc_fragColor
#define gl_FragDepthEXT gl_FragDepth
#define texture2D texture
#define textureCube texture
#define texture2DProj textureProj
#define texture2DLodEXT textureLod
#define texture2DProjLodEXT textureProjLod
#define textureCubeLodEXT textureLod
#define texture2DGradEXT textureGrad
#define texture2DProjGradEXT textureProjGrad
#define textureCubeGradEXT textureGrad
precision highp float;
precision highp int;
#define HIGH_PRECISION
#define SHADER_NAME ShaderMaterial
uniform mat4 viewMatrix;
uniform vec3 cameraPosition;
uniform bool isOrthographic;
#define TONE_MAPPING
#ifndef saturate
    #define saturate( a ) clamp( a, 0.0, 1.0 )
#endif
uniform float toneMappingExposure;
vec3 LinearToneMapping( vec3 color ) {
    return toneMappingExposure * color;
}
vec3 ReinhardToneMapping( vec3 color ) {
    color *= toneMappingExposure;
    return saturate( color / ( vec3( 1.0 ) + color ) );
}
vec3 OptimizedCineonToneMapping( vec3 color ) {
    color *= toneMappingExposure;
    color = max( vec3( 0.0 ), color - 0.004 );
    return pow( ( color * ( 6.2 * color + 0.5 ) ) / ( color * ( 6.2 * color + 1.7 ) + 0.06 ), vec3( 2.2 ) );
}
vec3 RRTAndODTFit( vec3 v ) {
    vec3 a = v * ( v + 0.0245786 ) - 0.000090537;
    vec3 b = v * ( 0.983729 * v + 0.4329510 ) + 0.238081;
    return a / b;
}
vec3 ACESFilmicToneMapping( vec3 color ) {
    const mat3 ACESInputMat = mat3(
    vec3( 0.59719, 0.07600, 0.02840 ), vec3( 0.35458, 0.90834, 0.13383 ), vec3( 0.04823, 0.01566, 0.83777 )
    );
    const mat3 ACESOutputMat = mat3(
    vec3(	1.60475, -0.10208, -0.00327 ), vec3( -0.53108, 1.10813, -0.07276 ), vec3( -0.07367, -0.00605, 1.07602 )
    );
    color *= toneMappingExposure / 0.6;
    color = ACESInputMat * color;
    color = RRTAndODTFit( color );
    color = ACESOutputMat * color;
    return saturate( color );
}
vec3 CustomToneMapping( vec3 color ) {
    return color;
}
vec3 toneMapping( vec3 color ) {
    return LinearToneMapping( color );
}
#define OPAQUE
vec4 LinearToLinear( in vec4 value ) {
    return value;
}
vec4 LinearTosRGB( in vec4 value ) {
    return vec4( mix( pow( value.rgb, vec3( 0.41666 ) ) * 1.055 - vec3( 0.055 ), value.rgb * 12.92, vec3( lessThanEqual( value.rgb, vec3( 0.0031308 ) ) ) ), value.a );
}
vec4 linearToOutputTexel( vec4 value ) {
    return LinearTosRGB( value );
}
uniform sampler2D tDiffuse_color;
uniform sampler2D tDiffuse_select;
uniform vec2 resolution;
uniform vec3 userSelectColor;
varying vec2 vUv;


//获得边缘权重因子

float getEdgeFactor (sampler2D tDiffuse, vec2 vUv) {
    float edgeLength = 2.0;
    vec2 texel = resolution;
    
    //1.中心像素先检测,判断是否在选中范围内,否则可直接跳出
    
    float tx1y1 = texture2D( tDiffuse, vUv + texel * vec2(  0, 0 ) ).r;
    if(tx1y1 == 0.0) return 0.0;//当不再选中渲染范围内时,直接跳出
    
    
    
    //2.四角检测,判断是否在内部,若在,则不在边缘,可跳出
    float tx0y0 = texture2D( tDiffuse, vUv + texel * vec2( -edgeLength, -edgeLength ) ).r;
    float tx0y2 = texture2D( tDiffuse, vUv + texel * vec2( -edgeLength, edgeLength ) ).r;
    float tx2y0 = texture2D( tDiffuse, vUv + texel * vec2(  edgeLength, -edgeLength ) ).r;
    float tx2y2 = texture2D( tDiffuse, vUv + texel * vec2(  edgeLength, edgeLength ) ).r;
    if(tx0y0 + tx0y2 + tx2y0 + tx2y2 == 4.0) return 0.0;
    
    
    
    // first column
    
    float tx0y1 = texture2D( tDiffuse, vUv + texel * vec2( -edgeLength, 0 ) ).r;
    
    // second column
    
    float tx1y0 = texture2D( tDiffuse, vUv + texel * vec2(  0, -edgeLength ) ).r;
    float tx1y2 = texture2D( tDiffuse, vUv + texel * vec2(  0, edgeLength ) ).r;
    
    // third column
    
    float tx2y1 = texture2D( tDiffuse, vUv + texel * vec2(  edgeLength, 0 ) ).r;
    
    
    
    // kernel definition (in glsl matrices are filled in column-major order)
    
    const mat3 Gx = mat3( -1, -2, -1, 0, 0, 0, 1, 2, 1 ); // x direction kernel
    
    const mat3 Gy = mat3( -1, 0, 1, -2, 0, 2, -1, 0, 1 ); // y direction kernel
    
    
    
    // gradient value in x direction
    float valueGx = Gx[0][0] * tx0y0 + Gx[1][0] * tx1y0 + Gx[2][0] * tx2y0 +
    Gx[0][1] * tx0y1 + Gx[1][1] * tx1y1 + Gx[2][1] * tx2y1 +
    Gx[0][2] * tx0y2 + Gx[1][2] * tx1y2 + Gx[2][2] * tx2y2;
    
    // gradient value in y direction
    
    float valueGy = Gy[0][0] * tx0y0 + Gy[1][0] * tx1y0 + Gy[2][0] * tx2y0 +
    Gy[0][1] * tx0y1 + Gy[1][1] * tx1y1 + Gy[2][1] * tx2y1 +
    Gy[0][2] * tx0y2 + Gy[1][2] * tx1y2 + Gy[2][2] * tx2y2;
    
    
    // magnitute of the total gradient
    
    return sqrt( ( valueGx * valueGx ) + ( valueGy * valueGy ) );
}
void main() {
    vec4 texel_color = texture2D( tDiffuse_color, vUv );
    vec4 texel_select = texture2D( tDiffuse_select, vUv );
    
    
    关闭边缘检测
    
    //float a = texel_select.a == 0.0 ? 0.0 : 0.6;
    //gl_FragColor = mix(texel_color, texel_select, a);
    //return;
    
    
    //开启边缘检测
    vec4 selectColor = vec4(userSelectColor, 1.0);
    vec4 edgeColor = vec4(1.0, 1.0, 1.0, 1.0);
    float edgeFactor = texel_select.r == 0.0 ? 0.0 : getEdgeFactor(tDiffuse_select, vUv);
    if(edgeFactor == 0.0) {
        float mixFactor = texel_select.r == 0.0 ? 0.0 : 0.5;
        gl_FragColor = mix(texel_color, selectColor, mixFactor);
    }
    else {
        gl_FragColor = edgeColor;
    }

}

网站公告

今日签到

点亮在社区的每一天
去签到