Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement 3D layers #840

Merged
merged 23 commits into from
Mar 31, 2023

Conversation

OverloadedOrama
Copy link
Member

@OverloadedOrama OverloadedOrama commented Mar 27, 2023

Screenshot_20230328_021323

Bringing the power of Godot's 3D engine into Pixelorama. Introducing a new layer type, 3D layers! 3D layers allow for the usage of 3D objects into Pixelorama, in 2D space. They get automatically pixelated, depending on the size of the canvas. Artists can now use a variety of 3D shapes, including boxes, spheres, capsules, cylinders, prisms and even 3D text! It is also possible to import custom .obj models (thanks to gd-obj). For lighting, you can use directional lights, spotlights and point lights.

Current features include:

  • Non-destructive editing of 3D shapes (easy rotating, scaling etc) using a new 3D shape edit tool, but can be made destructive if merged with a pixel layer. With undo/redo support.
  • Ready-to-use lighting system, as requested in Using 3D and Light #596.
  • Supports perspective, orthogonal and frustum camera projections.
  • Can be used to easily convert 3D to pixel art.
  • Different 3D object properties for every frame, thus allowing for animations.
  • Can help with perspective drawing, as an alternative workflow to the perspective editor.

This PR also makes the following changes:

  • Removes the "Create a new group layer" button from the timeline, moving it into a menu instead, which can be accessed from right next to the "Create a new layer" button.
  • Introduces a system that makes certain tools hide and appear on specific layer types. For example, draw tools only appear in pixel layers, while the new 3D shape tool only appears in 3D layers. Also useful for Vector layers #839.
  • Adds a new custom ValueSliderV3 node, based of ValueSliderV2.

To-do:

  • Add the new translation strings.

3d cube spin 8x

Future improvements outside the scope of this PR:

  • A better icon for the 3D shape edit tool (current one is a placeholder)
  • Various UI improvements to the 3D shape edit tool options, such as adding icons for the add and remove object buttons.
  • A scene tree. Right now, there is an option button that lets the user select an object, other than clicking on it.
  • Editing material properties for the objects.
  • A torus shape. Will be possible when Godot 3.6 is out, or when we upgrade to 4.0.
  • Better gizmos for point lights and spotlights.
  • When Layers FX (FX Layers #619) are implemented, 3D layers can have a lot of shader-based effects, like shape outlining, or changing how the lighting looks entirely, like limiting the color palette (could be done with Gradient Maps and constant interpolation). This can be used to do stuff such as easy dithered lighting (something like this https://godotshaders.com/shader/dither-gradient-shader/)
  • Some way of interpolating values between frames, for easy animation.
  • Parent objects to edit multiple objects together.
  • Some way of editing multiple objects, even between different frames. Maybe with cel linking?
  • Choose fonts for the Text meshes.
  • Import .gltf files (should be easy when we upgrade to Godot 4.0).
  • Import animated models. Not sure how hard that would be, and if possible at all.

image
(The above image is a sphere object, illuminated by a directional light. I merged it into a pixel layer, and applied a Gradient Map with constant interpolation on it to achieve this effect. Not the best workflow at the moment, but it will improve tremendously when Layers FX are implemented.)

@@ -387,6 +387,8 @@ func blend_layers(
layer_image.copy_from(frame.cels[export_layers - 2].image)
elif layer is GroupLayer:
layer_image.copy_from(layer.blend_children(frame, Vector2.ZERO))
elif layer is Layer3D:
layer_image.copy_from(frame.cels[export_layers - 2].get_image())
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this part could probably be:
if layer is GroupLayer:
layer_image.copy_from(layer.blend_children(frame, Vector2.ZERO))
else:
layer_image.copy_from(frame.cels[export_layers - 2].get_image())

right?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, I changed it.

@@ -18,10 +18,10 @@ func blend_children(frame: Frame, origin := Vector2.ZERO) -> Image:
for layer in children:
if not layer.is_visible_in_hierarchy():
continue
if layer is PixelLayer:
var cel: PixelCel = frame.cels[layer.index]
if layer is PixelLayer or layer is Layer3D:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Something like if not layer is GroupLayer might be nicer to make it not need every other layer type, but I guess it doesn't work because of the comment "Only if layer is GroupLayer, cannot define this due to cyclic reference error" on the else below. Does doing if not layer is get_script() work? If it does I guess the condition should be flipped to not have not in front

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup, it seems to be working. I changed it.

@OverloadedOrama OverloadedOrama merged commit 91aea32 into Orama-Interactive:master Mar 31, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants