Cesium Model 中的剪裁平面 (ClippingPlane)

news2024/11/24 19:31:27

Cesium Model 中的剪裁平面 (ClippingPlane)

在这里插入图片描述

参考: https://www.cnblogs.com/webgl-angela/p/9197672.html

Cesium Model 中的剪裁平面 (ClippingPlane)

// 相关类:
class ClippingPlaneCollection {}
class ClippingPlane {}

// 剪裁的整体流程:
Model.prototype.update = () => {
  //...

  // 1.剪裁纹理的构建
  updateClippingPlanes()

  // 2.Shader 的构建
  buildDrawCommands()

  // 3.剪裁矩阵的构建
  updateReferenceMatrices();

  //...
}
1、剪裁纹理的构建
ClippingPlaneCollection.prototype.update = () => {
  //...

  // 1. 计算纹理的分辨率, { x: 剪裁平面的数量, y: 2 }
  computeTextureResolution()

  // 2. 创建纹理
  clippingPlanesTexture = new Texture()

  // 3. 将剪裁平面数据打包成浮点数的数组 _float32View
  packPlanesAsFloats()

  // 4.拷贝图片数据 _float32View 到纹理中
  clippingPlanesTexture.copyFrom()

  //...
}
2、Shader 的构建
ModelClippingPlanesPipelineStage.process = () => {
  const uniformMap = {
    model_clippingPlanes: function () {
      return clippingPlanes.texture;
    },
    model_clippingPlanesEdgeStyle: function () {
      const style = Color.clone(clippingPlanes.edgeColor);
      style.alpha = clippingPlanes.edgeWidth;
      return style;
    },
    model_clippingPlanesMatrix: function () {
      return model._clippingPlanesMatrix;
    },
  };
};
3、剪裁矩阵的构建
functin updateReferenceMatrices() {
  // ...

  // 模型空间 转换到 世界空间
  const referenceMatrix = model.modelMatrix;

  // 模型空间 转换到 裁剪平面空间
  const clippingPlanesModelMatrix = model._clippingPlanes.modelMatrix;

  // 世界空间 转换到 视图空间
  clippingPlanesMatrix = Matrix4.multiply(
    context.uniformState.view3D,
    referenceMatrix,
    clippingPlanesMatrix
  );

  // 视图空间 转换到 裁剪平面空间, 在视图空间中调整模型的裁剪平面
  // 由于裁剪平面的定义与模型空间无关,因此即使在视图空间中调整,裁剪平面的功能仍然相同:定义哪些模型部分应该被渲染、哪些部分应该被剔除。
  clippingPlanesMatrix = Matrix4.multiply(
    clippingPlanesMatrix,
    clippingPlanesModelMatrix,
    clippingPlanesMatrix
  );

 // 裁剪平面空间 转换到 视图空间
  model._clippingPlanesMatrix = Matrix4.inverseTranspose(
    clippingPlanesMatrix,
    model._clippingPlanesMatrix
  );

  // ...
}

4、Shader 赏析
/**
 * Transforms a plane.
 *
 * @name czm_transformPlane
 * @glslFunction
 *
 * @param {vec4} plane The plane in Hessian Normal Form.
 * @param {mat4} transform The inverse-transpose of a transformation matrix.
 */
vec4 czm_transformPlane(vec4 plane, mat4 transform) {
    vec4 transformedPlane = transform * plane;
    // Convert the transformed plane to Hessian Normal Form
    float normalMagnitude = length(transformedPlane.xyz);
    return transformedPlane / normalMagnitude;
}

vec4 getClippingPlane(
    highp sampler2D packedClippingPlanes,
    int clippingPlaneNumber,
    mat4 transform
) {
    int pixY = clippingPlaneNumber / CLIPPING_PLANES_TEXTURE_WIDTH;
    int pixX = clippingPlaneNumber - (pixY * CLIPPING_PLANES_TEXTURE_WIDTH);
    float pixelWidth = 1.0 / float(CLIPPING_PLANES_TEXTURE_WIDTH);
    float pixelHeight = 1.0 / float(CLIPPING_PLANES_TEXTURE_HEIGHT);
    float u = (float(pixX) + 0.5) * pixelWidth; // sample from center of pixel
    float v = (float(pixY) + 0.5) * pixelHeight;
    vec4 plane = texture(packedClippingPlanes, vec2(u, v));
    return czm_transformPlane(plane, transform);
}

