S&box Wiki

Revision Difference

RenderHooks#547606

<cat>Code.Camera</cat>⤶ <title>RenderHooks</title>⤶ ⤶ # What are RenderHooks⤶ ⤶ Render Hooks allow you to run your code during certain points in the render pipeline. For example⤶ ⤶ * Drawing post process before UI⤶ * Drawing effects before the viewmodel is rendered⤶ ⤶ # How to create them⤶ ⤶ A simple renderhook that renders the screen green looks like this.⤶ ⤶ ```⤶ internal class MyRenderHook : RenderHook ⤶ {⤶ public Color MyColor { get; set; }⤶ ⤶ public override void OnStage( SceneCamera target, Stage renderStage )⤶ {⤶ if ( renderStage == Stage.BeforeViewmodel )⤶ {⤶ Graphics.Clear( Color.Green );⤶ }⤶ }⤶ }⤶ ```⤶ ⤶ This renders before the viewmodel.. which means that the viewmodel and post processing and UI will be drawn on top of it.⤶ ⤶ <upload src="1/8daa0471dfb1a92.jpg" size="43131" name="sbox_0194.jpg" />⤶ ⤶ # How to add to a camera⤶ ⤶ Renderhooks need to be added to a SceneCamera. The main game's SceneCamera is available at `Map.Camera`. So clientside, in some function like `FrameSimulate` you might do something like this.⤶ ⤶ ```⤶ var hook = Map.Camera.FindOrCreateHook<MyRenderHook>();⤶ hook.Enabled = IsPlayerDead();⤶ hook.MyColor = Color.Random;⤶ ```⤶ ⤶ Alternatively, if you're gonna want your renderhook to be called every frame on the main game camera you can add this attribute to it.⤶ ⤶ ```⤶ [SceneCamera.AutomaticRenderHook]⤶ ```⤶ ⤶ # OnFrame⤶ ⤶ In your renderhook OnFrame will be called immediately before every frame. If what you're doing involves moving/creating/placing/adjusting SceneObjects then this is a great place to do it.⤶ ⤶ # Example⤶ ⤶ ```⤶ [SceneCamera.AutomaticRenderHook]⤶ public partial class MyPostProcessEffect : RenderHook ⤶ {⤶ RenderAttributes attributes = new RenderAttributes();⤶ Material effectMaterial = Material.Load( "materials/my_awesome_material.vmat" );⤶ ⤶ public override void OnStage( SceneCamera target, Stage renderStage )⤶ {⤶ // Don't render is local pawn is dead⤶ if ( Local.Pawn.Health <= 0 )⤶ return;⤶ ⤶ if ( renderStage == Stage.BeforePostProcess )⤶ {⤶ // Set some dumb attributes⤶ attributes.Set( "CameraFOV", target.FieldOfView.DegreeToRadian() );⤶ attributes.Set( "PawnHealth", Local.Pawn.Health / 100.0f );⤶ ⤶ // Grab the current screen texture and put it in "ColorBuffer"⤶ Graphics.GrabFrameTexture( "ColorBuffer", attributes );⤶ ⤶ // Draw our effect material, which is probably using a special post process⤶ // shader that uses all the attributes to do cool effects⤶ Graphics.Blit( effectMaterial, attributes );⤶ }⤶ }⤶ }⤶ ```⤶ ⤶