Hello everyone! Today I made a script for anyone to use. I made some customizable Auto Exposure that uses EditableImage and the CaptureService.
Roblox Model
(Put in either StarterCharacterScripts or StarterPlayerScripts)
OR
Source Code:
local screenshotAPI = game:GetService("CaptureService")
local asset = game:GetService("AssetService")
local screen = Instance.new("EditableImage")
local lighting = game:GetService("Lighting")
local tween = game:GetService("TweenService")
screen.Size = Vector2.new(1024,1024)
local updateRate = 2
local resolution = 50
local targetEV = 10
local calibrationConstant = 5
local adjustTime = 1
local difference = {} --no touchy!
local ogExposure = lighting.ExposureCompensation
function log2(x: number)
return (math.log10(x)/math.log10(2))
end
function CalculateNewExposure(brightness: number)
local luminance = brightness*100
local ev = log2(luminance)+calibrationConstant
local compensation = targetEV-ev
return compensation
end
function GetAverageBrightness()
local brightness = {}
local total = 0
for x=1,screen.Size.X,resolution do
for y=1,screen.Size.Y,resolution do
pcall(function()
local pixel = screen:ReadPixels(Vector2.new(x,y),Vector2.one)
if pixel then
local color = Color3.new(pixel[1],pixel[2],pixel[3])
local h,s,v = color:ToHSV()
total+=v
table.insert(brightness,v)
end
end)
end
end
return total/#brightness
end
function UpdateScreen()
screenshotAPI:CaptureScreenshot(function(capture)
screen = asset:CreateEditableImageAsync(capture)
local brightness = GetAverageBrightness()
tween:Create(lighting,TweenInfo.new(adjustTime),{ExposureCompensation = CalculateNewExposure(brightness)}):Play()
end)
end
local last = tick()
game:GetService("RunService").RenderStepped:Connect(function()
UpdateScreen()
end)
Variables: targetEVthe target exposure (default is 10) calibrationConstantthe calibration constant (default is 5) adjustTimetime taken to adjust to the new exposure, in seconds (default is 1)
Performance:
The most FPS I lost was 2, and that was in studio on future lighting.
Showcase:
(not sure why the video was laggy, I had over 230 fps while recording…)
Looks good, but the exposure does not need to be updated every frame, and also you could split the work load across multiple frames to squeeze back in that extra lost framerate.
I noticed one feature (Watch the video). I use the factory settings that were set in the script. In such dark places, fluctuations are often observed.
Overall, this is a very useful resource. I hope that in the future it will improve and become completely user-friendly. Although it is already usable now, but I am confused by these fluctuations.!
Biggest problem with this method is very likely memory leak.
You’re constantly saving screenshots to the memory.
I don’t know if capture service deletes screenshots after some time but if it doesn’t, the game will crash after some time.
I believe that is caused by always going based on the screen with the exposure compensation. A dark area would go bright, and then it would become dark to smoothen out. A light area is always bright so that it would darken with slight fluctuations. I’m not sure why this happens, I could probably add something that reduces the observed pixel brightness so that it would use the original screen brightness at that point.