Skip to main content

Camera

The camera allows you to take screenshots or even render video from the world to your display! Our camera looks great while not even touching the raytracing. There's no raytracing happening! just rays going everywhere as a multicast!

This doesn't even touch the complicated math! Just addition, subtraction, division, and multiplication.

Performance note!

Cameras in ScrapComputers use multicast to get the frame or video. However, raycasts in scrap mechanic that we (Modders) have access to are slow. This is because (According to VeraDev) it's handled by the CPU. If it was a GPU then it wouldn't take a lot of time.

The bigger the resolution you take the frame. The longer it would take to send all of those ray casts. You can see how many ray casts you're going to use by just using simple math. The formula to calculate that is: width * height.

We have to do a multicast since there's no other way to do it. So if you're going to use the camera, If your game freezes when you get a frame/video, Then the multicast is busy.


Structures

PixelRayResult

This is either the raw raycast result of the pixel or a modified safe version if the environment is in safe mode. In the unsafe environment mode, you will recieve the raycastResult as userdata, please see raycastResult for more information.

If you are in the safe environemnt the raw game raycastResult is made safe and important data is returned as a table:

{
directionWorld = raycastResult.directionWorld, -- The direction world
fraction = raycastResult.fraction , -- The fraction
normalLocal = raycastResult.normalLocal , -- The normal local
normalWorld = raycastResult.normalWorld , -- The normal world
originWorld = raycastResult.originWorld , -- The origin world
pointLocal = raycastResult.pointLocal , -- The point local
pointWorld = raycastResult.pointWorld , -- The point world
type = raycastResult.type , -- The type
valid = raycastResult.valid , -- If its valid
material = material , -- The ground material if hit terrainSurface or terrainAsset
color = color -- The color of the userdata object (if it exists)
}

DrawerFunction

The drawer function is a function that recieves data from the raw raycasts of the camera, this allows you to fully customise how the camera draws a pixel based on the raycasts information.

Arguments:

  • hit [ boolean ] If the raycast has hit anything or not.
  • raycastResult [ PixelRayResult ] The raycast result of the ray.
  • x [ number ] The x-coordinate of the current pixel.
  • y [ number ] The y-coordinate of the current pixel.

The drawer function should be formatted as follows:

local function DrawerFunction(hit, raycastResult, x, y)
--[[your code here]]

return color -- can either be color userdata or a hex string
end

Here is an example of a drawer function that makes an image similar to the depthFrame function:

local function DrawerFunction(hit, raycastResult, x, y)
local color = sm.color.new(0, 0, 0)

if hit then
color = sm.color.new(1, 1, 1) * (1 - result.fraction)
end

return color
end

Functions

frame

Camera.frame( display, width, height )

Takes a frame (aka a screenshot).

Arguments::

  • display [ Display ] The display to draw the frame to.
  • width [ integer? ] The width of the frame (Defaults to display width).
  • height [ integer? ] The height of the frame (Defaults to display height).

depthFrame

Camera.depthFrame( display, focalLength, width, height )

Takes a depth map frame (aka a screenshot).

Arguments::

  • display [ Display ] The display to draw the frame to.
  • focalLength [ number ] The focal length to focus the camera on, in meters.
  • width [ integer? ] The width of the frame (Defaults to display width).
  • height [ integer? ] The height of the frame (Defaults to display height).

maskedFrame

Camera.maskedFrame( display, mask, width, height )

Takes a masked map frame (aka a screenshot).

In case mask is a string[]: Each string is a raycast result type. If a raycast's type matches the pixel, it will be white or else black. In case mask is a string: If a raycast's type matches with the mask, the pixel's color would be white and else black.

If you do not know what the value(s) for the mask should be, (Find them by clicking this) URL.

Arguments:

  • display [ Display ] The display to draw the frame to.
  • mask [ string|string[] ] The mask for the raycast's to set.
  • width [ integer? ] The width of the frame (Defaults to display width).
  • height [ integer? ] The height of the frame (Defaults to display height).

video

Camera.video( display, sliceWidth, width, height )

Like the frame function but it's as slices meaning you could make CCTV cameras without lagging a lot! It's just that the refresh rate would be lower.

Arguments:

  • display [ Display ] The display to draw the frame to.
  • sliceWidth [ integer ] The ammount of slices the camera does per tick.
  • width [ integer? ] The width of the frame (Defaults to display width).
  • height [ integer? ] The height of the frame (Defaults to display height).

advancedFrame

Camera.advancedFrame( display, width, height )
Performance note!

The advanced functions use CPU-Based Raytracing (Via Raycasting) to render your frame(s). So this will use a ton of your CPU!

Takes a frame (aka a screenshot).

Arguments:

  • display [ Display ] The display to draw the frame to.
  • width [ integer? ] The width of the frame (Defaults to display width).
  • height [ integer? ] The height of the frame (Defaults to display height).

advancedVideo

Camera.advancedVideo( display, sliceWidth, width, height )
Performance note!

The advanced functions use CPU-Based Raytracing (Via Raycasting) to render your frame(s). So this will use a ton of your CPU!

Like the advancedFrame function but it's as slices meaning you could make CCTV cameras without lagging a lot! It's just that the refresh rate would be lower.

Arguments:

  • display [ Display ] The display to draw the frame to.
  • sliceWidth [ integer ] The ammount of slices the camera does per tick.
  • width [ integer? ] The width of the frame (Defaults to display width).
  • height [ integer? ] The height of the frame (Defaults to display height).

customFrame

Camera.customFrame( display, drawer, width, height )

This is a function which allows you to use your own drawer function to create images.

Arguments:

  • display [ Display ] The display to draw the frame to.
  • drawer [ DrawerFunction ] The drawer function.
  • width [ integer? ] The width of the frame (Defaults to display width).
  • height [ integer? ] The height of the frame (Defaults to display height).

customVideo

Camera.customVideo( display, drawer, sliceWidth, width, height )

This is a function which allows you to use your own drawer function to create video.

Arguments:

  • display [ Display ] The display to draw the frame to.
  • drawer [ DrawerFunction ] The drawer function.
  • sliceWidth [ integer ] The ammount of slices the camera does per tick.
  • width [ integer? ] The width of the frame (Defaults to display width).
  • height [ integer? ] The height of the frame (Defaults to display height).

setRange

Camera.setRange( int )

Sets the cameras range in meters.

Arguments:

  • int [ integer ] The range in meters.

setShadowRange

Camera.setShadowRange( int )
Performance note!

The higher this is, the better shadows you can get as the raytracing is able to cast a shadow from further away, but longer raycasts are more computationally expensive.

Sets the range that shadows are able to cast from.

Arguments:

  • int [ integer ] The range in meters.

setFov

Camera.setFov( int )

Sets the cameras fov in degrees.

Arguments:

  • int [ integer ] The fov in degrees.

setOffsetX

Camera.setOffsetX( int )

Sets the cameras x offset, this is the number that gets added to its respective coordinate as the camera draws to the display at (1, 1) by default.

Arguments:

  • int [ integer ] The x offset.

setOffsetY

Camera.setOffsetY( int )

Sets the cameras y offset, this is the number that gets added to its respective coordinate as the camera draws to the display at (1, 1) by default.

Arguments:

  • int [ integer ] The y offset.