Revision Difference
render_rendertargets#561334
<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.
* Each pixel in the Render Target's Color Channel has a red, green, blue, and alpha value.⤶
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.
* Each pixel in the Depth Buffer has a whole, integer number between 0-255 where 0 is close to the camera and 255 is far from the camera. ⤶
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.
* Each pixel in the Stencil buffer has a whole, integer number between 0-255 which is used by the rendering system during drawing operations to determine if that pixel should 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
-- 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>
<image src="b2b4c/8dc44882df9fabc.gif" size="11907971" name="HulaExample.gif" />
</output>
</example>