Cesium高阶学习二、Cesium渲染器

一、简介

我们都知道,Cesium是一个WebGL引擎,其绘图操作底层都是调用的WebGL绘图接口,Cesium将底层与WebGL交互的操作封装到了一个渲染模块,我们也可以称该模块为Cesium渲染器。

封装渲染器的好处:
重用性,将与WebGL交互的部分封装到一个模块,在Cesium其他地方都可以调用
移植性,减小WebGL更新带来的影响,
状态管理,Webgl是一个状态机,渲染器能够统一管理这些状态
性能,Cesium团队具有丰富的经验,封装的渲染器能够保证程序性能

Cesium渲染器源码位于packages/engine/Source/Renderer目录下:
在这里插入图片描述

Cesium的渲染器会涉及到很多WebGL的概念,如果您不熟悉WebGL相关的概念,可以先参考“WebGL编程指南”一书。下面就开始学习重要的对象:

1、Buffer 顶点缓冲对象,即常说的VBO,源码如下:

function Buffer(options) {
   
    
   const gl = options.context._gl;
   const bufferTarget = options.bufferTarget;
   const typedArray = options.typedArray;
   let sizeInBytes = options.sizeInBytes;
   const usage = options.usage;
   const hasArray = defined(typedArray);  

   if (hasArray) {
   
   
     sizeInBytes = typedArray.byteLength;
   } 
   const buffer = gl.createBuffer();
   gl.bindBuffer(bufferTarget, buffer);
   gl.bufferData(bufferTarget, hasArray ? typedArray : sizeInBytes, usage);
   gl.bindBuffer(bufferTarget, null);   
} 

Buffer.createVertexBuffer = function (options) {
   
   
  ...
};  
Buffer.createIndexBuffer = function (options) {
   
   
  ...
};

2、VertextArray 顶点数组对象,即常说的VAO,创建一个VAO,最常用的是VertexArray.fromGeometry()方法,而不是new VertexArray(),源码如下:

function VertexArray(options) {
   
   
 ...
 this._numberOfVertices = numberOfVertices;
 this._hasInstancedAttributes = hasInstancedAttributes
<think>好的,我现在需要回答用户关于“GL_OES_standard_derivatives”的问题。首先,用户之前问过关于Cesium中获取表面法线的内容,现在转向WebGL扩展,可能是在处理着色器时遇到了相关需求。 首先,我应该明确GL_OES_standard_derivatives是什么。根据之前的了解,这是一个WebGL的扩展,允许在片段着色器中使用导数函数,比如dFdx和dFdy。这些函数用于计算变量的屏幕空间导数,常用于法线贴图、边缘检测等效果。 接下来,我需要确认这个扩展的兼容性和支持情况。用户可能想知道哪些浏览器或设备支持它,以及如何启用。例如,在WebGL 1.0中,这个扩展需要显式启用,而在WebGL 2.0中,这些函数已经是核心部分,不需要扩展。 然后,用户可能想知道实际应用场景。例如,在Cesium中处理地形法线时,可能会用到导数来计算梯度,进而生成法线。这时候需要说明如何在着色器中启用扩展,并正确使用相关函数。 还需要注意语法和限制,比如导数函数只能在片段着色器中使用,且不能在条件语句内调用。此外,性能影响也是一个考虑点,频繁使用可能影响渲染效率。 用户可能遇到的问题包括无法启用扩展导致着色器编译错误,或者在不同设备上的兼容性问题。应该提供检查扩展是否支持的代码示例,以及如何处理不支持的情况。 最后,需要将信息组织成结构清晰的步骤,包括扩展的作用、启用方法、使用示例、注意事项等,确保用户能逐步理解和应用。</think>--- ### **1. 扩展概述** **GL_OES_standard_derivatives** 是 WebGL 的一个扩展,主要用于在片段着色器(Fragment Shader)中访问**屏幕空间导数函数**,例如: - `dFdx(p)`:计算变量 `p` 在水平方向(x轴)的变化率。 - `dFdy(p)`:计算变量 `p` 在垂直方向(y轴)的变化率。 - `fwidth(p)`:等价于 `abs(dFdx(p)) + abs(dFdy(p))`,用于估算变量 `p` 的变化范围。 这些函数在实时渲染中常用于实现**边缘检测**、**抗锯齿(AA)**、**法线贴图**等高阶效果。 --- ### **2. 兼容性与启用方式** #### **(1) 兼容性** - **WebGL 1.0**:需通过扩展声明启用(非所有设备支持)。 - **WebGL 2.0**:已内置于核心规范,无需启用扩展。 #### **(2) 启用步骤** 在初始化 WebGL 上下文时检查并启用扩展: ```javascript const gl = canvas.getContext("webgl"); // 检查是否支持 if (gl.getExtension("GL_OES_standard_derivatives")) { console.log("支持 GL_OES_standard_derivatives"); } else { console.error("不支持该扩展"); } // 在着色器中声明使用(需在片元着色器顶部添加): // #extension GL_OES_standard_derivatives : enable ``` --- ### **3. 典型应用场景** #### **(1) 边缘检测(Outline)** 通过计算颜色或深度的导数识别物体边缘: ```glsl #extension GL_OES_standard_derivatives : enable precision highp float; varying vec2 v_uv; uniform sampler2D u_texture; void main() { vec3 color = texture2D(u_texture, v_uv).rgb; float edge = length(fwidth(color)) * 10.0; // 颜色变化幅度 gl_FragColor = edge > 0.5 ? vec4(0,0,0,1) : vec4(color, 1.0); } ``` #### **(2) 法线贴图增强细节** 通过导数计算表面梯度,动态生成法线: ```glsl #extension GL_OES_standard_derivatives : enable precision highp float; varying vec2 v_uv; uniform sampler2D u_heightMap; void main() { float height = texture2D(u_heightMap, v_uv).r; vec3 dx = dFdx(vec3(v_uv, height)); vec3 dy = dFdy(vec3(v_uv, height)); vec3 normal = normalize(cross(dx, dy)); // 叉乘得到法线 gl_FragColor = vec4(normal * 0.5 + 0.5, 1.0); } ``` #### **(3) 抗锯齿(Anti-Aliasing)** 平滑纹理或几何边缘的锯齿: ```glsl #extension GL_OES_standard_derivatives : enable precision highp float; varying vec2 v_uv; uniform sampler2D u_texture; void main() { vec2 uv = v_uv; vec2 dx = dFdx(uv); // 计算UV导数 vec2 dy = dFdy(uv); vec4 color = texture2DGrad(u_texture, uv, dx, dy); // 使用导数采样 gl_FragColor = color; } ``` --- ### **4. 关键注意事项** 1. **仅限片段着色器** `dFdx` 和 `dFdy` 只能在片段着色器中使用,顶点着色器不支持。 2. **禁用条件分支** 避免在 `if` 或循环内调用导数函数,可能导致未定义行为。 3. **性能影响** 导数计算依赖硬件插值,频繁使用可能影响性能,尤其在移动端。 4. **精度要求** 建议使用 `highp` 精度声明变量,避免低精度导致的误差。 --- ### **5. 替代方案** 若目标平台不支持此扩展,可考虑以下方法: - **预计算法线**:在建模阶段生成法线贴图。 - **屏幕空间差分**:通过相邻像素手动计算近似导数(牺牲性能)。 --- 通过合理使用 `GL_OES_standard_derivatives`,可显著提升 WebGL 渲染效果,但需权衡兼容性与性能优化。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Cesium进阶学习

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值