1. A concise explanation of the problem you're experiencing.
I am working on custom render in Cesium and now I can draw something to framebuffer.
I try to draw the framebuffer to screen with its depth information. The color is drawn to the screen but the depth is incorrect.
I know that Cesium uses log depth by default, but I think it is not the cause of my problem because I merely want to copy the depth to the screen.
BTW, when render to the screen directly(set the option framebuffer : undefined) I get correct depth, but I need to
capture the render result for further process, so I have to render to framebuffer
2. A minimal code example. If you've found a bug, this helps us reproduce and repair it.
Here is what I did, I extract the important parts of my code, you can see my complete code in my Github https://github.com/RaymanNg/3D-Wind-Field
1. setup the texture
var createTexture = function (options, typedArray) {
if (Cesium.defined(typedArray)) {
// typed array needs to be passed as source option, this is required by Cesium.Texture
var source = {};
source.arrayBufferView = typedArray;
options.source = source;
}
var texture = new Cesium.Texture(options);
return texture;
}
const dataTextureSampler = new Cesium.Sampler({
// the values of data texture should not be interpolated
minificationFilter: Cesium.TextureMinificationFilter.NEAREST,
magnificationFilter: Cesium.TextureMagnificationFilter.NEAREST
});
const colorTextureOptions = {
context: context,
width: context.drawingBufferWidth,
height: context.drawingBufferHeight,
pixelFormat: Cesium.PixelFormat.RGBA,
pixelDatatype: Cesium.PixelDatatype.UNSIGNED_BYTE,
sampler: dataTextureSampler
}
const depthTextureOptions = {
context: context,
width: context.drawingBufferWidth,
height: context.drawingBufferHeight,
pixelFormat: Cesium.PixelFormat.DEPTH_COMPONENT,
pixelDatatype: Cesium.PixelDatatype.UNSIGNED_SHORT,
sampler: dataTextureSampler
}
colorTexture = createTexture(colorTextureOptions);
depthTexture = createTexture(depthTextureOptions);
2. setup the framebuffer
var createFramebuffer = function (colorTexture, depthTexture) {
var framebuffer = new Cesium.Framebuffer({
context: context,
colorTextures: [colorTexture],
depthTexture: depthTexture
});
return framebuffer;
}
framebuffer = createFramebuffer(colorTexture, depthTexture);
3. setup the drawCommand
var uniformMap = {
screenColor: function () {
return colorTexture;
},
screenDepth: function () {
return depthTexture;
}
};
new Cesium.DrawCommand({
owner: this,
vertexArray: createVertexArray(context),
primitiveType: primitiveType,
uniformMap: uniformMap,
modelMatrix: Cesium.Matrix4.IDENTITY,
shaderProgram: shaderProgram,
framebuffer: framebuffer,
renderState: renderState,
pass: Cesium.Pass.OPAQUE
});
4. the glsl code
frag shader:
uniform sampler2D screenColor;
uniform sampler2D screenDepth;
varying vec2 textureCoordinate;
void main() {
vec4 color = texture2D(screenColor, textureCoordinate);
float depth = texture2D(screenDepth, textureCoordinate).r;
gl_FragColor = color;
gl_FragDepthEXT = depth;
}
3. Context. Why do you need to do this? We might know a better way to accomplish your goal.
I want to make a GPU particle system, you can see the full problem context in my previous threads:
https://groups.google.com/forum/#!topic/cesium-dev/gjjd9TNeY2A
https://groups.google.com/forum/#!topic/cesium-dev/7kCcITmGbEA
4. The Cesium version you're using, your operating system and browser.
Cesium 1.53