hi!!
I found a way to render to texture,but this demo not working in version 1.86.
I try to run this demo,I got a black screen.
I trapped in this problem a week,I need help.
Welcome to the community! I apologize for the delayed response - I was at GEOINT all of last week.
I am also having trouble running the sandcastle demo that you shared. Have you tried copying the code and running it on a local build?
-Sam
I have tried it on local build,but it still doesn’t work.
--------------------------------update-----------------------------
I try to create a custom primitive,and set Framebuffer,which took effect. but It seems not clear previous frame.I dont know how to clear.(my english is not very good. I hope I can express it clearly)
------------------------------------------------update-------------------------------------
look function update() .
class MyPrimitive{
constructor(modelMatrix,context,framebuffer){
this.framebuffer = framebuffer
var v0 = [0.5, 0.5, 0];
var v1 = [-0.5, 0.5, 0];
var v2 = [-0.5, -0.5, 0];
var v3 = [0.5, -0.5, 0];
var vertex = [
...v0, ...v1, ...v2, ...v3
]
var positions = new Float64Array(vertex)
var nny = [0,-1,0]
var normals = new Float32Array([
...nny, ...nny, ...nny, ...nny
])
var sts = new Float32Array([
1.,1.,
0.,1.,
0.,0.,
1.,0.
])
var indices = new Uint16Array([
0,1,2,0,2,3
])
//纹理
var texture = undefined
var imageUri = 'http://localhost:8080/Widgets/Images/ImageryProviders/bingAerial.png'
Cesium.Resource.createIfNeeded(imageUri).fetchImage().then(function(image){
console.log('图片已加载')
var textureObj;
if(Cesium.defined(image.internalFormat)){
textureObj = new Cesium.Texture({
context:context,
pixelFormat: image.internalFormat,
width: image.width,
height: image.height,
source: {
arrayBufferView: image.bufferView
}
})
}else{
textureObj = new Cesium.Texture({
context:context,
source:image
})
}
texture = textureObj
})
// 1.6 定义attributeLocations
var attributeLocations = {
position: 0,
normal: 1,
textureCoordinates: 2,
};
var vs = `
attribute vec3 position;
attribute vec3 normal;
attribute vec2 st;
attribute float batchId;
varying vec3 v_positionEC;
varying vec3 v_normalEC;
varying vec2 v_st;
void main(){
v_positionEC = (czm_modelView * vec4(position, 1.0)).xyz;
v_normalEC = czm_normal * normal;
v_st = st;
gl_Position = czm_modelViewProjection * vec4(position, 1.0);
}
`
var fs = `
varying vec3 v_positionEC;
varying vec3 v_normalEC;
varying vec2 v_st;
uniform sampler2D myImage;
void main(){
vec3 positionToEyeEC = -v_positionEC;
vec3 normalEC = normalize(v_normalEC);
#ifdef FACE_FORWARD
normalEC = faceforward(normalEC, vec3(0.0, 0.0, 1.0), -normalEC);
#endif
czm_materialInput materialInput;
materialInput.normalEC = normalEC;
materialInput.positionToEyeEC = positionToEyeEC;
materialInput.st = v_st;
//An czm_material with default values.
//Every material's czm_getMaterial should use this default material as a base for the material it returns.
//The default normal value is given by materialInput.normalEC.
czm_material material = czm_getDefaultMaterial(materialInput);
material.diffuse = texture2D(myImage, materialInput.st).rgb;
// #ifdef FLAT
gl_FragColor = vec4(material.diffuse + material.emission, material.alpha);
// #else
// gl_FragColor = czm_phong(normalize(positionToEyeEC), material);
// #endif
}
`
//创建vertexArray(Geometry)
function createVertexArray(context){
var geometry = new Cesium.Geometry({
attributes: {
position: new Cesium.GeometryAttribute({
// vtxf 使用double类型的position进行计算
// componentDatatype : Cesium.ComponentDatatype.DOUBLE,
componentDatatype: Cesium.ComponentDatatype.FLOAT,
componentsPerAttribute: 3,
values: positions
}),
normal: new Cesium.GeometryAttribute({
componentDatatype: Cesium.ComponentDatatype.FLOAT,
componentsPerAttribute: 3,
values: normals
}),
textureCoordinates: new Cesium.GeometryAttribute({
componentDatatype: Cesium.ComponentDatatype.FLOAT,
componentsPerAttribute: 2,
values: sts
})
},
// Workaround Internet Explorer 11.0.8 lack of TRIANGLE_FAN
indices: indices,
primitiveType: Cesium.PrimitiveType.TRIANGLES,
boundingSphere: Cesium.BoundingSphere.fromVertices(positions)
});
var vertexArray = Cesium.VertexArray.fromGeometry({
context: context,
geometry: geometry,
attributeLocations: attributeLocations,
bufferUsage: Cesium.BufferUsage.STATIC_DRAW,
// interleave : true
});
return vertexArray;
}
//创建command
function createCommand(context){
var translucent = false
var closed = true
// 借用一下Appearance.getDefaultRenderState
var rawRenderState = Cesium.Appearance.getDefaultRenderState(translucent, closed, undefined);
var renderState = Cesium.RenderState.fromCache(rawRenderState);
var vertexShaderSource = new Cesium.ShaderSource({
sources: [vs]
});
var fragmentShaderSource = new Cesium.ShaderSource({
sources: [fs]
});
var uniformMap = {
myImage: function() {
if (Cesium.defined(texture)) {
return texture;
} else {
return context.defaultTexture;
}
}
}
var shaderProgram = Cesium.ShaderProgram.fromCache({
context: context,
vertexShaderSource: vertexShaderSource,
fragmentShaderSource: fragmentShaderSource,
attributeLocations: attributeLocations
});
return new Cesium.DrawCommand({
vertexArray: createVertexArray(context),
primitiveType: Cesium.PrimitiveType.TRIANGLES,
renderState: renderState,
shaderProgram: shaderProgram,
uniformMap: uniformMap,
owner: this,
framebuffer : framebuffer?framebuffer:undefined,
pass: Cesium.Pass.OPAQUE,
modelMatrix: modelMatrix,
})
}
//清空命令
function createClearCommand(fb){
// var c = Cesium.ClearCommand.ALL
return new Cesium.ClearCommand({
pass:Cesium.Pass.OPAQUE,
framebuffer:this.framebuffer,
color:new Cesium.Color(0.,0.,0.,0.),
})
}
this.show = true
this._command = undefined
this._createCommand = createCommand;
this._cCommand = undefined
this._createClearCommand = createClearCommand;
}
update(frameState){
if(!this.show){
return
}
if(!Cesium.defined(this._cCommand) && this.framebuffer){
this._cCommand = this._createClearCommand(this.framebuffer)
}
if(!Cesium.defined(this._command)){
this._command = this._createCommand(frameState.context)
}
if(Cesium.defined(this._cCommand)){
frameState.commandList.push(this._cCommand)
}
if(Cesium.defined(this._command)){
frameState.commandList.push(this._command)
}
}
isDestroyed() {
return false;
}
destroy() {
if (Cesium.defined(this._command)) {
this._command.shaderProgram = this._command.shaderProgram && this._command.shaderProgram.destroy();
}
return destroyObject(this);
}
}
============================update==================================
I think I solved this problem.
function createClearCommand(){
return new Cesium.ClearCommand({
pass:Cesium.Pass.OPAQUE,
color:new Cesium.Color(0.,0.,0.,0.),
framebuffer:this.framebuffer,
stencil : 0,
owner : this,
depth: 1.0,
})
}
Amazing work! It looks like your most recent update fixed the issue. Please reach out if you have any other questions or concerns.
-Sam
Can you offer me a demo? I have been confused on render to texture for a long time
texture in framebuffer._colorTextures.
class MyPrimitive{
constructor(modelMatrix,context,framebuffer){
this.framebuffer = framebuffer
var v0 = [0.5, 0.5, 0];
var v1 = [-0.5, 0.5, 0];
var v2 = [-0.5, -0.5, 0];
var v3 = [0.5, -0.5, 0];
var vertex = [
...v0, ...v1, ...v2, ...v3
]
var positions = new Float64Array(vertex)
var nny = [0,-1,0]
var normals = new Float32Array([
...nny, ...nny, ...nny, ...nny
])
var sts = new Float32Array([
1.,1.,
0.,1.,
0.,0.,
1.,0.
])
var indices = new Uint16Array([
0,1,2,0,2,3
])
//纹理
var texture = undefined
var imageUri = 'http://localhost:8080/Widgets/Images/ImageryProviders/bingAerial.png'
Cesium.Resource.createIfNeeded(imageUri).fetchImage().then(function(image){
console.log('图片已加载')
var textureObj;
if(Cesium.defined(image.internalFormat)){
textureObj = new Cesium.Texture({
context:context,
pixelFormat: image.internalFormat,
width: image.width,
height: image.height,
source: {
arrayBufferView: image.bufferView
}
})
}else{
textureObj = new Cesium.Texture({
context:context,
source:image
})
}
texture = textureObj
})
// 1.6 定义attributeLocations
var attributeLocations = {
position: 0,
normal: 1,
textureCoordinates: 2,
};
var vs = `
attribute vec3 position;
attribute vec3 normal;
attribute vec2 st;
attribute float batchId;
varying vec3 v_positionEC;
varying vec3 v_normalEC;
varying vec2 v_st;
void main(){
v_positionEC = (czm_modelView * vec4(position, 1.0)).xyz;
v_normalEC = czm_normal * normal;
v_st = st;
gl_Position = czm_modelViewProjection * vec4(position, 1.0);
}
`
var fs = `
varying vec3 v_positionEC;
varying vec3 v_normalEC;
varying vec2 v_st;
uniform sampler2D myImage;
varying vec3 v_normal;
void main(){
vec3 positionToEyeEC = -v_positionEC;
vec3 normalEC = normalize(v_normalEC);
#ifdef FACE_FORWARD
normalEC = faceforward(normalEC, vec3(0.0, 0.0, 1.0), -normalEC);
#endif
czm_materialInput materialInput;
materialInput.normalEC = normalEC;
materialInput.positionToEyeEC = positionToEyeEC;
materialInput.st = v_st;
//An czm_material with default values.
//Every material's czm_getMaterial should use this default material as a base for the material it returns.
//The default normal value is given by materialInput.normalEC.
czm_material material = czm_getDefaultMaterial(materialInput);
material.diffuse = texture2D(myImage, materialInput.st).rgb;
// #ifdef FLAT
gl_FragColor = vec4(material.diffuse + material.emission, material.alpha); //vec4(normalEC.xyz,1.);
// #else
// gl_FragColor = czm_phong(normalize(positionToEyeEC), material);
// #endif
}
`
//创建vertexArray(Geometry)
function createVertexArray(context){
var geometry = new Cesium.Geometry({
attributes: {
position: new Cesium.GeometryAttribute({
// vtxf 使用double类型的position进行计算
// componentDatatype : Cesium.ComponentDatatype.DOUBLE,
componentDatatype: Cesium.ComponentDatatype.FLOAT,
componentsPerAttribute: 3,
values: positions
}),
normal: new Cesium.GeometryAttribute({
componentDatatype: Cesium.ComponentDatatype.FLOAT,
componentsPerAttribute: 3,
values: normals
}),
textureCoordinates: new Cesium.GeometryAttribute({
componentDatatype: Cesium.ComponentDatatype.FLOAT,
componentsPerAttribute: 2,
values: sts
})
},
// Workaround Internet Explorer 11.0.8 lack of TRIANGLE_FAN
indices: indices,
primitiveType: Cesium.PrimitiveType.TRIANGLES,
boundingSphere: Cesium.BoundingSphere.fromVertices(positions)
});
var vertexArray = Cesium.VertexArray.fromGeometry({
context: context,
geometry: geometry,
attributeLocations: attributeLocations,
bufferUsage: Cesium.BufferUsage.STATIC_DRAW,
// interleave : true
});
return vertexArray;
}
//创建command
function createCommand(context){
var translucent = false
var closed = true
// 借用一下Appearance.getDefaultRenderState
var rawRenderState = Cesium.Appearance.getDefaultRenderState(translucent, closed, undefined);
var renderState = Cesium.RenderState.fromCache(rawRenderState);
var vertexShaderSource = new Cesium.ShaderSource({
sources: [vs]
});
var fragmentShaderSource = new Cesium.ShaderSource({
sources: [fs]
});
var uniformMap = {
myImage: function() {
if (Cesium.defined(texture)) {
return texture;
} else {
return context.defaultTexture;
}
}
}
var shaderProgram = Cesium.ShaderProgram.fromCache({
context: context,
vertexShaderSource: vertexShaderSource,
fragmentShaderSource: fragmentShaderSource,
attributeLocations: attributeLocations
});
return new Cesium.DrawCommand({
vertexArray: createVertexArray(context),
primitiveType: Cesium.PrimitiveType.TRIANGLES,
renderState: renderState,
shaderProgram: shaderProgram,
uniformMap: uniformMap,
owner: this,
framebuffer : framebuffer?framebuffer:undefined,
pass: Cesium.Pass.OPAQUE,
modelMatrix: modelMatrix,
})
}
//清空命令
function createClearCommand(fb){
return new Cesium.ClearCommand({
pass:Cesium.Pass.OPAQUE,
color:new Cesium.Color(0.,0.,0.,0.),
framebuffer:this.framebuffer,
// stencil : 0,
// owner : this,
depth: 1.0,
})
}
this.show = true
this._command = undefined
this._createCommand = createCommand;
this._cCommand = undefined
this._createClearCommand = createClearCommand;
}
update(frameState){
if(!this.show){
return
}
if(!Cesium.defined(this._cCommand) && this.framebuffer){
this._cCommand = this._createClearCommand()
}
if(Cesium.defined(this._cCommand)){
frameState.commandList.push(this._cCommand)
}
if(!Cesium.defined(this._command)){
this._command = this._createCommand(frameState.context)
}
if(Cesium.defined(this._command)){
frameState.commandList.push(this._command)
}
}
isDestroyed() {
return false;
}
destroy() {
if (Cesium.defined(this._command)) {
this._command.shaderProgram = this._command.shaderProgram && this._command.shaderProgram.destroy();
}
return destroyObject(this);
};
}
Thank you, I would try it, merry Christmas!
Thank you @linsanda for sharing that code example!
你好!我看了你的代码是有中文注释,我直接用中文提问了,表达更准确些。我最近也在研究把上一个primitive 渲染存到framebuffer里面的texture,然后再把framebuffer里面的colorTexture贴图到下一个primitive,尝试过很多次,不知道如何使用/解决,请问你是如何解决的,可否赐教?
Hello! I saw that your code has Chinese comments. I asked questions directly in Chinese. Recently, I have been studying how to save the last primitive rendering to the texture in the framebuffer, and then map the colortexture in the framebuffer to the next primitive. I have tried many times. I don’t know how to use / solve it. How do you solve it? Can you give me some advice?
老哥!你的问题解决了吗,我也有一样的问题。