1. A concise explanation of the problem you're experiencing.
I want to perform particle computation in GPU and use the result to render the particle. Now I am able to perform the computation with WebGL, and I am trying to render the result of computation to a texture.
2. A minimal code example. If you've found a bug, this helps us reproduce and repair it.
I don't have a code example but a rough plan:
The source code of DrawCommand contains a framebuffer option.
https://github.com/AnalyticalGraphicsInc/cesium/blob/039375c3c33c577a5afae3bff62da83c819fe50b/Source/Renderer/DrawCommand.js#L34
Maybe I can create a Cesium.Framebuffer and pass it to the DrawCommand?
https://github.com/AnalyticalGraphicsInc/cesium/blob/master/Source/Renderer/Framebuffer.js
Then I may use the _colorTextures(I am not sure which texture to use) of Framebuffer as a uniform?
Finally I set up a custom primitive with custom vertex and fragment shader source by using MaterialAppearence and begin my custom WebGl render?
I am not sure whether it will works. I will appreciate it if you can tell me a better(simpler) solution.
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/vR7H4KJURJ8
https://groups.google.com/forum/#!topic/cesium-dev/7kCcITmGbEA
4. The Cesium version you're using, your operating system and browser.
Cesium 1.53
omar
February 18, 2019, 3:50am
2
The best example I’ve found for rendering to a texture in CesiumJS is on Scene.pick:
* Post passes update. Execute any pass invariant code that should run after the passes here.
*
*/
updateDebugShowFramesPerSecond(this, shouldRender);
tryAndCatchError(this, postPassesUpdate);
// Often used to trigger events (so don't want in trycatch) that the user might be subscribed to. Things like the tile load events, ready promises, etc.
// We don't want those events to resolve during the render loop because the events might add new primitives
callAfterRenderFunctions(this);
if (shouldRender) {
this._postRender.raiseEvent(this, time);
frameState.creditDisplay.endFrame();
}
};
/**
* Update and render the scene. Always forces a new render frame regardless of whether a render was
* previously requested.
* @param {JulianDate} [time] The simulation time at which to render.
This file has been truncated. show original
The way it works is the scene is rendered with a special pick pass, where each primitive renders a unique solid color. A framebuffer is created, and it’s set on the Pass:
});
this._passState.framebuffer = this._fb;
}
this._passState.viewport.width = width;
this._passState.viewport.height = height;
return this._passState;
};
var colorScratch = new Color();
PickFramebuffer.prototype.end = function(screenSpaceRectangle) {
var width = defaultValue(screenSpaceRectangle.width, 1.0);
var height = defaultValue(screenSpaceRectangle.height, 1.0);
Then, when a DrawCommand is executed, the context uses the given framebuffer:
// The command's framebuffer takes presidence over the pass' framebuffer, e.g., for off-screen rendering.
var framebuffer = defaultValue(drawCommand._framebuffer, passState.framebuffer);
var renderState = defaultValue(drawCommand._renderState, this._defaultRenderState);
shaderProgram = defaultValue(shaderProgram, drawCommand._shaderProgram);
uniformMap = defaultValue(uniformMap, drawCommand._uniformMap);
beginDraw(this, framebuffer, passState, shaderProgram, renderState);
continueDraw(this, drawCommand, shaderProgram, uniformMap);
};
Context.prototype.endFrame = function() {
var gl = this._gl;
gl.useProgram(null);
this._currentFramebuffer = undefined;
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
var buffers = scratchBackBufferArray;
if (this.drawBuffers) {
this.glDrawBuffers(buffers);
}
When this framebuffer is used, the attached colorTextures are drawn to. For the case of the Scene.pick, the pixels are then read back to check which object the mouse clicked on:
So to summarize, if you want to draw to a texture in CesiumJS, you have to create a framebuffer, and one colorTexture, then set it as the framebuffer on passState for your custom draw command.
Thanks for your help!
I wrote a example of render to texture . I hope it can help others
It is a rough(and probably imperfect) example, if someone has a better idea, please feel free to improve it.
Omar Shehata omar.sameh.shehata@gmail.com 于2019年2月18日周一 上午11:50写道:
omar
February 19, 2019, 2:15pm
4
This is awesome Rayman! Thanks for sharing this!!!
I’ve definitely bookmarked this thread. I’m sure it will help a lot of people. Hopefully it can serve as a basis for a future tutorial.
Hi,It seems the cull setting of renderState didn’t work.in DrawCommand which has a framebuffer instance.
https://groups.google.com/forum/#!searchin/cesium-dev/framebuffer%7Csort:date/cesium-dev/uK_QAdHBAHM/yu4lStHxBQAJ
在 2019年2月19日星期二 UTC+8上午8:54:13,Rayman Ng写道: