Cesium高级教程-反射水面-渲染结果作为材质使用
作为纹理使用
上一节我们可视化了反射相机的渲染结果,本节我们将渲染结果作为材质贴合到一个面几何上看看效果
let colorTexture = Cesium.Texture.fromFramebuffer({
context: viewer.scene.context,
framebuffer: fbo
})
colorTexture.type = 'sampler2D';
const polygon = new Cesium.PolygonGeometry({
polygonHierarchy: new Cesium.PolygonHierarchy(positions),
height: 80,
});
const geometry = Cesium.PolygonGeometry.createGeometry(polygon);
const instance = new Cesium.GeometryInstance({
geometry: geometry,
});
let appearance = new Cesium.MaterialAppearance({
material: new Cesium.Material({
fabric: {
type: "Image",
uniforms: {
image: colorTexture
}
}
})
})
viewer.scene.primitives.add(new Cesium.Primitive({
geometryInstances: instance,
appearance: appearance
}));
效果如下图所示
示例效果可到 xt3d 官网 运行查看
存在的问题
可以看到目前存在两个问题
范围不对
可以看到整个场景渲染的范围都被显示出来,此时这个结果其实是正确的,因为理论上结果就是这样,我们将反射相机渲染的结果作为一张纹理贴合到面几何上,因为反射相机所绘制的范围肯定是比几何范围大的,所以这张纹理代表的范围不只几何范围,直接把这个纹理贴合到这个几何上,那结果肯定就是这样,所以我们需要干扰一下着色器,使其看起来是我们想要的效果。
左右颠倒
因为反射是从下往上看,所有左右颠倒也是正常的
修改着色器
针对上面两个问题我们需要从着色器中进行解决,我们修改Appearance
的着色器(这里我们修改Material
的source
)
x轴翻转
let appearance = new Cesium.MaterialAppearance({
materialSupport: Cesium.MaterialAppearance.MaterialSupport.ALL,
material: new Cesium.Material({
fabric: {
type: "Image",
uniforms: {
image: colorTexture
},
source: `
czm_material czm_getMaterial(czm_materialInput materialInput)
{
vec2 uv=materialInput.st;
...
czm_material material = czm_getDefaultMaterial(materialInput);
material.diffuse = texture(image,uv).rgb;
return material;
}
`
},
})
})
我们在着色器中对纹理做x轴做一个翻转
示例效果可到 xt3d 官网 运行查看
这样结果看上去就舒服多了!接下来我们看看如何纠正显示的范围
纠正范围
因为我们将渲染的结果作为一张纹理贴到几何上,这张纹理的范围是整个反射相机渲染的范围,所以肯定也会显示摄像机看到的其他区域。
为了解决这个问题,我们需要将几何的点投影到屏幕空间,然后通过屏幕空间的坐标对纹理进行采样,这里还有一种最简单的方式,将几何的纹理坐标换成渲染窗口的坐标,代码如下
source: `
czm_material czm_getMaterial(czm_materialInput materialInput)
{
//vec2 uv=materialInput.st;
...
czm_material material = czm_getDefaultMaterial(materialInput);
material.diffuse = texture(image,uv).rgb;
return material;
}
示例效果可到 xt3d 官网 运行查看
此时感觉应该差不多了,但是,当您移动场景的时候您会发现又出现问题了
示例效果可到 xt3d 官网 运行查看
当水面位于屏幕中间的时候,好像结果就是正确的,当移动场景时会发现渲染结果和场景发生了错位,这是啥原因呢? 原因下一节讲解。您也可以先自己思考一下到底是什么原因。
更多内容见 Cesium高级教程-教程简介