Architecture Texture Coordinates in Cycles #48699

Open
opened 2016-06-21 14:55:50 +02:00 by Dalai Felinto · 20 comments

Hello dear Cycles team and developers :)

I've been working in an archiviz project and stumbled upon a short come of Cycles: we don't have a straightforward way of setting world-based-dimensioned textures . This is a must for architecture, and I can give a few real-world use cases if requested.

As a Blender user I came up with a node system that can handle this. You can check my approach here: http://www.dalaifelinto.com/?p=1198. Basically what this does it to take the Object texture coordinate and transform it based on the face normal (so we have an unstretched mapping for X, Y and Z).

As a Blender/Cycles developer I think we can do even better, and have this feature into master once we agree on the design and approach for the implementation.

I wonder why this never came up before as an issue. As a side note, if you read the Expose 3D Blender migration post on BlenderNation (http://www.blendernation.com/2016/06/21/story-expose-3d-established-3d-visualization-company-switch-blender-entirely/) you will find that they consider the "Lack of architectural UV mapping" as the number one "flaw" of Cycles rendering.

My initial suggestion would be to have a Node where you could control (via socket input) the offset, scale and rotation of the texture. At first I would like to keep it simple and have offset to be a Vector(2), Scale to be a Vector(2), and Rotation to be a Float. In other words, I wouldn't bother with having per-axis nitty-gritty control. Also, the object size should NOT affect the texture size (unlike my original approach, or even the one from the "Sure UVW mapping” addon used by the Expose 3D team). I'm not sure if this last bit is possible though.

Any thoughts?

Hello dear Cycles team and developers :) I've been working in an archiviz project and stumbled upon a short come of Cycles: we don't have a straightforward way of setting world-based-dimensioned textures . This is a must for architecture, and I can give a few real-world use cases if requested. As a Blender user I came up with a node system that can handle this. You can check my approach here: http://www.dalaifelinto.com/?p=1198. Basically what this does it to take the Object texture coordinate and transform it based on the face normal (so we have an unstretched mapping for X, Y and Z). As a Blender/Cycles developer I think we can do even better, and have this feature into master once we agree on the design and approach for the implementation. I wonder why this never came up before as an issue. As a side note, if you read the Expose 3D Blender migration post on BlenderNation (http://www.blendernation.com/2016/06/21/story-expose-3d-established-3d-visualization-company-switch-blender-entirely/) you will find that they consider the "Lack of architectural UV mapping" as the number one "flaw" of Cycles rendering. My initial suggestion would be to have a Node where you could control (via socket input) the offset, scale and rotation of the texture. At first I would like to keep it simple and have offset to be a Vector(2), Scale to be a Vector(2), and Rotation to be a Float. In other words, I wouldn't bother with having per-axis nitty-gritty control. Also, the object size should NOT affect the texture size (unlike my original approach, or even the one from the "Sure UVW mapping” addon used by the Expose 3D team). I'm not sure if this last bit is possible though. Any thoughts?
Author
Owner

Changed status to: 'Open'

Changed status to: 'Open'
Author
Owner

Added subscriber: @dfelinto

Added subscriber: @dfelinto

Added subscriber: @SteffenD

Added subscriber: @SteffenD
Member

Added subscriber: @MartijnBerger

Added subscriber: @MartijnBerger
Member

I am unsure how robust your approach is to the corner alignment problem but even if it is 100% robust I am still not sure we might not want to keep the generation for this on the blender side of things.

For some kinds of textures in combination with artistic preferences it likely will remain needed to be able to manually tweak things.

I think a way to force world scale on textures independent of what the object scale may be. or to unwrap to world-scale / unwrap with these architectural properties kept intact could also solve this issue.

I am unsure how robust your approach is to the corner alignment problem but even if it is 100% robust I am still not sure we might not want to keep the generation for this on the blender side of things. For some kinds of textures in combination with artistic preferences it likely will remain needed to be able to manually tweak things. I think a way to force world scale on textures independent of what the object scale may be. or to unwrap to world-scale / unwrap with these architectural properties kept intact could also solve this issue.
Member

Added subscriber: @jesterking

Added subscriber: @jesterking
Member

For RhinoCycles we have implemented a set of texture coordinates that might be useful for this:

WCS Box
Env Spherical
Env EMap
Env Light probe
Env Box
Env Cubemap
Env Cubemap Vertical Cross
Env Cubemap Horizontal Cross
Env Hemispherical

This probably covers most of what you want.

I can prepare a patch for the Cycles side. The Blender side still needs adding, since we didn't need that.

https://github.com/mcneel/cycles/blob/ccsycles_rhino/src/kernel/svm/svm_tex_coord.h

nodes.cpp : https://github.com/mcneel/cycles/blob/ccsycles_rhino/src/render/nodes.cpp#L2616

