Skip to content

feat: manual base texture selection before read textures from shading nodes - #394

Open
Aslan-M2 wants to merge 4 commits into
StjerneIdioten:developfrom
Aslan-M2:develop
Open

feat: manual base texture selection before read textures from shading nodes#394
Aslan-M2 wants to merge 4 commits into
StjerneIdioten:developfrom
Aslan-M2:develop

Conversation

@Aslan-M2

@Aslan-M2 Aslan-M2 commented Apr 6, 2026

Copy link
Copy Markdown

Adds a selection for base textures in the Material Properties tab. If textures are selected here, they will be used preferentially instead of being read from the shading nodes. This resolves the issue when textures are not directly connected to the shader but are instead distributed across multiple nodes.

Aslan-M2 added 4 commits April 3, 2026 10:38
… nodes

Adds a selection for base textures in the Material Properties tab. If textures are selected here, they will be used preferentially instead of being read from the shading nodes. This resolves the issue when textures are not directly connected to the shader but are instead distributed across multiple nodes.
@StjerneIdioten

Copy link
Copy Markdown
Owner

@Aslan-M2 Did you make any other changes from the other PR other than which branch it goes to? 😅

@Aslan-M2

Aslan-M2 commented Apr 7, 2026

Copy link
Copy Markdown
Author

yes, addon/i3dio/node_classes/material.py and addon/i3dio/ui/shader_picker.py

Sorry, pull requests for open-source projects are new to me regarding GitHub. I don't know if I did everything correctly, but both files should be updated.

@StjerneIdioten

Copy link
Copy Markdown
Owner

@NMC-TBone Any thoughts on this?

@Aslan-M2

Aslan-M2 commented Apr 7, 2026

Copy link
Copy Markdown
Author
image

Unless I've missed something, it only loads the base textures via the shader nodes. If they aren't directly connected, they remain empty. With this "update," you can now select the textures directly and definitively for the base textures.

@StjerneIdioten

Copy link
Copy Markdown
Owner

Unless I've missed something, it only loads the base textures via the shader nodes. If they aren't directly connected, they remain empty. With this "update," you can now select the textures directly and definitively for the base textures.

No that is accurate, it comes from a simpler version of the shader stuff back in the early Blender 2.8 days and the first exporter. The idea was to integrate it more directly with Blender and since you would set those textures in the shader nodes to show them in the Blender viewport anyway, I would just pull them from there.

@NMC-TBone

Copy link
Copy Markdown
Contributor

Hmm, I have been thinking about this for a little bit now. I think the general direction makes sense. Currently the exporter reads the classic base textures from the BSDF shader node setup, which is fine for people already comfortable with Blender materials and all that stuff, but it is not always the most discoverable workflow for newer modders.
That said, I am not 100% convinced by the implementation yet😅

My main concern is that this introduce a "second source of truth". The node tree can say one thing, while the new props say something else. That could potentially be a confusion thing to some people.

At the same time, I do think there is a great value in exposing these textures directly in the props panel. Not only for discoverability, but also because it could give the exporter a more explict place to read/get the data from. that could simplify the exporter quite a bit and also make addons like material visualizer more reliable since everything can be synced from one "known place" instead of trying to capture already added nodes in the node tree etc.

So IMO, the main question is whether these props should be:

  • The main place to assign the base textures, with an operator or sync logic to push them to and/or read them from the shader nodes, or
  • Clearly option export overrides, while the current node-driven workflow remiains the default (like this PR propose)

If we add this, I think we should try to be a bit careful not to keep two equal workflows forever. That will give us more code to maintain and more questions about what is actually considered the "right workflow".

The UI/props could utilize the layout.templateID() to make it look the same as other image related stuff in blender
image

There are also few followup questions that likely also could occur if we go in this direction. For example if base texutres become properties, should other related values like normal strenght/bump depth, smoothness, metalness etc also get their own props?
image

To be clear, I like the direction. I just think it would be good to refine the workflow a bit before merging it and ensure that this will be a solid long-term solution.

I really do think there is something appealing about the exporter not needing to inspect the shader nodes for these "base maps" at all and instead reading them directly from predef props. That would reduce a lot of special handling on the export side of things. The tradeoff is of course that it moves a bit away from the workflow Blender users are generally used to and other pipelines/exporters/importers use. Even if it beceomes more expliect and closer to something you would see in Giants Editor.

@Aslan-M2

Aslan-M2 commented Apr 7, 2026

Copy link
Copy Markdown
Author

I’m not entirely sure if I understood everything correctly, since I had the text translated into German using Google Translate.

But regarding the workflow: I’m not a Blender professional or a trained/studied 3D modeler. I can only speak from my own workflow. For example, when building infrastructure or objects where you want to visualize vMasks directly in Blender, you end up not having the texture nodes directly connected to the Principled BSDF anymore. Instead, there are several nodes in between that mix things and so on. In that case, reading the base textures from the shader nodes no longer works.

In my infrastructure example, I created nodes that visualize the vertex colors from the vertexPaintShader. That means I can clearly see where blending textures run and where the snow texture overlay is located. To do this, I have to configure several nodes. Since I don’t want to constantly reconfigure shader nodes for every export, or reassign the base textures for 10 materials in the Giants Editor, I added an optional feature where you can directly link the base textures.

