Tuesday, August 4, 2026

City Parks and Residential Grass

I didn't get a chance to write a July blog post for various reasons. I was busy with summer related activities and work (full time job) tasks. I also didn't add much new content the past month or two. It was mostly bug fixes and optimizations. I did make some progress with parks and residential areas. Most notably, I added proper grass blades to the city areas that were using grass textured ground. There were some smaller improvements such as adding ivy to house walls, adding park restroom skylights, improving the look of park creeks, and making people walk on park paths. I originally wasn't going to write a post on this because it was too small a topic, but I haven't done any major improvements since adding data centers.

This time around I'm going to show what I did and then go back to explain the details. Here's a video I recorded a few weeks ago showing the new look of city parks.

 

There are a few bugs visible in this video that I already fixed: grass in the walkway, wrong splash footstep sounds, woman stuck by a parked car near the end.

Grass

I've had proper fields of grass blades supported in 3DWorld's tiled/infinite terrain system for many years. I even wrote a blog post on the topic back in 2018 before I started working on procedural cities. This uses instanced blocks of randomly placed grass triangles that are curved using an OpenGL tessellation shader and move with the wind. I use a texture to mask off the area of the terrain that has grass and read heightmap values to translate grass to the correct elevation in the vertex shader. Distant grass is drawn with reduced triangle sets where pairs of neighboring grass blades are merged into a single larger triangle with summed area and average color.

All of these optimizations allow terrain and grass rendering to run at hundreds of FPS (frames per second) on dedicated graphics cards, though the framerate struggles to meet 30 FPS on integrated graphics. That's why I have both a config file option and keyboard shortcut to disable grass if needed. It defaults to on since 3DWorld targets PCs with dedicated GPUs from the last decade.

The challenge for grass is that cities are drawn as flat quads at fixed elevation and don't use the terrain system. The terrain mesh is masked off and not drawn in these areas. Instead, there are flat roads, sidewalks, concrete, and grass textures for parks and residential plots. What I need is to draw grass blades over these plots and parks, but without also drawing the terrain. I can do this by adding custom terrain weights that sum to a value greater than one, and use that in the terrain shader to disable the ground but still enable grass in the grass shader. This enables flowers as well, since they use the same set of textures and similar shaders.

I just have to set the heightmap values to match the height of the city, so that the grass is drawn at the correct elevation. Except it's not that simple, because parks have hills, ponds, and creeks at heights above or below the rest of the city. So I have to sample these height values from parks when creating the heightmap for each terrain tile. Technically, I only need to set heights for the hills because there's no grass at the bottom of ponds and creeks. But it's simpler if I can set the low points as well and use this for setting the player height rather than querying the park at each frame.

City park with grass around the path and a person walking.

The next problem is that I don't want grass everywhere inside parks and residential plots. It needs to be excluded from areas with houses, restrooms, driveways, swimming pools, park paths, creeks, and ponds. Those last few items are complex shapes that my simple cube intersection system can't easily handle. Paths are represented by a series of 100 points along a centerline and a constant width, which is definitely neither easy nor efficient to test blocks of grass against. This means grass needs to be placed using point + radius queries for each grid texel, where the query returns false (no grass) when the circular shape intersects any grass blocker object. This should guarantee no grass blades sprouting up in the middle of the sidewalk.

With enough effort, this does work. However, the terrain material mask is too low resolution to get good grass coverage. The 128x128 base texture represents areas of around 4 meters in size, which produces grass coverage that's too sparse around small objects such as park paths. Any small object masks off a 4m x 4m area where there's no grass. It's actually worse than that, because of the way grass density is smoothly interpolated across texels. If I want to have zero grass on driveways and sidewalks, I have to check even more than 4m away to guarantee the weight function drops to zero before hitting a grass blocker object.

City park with grass, a swing set, a hill on the right, and a restroom in the back.

My solution was to create a higher resolution 1024x1024 weights texture to use in place of the 128x128 lower resolution texture for any terrain tiles that overlap a city area with grass. This results in higher resolution textures embedded within the 2D array of normal textures. Cities are typically around 1.5 terrain tiles in size, resulting in 2x2, 2x3, or 3x3 blocks of higher resolution textures. The good news is that there's usually only one city close enough to show grass at a time, which limits the memory needed to around 36MB (3x3 tiles * 4 one-byte weight values * 1024x1024 texels). The borders of the texture need special care to interpolate edge values so that they meet with the lower resolution texture edges seamlessly. This was accomplished by using an image upscaling operation for areas outside the city bounds where normal heightmap terrain is drawn. All of this took a long time to get right.