edit: almost forgot to mention that to successfully use this we added also a MatrixMathNode:
https://github.com/mcneel/RhinoCycles/blob/master/RenderEngine.Utils.cs#L175
https://github.com/mcneel/cycles/blob/ccsycles_rhino/src/render/nodes.h#L866
https://github.com/mcneel/cycles/blob/ccsycles_rhino/src/render/nodes.cpp#L4245
https://github.com/mcneel/cycles/blob/ccsycles_rhino/src/kernel/svm/svm_math.h#L49

For RhinoCycles we have implemented a set of texture coordinates that might be useful for this: WCS Box Env Spherical Env EMap Env Light probe Env Box Env Cubemap Env Cubemap Vertical Cross Env Cubemap Horizontal Cross Env Hemispherical This probably covers most of what you want. I can prepare a patch for the Cycles side. The Blender side still needs adding, since we didn't need that. https://github.com/mcneel/cycles/blob/ccsycles_rhino/src/kernel/svm/svm_tex_coord.h nodes.cpp : https://github.com/mcneel/cycles/blob/ccsycles_rhino/src/render/nodes.cpp#L2616 edit: almost forgot to mention that to successfully use this we added also a MatrixMathNode: https://github.com/mcneel/RhinoCycles/blob/master/RenderEngine.Utils.cs#L175 https://github.com/mcneel/cycles/blob/ccsycles_rhino/src/render/nodes.h#L866 https://github.com/mcneel/cycles/blob/ccsycles_rhino/src/render/nodes.cpp#L4245 https://github.com/mcneel/cycles/blob/ccsycles_rhino/src/kernel/svm/svm_math.h#L49

Added subscriber: @bliblubli

Added subscriber: @bliblubli

Not only for architecture would it be a great addition. It would save a lot of time for many artists. Maybe a UV modifier would be an even better solution to make it real time, view-port ready and compatible with all rendering engines out of the box.
But the node solution from Nathan is already done and gives more flexibility for artists as mentioned by Martijn, so it looks like the best solution.

Not only for architecture would it be a great addition. It would save a lot of time for many artists. Maybe a UV modifier would be an even better solution to make it real time, view-port ready and compatible with all rendering engines out of the box. But the node solution from Nathan is already done and gives more flexibility for artists as mentioned by Martijn, so it looks like the best solution.

Added subscriber: @brecht

Added subscriber: @brecht

To specify lengths in world space and align to the corner of the bounding box, it should be possible to start from generated coordinates, which are normalized 0..1 inside the bounding box. The generated coordinates can be projected based on the object space normal, and then scaled to account for the normalized to object and object to world space transforms.

The object to world space matrix is available to shaders, and the ATTR_STD_GENERATED_TRANSFORM or generated_transform attribute gives you an object space to normalized space matrix. To me that seems enough information to implement this in a shader. For efficiency, scaling could be precomputed and stored as an attribute, but it's not strictly required to get this working.

A UV modifier would not be able to account for object to world space scaling. Having the world space length specified in the material nodes also seems easier if you want to build a collection of materials and reuse them easily, you could just apply the material and get the correct scale without having to remember to add a modifier.

Some other ideas:

  • The Vector Transform node could support the normalized space at some point too, if someone wants to make a custom node group to do mappings like this.
  • Rounding the scale factor to an integer could be useful for some types of textures, if you want e.g. floor tiles to fit exactly and are ok with the world space length being slightly different than specified.
  • For the UI, perhaps this could fit with the mapping options built into each Cycles texture node, with some way to specify the texture coordinates without having to add more nodes. We should really make those more discoverable in the UI though. Currently they can only be edited in the properties editor texture tab, when a texture node is active. They are not visible in the node editor, maybe they should be in a popup or panel.
To specify lengths in world space and align to the corner of the bounding box, it should be possible to start from generated coordinates, which are normalized 0..1 inside the bounding box. The generated coordinates can be projected based on the object space normal, and then scaled to account for the normalized to object and object to world space transforms. The object to world space matrix is available to shaders, and the `ATTR_STD_GENERATED_TRANSFORM` or `generated_transform` attribute gives you an object space to normalized space matrix. To me that seems enough information to implement this in a shader. For efficiency, scaling could be precomputed and stored as an attribute, but it's not strictly required to get this working. A UV modifier would not be able to account for object to world space scaling. Having the world space length specified in the material nodes also seems easier if you want to build a collection of materials and reuse them easily, you could just apply the material and get the correct scale without having to remember to add a modifier. Some other ideas: * The Vector Transform node could support the normalized space at some point too, if someone wants to make a custom node group to do mappings like this. * Rounding the scale factor to an integer could be useful for some types of textures, if you want e.g. floor tiles to fit exactly and are ok with the world space length being slightly different than specified. * For the UI, perhaps this could fit with the mapping options built into each Cycles texture node, with some way to specify the texture coordinates without having to add more nodes. We should really make those more discoverable in the UI though. Currently they can only be edited in the properties editor texture tab, when a texture node is active. They are not visible in the node editor, maybe they should be in a popup or panel.

Added subscriber: @BartekMoniewski

Added subscriber: @BartekMoniewski

Added subscriber: @DuarteRamos

Added subscriber: @DuarteRamos

Please forgive me if I am missing something trivial here, but I am an architect working daily in Blender and rendering in Cycles (hell I am doing it right this very moment ;) ) and for a very very very long time I ached for something like this in Blender.
It was my number one feature request for a while, I also though I wanted that "UV Modifier" like 3DSMax has one, and I even went through Sure UVW mapping addon and alikes. That is until I learned how to use nodes properly.

Isn't all this solved simply by using "Object Coordinates" from the Input > Texture Coordinates node ?
That is what it does, it gives you texture sizing options in Blender scene units virtually allowing you to define real-world-size for images in scene units.
Only problem remaining is when objects are not uniformly scaled, which is quickly solved by applying a Vector Transform node from Local to World coordinates to the output of the Object socket.

Ever since I found out about this I never looked back and I use it daily to set size to textures for my arch viz projects. Particularly useful for ceramic tile, or woodboards, etc which usually have precise measurements like 2m per 20 cm or the like. It even works perfectly for procedural textures like cycles bricks, no need for particularly complex node setups and workarounds.

Again please forgive me if I missed something but it seems we are talking about the same thing and it's a problem I haven't really had for a while now.

Please forgive me if I am missing something trivial here, but I am an architect working daily in Blender and rendering in Cycles (hell I am doing it right this very moment ;) ) and for a very very very long time I ached for something like this in Blender. It was my number one feature request for a while, I also though I wanted that "UV Modifier" like 3DSMax has one, and I even went through Sure UVW mapping addon and alikes. That is until I learned how to use nodes properly. Isn't all this solved simply by using "Object Coordinates" from the *Input > Texture Coordinates* node ? That is what it does, it gives you texture sizing options in Blender scene units virtually allowing you to define real-world-size for images in scene units. Only problem remaining is when objects are not uniformly scaled, which is quickly solved by applying a *Vector Transform* node from *Local* to *World* coordinates to the output of the *Object* socket. Ever since I found out about this I never looked back and I use it daily to set size to textures for my arch viz projects. Particularly useful for ceramic tile, or woodboards, etc which usually have precise measurements like 2m per 20 cm or the like. It even works perfectly for procedural textures like cycles bricks, no need for particularly complex node setups and workarounds. Again please forgive me if I missed something but it seems we are talking about the same thing and it's a problem I haven't really had for a while now.

Added subscriber: @Sergey

Added subscriber: @Sergey

@DuarteRamos it works great as long as you have angles near the 90° everywhere in you object and your mash is not rotated, only the object containing it. As soon as you import a model with faces not following the world axis or have faces with complicated orientation, etc... the simple node setup you mention will give noticeable distortions. For cubic architecture, it works, but if you model with nurbs/curves or anything not cubic, it just can't do it properly. Or you have to send me your nodegroup :)

@DuarteRamos it works great as long as you have angles near the 90° everywhere in you object and your mash is not rotated, only the object containing it. As soon as you import a model with faces not following the world axis or have faces with complicated orientation, etc... the simple node setup you mention will give noticeable distortions. For cubic architecture, it works, but if you model with nurbs/curves or anything not cubic, it just can't do it properly. Or you have to send me your nodegroup :)

Ah I see, that's right. I did manage to make my own "Cube Mapping" custom node that masks he mesh faces through normals and applies the correct projection to the face.
It can easily be modified to fade smoothly between normals and with an even more complex node setup it could have more "normal steps" for more accurate projections on curved surfaces, but as you mentioned it will create visible seams and is bound to fail sooner or later if the mesh is more complex.

One small complaint I do still have which, I'm not sure, but I think may fit in this discussion is the fact that the Bricks procedural texture is particularly hard to use on non planar meshes, at least without unwrapping first, which partially defeats one the the appeals of procedural textures: not having to unwrap.

Since it is always projected from one axis the same node setup can never be applied successfully on say a mesh comprised of walls (vertical surfaces) and floors (horizontal surfaces) as is often the case.
I mean I can happily use it with my above mentioned custom cube mapping node (it was the reason I created it in the first place), but a native solution not requiring workarounds would be desirable. For example it would be nice if the bricks texture was "volumetric" by nature like 3Ds Max's "Tiles" texture.

If you like I'd be happy to share my node setup

