Getting the color of clicked part while ignoring invisible parts

I want to make a tool that when equipped and “used”, shows the player the exact color values of whatever part they clicked. Currently, I’m on the step where I need to find out what part the player clicked.
I had an older version that worked fine, but then I realized it also detected completely invisible parts. This is annoying, and is certainly not something the player wants to happen.
That said, this is giving me WAY more trouble than it’s worth to figure out. I think my main problem is just not understanding how raycasting works at all.

Listed below is my current LocalScript in the “eyedropper” tool.

local uis = game:GetService("UserInputService")

function getMouseTarget()

	local cursorPosition = uis:GetMouseLocation()
	local oray = game.workspace.CurrentCamera:ViewportPointToRay(cursorPosition.x, cursorPosition.y, 0)
	
	local params = RaycastParams.new()
	params.FilterType = Enum.RaycastFilterType.Include
	local prt = nil
	prt = game.workspace:Raycast(game.Workspace.CurrentCamera.CFrame.Position, (oray.Direction * 1000), params).Instance
	print(prt)
	
	local ignores = {}

	-- This part is meant to retry casting until any of the following criteria are met:
	  -- A non-invisible part is detected by the ray
	  -- The void is detected, in which the function returns nil
	while prt and prt:IsA("BasePart") and prt.Transparency == 1 do
		print("hit transparent")
		task.wait()
		table.insert(ignores, prt)
		params.FilterDescendantsInstances = ignores
		prt = game.workspace:Raycast(game.Workspace.CurrentCamera.CFrame.Position, (oray.Direction * 1000), params).Instance
	end
	
	return prt
end
	
script.Parent.Activated:Connect(function(input)
	local prt:BasePart? = getMouseTarget()
	if prt and prt:IsA("BasePart") then
		--Utilize prt.Color for showing the player the color, I'll get to writing this after I figure out what's going on with the rest of this code lol
	end
end)

This returns an error with each activation of the tool. Turns out, prt doesn’t have an Instance value tied to it like a RaycastResults value is supposed to. After further testing, turns out prt just never exists! If I remove the .Instance at the end of prt’s Raycast function and print the result of prt, it prints nil. Very annoying. I’ve tried looking into it in the documentation, but this is the best I can do. Any possible solutions or things I’m doing wrong?

Note: I cannot use any solutions that require me to set invisible parts to their own CollisionGroup. I’m already using CollisionGroups for their own purpose, and changing the CollisionGroups of invisible parts, even just locally, would break other stuff.

You have params.FilterType set to Include but your code appears to add parts to the table which should be Excluded?

This appears to have been part of the solution. I also re-ordered the lines so that the filtering is done before the first ray is cast like so:

function getMouseTarget()
	local cursorPosition = uis:GetMouseLocation()
	local oray = game.workspace.CurrentCamera:ViewportPointToRay(cursorPosition.x, cursorPosition.y, 0)
	
	local params = RaycastParams.new()
	local ignores = {}
	params.FilterDescendantsInstances = ignores
	params.FilterType = Enum.RaycastFilterType.Exclude
	local prt = nil
	local ray = game.workspace:Raycast(game.Workspace.CurrentCamera.CFrame.Position, (oray.Direction * 1000), params)
	if ray then prt=ray.Instance end
	
	
	while prt and prt:IsA("BasePart") and prt.Transparency == 1 do
		task.wait()
		table.insert(ignores, prt)
		params.FilterDescendantsInstances = ignores
		local ray = game.workspace:Raycast(game.Workspace.CurrentCamera.CFrame.Position, (oray.Direction * 1000), params)
		if ray then prt=ray.Instance end
	end
	
	return prt
end

Very cool! Thanks for the little notice.