float clip(vec4 fragCoord, sampler2D clippingPlanes, mat4 clippingPlanesMatrix) {
  // 视图空间的位置
    vec4 position = czm_windowToEyeCoordinates(fragCoord);
    vec3 clipNormal = vec3(0.0);

    // 视图空间的剪裁平面位置
    vec3 clipPosition = vec3(0.0);
    float pixelWidth = czm_metersPerPixel(position);

    float clipAmount = 0.0;
    bool clipped = true;

    for (int i = 0; i < CLIPPING_PLANES_LENGTH; ++i) {
        vec4 clippingPlane = getClippingPlane(clippingPlanes, i, clippingPlanesMatrix);
        clipNormal = clippingPlane.xyz;
        clipPosition = -clippingPlane.w * clipNormal;

        // 计算当前像素位置到裁剪平面的投影距离。这个距离是沿着裁剪平面法线的距离。如果这个距离小于等于0,则意味着像素位于裁剪平面的内部。
        float amount = dot(clipNormal, (position.xyz - clipPosition)) / pixelWidth;

        clipAmount = max(amount, clipAmount);
        clipped = clipped && (amount <= 0.0);
    }

    if (clipped) {
        discard;
    }
    return clipAmount;
}

void modelClippingPlanesStage(inout vec4 color)
{
    float clipDistance = clip(gl_FragCoord, model_clippingPlanes, model_clippingPlanesMatrix);
    vec4 clippingPlanesEdgeColor = vec4(1.0);
    clippingPlanesEdgeColor.rgb = model_clippingPlanesEdgeStyle.rgb;
    float clippingPlanesEdgeWidth = model_clippingPlanesEdgeStyle.a;

    if (clipDistance > 0.0 && clipDistance < clippingPlanesEdgeWidth) {
        color = clippingPlanesEdgeColor;
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1876442.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Mathematica训练课(45)-- 一些常用的函数Abs[],Max[]等函数用法

①绝对值函数&#xff1a;Abs[]函数 ②最大值和最小值函数 ③反函数

SAP ATP可用性检查简介

Availability Check,就是可用性检查,指的是要检查一下此物料是否能满足我的需求。 接到一张销售订单(SALES ORDER),客户要求数量为100PC,并且客户要求的出货日期是2024-07-01,此时我们的销售人员肯定会想到底能否出货给客人呢?系统中建立此单时,SAP就会做一个所谓的检…

实验八 T_SQL编程

题目 以电子商务系统数据库ecommerce为例 1、在ecommerce数据库&#xff0c;针对会员表member首先创建一个“呼和浩特地区”会员的视图view_hohhot&#xff0c;然后通过该视图查询来自“呼和浩特”地区的会员信息&#xff0c;用批处理命令语句将问题进行分割&#xff0c;并分…

17859划分准则小结

17859《划分准则》 发布时间&#xff1a;1999.9.13 实施时间&#xff1a;2001.1.1 计算机信息系统安全保护能力的五个等级&#xff1a; 第一级&#xff1a;用户自主保护级 第二级…

Java知识点整理 15 — MyBatis框架

一. 什么是 MyBatis MyBatis 是一款优秀的持久层框架&#xff0c;支持自定义 SQL、存储过程以及高级映射。它免除了几乎所有 JDBC代码以及手动设置参数和获取结果集的工作。MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO&#xff08;普通老式 Jav…

人脑网络的多层建模与分析

摘要 了解人类大脑的结构及其与功能的关系&#xff0c;对于各种应用至关重要&#xff0c;包括但不限于预防、处理和治疗脑部疾病(如阿尔茨海默病或帕金森病)&#xff0c;以及精神疾病(如精神分裂症)的新方法。结构和功能神经影像学方面的最新进展&#xff0c;以及计算机科学等…

决定佛蒙特州版图的关键历史事件:

​决定佛蒙特州版图的关键历史事件: 1. 早期探险与命名&#xff1a; - 1609年&#xff0c;法国探险家萨缪尔德尚普兰&#xff08;Samuel de Champlain&#xff09;到达了现在的佛蒙特州区域&#xff0c;并探索了尚普兰湖&#xff08;Lake Champlain&#xff09;。他将周围的山…

mwwz库添加对多模板匹配的支持:find_shape_models

多模板匹配的实现只需要对单模板匹配做一些扩展&#xff0c;传入的模板由不同的id表示&#xff0c;在金字塔顶层完成模板的分类&#xff0c;在剩下的金字塔完成对每一类模板的匹配&#xff0c;匹配结果由id标识。测试程序已集成该方法&#xff0c;清除模板后所创建的模板被看作…

Python基于决策树分类模型、支持向量机分类模型、随机森林分类模型和XGBoost分类模型实现月亮数据标签预测项目实战

说明&#xff1a;这是一个机器学习实战项目&#xff08;附带数据代码文档视频讲解&#xff09;&#xff0c;如需数据代码文档视频讲解可以直接到文章最后获取。 1.项目背景 在探索机器学习算法的性能与适用性时&#xff0c;我们往往需要依赖于精心设计的人工数据集来测试和验证…

全面对标GPT-4 Turbo,讯飞星火V4.0凭什么?

大数据产业创新服务媒体 ——聚焦数据 改变商业 自从ChatGPT爆火出圈之后&#xff0c;大模型就走上了发展的快车道。 一方面&#xff0c;大模型技术快速演进&#xff0c;Sora为我们打开了视频生成的想象空间&#xff0c;各大厂商争相打破大模型的“模态墙”&#xff0c;长文本…

pytest中的极其重要固件(request)的理解

pytest 是一个非常流行的Python测试框架&#xff0c;它为开发人员提供了丰寴的测试工具和功能。 在pytest中&#xff0c;固件&#xff08;fixture&#xff09;是一种非常核心的概念&#xff0c;用于设置测试前的预条件&#xff0c;清理测试后的环境&#xff0c;或者提供测试过…

什么是DEQ?

DEQ (Delivered Ex Quay, Duty Paid) 是指目的港码头交货 (……指定目的港)。 这种术语规定卖方在指定目的港码头将货物交给买方处置&#xff0c;并且不办理进口清关手续。 DEQ适用范围 DEQ术语仅适用于海运、内河运输或多式联运&#xff0c;并且在目的港码头卸货时使用。如…

RAG 基本流程及处理技巧 with LangChain

LLM 主要存在两个问题&#xff1a;幻想和缺乏领域知识。领域知识缺乏的原因是因为训练 LLM 本身的知识更新慢&#xff0c;对特定领域的知识也没有太细致的输入。 RAG 主要是解决 LLM 缺乏领域知识的问题。底层的逻辑是&#xff1a;把 LLM 作为逻辑推理引擎&#xff0c;而不是信…

【计算机网络仿真】b站湖科大教书匠思科Packet Tracer——实验10 IPv4地址 — 构造超网(无分类编址)

一、实验目的 1.加深对构造超网的理解&#xff1b; 二、实验要求 1.使用Cisco Packet Tracer仿真平台&#xff1b; 2.观看B站湖科大教书匠仿真实验视频&#xff0c;完成对应实验。 三、实验内容 1.构建网络拓扑&#xff1b; 2.根据各网络所指定的地址块完成以下工作&#…

Python 面试【中级】

欢迎莅临我的博客 &#x1f49d;&#x1f49d;&#x1f49d;&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:「stormsha的主页」…

Linux----> tail、cat、more、head、less的用法详解

1.tail命令&#xff1a;用于查看文件的最后几行内容。 基本用法&#xff1a;tail [选项] [文件] 常用选项&#xff1a; -n <行数>&#xff1a;显示最后的 <行数> 行。-f&#xff1a;实时显示文件新增内容&#xff0c;通常用于查看日志文件。 示例&#xff1a;…

程序中的Reduce(CPU和GPU)

前提 最近在看Reduce&#xff08;归约&#xff09;的相关知识和代码&#xff0c;做个总结。这里默认大家已经明白了Reduce的基础概念。 Reduce 根据参考链接一&#xff0c;Recude常见的划分方法有两种&#xff1a; 相邻配对&#xff1a;元素和它们相邻的元素配对 交错配对…

动态人物抠图换背景 MediaPipe

pip下载 MediaPipe pip install mediapipe -i 手部特征点模型包包含一个手掌检测模型和一个手部特征点检测模型。手掌检测模型在输入图片中定位手部&#xff0c;手部特征点检测模型可识别手掌检测模型定义的被剪裁手掌图片上的特定手部特征点。 由于运行手掌检测模型非常耗时&…

[图解]建模相关的基础知识-19

1 00:00:00,640 --> 00:00:04,900 前面讲了关系的这些范式 2 00:00:06,370 --> 00:00:11,570 对于我们建模思路来说&#xff0c;有什么样的作用 3 00:00:12,660 --> 00:00:15,230 我们建模的话&#xff0c;可以有两个思路 4 00:00:16,790 --> 00:00:20,600 一个…

【QT】按钮类控件 显示类控件

目录 按钮类控件 Push Button 设置按钮图标 按钮设置快捷键 设置鼠标点击按钮重复触发 Radio Button 单选框分组 Check Box 显示类控件 Label 常用属性 设置文本格式 给Label设置图片 Label标签设置边框 设置文本对齐方式 设置文本自动换行 设置文本缩进 设置…