DistanceFade - A transparency falloff effect for your games

Hi, I made this module for a game I’m working on and I wanted to release it to the community for use in your own projects

Showcase Video

What is DistanceFade?


DistanceFade is a module that aims to recreate transparency falloff shaders commonly found in games outside of Roblox.

The module essentially works by “projecting” the effect onto a table of target parts. The parts can be arranged with varying sizes and rotations to create different shapes for the effect (the thumbnail is 3 parts arranged in a curve, for example). 21 different customization settings allow for more complicated effects like animated textures, texture offsets, colors and more.

Note:
The module as it is now is more of a foundation than a perfect solution… it isn’t perfectly optimized and still has some flaws. I made it for a specific use case in my game (map barriers that fade in when close), but designed the module to be fairly flexible in what it can be used for. I probably won’t be updating it so feel free to modify and redistribute it as you see fit

If you’re interested in other stuff I make it’ll be on my yt channel here

Examples





Download


DistanceFade.rbxm (15.6 KB)

Template models

HexagonBarrier.rbxm (21.2 KB)
RedBarrier.rbxm (20.5 KB)
TransparentParts.rbxm (20.7 KB)
Forcefield.rbxm (56.4 KB)

Basic Usage


Step 1 - Initialization

Require the module and initialize it using the .new() constructor. You can have multiple forcefield objects running in the same script
local DistanceFade = require(game.ReplicatedStorage.DistanceFade) -- or wherever the module is located
local distanceFadeObj = DistanceFade.new() --initialize the object

Step 2 - Add target faces

DistanceFade works by applying the effect to individual BasePart faces. For every face you want to have the effect on, you need to use :AddFace() with 2 parameters, the target part and the Enum.NormalId of the face
local partToAdd -- can be any BasePart
distanceFadeObj:AddFace(partToAdd, Enum.NormalId.Front) -- can add to any face, in this case the front and back of the part
distanceFadeObj:AddFace(partToAdd, Enum.NormalId.Back)

Step 3 - Running the effect

Use :Step() to update the simulation at any time. Use Heartbeat for a visually smooth effect. TargetPos parameter is a Vector3
game:GetService("RunService").Heartbeat:Connect(function()
	local targetPos -- the position the effect is centered around
	distanceFadeObj:Step(targetPos) -- if parameter is nil, automatically targets local character's root part
end)

Step 4 - Apply settings

Use :UpdateSettings() to update the effect at any time (applies settings to all faces of that object). If you want to update the effect on individual faces, use :UpdateFaceSettings() (overwrites the object settings)
game:GetService("RunService").Heartbeat:Connect(function()
	local newSettings = {} --table of settings to modify. Full list below
	distanceFadeObj:UpdateSettings(newSettings)

	local targetPos -- the position the effect is centered around
	distanceFadeObj:Step(targetPos) -- if parameter is nil, automatically targets local character's root part
end)

Full list of settings:

local DEFAULT_SETTINGS = {
	["DistanceOuter"] = 16, -- Distance at which the effect starts to appear
	["DistanceInner"] = 4, -- Distance at which the effect is fully visible
	["EffectRadius"] = 16, -- Size of the effect when in range
	["EffectRadiusMin"] = 0, -- Size of the effect when out of range
	["EdgeDistanceCalculations"] = false, -- When set to true, distance to target is calculated from the face edges rather than the face itself. Can be more accurate in certain cases
	["Texture"] = "rbxassetid://18838056070", -- TextureId
	["TextureTransparency"] = 0, -- Transparency of the texture when in range
	["TextureTransparencyMin"] = 1, -- Transparency of the texture when out of range
	["BackgroundTransparency"] = 1, -- Transparency of the texture background when in range
	["BackgroundTransparencyMin"] = 1, -- Transparency of the texture background when out of range
	["TextureColor"] = Color3.fromRGB(255, 255, 255), -- Color of the texture
	["BackgroundColor"] = Color3.fromRGB(255, 255, 255), -- Color of the texture background
	["TextureSize"] = Vector2.new(8, 8), -- Size of the texture in studs per tile. Can potentially cause clipping issues if greater than EffectRadius * 2
	["TextureOffset"] = Vector2.new(0, 0), -- Texture offset in studs
	-- SurfaceGui settings
	["ZOffset"] = 0,
	["AlwaysOnTop"] = false,
	["Brightness"] = 1,
	["LightInfluence"] = 0,
	["MaxDistance"] = 1000,
	["PixelsPerStud"] = 100,
	["SizingMode"] = Enum.SurfaceGuiSizingMode.PixelsPerStud
}

More advanced examples can be found in the template models dropdown above. Also make sure to read through the module code if you want more in-depth explanations of each function. Please leave any questions or feedback and I’ll do my best to help

49 Likes

Hello, This is absoloutly wonderful!

I just had a question, How would you put this into startercharacter or starterplayer without it not glitching out…

Thank you!

Edit: Found the problem, If the parts are not named as single digit numbers “1” then it will not work.

Not sure why?

1 Like

Thanks! For your issue, If you’re using any of the scripts in the template models, they’re actually just normal scripts with the RunContext set to client, which are designed to be placed in workspace but not StarterPlayer or StarterCharacter. I believe a simple fix would be to just make a LocalScript and copy the code into that. :slight_smile:

1 Like

Ah yes, Thanks for letting me know. Thought i could run it on a server

2 Likes

OH this is actually pretty cool, shields and that sorta stuff would match perfectly with this @v1uxz

2 Likes

yess omg thanks for telling, ill see what i can use for

2 Likes

This effect is really cool! It’s so seamless, it’s hard to believe it was made in Roblox.

There’s an error that occurs with your HexagonBarrier example model:
image

It outputs every frame when my character is near the model.

2 Likes

I’d assume it’s probably just an error with Step() being called before all the parts are loaded in, can you tell me if that error happens every frame or just at the beginning? I couldn’t recreate it myself, I’m a little stumped lol

I found the issue. The folder you create in PlayerGui is removed when the player resets. Not sure how to work around this.

Repro steps:

  • Add the model to a baseplate file
  • Playtest, move near it (it works)
  • Reset and move near it, then the error appears every frame.
1 Like

this is really cool nice stuff

1 Like

Can you invert the fade effect? So that if you get close, it disappears instead

Yes, it appears its because a Folder is used in the PlayerGui for storing SurfaceGuis. I don’t think this is documented for Roblox instances.

Using a ScreenGui with ResetOnSpawn = false fixed the issue.

2 Likes

shoot I totally forgot about that, I’ll update it rn

If you invert the transparency curve values (at line 578 and 645) and set the visibility of the inner 4 tiles to false it MIGHT do the trick. Haven’t tested it tho

1 Like

updated all the rbxm files with the fix