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>