That problem confuse me for a long time.
If I want to draw a rectangle with a hole manually like this
Grey grid is the transparent area
Here's the node code
extends Node2D
func _draw():
draw_rect(Rect2(50, 200, 150, 150), Color(1, 0, 0, 0))
draw_circle(Vector2(200, 200), 100, Color(1, 0, 0, 0.9))
and the shader code:
shader_type canvas_item;
void fragment() {
COLOR.a = 1.0 - COLOR.a;
}
I think enable the shader, the result should be like this
The problem is draw() function is not draw all the things on a cache, then apply the shader, then draw it on the screen, it apply the shader after every time you call function like drawcircle(), draw_rect(), etc. So I cant draw some mask effects like the first image shows. And I try light2D, because light2D only support texture, so I cant use custom draw either.
So I dont know how to get the color from current drawing or just cache them into a texture/surface. I think it's a little bit complex for a blendmode function
This sounds like a duplicate of #31124 to me.
Unfortunately, due to how rendering pipelines work nowadays, it is a bit tricky to cut out a hole from an already-rendered object, as the information about the pixels behind it has already been lost.
To combat this problem, there exist a few solutions:
BackBufferCopy which renders right before the object, then render the object, and then render the hole with a shader which uses COLOR = texture(SCREEN_TEXTURE, SCREEN_UV). To make things more optimal, you might make the BackBufferCopy use COPY_MODE_RECT and a rectangle which covers the hole (in local coordinates).I think the backbuffercopy is what I need, just like in gamemaker, you render a stuff to the surface then use shader to the surface, but I think it's better if there's a way to get the buffer from current draw not the screen, on the other words, render current draw to a separate place. In godot I think we must put different layer into individual scene, but I dont't know how to do that concretely
@firecloud888 That would be the third option, but as I mentioned, achieving transparency in that layer is a bit not-simple.
Most helpful comment
Unfortunately, due to how rendering pipelines work nowadays, it is a bit tricky to cut out a hole from an already-rendered object, as the information about the pixels behind it has already been lost.
To combat this problem, there exist a few solutions:
BackBufferCopywhich renders right before the object, then render the object, and then render the hole with a shader which usesCOLOR = texture(SCREEN_TEXTURE, SCREEN_UV). To make things more optimal, you might make theBackBufferCopyuseCOPY_MODE_RECTand a rectangle which covers the hole (in local coordinates).