I can use the RenderingSever API to render a torus mesh to the scene.

using Godot;
using static System.GC;
using static Godot.RenderingServer;

[Tool, GlobalClass]
public partial class RenderingTorus : Node3D
{   
    // Add torus mesh
    private readonly Mesh _torus = ResourceLoader.Load<Mesh>("res://assets/new_torus_mesh.tres");
    private Rid? _torusInstance;
    
    public override void _Ready()
    {
        // Add torus mesh
        _torusInstance = InstanceCreate();
        InstanceSetBase(_torusInstance.Value, _torus.GetRid());
        InstanceSetScenario(_torusInstance.Value, GetWorld3D().Scenario);
    }
    
    public new void Dispose()
    {
        base.Dispose();
        if (_torusInstance.HasValue)
        {
            FreeRid(_torusInstance.Value);
        }
        SuppressFinalize(this);
    }
}

But when I try to render a Torus mesh to an icon I get, only a blank black icon.

using Godot;

public static class Renderer
{

    public static Texture2D CreateIcon()
    {

        // 
        Rid scenario = RenderingServer.ScenarioCreate();

        // Create Camera
        Rid camera = RenderingServer.CameraCreate();
        
        // Add light to the scenario
        Rid light = RenderingServer.SpotLightCreate();
        Rid lightInstance = RenderingServer.InstanceCreate();
        RenderingServer.InstanceSetBase(lightInstance, light);
        RenderingServer.InstanceSetScenario(lightInstance, scenario);

        // Add torus mesh
        Mesh torus = ResourceLoader.Load<Mesh>("res://assets/new_torus_mesh.tres");
        Rid torusInstance = RenderingServer.InstanceCreate();
        RenderingServer.InstanceSetBase(torusInstance, torus.GetRid());
        RenderingServer.InstanceSetScenario(torusInstance, scenario);

        // Create The new viewport
        Rid viewport = RenderingServer.ViewportCreate();
        RenderingServer.ViewportSetSize(viewport, 64, 64);
        RenderingServer.ViewportSetUpdateMode(viewport, RenderingServer.ViewportUpdateMode.Always);
        RenderingServer.ViewportSetScenario(viewport, scenario);
        RenderingServer.ViewportAttachCamera(viewport, camera);
        
        RenderingServer.ForceDraw();
        RenderingServer.ForceSync();
        
        Rid lastRenderedFrameId = RenderingServer.ViewportGetTexture(viewport);
        Image lastRenderedFrame = RenderingServer.Texture2DGet(lastRenderedFrameId);
        Texture2D texture2D = ImageTexture.CreateFromImage(lastRenderedFrame);
        
        RenderingServer.FreeRid(viewport);
        RenderingServer.FreeRid(scenario);
        RenderingServer.FreeRid(camera);
        RenderingServer.FreeRid(lightInstance);
        RenderingServer.FreeRid(light);
        RenderingServer.FreeRid(torusInstance);

        return texture2D;

    }
}

Is there anything I can do to render a mesh to an image?

  • xyz replied to this.

    madlad I don't see your code setting the camera transform. You should probably do that so the camera looks at the torus instead of staying in its default position at origin.

      xyz

      I've tried moving the torus over on the Z-axis but the texture is still all black.

          public static Texture2D CreateIcon()
          {
      
              Transform3D torusTransform = new(Basis.Identity, new Vector3(0, 0, -10));
              
              // 
              Rid scenario = RenderingServer.ScenarioCreate();
      
              // Create Camera
              Rid camera = RenderingServer.CameraCreate();
              
              // Add light to the scenario
              Rid light = RenderingServer.SpotLightCreate();
              Rid lightInstance = RenderingServer.InstanceCreate();
              RenderingServer.InstanceSetBase(lightInstance, light);
              RenderingServer.InstanceSetScenario(lightInstance, scenario);
      
              // Add torus mesh
              Mesh torus = ResourceLoader.Load<Mesh>("res://assets/new_torus_mesh.tres");
              Rid torusInstance = RenderingServer.InstanceCreate();
              RenderingServer.InstanceSetBase(torusInstance, torus.GetRid());
              RenderingServer.InstanceSetScenario(torusInstance, scenario);
              RenderingServer.InstanceSetTransform(torusInstance, torusTransform);
      
              // Create The new viewport
              Rid viewport = RenderingServer.ViewportCreate();
              RenderingServer.ViewportSetSize(viewport, 64, 64);
              RenderingServer.ViewportSetUpdateMode(viewport, RenderingServer.ViewportUpdateMode.Always);
              RenderingServer.ViewportSetScenario(viewport, scenario);
              RenderingServer.ViewportAttachCamera(viewport, camera);
              
              RenderingServer.ForceDraw();
              RenderingServer.ForceSync();
              
              Rid lastRenderedFrameId = RenderingServer.ViewportGetTexture(viewport);
              Image lastRenderedFrame = RenderingServer.Texture2DGet(lastRenderedFrameId);
              Texture2D texture2D = ImageTexture.CreateFromImage(lastRenderedFrame);
              
              RenderingServer.FreeRid(viewport);
              RenderingServer.FreeRid(scenario);
              RenderingServer.FreeRid(camera);
              RenderingServer.FreeRid(lightInstance);
              RenderingServer.FreeRid(light);
              RenderingServer.FreeRid(torusInstance);
      
              return texture2D;
      
          }