Ah I see, that's right. I did manage to make my own "Cube Mapping" custom node that masks he mesh faces through normals and applies the correct projection to the face. It can easily be modified to fade smoothly between normals and with an even more complex node setup it could have more "normal steps" for more accurate projections on curved surfaces, but as you mentioned it will create visible seams and is bound to fail sooner or later if the mesh is more complex. One small complaint I do still have which, I'm not sure, but I think may fit in this discussion is the fact that the *Bricks* procedural texture is particularly hard to use on non planar meshes, at least without unwrapping first, which partially defeats one the the appeals of procedural textures: not having to unwrap. Since it is always projected from one axis the same node setup can never be applied successfully on say a mesh comprised of walls (vertical surfaces) and floors (horizontal surfaces) as is often the case. I mean I can happily use it with my above mentioned custom cube mapping node (it was the reason I created it in the first place), but a native solution not requiring workarounds would be desirable. For example it would be nice if the bricks texture was "volumetric" by nature like 3Ds Max's "Tiles" texture. If you like I'd be happy to share my node setup

@dfelinto Your nodesetup gives strong distortions on an icosphere for some faces. Some other are good. So it doesn't really take the face normals to project the texture if I'm right?
icosphere.PNG made using brick texture from here: http://episcura.com/site/?id_project=936&c=0ce2d83d&utm_source=Episcura+Mailing+List&utm_campaign=5bb60b791e-Uncharted_TexturePack&utm_medium=email&utm_term=0_e5abd4945a-5bb60b791e-66905225&ct=t(Uncharted_Pack)&mc_cid=5bb60b791e&mc_eid=ba686934a3
@DuarteRamos Yes, would be good to compare with dfelinto 's one.

@dfelinto Your nodesetup gives strong distortions on an icosphere for some faces. Some other are good. So it doesn't really take the face normals to project the texture if I'm right? ![icosphere.PNG](https://archive.blender.org/developer/F318932/icosphere.PNG) made using brick texture from here: http://episcura.com/site/?id_project=936&c=0ce2d83d&utm_source=Episcura+Mailing+List&utm_campaign=5bb60b791e-Uncharted_TexturePack&utm_medium=email&utm_term=0_e5abd4945a-5bb60b791e-66905225&ct=t(Uncharted_Pack)&mc_cid=5bb60b791e&mc_eid=ba686934a3 @DuarteRamos Yes, would be good to compare with dfelinto 's one.

Sorry for the delay in replying, here is my node group setup for cycles cube mapping.

It basically "masks" the mesh faces by normal, so the correct mapping projection can be applied to each face according to the direction it is facing or it's angle.
It can be used along with the regular Vector Mapping node for further non-destructive adjustments outside the group, and has an additional control for the rotation of the side mapping. I often need it for using directly on bezier curve objects, depending on their orientation in the scene (screenshots 1 and 2).

Cycles_CubeMaping_A.jpg Cycles_CubeMaping_B.jpg

It works fairly well for relatively orthogonal objects, but of course it creates visible seams in curvy or more organic shapes.
The three Greater Than nodes in the "Masking Normals" frame could easily be replaced by a color ramp for a smooth transition, instead of a hard break.

Curiously the other day some question came up at Blender Stack Exchange with the same problem I tried to solve with this node setup, but someone else got to it before I did

Sorry for the delay in replying, here is my node group setup for cycles cube mapping. It basically "masks" the mesh faces by normal, so the correct mapping projection can be applied to each face according to the direction it is facing or it's angle. It can be used along with the regular *Vector Mapping* node for further non-destructive adjustments outside the group, and has an additional control for the rotation of the side mapping. I often need it for using directly on bezier curve objects, depending on their orientation in the scene (screenshots 1 and 2). ![Cycles_CubeMaping_A.jpg](https://archive.blender.org/developer/F319123/Cycles_CubeMaping_A.jpg) ![Cycles_CubeMaping_B.jpg](https://archive.blender.org/developer/F319124/Cycles_CubeMaping_B.jpg) It works fairly well for relatively orthogonal objects, but of course it creates visible seams in curvy or more organic shapes. The three *Greater Than* nodes in the "Masking Normals" frame could easily be replaced by a color ramp for a smooth transition, instead of a hard break. Curiously the other day some question came up at [Blender Stack Exchange ](http://blender.stackexchange.com/questions/56867/how-can-i-fix-this-generated-coordinated-texture-wrap/56870#56870) with the same problem I tried to solve with this node setup, but someone else got to it before I did

Added subscriber: @makizar

Added subscriber: @makizar
Brecht Van Lommel added this to the Render & Cycles project 2023-02-07 19:08:35 +01:00
Philipp Oeser removed the
Interest
Render & Cycles
label 2023-02-09 13:56:48 +01:00
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 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#48699
No description provided.