Add a nearest neighbor mode to the MAP UV compositor node. #115103

Merged
Martijn Versteegh merged 32 commits from Baardaap/blender:nearest_neighbopur_compositor_uvmap into main 2024-01-19 13:24:31 +01:00

If you use the Map UV node in the compositor with generated UV coordinates, for example for for per-pixel distortion effects or color lookups in a LUT texture the anisotropic sampling can be a hindrance leading to unwanted bleed between pixels in the input.

This PR adds an option to select Nearest Neighbour sampling on the compositor Map UV node.

If you use the Map UV node in the compositor with generated UV coordinates, for example for for per-pixel distortion effects or color lookups in a LUT texture the anisotropic sampling can be a hindrance leading to unwanted bleed between pixels in the input. This PR adds an option to select Nearest Neighbour sampling on the compositor Map UV node.
Martijn Versteegh added 4 commits 2023-11-18 18:04:59 +01:00
958db263e6 Add a nearest neighbour sampling mode to the compositor MapUV node.
By default the MapUV node does anisotropic filtering, but this interferes
with some (NPR) workflows, for example when you generate to UV coordinates
to use a separate image as a LUT, or for pixel based distortions.
Martijn Versteegh added 1 commit 2023-11-18 22:39:38 +01:00
Author
Member

Manual patch:

diff --git a/manual/compositing/types/transform/map_uv.rst b/manual/compositing/types/transform/map_uv.rst
index 329f48ec4..ba4ac828e 100644
--- a/manual/compositing/types/transform/map_uv.rst
+++ b/manual/compositing/types/transform/map_uv.rst
@@ -35,6 +35,8 @@ Properties
 Alpha
    Alpha threshold is used to fade out pixels on boundaries.
 
+Nearest Neighbour
+   Use nearest neighbour instead of anisotropic sampling for the input image.
 
 Outputs
 =======

Manual patch: ``` diff --git a/manual/compositing/types/transform/map_uv.rst b/manual/compositing/types/transform/map_uv.rst index 329f48ec4..ba4ac828e 100644 --- a/manual/compositing/types/transform/map_uv.rst +++ b/manual/compositing/types/transform/map_uv.rst @@ -35,6 +35,8 @@ Properties Alpha Alpha threshold is used to fade out pixels on boundaries. +Nearest Neighbour + Use nearest neighbour instead of anisotropic sampling for the input image. Outputs ======= ```
First-time contributor

As an example of what a nearest-neighbour interpolation UV Map node might be useful for.

Here is a palettized 64x64x64 LUT and a bayer matrix dither pattern.
branch-1-2-lut-stripe.png
bayer8x8.png

The LUT is applied by converting the R to U, the G to V, and then dividing the R by 64 and offsetting it by an integer (divided by 64) of the blue channel.

interpolated dither and palettization.png

Here is the result. No amount of math, snapping, dividing, or anything makes this work. The pixelation node similarly fails to correct anything. The UV Map node's automatic forced anisotropic filtering collapses the distances between disparate UV values making lines appear any time the blue value changes enough to shift the R(U) and G(V) into another gradient island.

Here is the result with a node set-up where nearest neighbour interpolation is active.

nearest neighbour dither and palettization.png

As an example of what a nearest-neighbour interpolation UV Map node might be useful for. Here is a palettized 64x64x64 LUT and a bayer matrix dither pattern. ![branch-1-2-lut-stripe.png](/attachments/a92ea80f-e816-4d88-9049-6d50d9840e5b) ![bayer8x8.png](/attachments/e2a5e455-6919-4a7e-83ad-7d0321f987ed) The LUT is applied by converting the R to U, the G to V, and then dividing the R by 64 and offsetting it by an integer (divided by 64) of the blue channel. ![interpolated dither and palettization.png](/attachments/aae4aa32-ab73-437d-a786-c3fa2c945474) Here is the result. No amount of math, snapping, dividing, or anything makes this work. The pixelation node similarly fails to correct anything. The UV Map node's automatic forced anisotropic filtering collapses the distances between disparate UV values making lines appear any time the blue value changes enough to shift the R(U) and G(V) into another gradient island. Here is the result with a node set-up where nearest neighbour interpolation is active. ![nearest neighbour dither and palettization.png](/attachments/5702d89b-0047-494a-9f6f-94d7a680a604)
Author
Member

Thanks for the explanation.

What is the bayer pattern used for?
could you add a .blend file with the nodetree?

