• cesium 源码分析 裁切面原理


    precision highp float;
    uniform vec4 u_baseColorFactor;
    uniform sampler2D u_baseColorTexture;
    uniform float u_metallicFactor;
    uniform float u_roughnessFactor;
    uniform vec3 u_emissiveFactor;
    varying vec2 v_texcoord_0;
    vec3 SRGBtoLINEAR3(vec3 srgbIn) 
    {
        return pow(srgbIn, vec3(2.2));
    }

    // srgb颜色空间到线性空间(gamma矫正)
    vec4 SRGBtoLINEAR4(vec4 srgbIn) 
    {
        vec3 linearOut = pow(srgbIn.rgb, vec3(2.2));
        return vec4(linearOut, srgbIn.a);
    }

    vec3 applyTonemapping(vec3 linearIn) 
    {
    #ifndef HDR 
        return czm_acesTonemapping(linearIn);
    #else 
        return linearIn;
    #endif 
    }

    vec3 LINEARtoSRGB(vec3 linearIn) 
    {
    #ifndef HDR 
        return pow(linearIn, vec3(1.0/2.2));
    #else 
        return linearIn;
    #endif 
    }

    vec2 computeTexCoord(vec2 texCoords, vec2 offset, float rotation, vec2 scale) 
    {
        rotation = -rotation; 
        mat3 transform = mat3(
            cos(rotation) * scale.x, sin(rotation) * scale.x, 0.0, 
           -sin(rotation) * scale.y, cos(rotation) * scale.y, 0.0, 
            offset.x, offset.y, 1.0); 
        vec2 transformedTexCoords = (transform * vec3(fract(texCoords), 1.0)).xy; 
        return transformedTexCoords; 
    }

    #ifdef USE_IBL_LIGHTING 
    uniform vec2 gltf_iblFactor; 
    #endif 
    #ifdef USE_CUSTOM_LIGHT_COLOR 
    uniform vec3 gltf_lightColor; 
    #endif 

    // 模型自身的颜色
    void gltf_clip_main() 
    {
        // 采集纹理
        vec4 baseColorWithAlpha = SRGBtoLINEAR4(texture2D(u_baseColorTexture, v_texcoord_0));
        // 颜色权重
        baseColorWithAlpha *= u_baseColorFactor;
        // 颜色
        vec3 baseColor = baseColorWithAlpha.rgb;
        // 颜色
        vec3 color = baseColor;
        // 转换到srgb空间
        color = LINEARtoSRGB(color);
        // 设置颜色
        gl_FragColor = vec4(color, 1.0);
    }

    // 得到裁切面
    vec4 getClippingPlane(highp sampler2D packedClippingPlanes, int clippingPlaneNumber, mat4 transform)
    {
        int pixY = clippingPlaneNumber / 1;
        int pixX = clippingPlaneNumber - (pixY * 1);
        // uv坐标
        float u = (float(pixX) + 0.5) * 1.0;
        float v = (float(pixY) + 0.5) * 0.5;
        // 获取裁切面
        vec4 plane = texture2D(packedClippingPlanes, vec2(u, v));
        // 将裁切面转换到世界位置(应该是乘以tileset的矩阵)
        return czm_transformPlane(plane, transform);
    }

    float clip(vec4 fragCoord, sampler2D clippingPlanes, mat4 clippingPlanesMatrix)
    {
        
        bool clipped = true;
        // 屏幕坐标转到视口坐标
        vec4 position = czm_windowToEyeCoordinates(fragCoord);
        vec3 clipNormal = vec3(0.0);
        vec3 clipPosition = vec3(0.0);
        float clipAmount = 0.0;
        // 当前点处的像素代表多少米
        float pixelWidth = czm_metersPerPixel(position);
        for (int i = 0; i < 1; ++i)
        {
            // 得到裁切面
            vec4 clippingPlane = getClippingPlane(clippingPlanes, i, clippingPlanesMatrix);
            // 裁切法线
            clipNormal = clippingPlane.xyz;
            // 裁切面上的点
            clipPosition = -clippingPlane.w * clipNormal;
            // 逆向出点坐标并于法线上进行投影长度计算,将投影长度转换为像素
            float amount = dot(clipNormal, (position.xyz - clipPosition)) / pixelWidth;
            // 每一次找到都看看是否是正数,即像素点在裁切面的正面还是反面
            clipAmount = max(amount, clipAmount);
            // 只要有一个为负数(在反面)就都在反面了
            clipped = clipped && (amount <= 0.0);
        }
        if (clipped)
        {
            // 剔除
            discard;
        }
        // 返回距离裁切面最远的那个距离
        return clipAmount;
    }

    uniform highp sampler2D gltf_clippingPlanes; 
    uniform mat4 gltf_clippingPlanesMatrix; 
    uniform vec4 gltf_clippingPlanesEdgeStyle; 
    void main() 

        // 原来的颜色
        gltf_clip_main(); 
        // 当前坐标点到裁切面最大距离计算
        float clipDistance = clip(gl_FragCoord, gltf_clippingPlanes, gltf_clippingPlanesMatrix); 
        vec4 clippingPlanesEdgeColor = vec4(1.0); 
        // 裁切面裁切模型时,模型边缘的颜色
        clippingPlanesEdgeColor.rgb = gltf_clippingPlanesEdgeStyle.rgb; 
        // 裁切面裁切模型时,模型边缘占用的像素数量
        float clippingPlanesEdgeWidth = gltf_clippingPlanesEdgeStyle.a; 
        // 裁切面外某一点与裁切面的距离在一个设定的宽度内就让它显示边缘颜色(像素距离),不在这个范围内显示模型颜色,在裁切面的背面被裁切了
        if (clipDistance > 0.0 && clipDistance < clippingPlanesEdgeWidth) 
        { 
            // 边缘的颜色
            gl_FragColor = clippingPlanesEdgeColor;
        } 

  • 相关阅读:
    使用php解压缩ZipArchive类实现后台管理升级的解决方案
    港联证券:市场有望从2024年起进入大众化折叠屏手机时代
    刪除表情 (踩坑)
    TENSEAL: A LIBRARY FOR ENCRYPTED TENSOR OP- ERATIONS USING HOMOMORPHIC ENCRYPTION 解读
    QT编译Opencv库过程中出现的问题总结
    鸿蒙开发HarmonyOS4.0入门与实践
    【ES专题】ElasticSearch功能详解与原理剖析
    python 远程代码第一次推送
    48-安装软件并管理服务
    分布式与一致性协议之CAP(四)
  • 原文地址:https://blog.csdn.net/tianyapai/article/details/126127499