I create this thread because @Nocturnial told me that he did some similar refactorings in his fork of the Render Workbench.
The material changes are similar. Except he uses a dict and I created a RenderMaterial class instead.
I went for a dict before, but I like the class approach more. It has two advantages.
With a dict you have to write “material[‘color’]” with a class you can write “material.color”. I think the later is easier to read. But this might be personal taste.
A class can be extended in the future to have methods. E.g. all renderers for now have the same use for the color. Create a comma separated list of the RGB values. So this could easily be implemented as a “getColorString” method on the RenderMaterial. @Nocturnial solved it by using a DiffuseColor property that is already a string. I think this is less flexible because maybe in the future we have a renderer that needs another representation of colors. Having a list of numbers is easier to transform the having to split a string back into its separate parts.
[quote=Nocturnial post_id=332631 time=1567943645 user_id=26906]
I don’t mind being pinged. But I really don’t understand why you pinged me for comments after you’ve issued a PR instead of before.
[/quote]
Perhaps to review the code?
[quote=Nocturnial post_id=332631 time=1567943645 user_id=26906]
But I really don’t understand why you pinged me for comments after you’ve issued a PR instead of before
[/quote]
As i wrote in the PR it is intented for discussion. Its easier to discuss actual code than simply talk about it.
Github makes it possible to write comments Into the code and stuff like this.
The PR must not be merged. It only needs to be reviewed. When this is the wrong direction we can still close the PR and create a new one.
The only thing I see that needs to be discussed is: should the material be a dict or a separate class. Aftetwards we can continue development separately without getting into conflict i think.
Having a dict to store the data in the class is also fine for me. But i would not use a “getFloat(“xxx”)” approach but instead add dedicated “getXxx()” methods like “getRoughness()” “getTextureFile()” and so on.
Because this gives a dedicated API. Otherwise i can do stuff like “getFloat(“TextureFile”)” and that makes not much sense
[quote=Nocturnial post_id=332809 time=1567980930 user_id=26906]
At the moment, I’m thinking about using a wrapper class around the material dictionary
[/quote]
Using the material dictionary directly will not work. Not everything is inside the core material.
Textures for example are handled by a external workbench. So we need a dedicated RenderMaterial that can have more properties than the native material.
Also roughness alone would not be enough. To get the most out of it, the renderer should support roughness maps also.
Putting everything into the core material might get confusing pretty soon i think.
[quote=Nocturnial post_id=332883 time=1568020425 user_id=26906]
It would make things a lot easier for me if it were that simple.
[/quote]
What should be simple? And what is complicated right now?
[quote=Nocturnial post_id=332883 time=1568020425 user_id=26906]
I’m not going to write a separate function for all those parameters.
[/quote]
When i look at blenders principeld bsdf it has 17 inputs. Where a lot of them are not so relevant i think. So we will end up with 10 dedicated methods. That is not that much in my opinion.
[quote=Nocturnial post_id=332883 time=1568020425 user_id=26906]
just because something has the same name in different shaders doesn’t mean they are the same
[/quote]
I know. When i talk about textures, i mean image files that are applied to the surface of an object.
But in povray “texture” has a totally different meaning. It maps to what we would call Material in FreeCAD.
But neverteless FreeCADs RenderMaterial should have a ImageTexture property and the povray renderer than knows how to transform the meaning of a FreeCAD texture to a povray texture.
Sure, forks are always a good thing. Most of the time it ends up bettering the original project.
About materials, I guess it’s indeed best to tune our minds here first…
Indeed it’s becoming necessary to prepare a structure for render materials.
My own suggestion would be to use FreeCAD materials for just as much as possible. They should contain everything we need: different color values, specific values for shaders, texture paths, etc. Even GLSL code maybe in some future As they can have additional custom values, the possibilities are basically limitless.
And it would allow you to for example, fine-tune a good concrete material, and have it rendering-ready and reuse it in your next models.
The material data is a dictionary https://www.freecadweb.org/wiki/Material so it’s pretty easy to use. I think we should prepare all the different renderers to work with such a dictionary…
Storing everything inside the material makes things easy that is true. But i think we loose a lot of flexibility with this approach.
E.g. with the arch texture workbench we can define multiple textures for the same material. This makes it pretty easy to check how a building looks with different kinds of fronts or roofings. E.g. a green roof with blue stucco walls or better use a grey roof and wooden fronts.
When everything is in the Material this is not possible anymore.
Now I can show you what I had in mind with texturing.
This are two cubes in FreeCAD. One with an Texture applied, the other without a texture.
When rendering the two cubes with the Render Workbench we get a result like this. There are no textures applied
When using the material pipelines I introduced in my branch, we now can get textures in the POV-Ray Renderer. This is the same scene rendered with the TextureConfig in the Material Pipeline of the Render Project.
To make this possible, we need a way to set properties in the Render Material, without touching the actual Material of the object itself. e.g. multiple object can have the same material. But the texture coordinates are different for each object and so they can not be stored inside the material.
Very interesting indeed!
However, I’d like to explore your proposal, to be sure to get all of it:
→ Could someone create a specific branch in the Render WB to explore that?
[quote=Nocturnial post_id=334195 time=1568474046 user_id=26906] @furti I’ve added support for version 2 of luxcore’s file format (SDL). If you’re planning to add support for it, I can do a quick backport so you’ll be able to use it with your code.
[/quote]
I will not have the time to implement textures for all renderers now. But making your improvements available for the upstream Renderer Workbench would be a cool thing in any case
[quote=Nocturnial post_id=334876 time=1568770666 user_id=26906]
Once I have implemented enough features, I should have a better understanding of what is needed.
[/quote]
Currently im thinking of something like that
[code] class RenderMaterial:
Def init(self, material):
self.material = material
self.overrides = {}
Def getValue(name):
If name in self.overrides:
Return self.overrides[name]
Return self.material[name]
Def setValue(name, value):
Self.overrides[name] = value
[/code]
This would have the advantage that the freecad material could be reused as much as possible and other workbenches have the possibility to override stuff on a per object basis.
+1 for @Nocturnial, your renderings are really amazing, especially Glass Materials!!!
@furti: I tried to test your code on my computer but I didn’t succeed: my fault, I think I get lost in branches, so I’m gonna wait for you to push your code upstream (very impatient).
However, looking at your work, it aroused me a question: shouldn’t your Arch Texture WB be merged into Render WB (as texturing is usually part of rendering workflow)?
I think the scope is different. Arch Texture provides basic rendering support, to see the results in the very 3D viewport of FreeCAD. It is not meant for photorealistic results.
The Render workbench is meant to prepare what you see in FreeCAD for use with a dedicated renderer. So, development is happening in parallel. Arch Texture does something, and Render picks up from there.
Furti is contributing to both projects where it makes sense:
I did use POV-Ray! But something went wrong somewhere in the workflow, and there was no texture in the resulting exported .pov file (and no texture rendered, of course). Unfortunately I didn’t have enough time to investigate more. However, don’t worry, it must certainly come from a misunderstanding of my part, or a problem of version in the branches I picked… If I find some time more, I’ll try again.
My proposition to merge was motivated by the following thoughts:
Basic rendering and external rendering are both about rendering, so it could be convenient for the user to have them in the same place. Material setting is a nearly-mandatory step if one wants a qualitative rendering, so we may want to simplify the workflow for the user : Arch/Part to create the object, Render to get it rendered (basic/external), including tweaking of Render Material
‘Arch Texture’ name may be misleading, because in the future we may want to texture and render objects (like parts…) that are not Arch objects…
But I agree there can be other approaches…
@furti and @nocturnial: Thank you, I finally succeeded, with your help!
Here is the result:
As you see, I dressed a cube with a Marble texture, a cube with a Wood texture, and a cylinder with the same Marble texture as the first cube… (all textures picked from Internet).
I’ll write some more comments later (for instance, you can see something weird happens to the cylinder), but to me, at this stage, there is something cool in @furti’s proposal!