godot_heightmap_plugin icon indicating copy to clipboard operation
godot_heightmap_plugin copied to clipboard

Adding brush properties (Brush Rotation, Brush Spacing, Min and Max size uncapped, random brush texture selection)

Open TheConceptBoy opened this issue 2 years ago • 13 comments

Just leaving this as a separate possible feature suggestion.

Artist will opt in to using graphics tablets / drawing monitors instead of a mouse to paint textures on terrain. These pens have additional inputs like pressure / tilt which can be used to drive various parameters of the brushes for creating some really versatile paint strokes.

Aside from pen pressure and tilt, the pen's movement can used to calculate angle/direction as well as speed of movement which can also be used to drive various parameters.

Also if the brushed preset could be set to an array of textures, it could be used to randomly pick a brush preset for some interesting effects.

TheConceptBoy avatar Dec 30 '21 20:12 TheConceptBoy

Using pen pressure could be a feature, but defining what it does sounds very vague in the way you describe it. Sure it can affect parameters, but we need to define which ones, and how a user would even configure that, in the range of possibility.

There is also an issue open about pen pressure already: https://github.com/Zylann/godot_heightmap_plugin/issues/245

Zylann avatar Dec 31 '21 17:12 Zylann

Well to start it off, the most important features to control with pen pressure are: Brush Size Brush Rotation Brush Image. image

In terms of letting the user chose which values drive which parameters, you can use Krita as an example. They have set up a very flexible way of painting your pen data with parameters: https://docs.krita.org/en/reference_manual/brushes/brush_settings/options.html#option-scatter

In the nutshell you can get a set of source data like pressure (provided by the pen driver) / direction (calculated) / speed of pen movement (calculated) / tilt (not all pens support this) and pair it with a parameter like size / rotation / am image from an array of brush images/ Scatter amount/ density and adjust how much influence the pen has over these values.

TheConceptBoy avatar Dec 31 '21 22:12 TheConceptBoy

I wonder what use there is for changing rotation and image based on pressure when editing terrain?