Thanks for the explanation. What is the bayer pattern used for? could you add a .blend file with the nodetree?
Martijn Versteegh added 1 commit 2023-11-22 12:28:31 +01:00
First-time contributor

I apologize for the delay, I was in crunch time all last week. Attached is a proper example of both shader-based (has certain limitations) and compositor-based (does not work at all, currently) dithering. The bayer8x8.png file is just a dithering matrix to offset colours into neighbouring values to create an ordered dither effect.

Everything should be packed in, and each type of dithering is demonstrated in its own scene.

https://www.youtube.com/watch?v=TmXe-ZGr5RM This is the project where it would've been handy to dither things as they were rendered. It had to be brought in as a post-processing effect in after-effects which was bizarrely slow and resulted in the final video (After Effects) render time being extended by like 3 hours. Maybe batch-converting the frames in aseprite next time would be a better solution, but there's no real reason why the compositor node set-up shouldn't work except that the compositor UV Map node has a handy quality of life feature (the anisotropic filtering) which is sadly impossible to turn off, by any means.

I apologize for the delay, I was in crunch time all last week. Attached is a proper example of both shader-based (has certain limitations) and compositor-based (does not work at all, currently) dithering. The bayer8x8.png file is just a dithering matrix to offset colours into neighbouring values to create an ordered dither effect. Everything should be packed in, and each type of dithering is demonstrated in its own scene. https://www.youtube.com/watch?v=TmXe-ZGr5RM This is the project where it would've been handy to dither things as they were rendered. It had to be brought in as a post-processing effect in after-effects which was bizarrely slow and resulted in the final video (After Effects) render time being extended by like 3 hours. Maybe batch-converting the frames in aseprite next time would be a better solution, but there's no real reason why the compositor node set-up shouldn't work except that the compositor UV Map node has a handy quality of life feature (the anisotropic filtering) which is sadly impossible to turn off, by any means.
Martijn Versteegh added 1 commit 2023-12-08 16:45:59 +01:00
Martijn Versteegh changed title from WIP: add a nearest neighbor mode to the MAP UV compositor node. to Add a nearest neighbor mode to the MAP UV compositor node. 2023-12-08 16:57:18 +01:00
Iliya Katushenock added this to the Compositing project 2023-12-08 17:03:16 +01:00
Omar Emara requested review from Omar Emara 2023-12-13 11:18:11 +01:00
Omar Emara requested changes 2023-12-15 11:52:07 +01:00
@ -19,6 +19,7 @@ void MapUVNode::convert_to_operations(NodeConverter &converter,
MapUVOperation *operation = new MapUVOperation();
operation->set_alpha(float(node->custom1));
operation->set_nearestNeighbour(bool(node->custom2));
Member

Better use CMP_NODE_MAP_UV_FILTERING.

Better use `CMP_NODE_MAP_UV_FILTERING`.
Author
Member

I don't really understand what you mean here?

create an enum type and use that instead of bool?

I don't really understand what you mean here? create an enum type and use that instead of bool?
Member

Use existing enum.

operation->set_filtering(node->custom2 & CMP_NODE_MAP_UV_FILTERING);
Use existing enum. ``` operation->set_filtering(node->custom2 & CMP_NODE_MAP_UV_FILTERING); ```
Author
Member

I can't seem to find this existing enum. Is it maybe something in a branch you have?

I grepped the whole source tree for CMP_NODE_MAP.

But I'll rewrite the somewhat strangely named CMPNodeMapUVNearestNeighbour enum I created to

typedef enum CMPNodeMapUVFiltering {
  CMP_NODE_MAPUV_ANISOTROPIC = 0,
  CMP_NODE_MAPUV_NEARESTNEIGHBOUR = 1,
} CMPNodeMapUVFiltering;

and use that.

I can't seem to find this existing enum. Is it maybe something in a branch you have? I grepped the whole source tree for CMP_NODE_MAP. But I'll rewrite the somewhat strangely named CMPNodeMapUVNearestNeighbour enum I created to ``` typedef enum CMPNodeMapUVFiltering { CMP_NODE_MAPUV_ANISOTROPIC = 0, CMP_NODE_MAPUV_NEARESTNEIGHBOUR = 1, } CMPNodeMapUVFiltering; ``` and use that.
Member

Sorry, I just meant CMP_NODE_MAPUV_NEARESTNEIGHBOUR you already created, but renamed to filtering as I suggested above.

Sorry, I just meant `CMP_NODE_MAPUV_NEARESTNEIGHBOUR` you already created, but renamed to filtering as I suggested above.
Baardaap marked this conversation as resolved
@ -70,3 +60,1 @@
dv / input_color_program_->get_height());
if (factor < 0.0f) {
alpha = 0.0f;
if (nearest_neighbour_) {
Member

This only handles the tiled compositor. The full frame compositor need to be handled in the update_memory_buffer_partial and update_memory_buffer_started methods below.

This only handles the tiled compositor. The full frame compositor need to be handled in the `update_memory_buffer_partial` and `update_memory_buffer_started` methods below.
Baardaap marked this conversation as resolved
@ -13,2 +13,4 @@
.compute_source("compositor_map_uv.glsl")
.do_static_compilation(true);
GPU_SHADER_CREATE_INFO(compositor_map_uv_nearest_neighbour)
Member

Those two infos could be shared. See compositor_split_info.hh for an example on how to do that.

Those two infos could be shared. See `compositor_split_info.hh` for an example on how to do that.
Baardaap marked this conversation as resolved
@ -6924,2 +6924,4 @@
RNA_def_property_ui_text(prop, "Alpha", "");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
prop = RNA_def_property(srna, "nearest_neighbour", PROP_BOOLEAN, PROP_NONE);
Member

I would prefer if we do the inverse. Name the option Filtering, make it default to true.

I would prefer if we do the inverse. Name the option `Filtering`, make it default to true.
Author
Member

Yeah that's more logical. I was being lazy as this way it doesn't need versioning because the default value for an non-existing property is zero. ;-)

Yeah that's more logical. I was being lazy as this way it doesn't need versioning because the default value for an non-existing property is zero. ;-)
@ -54,0 +55,4 @@
bool nearest_neighbour = get_nearest_neighbour();
GPUShader *shader = nearest_neighbour ?
context().get_shader("compositor_map_uv_nearest_neighbour") :
Member

