-
Basic information
Cesium version: a customized Cesium based on an older version, I can’t confirm which exact version.
OS: Windows 10
Browser: Chrome 111.0.5563.147 -
Target:
I intend to make a water reflection effect, similiar to what mentioned here: Water effects and animation - #3 by wzc339005483
To do that I need to create a reflect camera, and render it to the framebuffer as a texture. I try to render a extra frame to framebuffer, and use the texture to render the scene with different camera setting to a custom primitive which is the water surface.
- What I did/tried:
I created a newCesium.View
object with a newCesium.Camera
object, and use it as a offscreen view. During first render, I set the scene’s_view
to my newCesium.View
object,update the camera, and render the scene, but I only got a blank image in the texture. After that I set the view of the scene back to default and render another scene for on-screen display.
I have already taken care of rendering the framebuffer color texture.
- Related code:
Framebuffer definition:
let framebufferReflection = new Cesium.Framebuffer({
context: context,
colorTextures: [new Cesium.Texture({
context: context,
width: context.drawingBufferWidth,
height: context.drawingBufferHeight,
pixelFormat: Cesium.PixelFormat.RGBA,
})],
depthStencilTexture: new Cesium.Texture({
context: context,
width: context.drawingBufferWidth,
height: context.drawingBufferHeight,
pixelFormat: Cesium.PixelFormat.DEPTH_STENCIL,
pixelDatatype: Cesium.PixelDatatype.UNSIGNED_INT_24_8
})
});
Code for offscreen render:
function updateOffscreenCamera(camera, newPos, width, height){
camera.position = newPos;
// camera.rotateUp(90);
camera.frustum.width = width;
camera.frustum.aspectRatio = width / height;
return camera.frustum.computeCullingVolume(camera.positionWC, camera.directionWC, camera.upWC)
}
let { scene } = viewer
// 1. Create offscreen camera and view;
let offscreenCamera = new Cesium.Camera(scene);
let offscreenView = new Cesium.View(scene, offscreenCamera, new Cesium.BoundingRectangle(0, 0, context.drawingBufferWidth, context.drawingBufferHeight))
function tick() {
let { frameState } = scene;
let camera = viewer.scene.camera;
// let gl = scene.context._gl
offscreenCamera.position = viewer.camera.position;
offscreenCamera.direction = viewer.camera.direction;
offscreenCamera.up = viewer.camera.up;
offscreenCamera.frustum = viewer.camera.frustum;
const boundingRectangle = new Cesium.BoundingRectangle(0, 0, context.drawingBufferWidth, context.drawingBufferHeight);
offscreenView.viewport = boundingRectangle;
offscreenView.passState.viewport = boundingRectangle;
offscreenView.passState.framebuffer = framebufferReflection
scene._view = offscreenView
const { passState } = scene._view
let invertHeightPositionCartographic = new Cesium.Cartographic(
viewer.scene.camera.positionCartographic.longitude,
viewer.scene.camera.positionCartographic.latitude,
viewer.scene.camera.positionCartographic.height * 1.5
)
let invertHeightPosition = Cesium.Cartesian3.fromRadians(
invertHeightPositionCartographic.longitude,
invertHeightPositionCartographic.latitude,
invertHeightPositionCartographic.height
);
// 2. Update offscreen frame buffer texture
scene._view.globeDepth.update(context, passState, offscreenView.viewport, scene._defaultView.globeDepth._useHdr);
updateOffscreenCamera(offscreenView.camera, invertHeightPosition, context.drawingBufferWidth, context.drawingBufferHeight)
scene.updateFrameState();
frameState.passes.offscreen = true;
context.uniformState.update(frameState);
scene.updateEnvironment();
scene.updateAndExecuteCommands(passState, Cesium.defaultValue(scene.backgroundColor, Cesium.Color.TRANSPARENT));
scene.resolveFramebuffers(passState);
scene._view = scene._defaultView;
context.endFrame();
const pixels = context.readPixels({
x: 0,
y: 0,
width: context.drawingBufferWidth,
height: context.drawingBufferHeight,
framebuffer: framebufferReflection
});
// pixel is a blank image, all pixel value is [0,0,0,255]
viewer.resize();
scene.render();
Cesium.requestAnimationFrame(tick);
}
tick();
- Question:
Am I on the right track? Would this be able to do what I want? If not, what should I do instead?
Thanks