Optimized Interactive Grass Plugin

How does this compare to terrain grass, performance-wise?

2 Likes

V1.2 Release Notes :tada:

Bug Fixes :hammer_and_wrench:

  • Grass no longer twitches when the player stands still
  • Repeating sound issues resolved

New Features :star2:

  • Multiple Sounds Support: Play different sounds for various parts (e.g., Grass :seedling:, Flower :cherry_blossom:)
  • Expanded Config:
    • Sound mapping customization :musical_note:
    • Support for spatial audio and reverb effects :headphones:

Enjoy the update! :rocket:

Glad you enjoyed it, V.2 is out with bug fixes and more configurations.

Its designed to be efficient because it only activates grass near the player, and in tests with 25,000 grass meshes, there was only a small drop in FPS, which shows it’s pretty good at handling lots of grass without major lag. Works well for smaller game maps with lots of detail, but for large open-world games, use this with Roblox’s terrain grass for the best performance. Although, even if you are using Roblox’s terrain grass in for example an open world game, you can add hundreds of flowers and plants and make them interactable using this module and it won’t cause any lag. (For reference, the current game file/play testing place uses like 6k grass meshes, and there is no lag)

2 Likes

Important Note

I’ve decided to simplify things by switching to a paid plugin. It installs everything you need with one click and updates outdated code easily. This means I won’t have to provide separate game files and models for each version anymore. It also includes tagging features, so you don’t need additional plugins like Tag Editor to tag and untag things.
image

Hi,

How is this different then other free interactive grass scripts like

Thanks

1 Like

Hey, so mine doesn’t have major features that differentiate it from other free interactive grass scripts, the differences are mainly just simplicity since it takes like 10 seconds to set up, and being able to configure with the vast config in mine to adjust everything to your liking, I know this isn’t enough to justify mine being $5, which is why I’m planning on figuring out solutions as to more optimization, other players being able to see you move around in grass without lag, aswell as support for shaking your grass like how the wind shake module does, cause rn if you try to combine this with the windshake module its buggy. I’m looking for feedback on how I can improve my plugin to make it stand out, since right now it was just released today and doesn’t stand out that much.

It’s all good. So how would you go about making it so others can see the movement?

I assume you are currently using local scripts on the client?

1 Like

Yes, I’m using local scripts on the client. I’m not entirely sure how I could make it so others can see the movement but maybe remote events and fire it all to clients? so it wont tween the grass on the server but on everybodies client

V1.3 Release Notes :tada:

Wind Shake Support :leaves:

New Configuration Section :gear:

  • New “WindShake” section in the configuration. :dash:
	WindShake = {
		Enabled = false,  -- Enable/disable wind shake effect
		ScriptPath = Players.LocalPlayer.PlayerScripts.WindControllerClient,  -- Path to the wind shake script, not the module, the script that requires it
		},

New Notification UI :bell:

  • UI Notifications will pop up when you install the plugin, tag grass, untag grass, and uninstall the plugin, as well as errors. It will also include sounds, rather than only using the output to print messages! :yum:
    image

What this is really good for is making tall grass that is different and unique apart from terrain grass. :slight_smile:

In terms of performance advice, use ConnectParallel() where possible, actors, task.synchronize, task.desynchronize, and --!native, also occlusion culling for excluding objects physics not in view

1 Like

Hey, 2 questions

Does this use actors?
What performance methods do you use?

Besides that, pretty neat.

3 Likes

V1.4 Release Notes :muscle:

Performance Features :hammer_and_wrench:

  • Script now uses actors, task.synchronize, task.desynchronize, and --!native.

Occlusion Culling

  • Option to make grass not visible when the camera is not looking at it, although it’s not well optimized and leaving it not enabled is more smooth rather than enabled, spent like 10 minutes making it and realized its pointless and buggy so I scrapped it, but you can still enable it if you want I guess.
Video Showcase

Enjoy the update!

Yup, it looks the most satisfying with tall grass too. Thanks for the suggestions on improving the performance, I’ll look into it.

Yes, it uses actors. It uses a radius system to disable physics for grass that arent near you, so the game doesn’t constantly listen for those touch events. It also uses tags since tags are faster than looping through for example children in a folder or descendants in workspace with the names “Grass”. You should not experience any lag, especially if your grass is spread out and is a decal or has low polygons. Also has an okay occlusion culling system which can be toggled on or off which will move the grass not visible in the players camera to replicatedstorage.

In terms of occlusion culling, ROBLOX already does rendering occlusion culling, what your code should do is use that to determine whether to animate the grass or not.


	local camera=workspace.CurrentCamera

	local function IsInView(object,cameraViewportSize,key)

		local objectPosition = camera:WorldToViewportPoint(object.Position)
		-- Check if the object is within the camera's viewport
		--print(objectPosition)
		if objectPosition.X <= cameraViewportSize.X and
			objectPosition.Y <= cameraViewportSize.Y and
			objectPosition.Z > 0 then -- Z > 0 means the object is in front of the camera
			return true
		else
			return false
		end
	end
	
	local location=game.Players.LocalPlayer.PlayerScripts:WaitForChild("SmartBone-Actors")
	local function dontcullsmartbone()
		local cameraViewportSize = camera.ViewportSize
		for i,v in location:GetChildren() do 
		v.Runtime.Rendered.Value=true	
		end
	end
	local function cullsmartbone()
		local cameraViewportSize = camera.ViewportSize
		for i,v in location:GetChildren() do 
		
		if v.Runtime:FindFirstChild("Sourceobj") and IsInView(v.Runtime.Sourceobj.Value,cameraViewportSize) then
			v.Runtime.Rendered.Value=true
			if v.Runtime.Enabled==false then
				v.Runtime.Enabled=true
			end
		else v.Runtime.Rendered.Value=false	
		end
		end
	end
	local camcfram=camera.CFrame

	while true do
		task.wait(.6)
		if camcfram~=camera.CFrame then
		--pcall(function()
			cullsmartbone() 
		--dontcullsmartbone()
		--end)
		end
	end

This is an example usage of occlusion culling that does not use many resources, but does not include the bounding box which is more relevant to larger objects. In my experience if you want to use that I would not do it every frame, but just use it to determine if you should animate the grass or not. Finally, a distance check could be done on objects in view, check if the grass should be animated or perhaps the fidelity of the animation such as the frames per second.

I have done similar projects which were fish, and boids (birds insect) simulation.
Performance is very important, also offloading calculations to the server is good practice. Great job on your plugin! Glad to see you implemented the performance upgrades.
Here’s a link to something.
“Boids” Flocking Swarming Simulation Luau Algorithm - Library Animated Bird+Bats+Insects V.1.3 [Open Source] FREE MODEL - Resources / Community Resources - Developer Forum | Roblox

Womp womp, resource went paid, time to make my own version or use an alternative.

3 Likes

Alright, I’ll look into it. Isn’t occlusion culling gonna be a little unnecessary if I already have a radius system that disables the physics when I’m not near the grass?

well the radius system is good because it’s distance, occlusion culling is for objects that are not in view of the camera, such as objects behind the player’s field of view. It’s important not to do it every frame though as that could cause performance issues, this would allow the code to skip animating grass that is not seen by the player. It would be best to incorporate it into the radius calculation, so if the object passes the radius calculation it is checked for occlusion or vice versa

1 Like

are you not gonna update the model?