I know OSL wants to be all pure and fancy and the shader gaph be a pure DAG - and I can see the theoretical purity in that - but artists keep asking me for these things.And I don't think it's impossible, really. It can be done in a well-defined way.What am I talking about? About Treating attached shader inputs effectively as a "subroutine", to be able to "call" it with overridden globals, maybe even multiple times.
On u / v ... you took a little too much out of a simplified example....Besides, the model isn't "mess with global variables" in the uncontrolled way you are insinuating.Rather, it is a well-defined, cleanly scoped, temporary modification of state (parameters or "globals") while re-running code with a well defined set of parameters.
(Besides, it's not my fault OSL is working with a concept of "magical globals" - one of the parts of the language I dislike the most) :)
This is extremely useful in an insane number of cases. The "ShittyBlur" example was just the 1st that popped up in my head and was an easy way to describe what I mean conceptually in a simple example. Don't take it too literally...
--
You received this message because you are subscribed to the Google Groups "OSL Developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email to osl-dev+unsubscribe@googlegroups.com.
To post to this group, send email to osl...@googlegroups.com.
Visit this group at https://groups.google.com/group/osl-dev.
For more options, visit https://groups.google.com/d/optout.
To unsubscribe from this group and stop receiving emails from it, send an email to osl-dev+u...@googlegroups.com.
To post to this group, send email to osl...@googlegroups.com.
Visit this group at https://groups.google.com/group/osl-dev.
For more options, visit https://groups.google.com/d/optout.
I hear you guys and understand what you want: a way to take a shader node graph and call it like a subroutine, potentially multiple times with differing parameters.
I'm not a fan of "every time you grab a parameter, it magically re-evaluates the upstream network", because it's just a recipe for confusion and wasted computation. I won't even go into the details, but suffice it to say that I can rattle off edge cases where optimizations we depend on would be ruined.
But Zap's idea of some kind of explicit evaluate(paramname, ...) has merit and is possibly growing on me. It's a sharp tool that can easily be used to hurt yourself,
but at least it can never truly surprise you -- things can only re-execute if you call it, and it's very visible when you do this. It's still fraught with danger, details that we'd need to ponder, and some limitations we'd want to impose. As examples:
* Presumably it would invalidate the results *all the way up the chain* from the parameter being pulled?
* You would probably only be allowed to set new values of parameters (of the upstream subnet) that were previously marked as `lockgeom=0`, or else they might have been constant-folded away. (Unless, ick, you assume that any subnets that are potentially named by evaluate() would have wholesale drastically less optimization done to them.)
* If results from that multiply-executed subnet are used elsewhere in the network (I mean, one of its outputs is connected to some other input elsewhere, besides the things getting an evaluate() call), then the fact that the evaluation *order* of nodes is nondeterministic means that you won't know which of the output values (from the potentially several times it was called) will end up copied to other places. So maybe it's only safe/predictable to do this if the subnet in question ONLY connects to the node that is doing the evaluate() call. It probably also follows that nodes in a subnet implicated by an evaluate() call would not be able to participate in the "identical node deduplication" optimization that we currently do.
Now, as an aside, I just realized that a lot of your fantasy feature may be partially fulfilled with the "osl.imageio". Are you familiar with that?
// A simple Mandelbrot set generator shader
// mandelbrot.osl by Zap Andersson
// Modified: 2018-02-08
// Copyright 2018 Autodesk Inc, All rights reserved. This file is licensed under Apache 2.0 license
// https://github.com/ADN-DevTech/3dsMax-OSL-Shaders/blob/master/LICENSE.txt
shader Mandelbrot
[[ string help = "A four dimensional mandelbrot/julia set generator" ]]
(
vector UVW = vector(u,v,0)
[[ string help = "The coordinate to look up. Defaults to the standard UV channel" ]],
vector Center = 0,
float Scale = 0.35,
float ZImaginary = 0.0,
int Iterations = 100,
float ColorScale = 1.0,
float ColorPower = 1.0,
output color Col = 0,
output float Fac = 0.0,
)
{
vector pnt = (UVW - point(0.5,0.5,0)) / Scale - (Center + point(0,0.66,0));
float cR = pnt[0];
float cI = pnt[1];
float zR = pnt[2];
float zI = ZImaginary / Scale;
int num = 0;
for (num = 0; num < Iterations; num++)
{
float zR2 = zR * zR; // Real squared
float zI2 = zI * zI; // Imag. squared
if (zR2+zI2 > 4.0)
break; // Escapes to infinity
zI = 2 * zR * zI + cR;
zR = zR2 - zI2 + cI;
}
Fac = (float)(num * ColorScale)/ (float)Iterations;
Col = wavelength_color(420 + pow(Fac, ColorPower) * 2000);
}
I was able to render this volumetrically into this fancy movie:
https://www.youtube.com/watch?v=dNX4yhW3CJ0
But that thing was tediously rendered in Arnold w. actual volumetric shading.
I realized that I could probably fake it 1000 times faster by making my own hacky raymarcher.
But since we are lacking evaluate function, the only way to do it would be to literally hand-rewrite the shader like this:
void mandelbrot
(
vector UVW,
vector Center,
float Scale,
float ZImaginary,
int Iterations,
float ColorScale,
float ColorPower,
output color Col ,
output float Fac,
)
{
vector pnt = (UVW - point(0.5,0.5,0)) / Scale - (Center + point(0,0.66,0));
float cR = pnt[0];
float cI = pnt[1];
float zR = pnt[2];
float zI = ZImaginary / Scale;
int num = 0;
for (num = 0; num < Iterations; num++)
{
float zR2 = zR * zR; // Real squared
float zI2 = zI * zI; // Imag. squared
if (zR2+zI2 > 4.0)
break; // Escapes to infinity
zI = 2 * zR * zI + cR;
zR = zR2 - zI2 + cI;
}
Fac = (float)(num * ColorScale)/ (float)Iterations;
Col = wavelength_color(420 + pow(Fac, ColorPower) * 2000);
}
shader Mandelbrot
[[ string help = "A four dimensional mandelbrot/julia set generator" ]]
(
float start = 0.0,
float end = 100.0,
int steps = 10,
vector UVW = vector(u,v,0)
[[ string help = "The coordinate to look up. Defaults to the standard UV channel" ]],
vector Center = 0,
float Scale = 0.35,
float ZImaginary = 0.0,
int Iterations = 100,
float ColorScale = 1.0,
float ColorPower = 1.0,
output color Col = 0,
output float Fac = 0.0,
)
{
float fac = 0.0;
color col = 0.0;
float delta = (end - start) / steps;
for (int i = 0; i < steps; i++)
{
point pt = P + I * (start + delta * (i + noise("uperlin", P*10000)));
float z = pt[2];
pt[2] = 0.0;
mandelbrot(pt, Center, Scale, z, Iterations, ColorScale, ColorPower, col, fac);
Fac += fac;
Col += col;
}
Col /= steps;
Fac /= steps;
}
I had to rewrite the "shader" Mandelbrot to the "sub-function" mandelbrot, and then call this N times from my main shader instead, effectivly forcing me to build my 3d texture INTO my ray marcher.... That's silly, I shouldn't have had to do that!
Had there been an "evaluate" function, I would just have plugged my regular Mandelbrot into my raymarcher and, as they say, Bob would have been my Fathers Brother.
It would have *worked* exactly the same. The final optimized backend shading code would probably be identical to this case... but it would have been much more useful and flexible to the user, and much easier on the shader developer....
/Z
I realized that I could probably fake it 1000 times faster by making my own hacky raymarcher.
But since we are lacking evaluate function, the only way to do it would be to literally hand-rewrite the shader like this:
--
You received this message because you are subscribed to the Google Groups "OSL Developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email to osl-dev+u...@googlegroups.com.
To post to this group, send email to osl...@googlegroups.com.
Visit this group at https://groups.google.com/group/osl-dev.
For more options, visit https://groups.google.com/d/optout.
--
You received this message because you are subscribed to the Google Groups "OSL Developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email to osl-dev+u...@googlegroups.com.
To post to this group, send email to osl...@googlegroups.com.
Visit this group at https://groups.google.com/group/osl-dev.
For more options, visit https://groups.google.com/d/optout.
--
You received this message because you are subscribed to the Google Groups "OSL Developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email to osl-dev+u...@googlegroups.com.
To post to this group, send email to osl...@googlegroups.com.
Visit this group at https://groups.google.com/group/osl-dev.
For more options, visit https://groups.google.com/d/optout.
To unsubscribe from this group and stop receiving emails from it, send an email to osl...@googlegroups.com.
To post to this group, send email to osl...@googlegroups.com.
Visit this group at https://groups.google.com/group/osl-dev.
For more options, visit https://groups.google.com/d/optout.
--
You received this message because you are subscribed to the Google Groups "OSL Developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email to osl-dev+u...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/osl-dev/498ced5d-4cac-4cb0-ba3a-67c09676d763%40googlegroups.com.
To unsubscribe from this group and stop receiving emails from it, send an email to osl...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/osl-dev/498ced5d-4cac-4cb0-ba3a-67c09676d763%40googlegroups.com.
To unsubscribe from this group and stop receiving emails from it, send an email to osl...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/osl-dev/498ced5d-4cac-4cb0-ba3a-67c09676d763%40googlegroups.com.
Today it's easy to write a tri-planar shader that accepts image textures. But what if you want to tri-planar project something procedural (even something simple as an image texture through a color correction node) ... that's super hard now.
Today, if you want to make a triplanar feature that supports procedural things, you need to make two shaders, one that outputs the three image planes texture spaces. Then any texturing node/network, you have to clone three times. Then, you need another node that mixes the three projections based on the normal. While this works, it's insane spaghetti and very un-intuitive.
Sweet Jeebus NOOOO!!!
We tried this exact approach for our internal Autodesk renderer ART. It was a complete and utter disaster of maintainability in every conceivable way.
The complete and utter failure of the very approach you propose is exactly WHY I am requesting this feature in OSL; Letting the language do it is the only viable, clean way to do it.
No behind the scenes spaghetti juggling. That's just madness!!!
--
You received this message because you are subscribed to the Google Groups "OSL Developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email to osl-dev+u...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/osl-dev/83071f08-c9aa-4004-b247-13786f168229%40googlegroups.com.
--
You received this message because you are subscribed to the Google Groups "OSL Developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email to osl-dev+u...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/osl-dev/b693cd1b-ef0e-4b0b-ad43-5d395d04581e%40googlegroups.com.
--
You received this message because you are subscribed to the Google Groups "OSL Developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email to osl-dev+u...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/osl-dev/29362b10-522f-45a0-8b86-bd5adbb35217%40googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/osl-dev/CAM-xo924Hr4dsP%3D31d%2BeZsSF3-qPb7EGfzLJ%3DWDskz0sWS4SUA%40mail.gmail.com.
--
You received this message because you are subscribed to the Google Groups "OSL Developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email to osl-dev+u...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/osl-dev/b67b955e-2040-44c4-9b4f-d3628a0939ac%40googlegroups.com.
The classic "globals" are easy, because they are the same across the entire
accessed subgraph. And in my use cases, 99.9% I probably wanna modify *u*,
*v* or *P* only.
On 4 Nov 2019, at 15:47, Olivier Paquet <olivier...@gmail.com> wrote:So for us, OSL's lack of some features is a major feature.

Making triplanar textures without this feature is an excercise in mind-numbing pain
On 4 Nov 2019, at 17:49, Master Zap <zap.an...@gmail.com> wrote:
Some 2d shader has some uv input, in all my 2d texturing shaders the default value for this input is vector(u,v,0) meaning, if it's not connected to anything, it will get the u and v as the coordinate. Which, yes, in 3ds max is mapped to the default texture space (as does everyone else running OSL anywhere I'v seen, I know the spec calls them "parametric coordinates" but nobody uses them for that).Anyhoo, obviously we have arbitrary number of texture spaces. If you want to use anything other than the default texture space, you connect a shader that does the approriate getattribute call to get that texture space, easy! But if you *don't* connect anything, you get whatever u and v is - e.g. the default texture space. Super Easy and user friendly.So yes, there is a concept of "the UV's", which is completely well-defined and meaningful for something like this.As a user, I have this 2d texturing thing, which is set to use the default coordinate space. I plug that into my triplanar projection node, and it handles computing the texturing coordinates, evaluating the incoming texture at those coordinates, and mixing the results appropriately.I really don't understand in any way the resistance of being able to have such a useful feature.Making triplanar textures without this feature is an excercise in mind-numbing pain. Here's an example:
The shader you want to use has to exist thrice. To keep settings for those shaders in sync you need a settings node that feeds the parameters to the 3 copies of the shader. Horrible. And you need a separate three-plane coordinate generator and a separate three-plane mixing shader. It's just crazy.
If we had this feature, the previous mess would look like this:
<tri-nospaghetti.png>
What you wanna triplane goes into "Input". Done.How one can dislike this is beyond me, honestly./Z
--
You received this message because you are subscribed to the Google Groups "OSL Developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email to osl-dev+u...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/osl-dev/70092d7e-109a-4a19-b784-85553bf56bbc%40googlegroups.com.
<tri-spaghetti.png><tri-nospaghetti.png>
--
You received this message because you are subscribed to the Google Groups "OSL Developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email to osl-dev+u...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/osl-dev/7df066e8-5728-4ec4-873e-9076342229f9%40googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/osl-dev/AF71C718-4A41-401D-A3FE-F6BD240CDF5B%40gmail.com.