#Drawing on paper?

1 messages · Page 1 of 1 (latest)

quiet dagger
#

If I want to let the player draw on pages, do I just use render textures which I will then save?

For the erase, I can overwrite with an alpha 0 brush, right?

And I keep creating render textures for each new page the player uses? Is this the way?

It's a 3d game, so the drawing surface will be diagetic.

strange falcon
#

You'll save it as some texture format, but yeah

astral prairie
#

For relatively small textures, fully CPU side texture manipulation is valid option too. Could also consider using larger textures as atlases if you have a lot of pages. There's also this perhaps noteworthy mention on the RenderTexture docs (wouldn't be an issue with C# texture manipulation):

Keep in mind that render texture contents can become "lost" on certain events, like loading a new level, system going to a screensaver mode, in and out of fullscreen and so on

#

I have also seen a line renderer based drawing systems used though texture based are more tradional way I would say and make implementing erasers easier

drifting flame
#

HDRP cameras are expensive, which I think applies to RT cameras too

#

Compute Shaders would be performant and afaik don't "lose" textures in that way
But also require the most knowledge out of the typical options to implement

strange falcon
#

Think it's because it's always some struct copy, so yeah large textures can be slow

astral prairie
#

Using primarily Texture2D.SetPixels32 I made decently fast drawing application some years ago. It worked very smooth with textures up to Full HD, but beyond that it started getting slower

#

And even for larger textures, uploading the texture to GPU side was by far the slowest part iirc (Texture2D.Apply)

#

Only for very large brushes going through the pixels became slow

quiet dagger
#

Yea, I've also considered some kind of line renderer where the points would be saved as game objects or something

#

I don't know

#

I'm not very experienced with compute shaders, dunno if I could pull it off (I guess I could if I commit myself to learning how)

quiet dagger
#

What do you think of line renderers? I will need it for other similar things too.

It would seem like the healthiest solution for memory to me

astral prairie
# quiet dagger What do you think of line renderers? I will need it for other similar things too...

Definitely saving the stroke positions would be much more memory efficient though at the cost of runtime performance. I have little clue how performant it would be if you had a ton of line renderers rendered at once. If the user can draw as much as they like, the amount of separate lines could increase indefinitely.

The eraser feature is another problem that I'm bit unsure about. If you make it work the same way win 11 screenshot tool works where if you touch a line with the eraser, it erases the whole line, then the problem becomes trivial. If you want it to work like erasers usually do, it will become much harder. You could fake it by modifying the line renderers and cutting them into pieces when the eraser moves over it but even that isn't particularly easy to do. The more proper way would be to do some rendering trick by rendering the lines inculding erasings in the order they are drawn (or in reverse) and making it so the eraser lines always override a 0 alpha stroke. That would still probably require rendering them to a RenderTexture first to not erase stuff behind the lines

#

If you need to support multiple line colors, then you have to mess with the render order stuff regardless to make more recent strokes drawn on top

#

I have also seen custom mesh generation used for drawing features though in this case I don't see much value in that over the line renderer. Only thing it would make possible is properly carving the meshes by the eraser strokes though then it would require you to save the meshes instead of the strokes unless you wanted to generate the mesh again from the strokes every time the game is opened. At least as far as my imagination goes, texture based approach is the only one of the discussed options that can properly handle semitransparent strokes and eraser (like one that is fully opaque in the middle of the stroke and fades to transparent towards the edge)

#

Well that could actually work with the linerenderer approach with proper texture/shader with the render order tricks in place

astral prairie
#

If I was you, I would choose one of two options:

  1. Fully texture based approach where the texture is modified either on CPU or GPU. Saved to disk as image (PNG for instance).
  2. Line Renderer based approach where the eraser either removes the whole line at once or splits the line segment into two and keeps removing points from the line as long as the eraser is above the line. The line segments are saved as arrays of points (Vectors2s) + color + thickness etc.

1 would likely be better for runtime performance, worse for memory consumption, 2 the other way around. The choice also depends on the kind of drawings this is meant for (amount of strokes expected, complexity of the strokes, amount of color options etc.) and the visual quality requirements (resolution in pixels, line quality). There could also be a hybrid solution where a texture was used for displaying the drawing and modifying it but only the strokes were saved as point arrays and the image reconstructed from those strokes when the game was opened. At some point with enough strokes, the reconstruction process could get quite heavy though

quiet dagger
# astral prairie If I was you, I would choose one of two options: 1. Fully texture based approach...

Thanks for the detailed reply. I would go for option 1, but I'm afraid memory might become a problem. Or rather, it might be, depending on the user.

My map will be difficult to navigate (feature, not a bug)

The purpose of this is the user will be able to chart out the map himself and scribble on it to mark places, write on it etc. to navigate. He should in theory be able to decide how many pages to use, depending on the size and detail, it will be up to the user.

But of course, it will need to be technically limited in some way.

Render texture should be easier for this and more detailed (vs less dense points in a line renderer) but I'm just unsure of the performance implications of this

#

Another use of this is the user will be able to scribble any symbol on a device, which will then be used as a kind of hologram to project that symbol from a device. This one should probably be a simpler line renderer (thick lines, not that much space to draw, erasing probably not needed other than the whole symbol) but I'd probably be cool if I could use the same method for both

astral prairie
quiet dagger
astral prairie
# quiet dagger Oh yeah, 1k at most. And black and white for the map certainly

Then you can use a single channel format like R8 which should take less space on disk. I don't know how that will work if you need to have separate alpha channel but regardless it shouldn't be too bad. Just tried to do some scribbling with 1000x1000 image and even a colored one didn't get to a MB in size. With the size limit in place, I would not be too worried about disk space

quiet dagger
astral prairie
# quiet dagger Thanks. What anout RTs being expensive in hdrp as spazi said?

I don't think RTs are expensive but cameras may be. If I was implementing a drawing feature like this, I would not use a camera to render to the texture but rather a compute shader to modify the texture directly. That should be really cheap. Even without prior compute shader knowledge, it shouldn't be too hard to pull off.

strange falcon
#

All you need is one render texture / extra camera. Capture the mask you draw, then just use that render texture to modify your primary texture

#

per layer*

#

Well, one camera, one render texture, then a texture for each layer

#

You just need the render texture to capture the mask, but after that you can clear it