2D Vector Socket Type #92765

Open
opened 2021-11-02 23:57:51 +01:00 by Hans Goudey · 24 comments
Member

Many nodes, and UVs are more correct and intuitive with 2D vector sockets.
Using a more specific data type can make node networks more intuitive, and faster.

Though changing the math nodes is a larger topic/design challenge, initially many nodes can be changed to support this socket type:

  • Attribute statistic
  • Capture attribute
  • Transfer attribute
  • Image texture
  • Random value
  • Compare node (#92729)

2D vector attributes will have to be supported in many places that they aren't currently as well.

Other texture nodes can be supported when shader nodes is updated to support 2D vectors.

Many nodes, and UVs are more correct and intuitive with 2D vector sockets. Using a more specific data type can make node networks more intuitive, and faster. Though changing the math nodes is a larger topic/design challenge, initially many nodes can be changed to support this socket type: - Attribute statistic - Capture attribute - Transfer attribute - Image texture - Random value - Compare node (#92729) 2D vector attributes will have to be supported in many places that they aren't currently as well. Other texture nodes can be supported when shader nodes is updated to support 2D vectors.
Author
Member

Changed status from 'Needs Triage' to: 'Confirmed'

Changed status from 'Needs Triage' to: 'Confirmed'
Author
Member

Added subscriber: @HooglyBoogly

Added subscriber: @HooglyBoogly

Added subscriber: @GeorgiaPacific

Added subscriber: @GeorgiaPacific

Added subscriber: @Yuro

Added subscriber: @Yuro

Added subscriber: @MiroHorvath

Added subscriber: @MiroHorvath
Member

Added subscriber: @CharlieJolly

Added subscriber: @CharlieJolly
Member

Textures like noise already provide 2D/3D data using a vector socket. This has advantages for the user so that when changing mode this does not change the links. I think 2D sockets could be implemented as 3D/vector sockets but with a 2D UI. This UI flag would hide the Z channel in the user interface. This would also make implementing dynamic nodes easier as only the socket UI flag would need to be set to show that the socket is processing 2D data. Internally the node will take the XY channels of any connected 3D vector, This also raises the idea of implementing this as a dynamic data socket with support for 4D data too. This could potentially make it easier to implement overloaded functions in nodes. Currently there is a lot of boilerplate to handle sockets that could be avoided.

Textures like noise already provide 2D/3D data using a vector socket. This has advantages for the user so that when changing mode this does not change the links. I think 2D sockets could be implemented as 3D/vector sockets but with a 2D UI. This UI flag would hide the Z channel in the user interface. This would also make implementing dynamic nodes easier as only the socket UI flag would need to be set to show that the socket is processing 2D data. Internally the node will take the XY channels of any connected 3D vector, This also raises the idea of implementing this as a dynamic data socket with support for 4D data too. This could potentially make it easier to implement overloaded functions in nodes. Currently there is a lot of boilerplate to handle sockets that could be avoided.
Author
Member

In #92765#1250660, @CharlieJolly wrote:
This has advantages for the user so that when changing mode this does not change the links.

I think this is a separate issue honestly. Reusing links for sockets when changing types could be improved, even without this new socket type.

I think 2D sockets could be implemented as 3D/vector sockets but with a 2D UI. This UI flag would hide the Z channel in the user interface. This would also make implementing dynamic nodes easier as only the socket UI flag would need to be set to show that the socket is processing 2D data. Internally the node will take the XY channels of any connected 3D vector, This also raises the idea of implementing this as a dynamic data socket with support for 4D data too. This could potentially make it easier to implement overloaded functions in nodes. Currently there is a lot of boilerplate to handle sockets that could be avoided.

I agree the amount of boilerplate code should be improved, but I don't agree that the best way to do that is to actually pass around 3D vectors. This makes code more complicated for a few reasons:

  • Type inference becomes more complicated, because a 3D vector socket also has a length to pass around.
  • Areas that interact with node sockets also have to consider this, instead of just supporting another socket type.
  • Correspondence between socket types and the stored data is no longer simple.

Better ways to reduce boilerplate code, in my opinion:

  • Templated functions that can work on vectors of multiple lengths.
  • Dynamic type sockets in node declarations.
  • Improvements to multi-function signatures and API (less clear on the details here, but I think some improvements would be possible).

The part of your argument I find most convincing is that we could support arbitrary length (2,3,4,etc.) vectors somehow. I think in practice this would be more complicated though.

> In #92765#1250660, @CharlieJolly wrote: > This has advantages for the user so that when changing mode this does not change the links. I think this is a separate issue honestly. Reusing links for sockets when changing types could be improved, even without this new socket type. > I think 2D sockets could be implemented as 3D/vector sockets but with a 2D UI. This UI flag would hide the Z channel in the user interface. This would also make implementing dynamic nodes easier as only the socket UI flag would need to be set to show that the socket is processing 2D data. Internally the node will take the XY channels of any connected 3D vector, This also raises the idea of implementing this as a dynamic data socket with support for 4D data too. This could potentially make it easier to implement overloaded functions in nodes. Currently there is a lot of boilerplate to handle sockets that could be avoided. I agree the amount of boilerplate code should be improved, but I don't agree that the best way to do that is to actually pass around 3D vectors. This makes code more complicated for a few reasons: - Type inference becomes more complicated, because a 3D vector socket also has a length to pass around. - Areas that interact with node sockets also have to consider this, instead of just supporting another socket type. - Correspondence between socket types and the stored data is no longer simple. Better ways to reduce boilerplate code, in my opinion: - Templated functions that can work on vectors of multiple lengths. - Dynamic type sockets in node declarations. - Improvements to multi-function signatures and API (less clear on the details here, but I think some improvements would be possible). The part of your argument I find most convincing is that we could support arbitrary length (2,3,4,etc.) vectors somehow. I think in practice this would be more complicated though.
Member

Adding a 2D socket is straight forward as it can basically copy the existing 3D socket.

It would be beneficial to do this in parallel with a reference implementation porting a node such as the Vector Math Node for Cycles/OSL/Eevee/GN to explore boilerplate and UX. E.g. now with coloured wires, type is much more visible, should there be an Auto data type mode? Some of this was implemented in the legacy Attribute nodes but not in the shader node implementations.

Adding a 2D socket is straight forward as it can basically copy the existing 3D socket. It would be beneficial to do this in parallel with a reference implementation porting a node such as the Vector Math Node for Cycles/OSL/Eevee/GN to explore boilerplate and UX. E.g. now with coloured wires, type is much more visible, should there be an Auto data type mode? Some of this was implemented in the legacy Attribute nodes but not in the shader node implementations.
Author
Member

I think it's okay as a first step to add the socket type and use it in some geometry nodes.
Supporting 2D vectors in shader nodes is a separate project that should also be done, but I think it increases the scope of this task a little too much.

We should support type inferencing in the future (automatically changing node types when connecting them to different sockets. I think we should design with that feature in mind.

I think it's okay as a first step to add the socket type and use it in some geometry nodes. Supporting 2D vectors in shader nodes is a separate project that should also be done, but I think it increases the scope of this task a little too much. We should support type inferencing in the future (automatically changing node types when connecting them to different sockets. I think we should design with that feature in mind.
Member

In #92765#1252587, @HooglyBoogly wrote:
We should support type inferencing in the future (automatically changing node types when connecting them to different sockets. I think we should design with that feature in mind.

Yes totally!

> In #92765#1252587, @HooglyBoogly wrote: > We should support type inferencing in the future (automatically changing node types when connecting them to different sockets. I think we should design with that feature in mind. Yes totally!

Added subscriber: @Aeraglyx

Added subscriber: @Aeraglyx

Added subscriber: @brecht

Added subscriber: @brecht

I only saw this task late, but personally I'd really rather not do this. I don't know the amount of work this is for the geometry nodes team, but if we want to maintain consistency across node systems in Blender this will also lead to a bunch of work for shader and texture nodes, that I don't think is worth committing the time to.

I think in terms of usability this is a really minor issue, that is not worth adding a lot of complexity across Blender for.

I only saw this task late, but personally I'd really rather not do this. I don't know the amount of work this is for the geometry nodes team, but if we want to maintain consistency across node systems in Blender this will also lead to a bunch of work for shader and texture nodes, that I don't think is worth committing the time to. I think in terms of usability this is a really minor issue, that is not worth adding a lot of complexity across Blender for.
Author
Member

The amount of work for geometry nodes beyond this initial patch adding the socket type is very small. Almost all math is templated, so usually the most that's necessary is adding cases to switch statements, etc. This will get better when we have multi-type sockets implemented (#95448).
Code should be written so that this is easy, and indeed, where we've used templates and other concepts, it is. For texture nodes, since the implementation would be started from scratch, hopefully in a rather type-agnostic way, I don't think this would be a problem at all.

But I'm guessing you're really referring to the current state of the code, particularly in shader nodes. There I have less experience, so I definitely won't try to tell you "it's simple!".
However, at the cost of a bit of performance, 2D vectors could just be handled as 3D vectors internally. Then it's just a few UI changes if we want to use the socket type somewhere, which IMO are pretty trivial.

In terms of usability, it's not the most important thing, but I think there are many places it acts as a teaching tool, saves effort, and simplifies node<->attribute exchange.
Generally I've noticed that this "wrong data type" has more of a UX impact than I expected, that's only anecdotal though. Some areas that it would help:

  • The image texture node input becomes clearer, helpful as a teaching tool.
  • Maybe most importantly, we can still have a near 1-1 mapping between node types and socket types. Currently when writing to a 2D vector attribute, the type is changed to 3D, which can make working with UVs harder
    • Supporting 2D vectors properly avoids having to add a "write 3D as 2D" option, which would complicate code and UX.
  • Any node that operates on or creates UVs would become clearer, easier to understand immediately.

Also, we're planning on adding more data types in the future anyway: rotations (#92967), and we've even discussed a transform data type, which may be especially useful for things like rigging nodes and nested instances.
So if the aim is consistency across editors, code will have to become more type agnostic anyway. Compared to those types, 2D vectors are trivial and can be easily emulated by 3D vectors internally if necessary.

We've also been having discussions about generalizing math nodes to work on more than just floats, see #95448, and #94899. Adding 2D vectors works well with those designs.

The amount of work for geometry nodes beyond this initial patch adding the socket type is very small. Almost all math is templated, so usually the most that's necessary is adding cases to switch statements, etc. This will get better when we have multi-type sockets implemented (#95448). Code should be written so that this is easy, and indeed, where we've used templates and other concepts, it is. For texture nodes, since the implementation would be started from scratch, hopefully in a rather type-agnostic way, I don't think this would be a problem at all. But I'm guessing you're really referring to the *current state* of the code, particularly in shader nodes. There I have less experience, so I definitely won't try to tell you "it's simple!". However, at the cost of a bit of performance, 2D vectors could just be handled as 3D vectors internally. Then it's just a few UI changes if we want to use the socket type somewhere, which IMO are pretty trivial. In terms of usability, it's not the most important thing, but I think there are many places it acts as a teaching tool, saves effort, and simplifies node<->attribute exchange. Generally I've noticed that this "wrong data type" has more of a UX impact than I expected, that's only anecdotal though. Some areas that it would help: - The image texture node input becomes clearer, helpful as a teaching tool. - Maybe most importantly, we can still have a near 1-1 mapping between node types and socket types. Currently when writing to a 2D vector attribute, the type is changed to 3D, which can make working with UVs harder - Supporting 2D vectors properly avoids having to add a "write 3D as 2D" option, which would complicate code and UX. - Any node that operates on or creates UVs would become clearer, easier to understand immediately. Also, we're planning on adding more data types in the future anyway: rotations (#92967), and we've even discussed a transform data type, which may be especially useful for things like rigging nodes and nested instances. So if the aim is consistency across editors, code will have to become more type agnostic anyway. Compared to those types, 2D vectors are trivial and can be easily emulated by 3D vectors internally if necessary. We've also been having discussions about generalizing math nodes to work on more than just floats, see #95448, and #94899. Adding 2D vectors works well with those designs.
Member

After working on adding vector support to the Map Range shader nodes I can see the benefits of having 2D as a subtype of a vector socket rather than a completely separate socket type. This flag can be used in the UI to show less channels and by the back end to determine which code to call. This has benefits of less sockets and node links to manage.

After working on adding vector support to the Map Range shader nodes I can see the benefits of having 2D as a subtype of a vector socket rather than a completely separate socket type. This flag can be used in the UI to show less channels and by the back end to determine which code to call. This has benefits of less sockets and node links to manage.
Author
Member

the benefits of having 2D as a subtype of a vector socket rather than a completely separate socket type.

This seems more complicated to me honestly. In one case you're extending an existing concept-- socket types-- to a add a new value. In the other hand you're adding something new, and instead of just checking the socket type, code that wants to use 2D vectors now has to check two things.
Also, the changes to map range was adding support for vectors entirely, which seems different than adding supporting vectors with a smaller size.

This has benefits of less sockets and node links to manage.

Can you talk more about this? Do you mean adding the 2D socket type to the declaration? This should be handled relatively soon by allowing declaring multi-type sockets in declarations.
And what do you mean by "fewer links"? You mean how the old links stay around when you change the type? That's also a similar problem, and unrelated to this task IMO.

> the benefits of having 2D as a subtype of a vector socket rather than a completely separate socket type. This seems *more* complicated to me honestly. In one case you're extending an existing concept-- socket types-- to a add a new value. In the other hand you're adding something new, and instead of just checking the socket type, code that wants to use 2D vectors now has to check two things. Also, the changes to map range was adding support for vectors entirely, which seems different than adding supporting vectors with a smaller size. > This has benefits of less sockets and node links to manage. Can you talk more about this? Do you mean adding the 2D socket type to the declaration? This should be handled relatively soon by allowing declaring multi-type sockets in declarations. And what do you mean by "fewer links"? You mean how the old links stay around when you change the type? That's also a similar problem, and unrelated to this task IMO.

For texture nodes, I think we would want to share as many nodes as possible with shader nodes, as well as the GPU implementation with Eevee shader nodes. So in that sense they are not being written from scratch.

Handling 2D as 3D consistently in shading requires more than UI changes. Nodes may fill in the 3rd component with a non-zero value (e.g. noise texture) or casting 3D to 2D may not set the 3rd component to zero, and then an operation like vector length gives a different result. I guess it requires automatically inserting a bunch of nodes that set the 3rd component to zero.

The image texture node in shading accepts 3D coordinates depending on the chosen projection. It's common in shading to map UV coordinates into 3D in some way, and this seems less convenient if you need to explicitly convert it to a 3D vector first before using e.g. vector math or mapping nodes to map it into 3D. In general users would now have to do explicit casting if type inference starts automatically adapting e.g. math nodes to 2D or 3D. This kind of inferencing can have unexpected consequences if it even affects nodes inside of a group for example and changes a bunch of math nodes from 2D to 3D, though I don't know if that's the plan.

For UV maps, I also wonder if users don't already have to specify that they want to output a UV map? Depending on the use case it may not make a difference, but for the UI in the UV editor, exporting to various file formats, you still need to know what is a UV coordinate or some other arbitrary 2D float attribute.

An argument in favor of 2D vectors is that MaterialX has them also, although I don't like that design.

For texture nodes, I think we would want to share as many nodes as possible with shader nodes, as well as the GPU implementation with Eevee shader nodes. So in that sense they are not being written from scratch. Handling 2D as 3D consistently in shading requires more than UI changes. Nodes may fill in the 3rd component with a non-zero value (e.g. noise texture) or casting 3D to 2D may not set the 3rd component to zero, and then an operation like vector length gives a different result. I guess it requires automatically inserting a bunch of nodes that set the 3rd component to zero. The image texture node in shading accepts 3D coordinates depending on the chosen projection. It's common in shading to map UV coordinates into 3D in some way, and this seems less convenient if you need to explicitly convert it to a 3D vector first before using e.g. vector math or mapping nodes to map it into 3D. In general users would now have to do explicit casting if type inference starts automatically adapting e.g. math nodes to 2D or 3D. This kind of inferencing can have unexpected consequences if it even affects nodes inside of a group for example and changes a bunch of math nodes from 2D to 3D, though I don't know if that's the plan. For UV maps, I also wonder if users don't already have to specify that they want to output a UV map? Depending on the use case it may not make a difference, but for the UI in the UV editor, exporting to various file formats, you still need to know what is a UV coordinate or some other arbitrary 2D float attribute. An argument in favor of 2D vectors is that MaterialX has them also, although I don't like that design.
Member

@HooglyBoogly I'm not clear on the difference between declaring multi-type sockets and actual 2D sockets. Maybe that's causing confusion on my part. For example, I'm thinking to support 2D in the map range node means adding 2D sockets in addition to the float and 3D vector sockets and the additional boilerplate code. For users, this would mean links and values would also change when switching mode etc. That's why I was suggesting 2D as a UI flag for vector sockets to solve those problems.

@HooglyBoogly I'm not clear on the difference between declaring multi-type sockets and actual 2D sockets. Maybe that's causing confusion on my part. For example, I'm thinking to support 2D in the map range node means adding 2D sockets in addition to the float and 3D vector sockets and the additional boilerplate code. For users, this would mean links and values would also change when switching mode etc. That's why I was suggesting 2D as a UI flag for vector sockets to solve those problems.

Added subscriber: @Carl-Skanoy

Added subscriber: @Carl-Skanoy

Added subscriber: @mod_moder

Added subscriber: @mod_moder

This comment was removed by @mod_moder

*This comment was removed by @mod_moder*

Added subscriber: @Thaina-Yu

Added subscriber: @Thaina-Yu

This option has been exist in blender 2.93 with attribute converter node. I am curious why it was removed ?

This option has been exist in blender 2.93 with attribute converter node. I am curious why it was removed ?
Sign in to join this conversation.
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
10 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#92765
No description provided.