Create erasable surface

I then get the error saying this.material.update() is not a function.

Are you sure you assigned material in Editor?..

Yes, it’s there when I check the editor: (bottom right)

Okay… What if you dump it before?

console.log(this.material) ?

It shows it:

Damn it, you need to extract resource.

Rename your attribute for materialAsset and add

this.material = this.materialAsset.resource;

Or simply change this.material.update() to this.material.resource.update()
But if I need to access the resource art of it later, your way might be quicker so I don’t have to type out this.material.resource all the time.

And do I want to change this.material.opacityMap to use the same?

Yep, since now you have to operate with this.material.resource.

In the debugger console opacityMap comes up as null when i do it that way.

EDIT: Wait never mind, it’s just because there isn’t one before hand

Okay, when try to set real opacity map with transparent pixels, as I said before.

Okay, honestly most of this code is lost on me. I can’t tell if the renderTarget stuff is doing anything and the pc.Textures I’ve created don’t seem to have a use as a result.

Going by the pipeline you mentioned earlier:

  1. Created the texture, don’t know if pc.RenderTarget is doing anything
  2. Obtain pointer position, haven’t done this
  3. Created the new layer and added scratch surface entity to it
  4. Set layer render target to new layer, I guess that’s done
  5. Use texture from first step as opacity map, I guess this is also done
  6. Copy texture to temp, also done, but not sure what purpose it serves
  7. Write custom shader, started but not done (8, 9, and 10 not done as a result)

Okay.

  1. Texture is using for opacity. Render target is for your layer, it makes it render there.
  2. It’s pretty easy, don’t care about that.
  3. How did you copy your texture?

The texture being this:

var texture = new pc.Texture(graphicsDevice,
    {
        width: 64,
        height: 32,
        format: pc.PIXELFORMAT_R8_G8_B8_A8
    });

I pretty much just did the same thing only called it tempTexture. But this just creates a new one, it doesn’t copy it I guess.

You have to specify onPostRender callback for your layer.

So Its like

var layer = this.app.scene.layers.getLayerByName("Surface");
layer.renderTarget = renderTarget ; // fix it, wrong for now
layer.onPostRender = function(cameraIndex) {
    console.log("here");
}

Exactly, You cant just copy texture by setting it. Because it copies only reference, not a value.
In order to copy texture you have to do it by GPU (it stores there).

So thats why we need this callback, when you layer rendered.

Which it didn’t seem to, the console.log in post render doesn’t get called.

Try to add some camera there.

Okay, there we go. It gets called now

Nice. Bth, have you tested it with real opacity map? Does it work?

I’m not entirely sure what you mean by that, but I have added an empty image to the opacity of the material in the editor. Setting the alpha test to anything above 0 makes the material go transparent.