S&box Wiki

Revision Difference

RenderHooks#549784

<cat>Code.Rendering</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.AfterPostProcess ) { 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. This renders after the post process stage.. which means that the 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 ); } } } ```