Sign in to follow this  
Paul C Skertich

3D Vertex Painting DirectX 11

Recommended Posts

I was curious about how I would go about vertex painting or terrain building with mouse picking. My idea was to have a off screen black render target. When the mouse clicks on a position of the terrain - it would load a round soft white texture onto the render target.  WHen the Terrain Editing is off - it will save the height map created by the off screen render target.


Vice Versa goes with perhaps blending in different textures using the same technique.


Just a rough idea but I wondered if anyone that has experience in this type would know how it's normally done.


Kind of like this


Share this post

Link to post
Share on other sites

i made a terrain editor like that a while ago

i just cast a ray & checked for intersection with the triangles of the terrain

the closest triangle intersected was chosen and the point of intersection was used to find the closest vertex on the triangle

that vertex was the start point of whatever effect you were using, the hill effect for example was something like

for each vertex

compute distance from start vertex

divide by range to put in (0,1) interval

then plug that into cosine and scale

then use that value to increase or decrease the vertex height

i used a dynamic vertex buffer & used a uniform grid as my spatial partitioning structure to speed it all up


if i was gonna make another one i'd use vertex texture fetches to offset the vertices of a triangle grid right in the vertex shader & just modify the heightmap

Edited by js09427

Share this post

Link to post
Share on other sites

I really like that! Great job! I was thinking more of painting on a off screen texture then save the offscreen texture as a height map. There was a nother video that had the same idea I can't find it though.


I'll try to give a example - I have it in my head but it's like what you did but a lot different. It's very very similiar to procedual per pixel texturing with a striking resemblance. I should get a working example soon to demonstrate what I'm talking about. The dynamic buffer will need to be there to constantly stay updating with the heighmap.


In your example did your calcuations use cpu or the gpu?

Share this post

Link to post
Share on other sites

Firstly, what is your target GPU? That, to a degree, will dictate how you approach this. A powerful desktop GPU with plenty of memory would suggests a GPU approach - a slow laptop GPU with limited memory may force a CPU approach.


Secondly, check out Scape. If you download it, you can use either a CPU GPU brushes to edit the heightmap. The GPU version is orders of magnitude faster (meaning far more fluid and reactive to user input).

Share this post

Link to post
Share on other sites

I downloaded the executable for scape and source. I like it but what I was thinking was this:


1) Create Render Target

2) Camera view can either be view from top view.

3) Translate mouse coords to ray picking.

4) Project an white round texture in the render target. Where ever the mouse is clicked of course.

5) Save render target as a height map and then Update the terrain vertex using map and unmap functions with the new data being created from the render target.


So, if the user created a plateu brush custom using texture then this can easily be created. If the user wants a soft round hill then it can created as a texture. The heighmap could either be used in the vertex shader like a tessleation displacement would function in the domain shader.


I can easily go with the calculated version of generating the terrain but I thought it would be awesome to and a challenge to do the above steps. Not only can this be applied to terrain generating but it can be used to blend two different textures together.


As in like poly painting in Zbrush and also the alpha brush used within Zbrush type approach.

Share this post

Link to post
Share on other sites

Sorry for the late reply! Here's one way of editing heightmap data:


Create you heighmap texture, say 4097x4097 in VRAM. Call this the terrain texture.


Now decide on the maximum brush size you want to use, say 1025x1025 (you only need to use a small region of this for small brushes). Create *two* textures of this size. Call the first the brush texture, and the second the destination texture.


Ideally, use R32_FLOAT texture formats for all three textures, because you can store any unclamped floating point values (including negative).


Assuming you've got the world location of the mouse, render a quad into the destination texture the size of the brush, using the region from the heightmap and the region from the brush as texture inputs, add/subtract the values (and set min/max values for plateau's and canyons etc.). Now copy the contents of the destination back to the heightmap, and render.


In summary, if I set a brush size of 9 pixels, I'd create a 9x9 fp32 brush texture on the cpu and sub-copy it to the top left of the brush texture. I'd then draw a 9x9 quad to the destination texture using a 9x9 region from the heightmap centred on the mouse plus the 9x9 region from the brush. Do whatever math is appropriate, and then copy the 9x9 region from the destination texture back to the heightmap texture. Render the scene using the new heightmap data.

Edited by mark ds

Share this post

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this