# HTMLCFD **Repository Path**: tong_yan_jun/htmlcfd ## Basic Information - **Project Name**: HTMLCFD - **Description**: CFD页面交互效果,可在手机网页上访问 - **Primary Language**: JavaScript - **License**: Not specified - **Default Branch**: master - **Homepage**: https://htmlcfd.vercel.app/ - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-03-12 - **Last Updated**: 2026-03-20 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Fluid Simulation 基于 Navier-Stokes 方程的实时交互式 WebGL 流体模拟。 ## 预览 ![Fluid Simulation](https://via.placeholder.com/800x400/0a0a0a/ffffff?text=Fluid+Simulation) 通过鼠标/触摸滑动创建流体效果,小范围扰动产生精细涡结构。点击右上角按钮切换视觉风格,按钮同时作为流体壁面边界。 ## 快速开始 ### 安装依赖 ```bash npm install ``` ### 开发模式 ```bash npm run dev ``` 访问 http://localhost:5173 ### 生产构建 ```bash npm run build ``` 构建产物输出到 `dist/` 目录。 ### 预览构建结果 ```bash npm run preview ``` ## 使用方法 | 操作 | 效果 | |------|------| | **鼠标拖动** | 在小范围内创建流体扰动,产生精细涡结构 | | **触摸滑动** | 移动端流体交互 | | **点击右上角按钮** | 切换视觉风格(Navier 彩色 / Smoke 单色) | > **壁面边界**:切换按钮同时作为流体壁面,流体经过按钮区域会绕开,模拟真实边界效果。 ## 技术架构 ### 物理管线 每帧执行以下步骤: ``` Advection → Splat → Divergence → Pressure (Jacobi 40x) → Projection → Render ``` | 步骤 | 作用 | |------|------| | **Advection** | 半拉格朗日平流,密度和速度随流场移动 | | **Splat** | 注入鼠标速度作为外力 | | **Divergence** | 计算速度场散度 ∇·u | | **Pressure** | Jacobi 迭代求解压力场 | | **Projection** | 速度场投影,满足不可压缩条件 | ### 文件结构 ``` src/ ├── main.ts # 入口,动画循环 ├── core/ │ ├── WebGLContext.ts # WebGL 2.0 上下文 + 扩展检查 │ ├── FBO.ts # 帧缓冲双缓冲系统 │ └── ShaderLoader.ts # GLSL 编译工具 ├── sim/ │ ├── FluidSimulator.ts # 物理管线编排 │ └── shaders/ # GLSL 着色器 │ ├── advection.frag # 平流 │ ├── splat.frag # 力注入 │ ├── divergence.frag # 散度 │ ├── jacobi.frag # 压力求解 │ └── project.frag # 速度投影 ├── render/ │ └── styles/ # 视觉风格 │ ├── navier.frag # Navier.ai 彩色风格 │ └── smoke.frag # 烟雾/墨水风格 ├── input/ │ └── PointerHandler.ts # 鼠标/触摸输入 └── config/ └── Config.ts # 物理参数配置 ``` ## 调试指南 ### 常见问题 #### 1. 页面黑屏,无流体效果 **检查控制台错误:** ```javascript // 打开浏览器开发者工具 (F12) // 查看是否有 WebGL 相关错误 ``` **可能原因:** - 浏览器不支持 WebGL 2.0 - 显卡驱动问题 #### 2. 流体"爆炸"或闪烁 **调整物理参数:** ```typescript // src/config/Config.ts { physics: { dt: 0.008, // 减小时间步长 viscosity: 0.0001, diffusion: 0.0001, pressureIterations: 40 // 增加迭代次数 } } ``` #### 3. 性能问题 **当前实现**:模拟分辨率与显示分辨率 1:1 匹配,在 1080p 屏幕上约 200万像素点物理计算。 **优化方案**:修改 `FluidSimulator.ts` 中的分辨率缩放: ```typescript // src/sim/FluidSimulator.ts resize() 方法 this.simWidth = Math.floor(width / 2); // 1/2 分辨率 this.simHeight = Math.floor(height / 2); ``` ### 调试工具 #### 查看着色器编译错误 ```typescript // src/core/ShaderLoader.ts 中的 compileShader 会抛出详细错误 // 包含完整的 GLSL 错误日志 ``` #### 检查 FBO 状态 ```typescript // 在 FBO.ts 中添加调试代码 const status = gl.checkFramebufferStatus(gl.FRAMEBUFFER); console.log('FBO Status:', status === gl.FRAMEBUFFER_COMPLETE ? 'OK' : 'Error'); ``` #### 可视化物理场 修改 `render()` 方法渲染不同字段: ```typescript // 渲染速度场(红色 = X速度,绿色 = Y速度) this.gl.useProgram(this.navierProgram.program); this.gl.bindTexture(this.gl.TEXTURE_2D, this.velocity.readTexture); // 渲染压力场 this.gl.bindTexture(this.gl.TEXTURE_2D, this.pressure.readTexture); ``` ### 浏览器兼容性 | 浏览器 | 版本要求 | |--------|----------| | Chrome | 56+ | | Firefox | 51+ | | Safari | 15+ | | Edge | 79+ | 检查 WebGL 2.0 支持: ```javascript const canvas = document.createElement('canvas'); const gl = canvas.getContext('webgl2'); console.log(gl ? 'WebGL 2.0 supported' : 'WebGL 2.0 NOT supported'); ``` ## 配置参数 ```typescript // src/config/Config.ts { physics: { dt: 0.016, // 时间步长(秒) viscosity: 0.0001, // 粘性系数 diffusion: 0.0001, // 扩散系数 pressureIterations: 40 // 压力求解迭代次数 }, interaction: { splatRadius: 0.015, // 扰动半径(归一化坐标,小值产生精细涡结构) forceMultiplier: 300 // 力放大系数 }, visual: { style: 'navier' // 视觉风格:'navier' | 'smoke' } } ``` ## 参考资料 - [Jos Stam - Stable Fluids (1999)](https://www.researchgate.net/publication/2447775_Real-Time_Fluid_Dynamics_for_Games) - [WebGL 2 Fundamentals](https://webgl2fundamentals.org/) - [Navier.ai](https://navier.ai/) - 视觉风格参考 ## License MIT