The textures for shaders are already linked via direct selection. My change keeps the current system, where textures are retrieved from the shader nodes, but it prioritizes those that are specified in the material properties.

5fc8e2c5db0105db495e9d1c4cf13dba

@NMC-TBone

Copy link
Copy Markdown
Contributor

Spent some more time thinking about this, and I realized there is another common modding workflow where this could be really useful.
A common problem is sharing blend files with other people, or having multiple people contribute to the same blend file. Textures used from game files often don't follow the blend file, unless they are packed into the file. But packing does not really solve the export-side problem either, because we still want the original data/game relative path to be preserved, e.g. as a $data/.... path.

So having the base texture paths stored explicitly as material/shader properties could be a big improvement. If a texture comes from the set game data directory, similar to how shader paths are handled, we could store it as a normalized $data/... path instead of relying on whatever Blender node/image setup happens to exist.

Then the material graph could become more of a viewport/preview representation, rather than the "source of truth" for export. We could have operators such as:

  • Pull base textures from the current material nodes into the I3D material properties
  • Push/apply the I3D material properties back into the Blender material graph for preview/editing
    (only with use of BSDF)

That would also avoid some of the "second source of truth" problem I mentioned earlier, because the explicit I3D material properties could become the exporters known source of truth, while the node tree is something that can be synced from/to those properties without having an impact on the exported result.

This will require a bigger change compared to the current PR, but I think it could be a really solid long-term direction. Especially for shared blend files, material visualizer workflows, and preserving proper game relative paths.

Wonder what @StjerneIdioten thinks about that?

@StjerneIdioten

Copy link
Copy Markdown
Owner

Wonder what @StjerneIdioten thinks about that?

Since I don't actually model, I don't know what would help people the most 😅 I don't think the texture fields should "override" anything, but more that if the BSDF node is present it should be set through it and otherwise we can show them if you don't have that node.

StjerneIdioten pushed a commit that referenced this pull request May 6, 2026
This will improve file path resolving during export by separating source path validation from the path written into the exported I3D. This makes the file export logic more reliable for Blender-relative paths, absolute paths and farm sim $data paths.

Added few new utility helpers that likely will be useful if we decide to go for the route I wrote here #394 (comment)

    Added validation for registered file paths before writing I3D file references
    Improved handling of missing/invalid teture paths
    Fixed the BLENDER copy strategy so it preserves paths relative to the .blend file folder
    Fixed an issue where aboslute path parts and filenames could accidnetally be treated as destination folders

e.g.
If a blender image node still contains a path to a deleted or moved texture:
//textures/missing_diffuse.dds
the exporter now warns that the source file does not exist, instead of silenetly writing a broken file reference into the I3D.

$data texture paths:
$data/shared/default_normal.dds
These paths are still written as $data/... in the exported I3D and are never copied, but the exporter will now validate them against the configured FS data path so we can warn the user about possible wrongly written path or simply invalid game asset.

BLENDER copy strategy:
e.g. a mod structure like:

myMod/
  shared/
    myShared_normal.dds
  vehicles/
    myVehicle1/
      myVehicle1.blend
      myVehicle1.i3d

a texture referenced from the blend file as:
../../shared/myShared_normal.dds
is now copied/exported with the same relative structure, so the I3D keeps a valid reference ot the shared texture.
Previously, absolute path parts or the filename itself could accidentally become destination folders, producing invalid nested output like:
export/USER/Desktop/.../work/fuelSafe_normal.dds/fuelSafe_normal.dds
@Aslan-M2

Aslan-M2 commented May 7, 2026

Copy link
Copy Markdown
Author

As I mentioned, the nodes are indeed for shading purposes in Blender. For simple models, you can certainly access them there; however, for more complex assets—such as buildings with all their various masks and so forth—the node setups appear significantly more extensive when you work directly within Blender using tools like Texture Paint. The same applies to my example regarding the roads: I want to be able to visualize where the snow is directly within Blender—hence the need for all those nodes.

I would suggest a hybrid approach: as a primary step, the system checks against a set of fixed values ​​(similar to my setup); if no textures are specified there, it then looks to the BSDF node. If nothing is found there either, it should simply leave the slot empty or handle it accordingly.

@StjerneIdioten

Copy link
Copy Markdown
Owner

As I mentioned, the nodes are indeed for shading purposes in Blender. For simple models, you can certainly access them there; however, for more complex assets—such as buildings with all their various masks and so forth—the node setups appear significantly more extensive when you work directly within Blender using tools like Texture Paint. The same applies to my example regarding the roads: I want to be able to visualize where the snow is directly within Blender—hence the need for all those nodes.

I would suggest a hybrid approach: as a primary step, the system checks against a set of fixed values ​​(similar to my setup); if no textures are specified there, it then looks to the BSDF node. If nothing is found there either, it should simply leave the slot empty or handle it accordingly.

I agree with having it check for "overrides" first like how you have it. Then check the BSDF node and finally either default or fail.

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.

3 participants