A question about Primitive render to texture

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.

@linsanda

Welcome to the community! :rocket: :grinning: 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-------------------------------------
GIF 2021-10-12 11-08-20
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.
GIF 2021-10-12 14-23-09

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,

        })

    }
1 Like

@linsanda

Amazing work! It looks like your most recent update fixed the issue. Please reach out if you have any other questions or concerns.

-Sam