Garry's Mod Wiki

Revision Difference

render_rendertargets#561327

<cat>Don'tListMePlease Dev</cat>⤶ <cat>Dev</cat>⤶ <title>Render Reference - Render Targets</title> # Render Library References These pages seek to provide helpful insight into the groups of functions provided by the <page text="Render Library">render</page>. The major function groups are: * <page text="Beams">Beam_Rendering</page> * <page text="Minification and Magnification Texture Filters">render_min_mag_filters</page> * **Render Targets** # What are Render Targets **A Render Target is a special kind of texture** that is created during gameplay via the game's code, rather than from a pre-existing image that is loaded from the game's files. **Render Targets have a fixed resolution, measured in pixels**, that is defined when they are first created. Unless your specific use-case has a reason not to, it's recommended to use the game's render resolution (Obtained via <page text="ScrW">Global.ScrW</page> and <page text="ScrH">Global.ScrH</page>.) **Render Targets have 3 layers:** 1. The Color Channel (or simply "Color") * This is what will be seen when the Render Target is drawn onto the screen. 2. The Depth Buffer (or simply "Depth") * This layer keeps track of how far away from the camera each in the Render Target pixel is. 3. The Stencil Buffer (or simply "Stencils") * The Stencil layer controls whether or not each individual pixel in the Render Target is able to be drawn to. * By default, the Stencil layer is configured so that all pixels can be drawn to.⤶ # What are Practical Uses for Render Targets? While this is not a complete or exhaustive list, here are some examples of situations where a Render Target would be useful: * A rear-view mirror for a vehicle. * A security camera feed shown on a TV in a building's security room. * A painting canvas that players can draw on. # Example Code ⤶ ⤶ <example> <description> The following example code should provide a good demonstration of how to set up a basic Render Target, how to draw 2D and 3D elements onto it, and then how to draw the Render Target onto the screen. </description> <code> -- Create the Render Target we'll be using throughout this example local renderTarget = GetRenderTarget( "RenderTargetExample", -- The name of the Render Target's Texture 1024, 1024 -- The size of the Render Target ) -- Create a Material that corresponds to the Render Target we just made local renderTargetMaterial = CreateMaterial( "RenderTargetExampleMaterial", -- All Materials need a name "UnlitGeneric", -- This shader will work great for drawing onto the screen, but can't be used on models -- To use this material on a model, this would need to use the "VertexLitGeneric" shader. { ["$basetexture"] = renderTarget:GetName(), -- Use our Render Target as the Texture for this Material ["$translucent"] = "1", -- Without this, the Material will be fully opaque and any translucency won't be shown } ) -- Used later for some 3D rendering local clientsideModel = ClientsideModel( "models/props_lab/huladoll.mdl", RENDERGROUP_OPAQUE ) clientsideModel:SetNoDraw( true ) -- An all-white material is built-in to the game local colorMaterial = Material( "color" ) -- This function just gives us something to draw that uses a 2D context -- It can be replaced with any other 2D drawing operation(s) local function DrawSomething2D() surface.SetMaterial( colorMaterial ) surface.SetDrawColor( Color( 255, 0, 255, 200 ) ) surface.DrawTexturedRectRotated( ScrW()/2, ScrH()/2, 500, 500, ( CurTime() * 200 ) % 360 ) end -- Same as DrawSomething2D, but with 3D content local function DrawSomething3D() -- To brighten the model without setting up lighting render.SuppressEngineLighting( true ) -- By default, 3D rendering to a Render Target will put the Depth Buffer into the alpha channel of the image. -- I do not know why this is the case, but we can disable that behavior with this function. render.SetWriteDepthToDestAlpha( false ) render.Model( { model = "models/props_lab/huladoll.mdl", -- You can ignore this math, it's just to make the hula doll do a little dance pos = Vector( 20, -math.sin( CurTime() * 7.5 ) * 0.35, -3.5 ), angle = Angle( 0, 180 + math.sin( CurTime() * 7.5 ) * 7, math.sin( CurTime() * 7.5 ) * 15 ) }, clientsideModel ) render.SetWriteDepthToDestAlpha( true ) render.SuppressEngineLighting( false ) end -- In a hook that runs every frame, draw to the Render Target -- Note: You could use any hook for this. hook.Add( "PreDrawEffects", "DrawingToExampleRenderTarget", function( isDrawingDepth, isDrawingSkybox, isDrawing3dSkybox ) -- Start drawing onto our render target render.PushRenderTarget( renderTarget ) -- Remove the Render Target's contents from the previous frame so we can draw a new one on a fresh "canvas" render.Clear( 0, 255, 0, 200, true, true ) -- Start drawing in a 2D context -- By default this hook provides a 3D context, so we need to change it. cam.Start2D() -- Draw some fun 2D content to the Render Target DrawSomething2D() cam.End2D() -- The hook's original 3D context has an unknown position and rotation. -- Because we want control over our Render Target, we need to start a new 3D context. -- You can think of this as setting up the "camera" we're about to render with. cam.Start3D( Vector( 0, 0, 0 ), -- The position of this 3D context's view Angle( 0, 0, 0 ), -- The direction this 3D context's view is pointing in 40 -- The field of view, in degrees ) -- Now that we're in a 3D context, let's draw something 3D DrawSomething3D() cam.End3D() -- Stop drawing on our render target and let the rendering system continue normally render.PopRenderTarget() end ) -- In a completely different hook, we can draw the Render Target to the screen via its Material -- This is done in a different hook purely to demonstrate that the Render Target can be used -- outside of the place it is drawn in. hook.Add( "DrawOverlay", "DrawingRenderTargetToScreen", function() surface.SetMaterial( renderTargetMaterial ) surface.SetDrawColor( Color( 255, 255, 255, 255 ) ) surface.DrawTexturedRectRotated( 300, 300, 500, 500, 0 ) end ) </code> <output> <upload src="b2b4c/8dc44882df9fabc.gif" size="11907971" name="HulaExample.gif" /> </output> </example>