Garry's Mod Wiki

Revision Difference

render_rendertargets#561324

<cat>Don'tListMePlease Dev</cat> <title>Render Reference - Render Targets</title> ⤶ <note>This page is under active development and should not be read by anyone, let alone people other than the author</note>⤶ # 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. # 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>