Much of that time was spent optimizing the system so that it can make up to 1M (1024x1024) queries into the city object system to determine the grass coverage value at each texel. This required many individual optimizations to get the worst case under the 16ms (~1/60s) frame time target. This included hierarchical queries, custom acceleration structures, caching/testing common grass blockers, and using multiple threads. In the end I was able to get the worst case time down to around 10ms, which is fast enough that there's no noticeable lag when creating new weight textures. This data is cached per city and only regenerated when the player moves far across the map.

City park with a creek and pond, and a woman walking along the path.

The final results look pretty good to me. It's not perfect. There are still some jagged edges of grass blade clusters along curved surfaces such as creeks and park paths. It's not that obvious because of how the grass geometry blends into the ground texture when looking down at a steep angle. I did put some effort into tuning the colors and texture scales so that these two features look very similar in the distance. The grass texture is a good representation of a field of grass viewed top down.

One missing feature is that I'm not removing grass at the base of trees. This is primarily because the tree occlusion map is the same lower 128x128 resolution as the terrain heightmap. If I use this for grass, the keep-out area around tree trunks is too blocky. I didn't want to increase the tree occlusion map resolution because it's only one component of a larger texture that stores other terrain properties such as ambient occlusion and shadow data. Increasing the resolution of the entire texture would take too much time and memory. 

Park Improvements

I've made a few other park improvements. Park restrooms have improved interiors with high ceilings and beams. Some of them even have skylights. They're now connected to the city electrical wires.

Fountains now have a water surface draw that occludes the grass under it. That means I don't need to use them as grass blockers. The water is reflective just like ponds and creeks and uses the same shader. I used a similar approach when drawing fountains inside malls.

The heightmap used for creeks and ponds has been improved so that creeks are wider and have smoother edges. I added rocks along the sides of creeks. Park path and creek crossings look a bit cleaner as well.

I modified the pedestrian path finding so that they prefer to follow park paths that go in the same general direction as their destination. I added logic for them to avoid walking in creeks, and to use park path crossings when they must cross a creek. This turned out to be too complex for the basic city path finding system, so I had to switch to using a grid-based approach like I use with building backrooms. This system is explained in a previous blog post. I had to make some adjustments to the end points of creeks to pull them back from the edge of the park so that there's more room for people to walk next to the sidewalks. This is important for pedestrians passing by each other.

Here is a recent overhead view of a park showing the grass, walkways, creek, and pond. 

Crossing park paths and creek with rocks.

Residential Yards

The screenshots above showed off the new look of parks. The same grass improvements apply to the yards of houses in residential cities. The only difference is that the set of blockers changes to include houses, driveways, walkways, and swimming pools. I think the results are quite nice compared to earlier screenshots. Adding vegetation is always an improvement.

A residential neighborhood with grass yards.

I added house driveways a while back. While I was working on grass, I thought it would be good to add walkways to the front doors of houses so that people don't have to walk through the grass. This also neatly solves the problem of grass clipping through the small step under exterior doors, because I can make walkways grass occluders just like driveways. I placed the mailbox next to the walkway (if there is one) rather than the driveway. Even with the higher grass map resolution, grass can still only be placed at a precision of around half to one meter square. (There are some constant factors so it's not an exact fraction of the 4m tile spacing.) This does leave some empty space at the edges of the walkway and driveway.

House with driveway + basketball hoop and walkway + mailbox. A digital alarm clock can be seen in the room on the right.

One of the other smaller items I've added is digital alarm clocks on the night stands in bedrooms. They use the same drawing logic as the digital clocks found on office building walls. The time is updated dynamically based on the current real time.

Wall Ivy 

I worked on improving residential city ivy between some of the grass-related changes. Ivy is far simpler and easier to work with compared to grass because it's a completely separate system that doesn't have to interact with the terrain. I'm free to do this however I want.

Each yard now has a random "maintenance" score that determines how well maintained it is. Yards with low maintenance have ivy that climbs over walls and hangs off the sides. I added a weight parameter to ivy branches that pulls them down into a curved shape as they grow longer while unsupported. This gives unmaintained ivy a more natural and wild look.

