
本文介绍了溯源:Cesium.Appearance 中的顶点着色器求职学习资料,有助于帮助完成毕业设计以及求职,是一篇很好的资料。
对技术面试,学习经验等有一些体会,在此分享。
- 0. 预备知识
- 1. czm_computePosition()
- 2. czm_translateRelativeToEye(vec3, vec3)
对于一个 MaterialAppearance 对象来说,它的顶点着色器代码默认为:
attribute vec3 position3DHigh; attribute vec3 position3DLow; attribute vec3 normal; attribute vec2 st; attribute float batchId; varying vec3 v_positionEC; varying vec3 v_normalEC; varying vec2 v_st; void main() { vec4 p = czm_computePosition(); v_positionEC = (czm_modelViewRelativeToEye * p).xyz; // position in eye coordinates v_normalEC = czm_normal * normal; // normal in eye coordinates v_st = st; gl_Position = czm_modelViewProjectionRelativeToEye * p; }
0. 预备知识
Cesium 拥有一个小规模的内置 glsl 库,预置了非常多 czm_
开头的函数、结构、常量。在自定义着色器的 Appearance、Material 类中,允许直接使用,Cesium 会自动把着色器代码合并、链接。
1. czm_computePosition()
很不幸的是,这个函数并不是完整地内置在 Source/Shaders
下的,Source/Shaders/Builtin/computePosition.glsl
这里面只有函数的声明,并没有,它的函数实现是动态生成的。
幸运的是,通过全文检索,我找到了它的生成代码,它位于 Primitive.js
文件中:
这个函数有点长,大家可以自己去看源代码
Primitive._modifyShaderPosition = function ( primitive, vertexShaderSource, scene3DOnly ) { // ... };
Cesium 会用正则去匹配你写的 attribute vec3 XXX3DHigh
和 attribute vec3 XXX3DLow
这两个顶点属性(attribute
)中的 XXX
,并以之构造函数名 czm_computeXXX
,当然它会把首字母给你大写了以符合函数命名规范。
默认情况下,这个 XXX 就等于 position
。所以,抽丝剥茧,在我们关心的三维模式下,这个函数其实可以省略成这样:
attribute vec3 position3DHigh; attribute vec3 position3DLow; vec4 czm_computePosition() { return czm_translateRelativeToEye(position3DHigh, position3DLow); }
到这一步,看到实际上作用的函数是 czm_translateRelativeToEye(vec3, vec3)
,而这一个函数在 内置的 glsl 中是有的了。
2. czm_translateRelativeToEye(vec3, vec3)
vec4 czm_translateRelativeToEye(vec3 high, vec3 low) { vec3 highDifference = high - czm_encodedCameraPositionMCHigh; vec3 lowDifference = low - czm_encodedCameraPositionMCLow; return vec4(highDifference + lowDifference, 1.0); }
它的作用是,将世界坐标减去相机中心坐标,返回一个齐次坐标,即将世界坐标平移到相机坐标系下,而不旋转。
有的朋友可能会有两个疑问:①世界坐标在哪里?②相机坐标在哪里?
- 0. 预备知识
- 1. czm_computePosition()
- 2. czm_translateRelativeToEye(vec3, vec3)
对于一个 MaterialAppearance 对象来说,它的顶点着色器代码默认为:
attribute vec3 position3DHigh; attribute vec3 position3DLow; attribute vec3 normal; attribute vec2 st; attribute float batchId; varying vec3 v_positionEC; varying vec3 v_normalEC; varying vec2 v_st; void main() { vec4 p = czm_computePosition(); v_positionEC = (czm_modelViewRelativeToEye * p).xyz; // position in eye coordinates v_normalEC = czm_normal * normal; // normal in eye coordinates v_st = st; gl_Position = czm_modelViewProjectionRelativeToEye * p; }
0. 预备知识
Cesium 拥有一个小规模的内置 glsl 库,预置了非常多 czm_
开头的函数、结构、常量。在自定义着色器的 Appearance、Material 类中,允许直接使用,Cesium 会自动把着色器代码合并、链接。
1. czm_computePosition()
很不幸的是,这个函数并不是完整地内置在 Source/Shaders
下的,Source/Shaders/Builtin/computePosition.glsl
这里面只有函数的声明,并没有,它的函数实现是动态生成的。
幸运的是,通过全文检索,我找到了它的生成代码,它位于 Primitive.js
文件中:
这个函数有点长,大家可以自己去看源代码
Primitive._modifyShaderPosition = function ( primitive, vertexShaderSource, scene3DOnly ) { // ... };
Cesium 会用正则去匹配你写的 attribute vec3 XXX3DHigh
和 attribute vec3 XXX3DLow
这两个顶点属性(attribute
)中的 XXX
,并以之构造函数名 czm_computeXXX
,当然它会把首字母给你大写了以符合函数命名规范。
默认情况下,这个 XXX 就等于 position
。所以,抽丝剥茧,在我们关心的三维模式下,这个函数其实可以省略成这样:
attribute vec3 position3DHigh; attribute vec3 position3DLow; vec4 czm_computePosition() { return czm_translateRelativeToEye(position3DHigh, position3DLow); }
到这一步,看到实际上作用的函数是 czm_translateRelativeToEye(vec3, vec3)
,而这一个函数在 内置的 glsl 中是有的了。
2. czm_translateRelativeToEye(vec3, vec3)
vec4 czm_translateRelativeToEye(vec3 high, vec3 low) { vec3 highDifference = high - czm_encodedCameraPositionMCHigh; vec3 lowDifference = low - czm_encodedCameraPositionMCLow; return vec4(highDifference + lowDifference, 1.0); }
它的作用是,将世界坐标减去相机中心坐标,返回一个齐次坐标,即将世界坐标平移到相机坐标系下,而不旋转。
有的朋友可能会有两个疑问:①世界坐标在哪里?②相机坐标在哪里?
- 0. 预备知识
- 1. czm_computePosition()
- 2. czm_translateRelativeToEye(vec3, vec3)
对于一个 MaterialAppearance 对象来说,它的顶点着色器代码默认为:
attribute vec3 position3DHigh; attribute vec3 position3DLow; attribute vec3 normal; attribute vec2 st; attribute float batchId; varying vec3 v_positionEC; varying vec3 v_normalEC; varying vec2 v_st; void main() { vec4 p = czm_computePosition(); v_positionEC = (czm_modelViewRelativeToEye * p).xyz; // position in eye coordinates v_normalEC = czm_normal * normal; // normal in eye coordinates v_st = st; gl_Position = czm_modelViewProjectionRelativeToEye * p; }
0. 预备知识
Cesium 拥有一个小规模的内置 glsl 库,预置了非常多 czm_
开头的函数、结构、常量。在自定义着色器的 Appearance、Material 类中,允许直接使用,Cesium 会自动把着色器代码合并、链接。
1. czm_computePosition()
很不幸的是,这个函数并不是完整地内置在 Source/Shaders
下的,Source/Shaders/Builtin/computePosition.glsl
这里面只有函数的声明,并没有,它的函数实现是动态生成的。
幸运的是,通过全文检索,我找到了它的生成代码,它位于 Primitive.js
文件中:
这个函数有点长,大家可以自己去看源代码
Primitive._modifyShaderPosition = function ( primitive, vertexShaderSource, scene3DOnly ) { // ... };
Cesium 会用正则去匹配你写的 attribute vec3 XXX3DHigh
和 attribute vec3 XXX3DLow
这两个顶点属性(attribute
)中的 XXX
,并以之构造函数名 czm_computeXXX
,当然它会把首字母给你大写了以符合函数命名规范。
默认情况下,这个 XXX 就等于 position
。所以,抽丝剥茧,在我们关心的三维模式下,这个函数其实可以省略成这样:
attribute vec3 position3DHigh; attribute vec3 position3DLow; vec4 czm_computePosition() { return czm_translateRelativeToEye(position3DHigh, position3DLow); }
到这一步,看到实际上作用的函数是 czm_translateRelativeToEye(vec3, vec3)
,而这一个函数在 内置的 glsl 中是有的了。
2. czm_translateRelativeToEye(vec3, vec3)
vec4 czm_translateRelativeToEye(vec3 high, vec3 low) { vec3 highDifference = high - czm_encodedCameraPositionMCHigh; vec3 lowDifference = low - czm_encodedCameraPositionMCLow; return vec4(highDifference + lowDifference, 1.0); }
它的作用是,将世界坐标减去相机中心坐标,返回一个齐次坐标,即将世界坐标平移到相机坐标系下,而不旋转。
有的朋友可能会有两个疑问:①世界坐标在哪里?②相机坐标在哪里?
部分转自互联网,侵权删除联系
最新评论