Thermal Scope

I’ve been trying to code a thermal scope sort of effect, similar to the MW2 style where players are a bright white on a black and white background. I’ve gotten close, I’ve gotten the players to show up white, but I cannot get the black and white screen effect. I have a color table and have a function that calls DrawColorModify with that table as an argument, and a hook.Add to RenderScreenSpaceEffects with that function, but I cannot get the screen to turn black and white.

The code I’ve pasted in is actually sorta hacked in from a nv/thermal goggle script I’ve found on the workshop, located here: http://steamcommunity.com/sharedfiles/filedetails/?id=224378049&searchtext=thermal

I can post the code from that if it would help, but I don’t want to clog the first post with code too much yet. Any ideas?


if CLIENT

	local Clr_FLIR = 
	{
		[ "$pp_colour_addr" ] 		= 0,
		[ "$pp_colour_addg" ] 		= 0,
		[ "$pp_colour_addb" ] 		= 0,
		[ "$pp_colour_brightness" ] = -0.65,
		[ "$pp_colour_contrast" ]	= 1,
		[ "$pp_colour_colour" ] 	= .2,
		[ "$pp_colour_mulr" ] 		= 0,
		[ "$pp_colour_mulg" ] 		= 0,
		[ "$pp_colour_mulb" ] 		= 0
	}

	local Clr_FLIR_Ents = 
	{
		[ "$pp_colour_addr" ] 		= 0,
		[ "$pp_colour_addg" ] 		= 0,
		[ "$pp_colour_addb" ] 		= 0,
		[ "$pp_colour_brightness" ] = 0.6,
		[ "$pp_colour_contrast" ]	= 1,
		[ "$pp_colour_colour" ] 	= 0,
		[ "$pp_colour_mulr" ] 		= 0,
		[ "$pp_colour_mulg" ] 		= 0,
		[ "$pp_colour_mulb" ] 		= 0
	}

	local NV_Status = false

	function SWEP:NV_FX()
		ply = self.Owner

		if ply:Alive() then
			DrawColorModify(Clr_FLIR)

			DrawBloom(	0,  					-- Darken
					1,				-- Multiply
					1, 				-- Horizontal Blur
					1, 				-- Vertical Blur
					0, 				-- Passes
					0, 				-- Color Multiplier
					0, 				-- Red
					0, 				-- Green
					0 ) 
		elseif not ply:Alive() then
			surface.PlaySound( sndOff )
			NV_Status = false
			hook.Remove("RenderScreenspaceEffects", "NV_FX")
			hook.Remove("PostDrawViewModel", "NV_PostDrawViewModel")
		end
	end


	function SWEP:NV_ToggleNightVision()
		ply = self.Owner
		if not ply:Alive() then
			return
		end

		if NV_Status == true then
			NV_Status = false

			hook.Remove("RenderScreenspaceEffects", "NV_FX")
			hook.Remove("PostDrawViewModel", "NV_PostDrawViewModel")
		else
			NV_Status = true

			CurScale = 0.2
			hook.Add("RenderScreenspaceEffects", "NV_FX", NV_FX)
			hook.Add("PostDrawViewModel", "NV_PostDrawViewModel", NV_PostDrawViewModel)
		end
	end

	hook.Add("PostDrawOpaqueRenderables", "FLIRFX", function()	
		if GetConVarNumber("nv_type") < 2 or not NV_Status then
			return
		end

		render.ClearStencil()
		render.SetStencilEnable(true)

		render.SetStencilFailOperation(STENCILOPERATION_KEEP)
		render.SetStencilZFailOperation(STENCILOPERATION_KEEP)
		render.SetStencilPassOperation(STENCILOPERATION_REPLACE)
		render.SetStencilCompareFunction(STENCILCOMPARISONFUNCTION_ALWAYS)
		render.SetStencilReferenceValue(1)

		render.SuppressEngineLighting(true)

		FT = FrameTime()

		for _, ent in pairs(ents.GetAll()) do
			if ent:IsNPC() or ent:IsPlayer() then
				if not ent:IsEffectActive(EF_NODRAW) then -- since there is no proper way to check if the NPC is dead, we just check if the NPC has a nodraw effect on him
					render.SuppressEngineLighting(true)
					ent:DrawModel()
					render.SuppressEngineLighting(false)
				end
			elseif ent:GetClass() == "class C_ClientRagdoll" then
				if not ent.Int then
					ent.Int = 1
				else
					ent.Int = math.Clamp(ent.Int - FT * 0.015, 0, 1)
				end

				render.SetColorModulation(ent.Int, ent.Int, ent.Int)
					render.SuppressEngineLighting(true)
						ent:DrawModel()
					render.SuppressEngineLighting(false)
				render.SetColorModulation(1, 1, 1)
			end
		end

		render.SuppressEngineLighting(false)

		render.SetStencilReferenceValue(2)
		render.SetStencilCompareFunction( STENCILCOMPARISONFUNCTION_EQUAL )
		render.SetStencilPassOperation( STENCILOPERATION_REPLACE )
		render.SetStencilReferenceValue(1)
		DrawColorModify(Clr_FLIR_Ents)

		render.SetStencilEnable( false )
	end)
end

So it’s not your code and you want it adapted?

Are you trying to achieve the WHITE-HOT / BLACK-HOT style of imaging? NV amplifies light, meaning it won’t work where no light exists which is why IR illuminators exist. WHITE-HOT means BLACK = cold. Players, running vehicles, etc should appear white, varying in grey-scale depending on temperature while ambient areas should remain black or also varying depending on heat.

BLACK-HOT is just the inverse of WHITE-HOT.

It may take some processing power, depending on how it’s done. You may be able to do the ambient dark easily with color mod, then on top of that use stencils to highlight players; if done right you may even be able to highlight key areas leaving clothing dimmer. But, that might be a decent place to start: Stencils. There’s a good stencil tutorial here: http://www.facepunch.com/threads/878986-Stencil-tutorial and http://forum.facepunch.com/showthread.php?t=1337232