local mat_Downsample = Material( "pp/downsample" ) local mat_Bloom = Material( "pp/bloom" ) local mat_BlurX = Material( "pp/blurx" ) local mat_BlurY = Material( "pp/blury" ) local tex_Bloom0 = render.GetBloomTex0() local tex_Bloom1 = render.GetBloomTex1() mat_Downsample:SetMaterialTexture( "$fbtexture", render.GetScreenEffectTexture() ) /*--------------------------------------------------------- Register the convars that will control this effect ---------------------------------------------------------*/ local pp_bloom = CreateClientConVar( "pp_bloom", "0", true, false ) // On/Off local pp_bloom_darken = CreateClientConVar( "pp_bloom_darken", "0.65", false, false ) // Decides the strength of the bloom local pp_bloom_multiply = CreateClientConVar( "pp_bloom_multiply", "2.0", false, false ) // Decides the strength of the bloom local pp_bloom_sizex = CreateClientConVar( "pp_bloom_sizex", "9.0", false, false ) // Horizontal blur size local pp_bloom_sizey = CreateClientConVar( "pp_bloom_sizey", "9.0", false, false ) // Vertical blur size local pp_bloom_color = CreateClientConVar( "pp_bloom_color", "1.0", false, false ) local pp_bloom_color_r = CreateClientConVar( "pp_bloom_color_r", "255", false, false ) local pp_bloom_color_g = CreateClientConVar( "pp_bloom_color_g", "255", false, false ) local pp_bloom_color_b = CreateClientConVar( "pp_bloom_color_b", "255", false, false ) local pp_bloom_passes = CreateClientConVar( "pp_bloom_passes", "1", false, false ) /*--------------------------------------------------------- Can be called from engine or hooks using bloom.Draw ---------------------------------------------------------*/ function DrawBloom( darken, multiply, sizex, sizey, passes, color, colr, colg, colb ) // No bloom for crappy gpus if ( !render.SupportsPixelShaders_2_0() ) then return end // Todo: Does this stop it working properly when rendered to a rect? local w = ScrW() local h = ScrH() // Copy the backbuffer to the screen effect texture render.UpdateScreenEffectTexture() // Store the render target so we can swap back at the end local OldRT = render.GetRenderTarget(); // The downsample material adjusts the contrast mat_Downsample:SetMaterialFloat( "$darken", darken ) mat_Downsample:SetMaterialFloat( "$multiply", multiply ) // Downsample to BloomTexture0 render.SetRenderTarget( tex_Bloom0 ) render.SetMaterial( mat_Downsample ) render.DrawScreenQuad() mat_BlurX:SetMaterialTexture( "$basetexture", tex_Bloom0 ) mat_BlurY:SetMaterialTexture( "$basetexture", tex_Bloom1 ) mat_BlurX:SetMaterialFloat( "$size", sizex ) mat_BlurY:SetMaterialFloat( "$size", sizey ) for i=1, passes do render.SetRenderTarget( tex_Bloom1 ) render.SetMaterial( mat_BlurX ) render.DrawScreenQuad() render.SetRenderTarget( tex_Bloom0 ) render.SetMaterial( mat_BlurY ) render.DrawScreenQuad() end render.SetRenderTarget( OldRT ); mat_Bloom:SetMaterialFloat( "$levelr", colr ) mat_Bloom:SetMaterialFloat( "$levelg", colg ) mat_Bloom:SetMaterialFloat( "$levelb", colb ) mat_Bloom:SetMaterialFloat( "$colormul", color ) mat_Bloom:SetMaterialTexture( "$basetexture", tex_Bloom0 ) render.SetMaterial( mat_Bloom ) render.DrawScreenQuad() end /*--------------------------------------------------------- The function to draw the bloom (called from the hook) ---------------------------------------------------------*/ local function DrawInternal() // No bloom for crappy gpus if ( !render.SupportsPixelShaders_2_0() ) then return end if ( !pp_bloom:GetBool() ) then return end if ( !GAMEMODE:PostProcessPermitted( "bloom" ) ) then return end DrawBloom( pp_bloom_darken:GetFloat(), pp_bloom_multiply:GetFloat(), pp_bloom_sizex:GetFloat(), pp_bloom_sizey:GetFloat(), pp_bloom_passes:GetFloat(), pp_bloom_color:GetFloat(), pp_bloom_color_r:GetFloat()/255, pp_bloom_color_g:GetFloat()/255, pp_bloom_color_b:GetFloat()/255 ) end hook.Add( "RenderScreenspaceEffects", "RenderBloom", DrawInternal ) /* // Control Panel */ local function BuildControlPanel( CPanel ) CPanel:AddControl( "Header", { Text = "#Bloom", Description = "#Bloom_Information" } ) CPanel:AddControl( "CheckBox", { Label = "#Bloom_Toggle", Command = "pp_bloom" } ) local params = { Options = {}, CVars = {}, Label = "#Presets", MenuButton = "1", Folder = "bloom" } params.Options[ "#Default" ] = {pp_bloom_passes = "1", pp_bloom_darken = "0.65", pp_bloom_multiply = "2.0", pp_bloom_sizex = "9", pp_bloom_sizey = "9", pp_bloom_color = "1.0", pp_bloom_color_r = "255", pp_bloom_color_g = "255", pp_bloom_color_b = "255" } params.CVars = { "pp_bloom_passes", "pp_bloom_darken", "pp_bloom_multiply", "pp_bloom_sizex", "pp_bloom_sizey", "pp_bloom_color", "pp_bloom_color_r", "pp_bloom_color_g", "pp_bloom_color_b" } CPanel:AddControl( "ComboBox", params ) CPanel:AddControl( "Slider", { Label = "#Bloom_Passes", Command = "pp_bloom_passes", Type = "Integer", Min = "0", Max = "30" } ) CPanel:AddControl( "Slider", { Label = "#Bloom_Darken", Command = "pp_bloom_darken", Type = "Float", Min = "0", Max = "1" } ) CPanel:AddControl( "Slider", { Label = "#Bloom_Multiply", Command = "pp_bloom_multiply", Type = "Float", Min = "0", Max = "5" } ) CPanel:AddControl( "Slider", { Label = "#Bloom_BlurX", Command = "pp_bloom_sizex", Type = "Float", Min = "0", Max = "50" } ) CPanel:AddControl( "Slider", { Label = "#Bloom_BlurY", Command = "pp_bloom_sizey", Type = "Float", Min = "0", Max = "50" } ) CPanel:AddControl( "Slider", { Label = "#Bloom_Color_Multiplier", Command = "pp_bloom_color", Type = "Float", Min = "0", Max = "20" } ) CPanel:AddControl( "Color", { Label = "#Bloom_Color", Red = "pp_bloom_color_r", Green = "pp_bloom_color_g", Blue = "pp_bloom_color_b", ShowAlpha = "0", ShowHSV = "1", ShowRGB = "1" } ) end /* // Tool Menu */ local function AddPostProcessMenu() spawnmenu.AddToolMenuOption( "PostProcessing", "PPShader", "Bloom", "#Bloom", "", "", BuildControlPanel, { SwitchConVar = "pp_bloom" } ) end hook.Add( "PopulateToolMenu", "AddPostProcessMenu_Bloom", AddPostProcessMenu )