Prefer to move into its own method, get_shader_name.

Prefer to move into its own method, `get_shader_name`.
Baardaap marked this conversation as resolved
@ -90,0 +97,4 @@
bool get_nearest_neighbour()
{
return bnode().custom2 != 0;
Member

Better use CMP_NODE_MAP_UV_FILTERING.

Better use `CMP_NODE_MAP_UV_FILTERING`.
Baardaap marked this conversation as resolved
Martijn Versteegh added 6 commits 2023-12-21 16:06:50 +01:00
Martijn Versteegh added 2 commits 2023-12-21 22:54:10 +01:00
Martijn Versteegh added 1 commit 2023-12-21 23:02:46 +01:00
Omar Emara requested changes 2023-12-22 10:46:37 +01:00
@ -19,6 +19,8 @@ void MapUVNode::convert_to_operations(NodeConverter &converter,
MapUVOperation *operation = new MapUVOperation();
operation->set_alpha(float(node->custom1));
operation->set_nearestNeighbour(static_cast<CMPNodeMapUVFiltering>(node->custom2) ==
Member

Use snake_case instead of camelCase. I know some code in the compositor uses it, but it is remnants of older code.

Use `snake_case` instead of `camelCase`. I know some code in the compositor uses it, but it is remnants of older code.
Baardaap marked this conversation as resolved
@ -2539,6 +2539,12 @@ typedef enum CMPNodeCombSepColorMode {
CMP_NODE_COMBSEP_COLOR_YUV = 4,
} CMPNodeCombSepColorMode;
/* Filtering modes Compositor MapUV node */
Member

Mention where this is stored. Stored in custom2. End comments with a period.

Mention where this is stored. `Stored in custom2.` End comments with a period.
Author
Member

will do. Ending with a period feels a bit out of place though, as most of the comments surrounding it don't, which is why I didn't either. But the styleguide does say to make full sentences I think so...

will do. Ending with a period feels a bit out of place though, as most of the comments surrounding it don't, which is why I didn't either. But the styleguide does say to make full sentences I think so...
Baardaap marked this conversation as resolved
@ -2542,0 +2542,4 @@
/* Filtering modes Compositor MapUV node */
typedef enum CMPNodeMapUVFiltering {
CMP_NODE_MAPUV_ANISOTROPIC = 0,
CMP_NODE_MAPUV_NEARESTNEIGHBOUR = 1,
Member

Sorry for the nitpicking. Put an underscore between MAP_UV and NEAREST_NEIGHBOUR.

Sorry for the nitpicking. Put an underscore between MAP_UV and NEAREST_NEIGHBOUR.
Baardaap marked this conversation as resolved
Martijn Versteegh added 2 commits 2023-12-22 12:09:26 +01:00
Martijn Versteegh added 1 commit 2023-12-22 12:16:37 +01:00
buildbot/vexp-code-patch-lint Build done. Details
buildbot/vexp-code-patch-darwin-x86_64 Build done. Details
buildbot/vexp-code-patch-darwin-arm64 Build done. Details
buildbot/vexp-code-patch-linux-x86_64 Build done. Details
buildbot/vexp-code-patch-windows-amd64 Build done. Details
buildbot/vexp-code-patch-coordinator Build done. Details
cb10e7d5e0
Merge branch 'main' into nearest_neighbopur_compositor_uvmap
Author
Member

@blender-bot package

@blender-bot package
Member

Package build started. Download here when ready.

Package build started. [Download here](https://builder.blender.org/download/patch/PR115103) when ready.
Author
Member

The tests pass.

The tests pass.
Member

Now that I think about it, I think maybe we should consider adding bilinear and bicubic as well. Much like the transform node for consistency.

Now that I think about it, I think maybe we should consider adding bilinear and bicubic as well. Much like the transform node for consistency.
Author
Member

Now that I think about it, I think maybe we should consider adding bilinear and bicubic as well. Much like the transform node for consistency.

I'd much prefer to do that as a second patch and get this one in first. The code path through the cpu compositor could use some cleanup before adding more interpolation modes(*) in and I created this patch with minimal changes in mind. I'd prefer to not balloon this patch to the point I won't have time to finish it soon(ish) because I'm quite busy outside of blender stuff.

(*) for example the function called to do the anisotropic sampling is named like it should do nearest neighbour, but then does anisotropic sampling anyway. Either because the anisotropic sampling was added later, or because stuff was re-used in a slightly inconsistent way.

> Now that I think about it, I think maybe we should consider adding bilinear and bicubic as well. Much like the transform node for consistency. I'd much prefer to do that as a second patch and get this one in first. The code path through the cpu compositor could use some cleanup before adding more interpolation modes(*) in and I created this patch with minimal changes in mind. I'd prefer to not balloon this patch to the point I won't have time to finish it soon(ish) because I'm quite busy outside of blender stuff. (*) for example the function called to do the anisotropic sampling is named like it should do nearest neighbour, but then does anisotropic sampling anyway. Either because the anisotropic sampling was added later, or because stuff was re-used in a slightly inconsistent way.
Member

Alright, no problem. However, to avoid future issues with versioning. Extend the enum into a full 4-option enum:

typedef enum CMPNodeMapUVFiltering {
  CMP_NODE_MAP_UV_FILTERING_NEAREST = 0,
  CMP_NODE_MAP_UV_FILTERING_BILINEAR = 1,
  CMP_NODE_MAP_UV_FILTERING_BICUBIC = 2,
  CMP_NODE_MAP_UV_FILTERING_ANISOTROPIC = 3,
} CMPNodeMapUVFiltering;

But in RNA, only add the nearest and anisotropic variants.

static const EnumPropertyItem node_map_uv_filter_type_items[] = {
    {CMP_NODE_MAP_UV_FILTERING_NEAREST, "NEAREST", 0, "Nearest", ""},
    {CMP_NODE_MAP_UV_FILTERING_ANISOTROPIC, "ANISOTROPIC", 0, "Anisotropic", ""},
    {0, nullptr, 0, nullptr, nullptr},
};

Additionally, name the RNA entry filter_type.

It is important to keep the same naming and ordering because we intend to unify all of them into a single enum, much like we have RNA node_sampler_type_items at the moment.

Alright, no problem. However, to avoid future issues with versioning. Extend the enum into a full 4-option enum: ``` typedef enum CMPNodeMapUVFiltering { CMP_NODE_MAP_UV_FILTERING_NEAREST = 0, CMP_NODE_MAP_UV_FILTERING_BILINEAR = 1, CMP_NODE_MAP_UV_FILTERING_BICUBIC = 2, CMP_NODE_MAP_UV_FILTERING_ANISOTROPIC = 3, } CMPNodeMapUVFiltering; ``` But in RNA, only add the nearest and anisotropic variants. ``` static const EnumPropertyItem node_map_uv_filter_type_items[] = { {CMP_NODE_MAP_UV_FILTERING_NEAREST, "NEAREST", 0, "Nearest", ""}, {CMP_NODE_MAP_UV_FILTERING_ANISOTROPIC, "ANISOTROPIC", 0, "Anisotropic", ""}, {0, nullptr, 0, nullptr, nullptr}, }; ``` Additionally, name the RNA entry `filter_type`. It is important to keep the same naming and ordering because we intend to unify all of them into a single enum, much like we have RNA `node_sampler_type_items` at the moment.
Author
Member

I can do this. but it will mean I'll have to add versioning as well because the anisotropic option no longer is 0

I can do this. but it will mean I'll have to add versioning as well because the anisotropic option no longer is 0
Member

The versioning is unconditional initialization, so should be simple enough. If you don't have time, I can update the patch myself be merging.

The versioning is unconditional initialization, so should be simple enough. If you don't have time, I can update the patch myself be merging.
Martijn Versteegh added 2 commits 2023-12-28 11:44:18 +01:00
Martijn Versteegh changed title from Add a nearest neighbor mode to the MAP UV compositor node. to WIP: Add a nearest neighbor mode to the MAP UV compositor node. 2023-12-28 11:44:33 +01:00
Author
Member

re-added WIP prefix because I still need to add versioning code now that anisotropic no longer has value 0 in the enum .

re-added WIP prefix because I still need to add versioning code now that anisotropic no longer has value 0 in the enum .
Author
Member

The versioning is unconditional initialization, so should be simple enough. If you don't have time, I can update the patch myself be merging.

It should be simple, but I'll have to look into how it work again. If it's routine for you that takes you less than 20 minutes please go ahead ;-) But don't spend to much time on it, I can do it somewhere next week and there's no hurry.

> The versioning is unconditional initialization, so should be simple enough. If you don't have time, I can update the patch myself be merging. It should be simple, but I'll have to look into how it work again. If it's routine for you that takes you less than 20 minutes please go ahead ;-) But don't spend to much time on it, I can do it somewhere next week and there's no hurry.
Martijn Versteegh added 1 commit 2024-01-12 14:45:27 +01:00
Martijn Versteegh added 1 commit 2024-01-12 14:45:35 +01:00
Martijn Versteegh changed title from WIP: Add a nearest neighbor mode to the MAP UV compositor node. to Add a nearest neighbor mode to the MAP UV compositor node. 2024-01-12 15:21:42 +01:00
Martijn Versteegh added 1 commit 2024-01-12 23:02:04 +01:00
Omar Emara requested changes 2024-01-17 15:12:17 +01:00
Omar Emara left a comment
Member

The node is missing an init function that sets custom2 to anisotropic.

The node is missing an init function that sets custom2 to anisotropic.
@ -0,0 +10,4 @@
vec2 uv_coordinates = texture_load(uv_tx, texel).xy;
/* Sample the input using the UV coordinates passing in the computed gradients in order to
Member

This comment is no longer needed.

This comment is no longer needed.
Baardaap marked this conversation as resolved
@ -37,6 +37,7 @@ static void cmp_node_map_uv_declare(NodeDeclarationBuilder &b)
static void node_composit_buts_map_uv(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiItemR(layout, ptr, "alpha", UI_ITEM_R_SPLIT_EMPTY_NAME, nullptr, ICON_NONE);
uiItemR(layout, ptr, "filter_type", UI_ITEM_R_SPLIT_EMPTY_NAME, nullptr, ICON_NONE);
Member

Draw the filter type first. Use an empty name, nullptr becomes "".

Draw the filter type first. Use an empty name, `nullptr becomes ""`.
Baardaap marked this conversation as resolved
@ -60,3 +64,4 @@
}
const Result &input_image = get_input("Image");
GPU_texture_mipmap_mode(input_image.texture(), true, true);
Member

This call and the below one should be inside if blocks for nearest_neighbour. With filtering explicitly set to false in the false case.

This call and the below one should be inside if blocks for `nearest_neighbour`. With filtering explicitly set to false in the false case.
Author
Member

I take it you mean setting mipmap+filtering to false for the nearest_neighbour case?

I take it you mean setting mipmap+filtering to false for the nearest_neighbour case?
Member

Yes.

Yes.
Baardaap marked this conversation as resolved
@ -90,0 +98,4 @@
return bnode().custom2 == CMP_NODE_MAP_UV_FILTERING_NEAREST;
}
private:
Member

No need for private, since this is an implementation only clase.

No need for private, since this is an implementation only clase.
Author
Member

l'll take it out. Personally I think it's good practice to mark any functions for internal use in the class as private, but I don't care too much.

l'll take it out. Personally I think it's good practice to mark any functions for internal use in the class as private, but I don't care too much.
Baardaap marked this conversation as resolved
Author
Member

The node is missing an init function that sets custom2 to anisotropic.

oops. I thought that would be handled by setting the default in rna. will do

> The node is missing an init function that sets custom2 to anisotropic. oops. I thought that would be handled by setting the default in rna. will do
Martijn Versteegh added 4 commits 2024-01-17 19:33:05 +01:00
8ce7e22f57 -Show filter type first
-Don't use mipmapping and anisotropic filtering for the nearest_neighbour case.
-Take out unneeded 'private;'
buildbot/vexp-code-patch-lint Build done. Details
buildbot/vexp-code-patch-linux-x86_64 Build done. Details
buildbot/vexp-code-patch-darwin-arm64 Build done. Details
buildbot/vexp-code-patch-windows-amd64 Build done. Details
buildbot/vexp-code-patch-darwin-x86_64 Build done. Details
buildbot/vexp-code-patch-coordinator Build done. Details
f7b37f6d3f
Merge branch 'main' into nearest_neighbopur_compositor_uvmap
Member

@blender-bot build

@blender-bot build
Martijn Versteegh added 1 commit 2024-01-18 13:28:59 +01:00
Omar Emara approved these changes 2024-01-18 16:11:03 +01:00
Martijn Versteegh added 2 commits 2024-01-19 13:16:57 +01:00
Martijn Versteegh added 1 commit 2024-01-19 13:18:38 +01:00
Martijn Versteegh merged commit a3b7674c6e into main 2024-01-19 13:24:31 +01:00
Martijn Versteegh deleted branch nearest_neighbopur_compositor_uvmap 2024-01-19 13:24:33 +01:00
Sign in to join this conversation.
No reviewers
No Label
Interest
Alembic
Interest
Animation & Rigging
Interest
Asset Browser
Interest
Asset Browser Project Overview
Interest
Audio
Interest
Automated Testing
Interest
Blender Asset Bundle
Interest
BlendFile
Interest
Collada
Interest
Compatibility
Interest
Compositing
Interest
Core
Interest
Cycles
Interest
Dependency Graph
Interest
Development Management
Interest
EEVEE
Interest
EEVEE & Viewport
Interest
Freestyle
Interest
Geometry Nodes
Interest
Grease Pencil
Interest
ID Management
Interest
Images & Movies
Interest
Import Export
Interest
Line Art
Interest
Masking
Interest
Metal
Interest
Modeling
Interest
Modifiers
Interest
Motion Tracking
Interest
Nodes & Physics
Interest
OpenGL
Interest
Overlay
Interest
Overrides
Interest
Performance
Interest
Physics
Interest
Pipeline, Assets & IO
Interest
Platforms, Builds & Tests
Interest
Python API
Interest
Render & Cycles
Interest
Render Pipeline
Interest
Sculpt, Paint & Texture
Interest
Text Editor
Interest
Translations
Interest
Triaging
Interest
Undo
Interest
USD
Interest
User Interface
Interest
UV Editing
Interest
VFX & Video
Interest
Video Sequencer
Interest
Virtual Reality
Interest
Vulkan
Interest
Wayland
Interest
Workbench
Interest: X11
Legacy
Blender 2.8 Project
Legacy
Milestone 1: Basic, Local Asset Browser
Legacy
OpenGL Error
Meta
Good First Issue
Meta
Papercut
Meta
Retrospective
Meta
Security
Module
Animation & Rigging
Module
Core
Module
Development Management
Module
EEVEE & Viewport
Module
Grease Pencil
Module
Modeling
Module
Nodes & Physics
Module
Pipeline, Assets & IO
Module
Platforms, Builds & Tests
Module
Python API
Module
Render & Cycles
Module
Sculpt, Paint & Texture
Module
Triaging
Module
User Interface
Module
VFX & Video
Platform
FreeBSD
Platform
Linux
Platform
macOS
Platform
Windows
Priority
High
Priority
Low
Priority
Normal
Priority
Unbreak Now!
Status
Archived
Status
Confirmed
Status
Duplicate
Status
Needs Info from Developers
Status
Needs Information from User
Status
Needs Triage
Status
Resolved
Type
Bug
Type
Design
Type
Known Issue
Type
Patch
Type
Report
Type
To Do
No Milestone
No project
No Assignees
4 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: blender/blender#115103
No description provided.