Module3D V6.1 (ViewportFrame Implementation)

I have been maintaining Module3D for several years, each being better than the last (except version 5 in some cases). With Roblox’s new ViewportFrames comes a better way to handle the task of adorning models to frames. Previously, you could not use the module with SurfaceGuis, and you won’t get smooth performance with large models. Now both are possible, and at the same time!


Advantages Of V6
Module3D V6 is a complete re-write to utilize ViewportFrames instead of positioning objects and correcting the orientation. The advantages of the new implementation this include:

  • More and larger models can be adorned without a performance hit.
  • Positioning frames in BillboardGuis behind the objects are no longer needed.
  • Post-processing effects no longer affect the objects.
  • Map lighting no longer affects the objects.
  • Objects adorned to the sides of the display don’t get distorted.
  • Clipping with the map is longer a problem.
  • Models can be adorned to SurfaceGuis.
  • Updating the rotation uses a lot fewer resources.
  • Properties like FiledOfView can be changed independently of the player’s camera.

Module API
The available API is included in the module. Here is what the module contains (excluding deprecated APIs):
	Creates a Model3D object.
	Attaches a model or part to a frame. Returns a Model3D object.
	Does not use a clone of the model so it can be referenced directly.

Model3D object (extends ViewportFrame):
	Model3D.Object3D - the model for the bounding box. If the input model was a model, it will be the same as the input.
	Model3D.AdornFrame - the frame the model is adorned to.
		Force updates the camera CFrame.
		Sets the CFrame offset.
		Automatically updates the camera CFrame.
		Returns the CFrame offset.
		Sets the multiplier for how far back the camera should go.
		Automatically updates the camera CFrame.
		Returns the depth multiplier

The following file uses the SurfaceGui example above including:

  • Module3D V6 and the Towers model are in ReplicatedStorage
  • SurfaceGUI and the script are in StarterGui

Local Script:

local Frame = script.Parent:WaitForChild("Frame")
local Module3D = require(game.ReplicatedStorage:WaitForChild("Module3D"))
local Towers = game.ReplicatedStorage:WaitForChild("Towers")

local Model3D = Module3D:Attach3D(Frame,Towers)
Model3D.Camera.FieldOfView = 5
Model3D.Visible = true

	Model3D:SetCFrame(CFrame.Angles(0,tick() % (math.pi * 2),0) * CFrame.Angles(math.rad(-10),0,0))

Module3D V6.1 Example.rbxl (379.5 KB)


This seems really useful, btw have you researched a way to make this new feature useful for Scopes,

I think i might be wrong about this actually.


Module3D won’t be ideal since you will need more direct control over the camera. I would recommend using a ViewportFrame, clone all the instances in the map, and set the camera’s field of view for the ViewportFrame to a lower value. You probably will need to make it a square or rectangle through.


Sounds like an interesting experiment!

This would require dual render, don’t even bother making this with a viewport frame, it will be too resource intensive.


This is incredible, going to use this.

Thank you so much!

It’s actually not very resource-intensive at all surprisingly.

I still wouldn’t do something like that currently as VIewportFrames currently lack all special 3D effects.


Can you make a mirror with this new feature?


I’m on it!


Incredible, thank you!!

1 Like

Since ViewportFrames are now live 2 months later, I have removed the beta warning. I am thinking about implementing it in the next (and probably only) update for Roblox Battle (2018 Edition).


Are you going to take advantage of the new addition to viewports?

1 Like

There will be a V6.1 at some point with these features, but I am not sure when. I have some other things to prioritize first.


Apologies for such a late reply, I must ask - does this module somehow get around the low image quality attached to using Viewport frames (highlighted in this post)? Recently I have been experimenting with Viewports for the first time and the low image quality (especially at smaller sizes) was quite disappointing considering the expectations I had for them. I was wondering if using one of these older 3D UI modules would be a good alternative to Viewports in my specific use case (making an inventory UI with relatively small icons).


This module doesn’t do anything on top of the existing implementation of viewport frames. Any quality problems (no anti-aliasing) from viewport frames will exist with this version.

1 Like

I have made some updates to Module3D that should be fairly future-proof, including adding a GitHub repository for those who use Rojo (requested by another developer). If you currently use V6 already, there are no compatibility problems if you didn’t add custom properties to the Model3D object.

The main change comes down to Model3D (returned from Module3D:Attach3D(Frame,Model)) now has API passthrough to the ViewportFrame. This means you can directly call methods and read/write properties, like Model3D.BackgroundColor3 and Model3D.LightDirection. If you use Model3D:SetActive(true) or Model3D:SetActive(false), you should move to Model3D.Visible = true and Model3D.Visible = false. The example in the original post has been updated for this.


How do I lock it into 1 position and stop it from automatically pulling the model into frame when I add parts that are large onto the model?


I am confused by what you are trying to do. Mind posting some images and some code with what is going on and what you actually want it to do?



When using module3d to clone the character, if parts are added like armor, for example, the model is set farther from the camera in order to fit all the parts in, is there any way to counter this and always have the model and the camera in the same place or base the cframe from a part like humanoidrootpart?


This functionality isn’t really supported, but shouldn’t be a problem with the current version unless you are calling Update, SetCFrame, or SetDepthMultiplier on the frame. Can you post some code that includes equipping armor if you aren’t calling these methods?