Ivy growing on a wall and branching out away from the edge. This is from an older screenshot before I added grass.

Ivy can now be found growing up the walls of some houses. I initially added the entire wall just like the edges of walls separating yards, but that looked wrong because ivy grew over windows. I went back and rewrote this part so that the ivy system accepts a list of areas to avoid, which are filled in with the windows along that wall of the house. Now the ivy will use the space between, above, and below windows to grow.

Ivy growing on two exterior walls of a house.

Here's another example with a different house.

Ivy growing along the wall of a house, between the windows.

This system has a lot of potential. I can in theory add arbitrary surfaces for ivy to grow on with exclusion regions, provided they're all axis aligned rectangles. It shouldn't be too difficult to extend this to other shapes that support point and line intersection queries.

That's all for this post. I don't have anything else planned at this time. I'm distracted by tasks and work and will get back to 3DWorld sometime later. I do have some items on my Trello board such as caves.

21 comments:

  1. Typolice!
    "usually only once city" should be "one"
    "along curves surfaces" should be "curved"
    "grass improvements applies to the yards" should be "apply"

    ReplyDelete
  2. The 3D grass looks much better than the flat ground texture. I would adjust the ground to be darker and much lower contrast, so it doesn't stand out as much. If there's a way to add variation to the individual blades, that would help a lot too. I do admire how the grass catches shadows!
    The length is strange though. For un-maintained grass, I would expect it to be much taller, uneven and clumpy, and many even taller stalks tipped with seed clusters. For mowed grass, I would expect it to be shorter and more dense, with square clipped-off blades from the mower instead of the fresh new-grown blades that taper to a point.

    ReplyDelete
    Replies
    1. I don't think the lower contrast ground texture looks as good when viewed from high above. I suppose I could experiment with the texture colors.

      It's difficult to customize the shape of each blade because it's drawn as uniform instanced triangles whose vertices are moved by the grass shader to create the curved shape. I can't easily select a different shape for different areas without adding significant complexity to the system. The only configurable inputs are constant length, color mask texture, and density mask texture. In fact the grass at the edge of the city may be drawn in the same draw call as the grass outside the city if they fall within the same terrain tile.

      Delete
  3. Now that you have the grass system working, do you think you could add reeds to the edges of creeks, and ponds? The bare muddy shores look so sickly and sad. A few cattails and bulrushes could really spruce things up! And then you would have the system for your wilderness zones as well.

    ReplyDelete
    Replies
    1. I did have some plants at the edges of ponds, but I must have removed them at some point. I think it was because they didn't look like plants that would be found there. I don't think these would be dense enough to require something like the grass system. I only need to add a new plant type for that, and then place some of these plants along ponds. Creating plants with code is very time consuming though, and there's not enough random variation if I use a 3D model. Maybe eventually...

      Delete
  4. It's still super strange to see giant portrait windows looking into a bathroom. Can't the poor inhabitants at least get you to render that portion of the scene at 1/16 resolution and then scale it up for a pixelated mosaicking effect?

    ReplyDelete
    Replies
    1. This is only a problem for corner bathrooms. I do have glass block windows that I use for most bathrooms that only have windows along one wall. There's some drawing problem where the player viewing from outside => glass block => inside => glass block doesn't render correctly. Some problem with the alpha blending/depth/stencil passes. I'll have to see if I can fix that, or maybe it did get fixed at some point, then I can put the glass block windows there.

      Delete
    2. I enabled glass block windows for corner bathrooms. It looks somewhat odd, but appears to work, so I suppose I can leave it enabled.

      I don't think I can easily render just the interior/bathroom and then draw it as a texture for the window. All objects inside a building with the same material are part of the same draw call, so I can't draw the interior of houses at a finer granularity than per-building. I would need to use the bounds of each window, or the set of windows along each wall, as a scissor test. But since the windows themselves aren't physical objects but are a repeating texture, there's no clean way to restrict it to only the windows associated with the bathroom vs. all the windows on the wall.

      Plus, if you had several floors of stacked bathrooms, it would be expensive to draw the scene separately for each one. Or multiple buildings with visible bathrooms. I can't cache the texture because it would change each frame with the camera perspective as the player moves. I can't select only the closest building/bathroom because then there would be obvious popping as the selected one changed.

      I may be able to mask off the windows with bathrooms using the stencil mask or another render target, and blur it per-pixel inside the mask as postprocessing. But that wouldn't work if there was something like a tree between the camera and the window as it would blur the tree as well.

      I did spend quite a while thinking about this, but I never solved it. I'm sure it would be easy to do in a tech demo of just one room of one building with one window. But making it scale to many buildings with many rooms and multiple windows each, without much effect on the framerate? No idea!

      Delete
  5. The ivy arcing away from the walls is a great improvement! I think scaling the leaves up to double their current size (and randomizing the sizes a bit as well) would help to sell them better. I feel like they should also be darker. Would it be helpful if I submit some PRs with my recommended "improvements"? I tried that a few years ago (5344 commits ago it looks like) but IIRC you preferred the hobby element to the open-source commit triage at the time. Let me know your preference. I'd be glad to help in some small ways where I can.

    ReplyDelete
    Replies
    1. If I make the leaves larger then they're more likely to clip through each other and through the wall, which looks bad. It's actually pretty difficult to determine where a collection of rotated quads will intersect each other, at least in an efficient way. There are different leaf sizes. The ones near the ends of the branches are smaller.

      If you want to look at the code, start with ivy_builder_t::add_leaves_to_branch() in city_plants.cpp. Maybe add some randomness to lsz_scale. That's pretty easy for me to do though, almost certainly the easiest change of you four comments.

      Delete
    2. The leaves were already randomly resized from -20% to +20%. I changed the upper bound to +40%. But there was a bug affecting leaf size for the hanging vines. The leaf direction is derived from the cross product of the branch dir with the wall normal. This is always magnitude 1 for ivy along the wall, since the vectors are orthogonal. But for hanging ivy, I need to normalize the cross product, otherwise the leaves are too short. This definitely improves the look.

      Delete
    3. I'm glad you found the bug! Improvement is good.
      I'd like to draw your attention to a pattern of thinking that has been gnawing Niddhägger-like at the roots of this project for basically ever. In the simplest possible terms, you are letting your left-brain tyrannize you. This sentence is a perfect example:
      "If I make the leaves larger then they're more likely to clip through each other and through the wall, which looks bad."
      It only looks "bad" to the delineation-oriented "this or that" left brain. If you are trying to do a per-leaf NASA-qualified simulation then this matters. If you want the ivy to look right, then the overall impression of the ivy matters much more.
      I mean, just look at this:
      https://cdn.80.lv/api/upload/content/55/5e67420791cb1.jpg
      There are alpha-card intersections all over the place! Is it technically "unrealistic"? Sure. But it looks great, and at the end of the day that's the job of graphics.

      But maybe I don't know what I'm talking about. If I'm right then intersecting alpha-cards would be used in almost every open-world or fantasy game: WoW, Guild Wars 2, Elder Scrolls, many Unreal and Unity titles, mobile games, etc. People would make hair cards on characters. There would be particle-like debris, hanging moss, ferns, and ground clutter in countless games, all crisscrossing each other. Even some modern high-end titles would still use the technique for distant LODs or specific stylized assets because it is extremely cheap.
      I poke fun, but we both know it's all true. The “unrealistic” intersections are the entire point: they let a handful of textured planes (or tris for even faster rendering) create the visual complexity of hundreds of individual leaves while staying friendly to real-time rendering budgets and sorting like you have in this project. Instead of making the cards smaller and smaller, you should be making them bigger and bigger. Put whole clusters of ivy leaves on a card, procedurally jitter the UVs (or render whole clusters to a texture at runtime) if you need the variation, and make some beautiful ivy!
      https://gamesartist.co.uk/wp-content/uploads/2025/09/HighPolyIvy_Final-1024x576.jpg

      I've heard time and again from you that you can't make this or that improvement because it would result in "unrealistic" outcomes. This is the left brain talking, and as long as you give that aspect of you veto power over the trade-offs you will always be shackled to the details at the expense of the whole.

      I love procgen, and I want you to do well and for this very cool project to succeed. I'm not saying you have to agree with me, but I'm certain you would get much better results much faster from a healthy balance between right and left brain thinking. As it is, your left brain is shooting down most of the progress you could be making.

      Delete
    4. Thanks for your feedback. But keep in mind that 3DWorld isn't a game, it's a world generator/simulator. If it was a game, I would have released something on Steam in the past 10+ years I've been working on the project. As a generator, the point is to get the details right to make a realistic environment. Why do you think I put so much effort into connecting everything correctly with pipes? Do you think a casual player would notice that? Of course not! But I see those things when playing games. I don't know what's wrong with me, but things like intersecting leaves really bother me if I can get close to them in a game. Leaves don't intersect in the real world!

      Yes, maybe you disagree on this. Maybe most people do. But these are the goals of my project. I'm not making just another game, I'm making something different. This is a hobby and is meant to be fun and interesting. I'm crazy enough that I find writing code to determine leaf quad intersections fun and interesting. I would much prefer this over creating a leaf texture in an image editor or creating a plant in a 3D modeler. I'm terrible at artistic things like that.

      Your example tree image looks good. But that's because it was likely created by hand and is placed in a known environment, possibly where the player can't view a leaf so close that it fills their screen. This approach is very common in games, but also time consuming to get right. The artist can tweak the lighting, rotate the leaf cards so that they meet the branch at the correct point, fix the bad looking intersections, etc. In my case the plants are all uniquely generated. The player can go anywhere in the world and get right up to them, and sometimes interact with them. And it has a full day/night cycle so the lighting is unknown. If I'm not careful I get intersections that look bad on *some* plant, and it really stands out to me. I can't release something to anyone else without fixing that.

      I have looked at several procedural ivy projects. Most of these have cards/quads for each leaf. I would say it's common in procgen for people to feel that adding multiple leaves per card only looks good when they can be hand placed. The trick to getting good performance is to only show what's visible, using proper LODs, which is actually easier than working with a full 3D model of the plant because it can be simplified and culled at the triangle level. The 3DWorld trees, ivy, new cat tails, etc. - all the vegetation in the city scene except for grass - add negligible frame time.

      Also, fun fact: 3DWorld started as a tree simulator back in my 2001 intro to graphics course, and won the best project award. The tree was generated in such detail that I could simulate leaves moving in the wind, snow interaction, and individual raindrops hitting, sliding down, and falling off leaves. I want to keep this detail because that's what differentiates it from all the other engines/games/tools. Very few projects that I'm aware of generate/simulate things to this level of detail.

      Delete
  6. Hi, I would like to know if this engine can be used to make actual full games? Like a 2010 AAA quality game. Because this looks very promising... especially considering that it's completely open source...

    ReplyDelete
    Replies
    1. Probably, but it wouldn't be easy. I don't have a scene editor and the engine isn't really separated from the game with a clean API. Plus there's no documentation. I assume someone could make a game with enough effort if they were willing to modify the code. I already have a first person shooter game, space combat game, and open world exploration system that could be turned into a game. They're built in/part of the code. Not AAA quality though.

      Delete
  7. Hey frank! i have to say i've been following your project for nearly 7 years now. I think it's awesome to see your still adding new cool stuff to it. One thing i really want to suggest is for you to create a new "scene" file that has all the new building types like the prisons, datacenters, restaurants, etc and so on generate in actual grid city plots. You've added so much extra location types over the past few years and loading up the default scene makes it hard to find these locations just flying around as most of them are scattered everywhere randomly.

    I think it's about time to have an updated world scene that takes advantage of the new building types and makes them more easily accessible. were maybe "residential" city grids get things like convenient stores or gas stops spawned within them would make sense. And a new type of "commercial district" city grid were all the new office building types, malls, datacenters, etc can generate. So that you can walk around roads and such and explore all the new content much more organically. You can also add a "industrial" grid type to make it easier to find and explore factories and such.

    Basically i think updating the existing residential grid type and adding a few new grid types will make finding and exploring all the new stuff much easier. I would say doing it that way might be more simple to add. You could go as far as implementing different plot "types" within the same city "grid" if you really were to tie things together but i would imagine that would require rebuilding the entire city gen system for that. it would be cool to have different "zoning" or plot types within the same city grid but i would imagine that would be quite complex.

    This might be quite a bit to ask but i thought i would atleast bring across the idea again as i think the lack of "zoning" or "themed" city grids are the biggest issue as 3dworld has alot more types of locations than it used to. And tying the new content into a more structured layout could be incredible witch is why i suggested a new scene type.

    One last suggestion is that i remember you adding the ability to change the seed for building generation years back. You could also add that for the overall layout of city grids/roads if you wish. But either way i'm glad your still experimenting with this :)

    Oh and i would also like to ask for a v1.5 64-bit precompile if you get the chance. At this point i should probably just install the latest visual studio as mine is outdated (2019) so that i can compile the latest builds of 3dworld properly XD

    ReplyDelete
    Replies
    1. Thanks for the feedback. There's currently no way to force a particular building type because each one has a pretty narrow requirement for building size, aspect ratio, number of floors, roof type, etc. Only a small subset can be successfully converted to something like a factory or data center. The buildings added to commercial cities tend to be too tall with a narrow footprint. Factories and data centers won't fit in existing city blocks. I may be able to work around that by increasing road spacing and reducing max building height. That could cause problems with other parts of the city such as the power lines, streetlight placement, traffic, etc. It's only ever been tested with the current road spacing value.

      The config file system has include file support, so it's possible to include the existing config_heightmap.txt in a new file and then override some of the parameters. It could be tricky to find a set of values that works correctly. It may be easier to restrict it to a single city no secondary buildings. At least that would be faster to generate/load.

      Note that you can use the '6' key to enable debug visualization for building types that places color coded boxes above special buildings. This color coding is also visible in map mode ('K' key). You can use the arrow keys to move the map around, press space bar to move the player (red dot) to the center of the map, and 'K' again to get back to first person mode at the new location. This is usually how I test the new building types. Maybe some of that isn't available in the build you have.

      Hospitals, schools, hotels, apartments, and parking structures are already placed in cities because there's no low height limit. And malls can be found in the ground under cities. It's mostly the industrial buildings that can't be placed because they're short and wide.

      Adding gas stations and convenience stores to residential cities should be possible. I just need to make a corner sub-plot into a gas station rather than a house yard. There are already special cases for parks.

      I can't easily add a seed to change the city and road layout. The problem is that these operations change (flatten) the heightmap, and this process is permanent and can't be undone. If I move the roads and cities then the old locations will still be flat/raised/lowered, and the areas with bridges and tunnels will be broken. Changing this would require reloading the heightmap. But that's one of the earliest and slowest steps of the load time, so you may as well just quit and reload the entire scene from scratch. And changing the road layout within the city would require regenerating cars, pedestrians, the skyway, the electrical network, connections to adjacent cities, etc. Changing the buildings affects almost nothing if they remain in their original plots, which is why it can be done in about a second.

      I'm currently using Visual Studio Insiders, Community 2026. I find it works quite well. It was simple to install and starts up quickly, and almost never crashes. If I create a new release I probably also need to share a new models data file. That's getting tricky because the file keeps growing and I'm almost out of space on Google Drive.

      Delete
    2. Okay, I added a v1.5 release build and a new v10 model data zip file.

      Delete
    3. For the special building types, I don't see an easy way to add this. Building type is determine in the geometry assignment step, after the building is placed, by matching each allowed type against a pretty narrow set of constraints involving the building size, shape, roof type, etc. This is internal to building setup and not something the city building placer has access to, so it can't place a building that it knows will be assigned to a special type. It can force the type (like I do with convenience stores and park restrooms), but that doesn't guarantee it can construct a valid building of that type. If the constraints for that type aren't met then it may assert or create something invalid.

      The reason you don't get industrial buildings and data centers in cities is because the min office building height is around 8 floors, which is too tall for those types. And also they're not flagged as the correct material - those building types want concrete block, but cities are mostly glass and steel materials. And the window sizes don't match the city material parameters.

      This can be fixed by changing the size and exterior texture parameters in building_materials.txt. But that can't be overridden with a new config file because the add_material command is a function call that adds the material, and a material can't be removed or updated in another config file. (At least not unless I add some sort of material naming system so that you can refer to and update a previous named material.) This would require a new building_materials.txt with some entries modified. I don't want to create (and have to maintain) a second 538 line text file that's slightly different.

      So, sorry, I don't think there's any easy way to do this. It would take many hours of work and hundreds of lines of new code. I prefer not to add all that complexity.

      Delete
    4. I appreciate the response frank! I was not aware there was a debug function to locate building types on the map. That helps quite a lot actually.

      Delete