If the goal is to replicate the feature set of a dedicated painting app like Krita, it could take a while to get there (also this won't benefit users with a mouse?). Sounds cool to have though

Zylann avatar Jan 01 '22 00:01 Zylann

The use for rotation and image change is that you can create seemingly random patterns. Like grass patches on pavement for texture painting. For example something like this: image

Right now you have to painstakingly paint each little patch manually. If you can drive a random image instead of the same image from the same angle, you can stamp very nice and organic patterns quickly. This sort of randomness could also be done as a standalone feature without being driven by pen pressure, thus including mouse users with it. Randomness could be used along with frequency of stamping which isn't digital pen dependent.

Terrain painting would also benefit from random brush for things like random craters / random elevations when paired with frequency.

Frequency of paint placement is actually something of problem I've seen across several plugins aside from this one. A tiniest of mouse movements registers as a splat of brushwork. Every minute movement, translates to an instant paint deposit and the only way to have somewhat of a control of it is to tone down the opacity, at which point the effect is accumulative. There has to be a way to spread out the brush stamp deposits over mouse movement distance. Say something like a slider and a text box for setting the minimum distance (uncapped) the mouse needs to move before the brush is stamped again.

If the goal is to replicate the feature set of a dedicated painting app like Krita, it could take a while to get there (also this won't benefit users with a mouse?).

Features like random brush image / frequency could be based on either pressure or cursor travel. In which case it's open for both mouse and pen users. I mean why not implement it for mouse users first and worry about pen pressure later?

Also random brush image can also improve mesh painting. If you're painting something like grass, having the brush chose a random image can make placing natural looking patches of grass much easier. Pair that with uncapped brush sizes and ability to set brush stamping frequency and you've got a very quick way of making organic looking mesh placements.

TheConceptBoy avatar Jan 01 '22 06:01 TheConceptBoy

I've renamed the subject to one that is more universal regardless of pen or mouse usage. Presently these properties can be set to random or be driven by distance / speed / direction of cursor movement.

TheConceptBoy avatar Jan 01 '22 07:01 TheConceptBoy

For brush rotation, I recall a separate addon for doing this (in a generic way, not just on heightmaps)

Zireael07 avatar Jan 01 '22 09:01 Zireael07

Note: currently brush painting is implemented with shaders: https://github.com/Zylann/godot_heightmap_plugin/tree/master/addons/zylann.hterrain/tools/brush/shaders Until Godot gets decent #include support, all the logic discussed here (dynamic size, dynamic image, dymamic rotation, maybe even dynamic affectation of maps) will have to be copy/pasted in every single shader. Dynamic size also means Viewports have to resize every frame, or be given a larger size than it is already. As for stamping frequency, in a game engine like Godot, it is a pain: it is possible to reduce frequency, but going above 60(fps) in the editor is not possible.

Zylann avatar Jan 01 '22 15:01 Zylann

As for stamping frequency, in a game engine like Godot, it is a pain: it is possible to reduce frequency, but going above 60(fps) in the editor is not possible.

To be honest, I was actually more hoping for an ability to slow it down. The problem here is that the brush doesn't stamp terrain or textures upon a click of the left mouse button, but upon drag and as you drag, every minute movement is triggering a paint stamp. Here in the video you can hear that I'm clicking in 3 different places and nothing appears, not until I drag the cursor across the terrain.

Having the option to randomize the rotation, decrease the frequency of stamping, auto-chose random image out of an array of images could allow us to for example sprinkle crass patches / sand pockets quickly. Right now you have to painstakingly hand paint each pocket/patch/segment by hand.

https://user-images.githubusercontent.com/52581279/147857568-d05547a2-1617-40bd-8041-250603fbf922.mp4

Until Godot gets decent #include support, all the logic discussed here (dynamic size, dynamic image, dymamic rotation, maybe even dynamic affectation of maps) will have to be copy/pasted in every single shader.

Why not have that functionality in a general script and have all those tools that need it extend that script? It's the way I program dozens of NPCs, they all have something unique of their own, but the generic dialogue code is in a general script they inherit from.

TheConceptBoy avatar Jan 01 '22 18:01 TheConceptBoy

Why not have that functionality in a general script and have all those tools that need it extend that script? It's the way I program dozens of NPCs, they all have something unique of their own, but the generic dialogue code is in a general script they inherit from.

Shaders currently do not have a way of extending each other (this is what #include achieves). The closest you could get is to write a script that preprocesses all the required shader variants, but this script needs to be run manually every time you update a shader.

Calinou avatar Jan 01 '22 20:01 Calinou

decrease the frequency of stamping

Which metric would you base this frequency on? Time or distance?

The use for rotation and image change is that you can create seemingly random patterns. Like grass patches on pavement for texture painting

Keep in mind terrain painting has very low-frequency results in a game though, it's not like painting a texture of ground you'd be able to see from a few meters distance. Even applied to splatmaps, random rotation would be largely enough to make it look random in game. In which way do you want pressure to rotate the brush? Just rotate by a larger angle the more pressure is applied?

The problem here is that the brush doesn't stamp terrain or textures upon a click of the left mouse button

image

Looks like pressure is only available in mouse movement events, not button press... so I will have to keep assuming zero on clicks


First version will look like this: image It is basic so there is room for improvement but I'm about to run out of time, holidays end soon

Zylann avatar Jan 01 '22 20:01 Zylann

I would say distance would be more flexible as the painter can control that with their palm. Also preferably uncapped as distance needs are different based on scale of terrain work - be it local details and foliage or global shapes.

On Sat, Jan 1, 2022, 3:54 PM Marc, @.***> wrote:

decrease the frequency of stamping

Which metric would you base this frequency on? Time or distance?

— Reply to this email directly, view it on GitHub https://github.com/Zylann/godot_heightmap_plugin/issues/294#issuecomment-1003616266, or unsubscribe https://github.com/notifications/unsubscribe-auth/AMRFHHZEOXYPIKFPJYGUE73UT5SXVANCNFSM5LAJRBOQ . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.

You are receiving this because you authored the thread.Message ID: @.***>

TheConceptBoy avatar Jan 03 '22 16:01 TheConceptBoy

Sliders cannot exist if they have no maximum, but they can be given a larger value if you click on them and type it. Also there is a maximum anyways since terrains cannot be larger than 4km.

I bumped sliders to 500px. By typing instead of sliding, I allowed a maximum size of 4000 pixels. Painting works but runs at 1fps on Ryzen 5 nVidia 1060 (memory likely high as well). Use at your own risk :)

The changes are available in the master branch.

Zylann avatar Jan 03 '22 16:01 Zylann

https://user-images.githubusercontent.com/52581279/147964857-a74ffa50-cc75-4951-976b-6e561461474d.mp4 Ok, got it updated and gave it a good testing. First things first - the extra brush size addition is perfect! It works exactly as it should and yes, at larger brush sizes it takes exponentially longer to process but from my experience working with Bledner / Substance Painter, that is to be expected of development tools. I'd honestly rather wait a few seconds after a large resolution brush stroke than to be able to paint it in the first place. After all - painting lag is temporary but the final result is priceless :) Brilliant work. Also the 4k size limit makes perfect sense as any larger than the terrain itself would be pretty limited in use case scenarios.

Now one particular note here is - every time you want to change the brush size that is past the 500 mark, you have to go into that panel. The funny thing is that, as a graphics tablet pen user, this isn't too horrendous of a problem since I can use the pen pressure to have full control over any size of brush from 0 to whatever max size I set - but mouse users will need to keep going into that panel to set the new size respectively. Now as a solution - why not have whatever you set as a maximum in the panel become the real maximum of the slider as well? This way less time spend going in and out of the configuration panel for both pen and mouse users.

https://user-images.githubusercontent.com/52581279/147965076-0284e305-14ae-42e7-acd4-8a93bb539111.mp4 I have then tested out the pen pressure and it is also implemented superbly. Seems to be behaving exactly the same as it did within painting programs. One particular adjustment I would recommend is to have a second red circle indicator represent the brush size if the user has enabled the pen pressure checkbox. It's only a quality of life improvement really as all painting programs

https://user-images.githubusercontent.com/52581279/147966165-c96320c8-4d49-4502-80ab-3780a4663fd0.mp4

Last few notes: The inclusion of both Framerate AND distance based stamping is very unexpected but also absolutely welcome. I was however not sure if the plugin somehow decided on prioritizing one over the other or if they are somehow interconnected together to determine the final rate of stamping. If the plugin choses one for the user or decides based on the last slider moved by the user, perhaps an indication of the one being used is on order? Other than that - phenomenal work.

I also realized that the distance based method can be used to place multimesh props at equal distances from one another, such as light poles, fence posts, trees within a orchard, etc. Anything non-interactable.

All around this is a humongous improvement. I honestly can't believe you've achieved it this quickly too.

TheConceptBoy avatar Jan 03 '22 18:01 TheConceptBoy