Home Unreal Engine

UDK - Material - Oren Nayar Help

1
polycounter lvl 12
Offline / Send Message
Ace-Angel polycounter lvl 12
Hey to all,

I'm trying to create an Oren Nayar material like this: https://lva.cg.tuwien.ac.at/cg1/wiki/doku.php?id=students:oren-nayar

But I'm running into some issues since I don't have any idea on the way certain functions are written.

For example, in the link, it says basically to Max and Min my alpha and beta functions, but I have no idea on how to do that in UDK.

Here is my current shader http://www.mediafire.com/?ss209mm85pvlnce

It's abit of a mess, so I uploaded the UPK file, if anyone could lend me a hand in taming this beast, it would be super!

Replies

  • Gestalt
    Offline / Send Message
    Gestalt polycounter lvl 11
    I'd be very interested in some info on this as well. So far I've basically been using fresnel on a custom material to fake different reflectance, which is simple enough to do(go by eye and tweak until it looks ok), but it isn't a solid setup by any means. I don't think standard oren-nayar takes into account bidirectional reflectance, but I'd be interested in if anyone has some ideas on that.
  • tharle
    Offline / Send Message
    tharle polycounter lvl 9
    right, firstly taking 1-cos(x) isnt the same as arcos(x). i dont think udk does inverse trigonometry but you might be able to write a custom function for it i guess. Just looking on Wikipedia there's a version of the formula rewritten just in terms of sin cos and tan which udk should be able to handle.

    secondly you need to double check your bodmas . currently for A you've got (1 - 0.5) * x rather than 1 - (0.5x) which isnt the same thing at all. you also seem to have completely omitted the squared term from your roughness factor in both A and B.

    as for your min and max question, it's as simple as comparing the two numbers and taking the higher or lower. ie use an if node and "if A > B then A, else B" would be the max(A,B). gets more complicated for more values of course but you've only got two here.

    Lastly i guess my question is why are you trying to do this? unless i'm misunderstanding something the oren-nayar shading model is used to simulate a rough surface which is what a normal map does and which is almost certainly more accurate, controllable and more efficient?
  • equil
    you can access all hlsl commands in udk;
    make a custom node
    return max(x,y)

    gestalt, i don't understand what you mean. Oren-Nayar accounts for a specific case of retroreflection, it's a brdf and is thus bidirectional. It has little to do with fresnel or specular reflections on it's own, it's just a step in the right direction for diffuse interreflection behavior.
  • Gestalt
    Offline / Send Message
    Gestalt polycounter lvl 11
    When I referred to 'fresnel' I basically meant using the dot product of the normal and light vector and using a power term to fake a reflectance function. Oren-nayer assumes even reflectance and does not take into account variability in the 'micro facet' surface (unless I'm missing a large part of what oren-nayer is). What I'm referring to is how the micro-facet structure of a material does not cause the same type of reflectance from various angles (ie oren-nayer won't account for an 'anisotropic' type of reflectance).

    Edit: I looked at the link and I think the formula is wrong. It doesn't make sense that you'd go through the trouble of finding the max and min and then take the sin of both and not use them differently. I looked up the formula on wiki and it says tanβ and not sin.
  • Vailias
    Offline / Send Message
    Vailias polycounter lvl 18
    FYI there are HLSL commands for inverse trig functions that you can write into a custom node. acos(x) would be one.

    OR you can get the arcosine by a 1/cos(x)

    Gestalt: Neither will a lambertian diffuse. So what?

    As far as aniostorpic effects, you can extend most specular models into anisotropic versions by splitting the reflectance vectors into parallel and perpendicular parts to your grain, and having separate coefficients for each.
  • Gestalt
    Offline / Send Message
    Gestalt polycounter lvl 11
    Some good references:

    http://www.cs.virginia.edu/~mjh7v/bib/Oren95.pdf
    A good source for Oren-Nayar with descriptions, tests, logic behind it, etc.

    http://graphics.stanford.edu/courses/cs448-05-winter/papers/nicodemus-brdf-nist.pdf
    A good source of terminology, formulas, etc.
  • LoTekK
    Offline / Send Message
    LoTekK polycounter lvl 17
    Max and Min my alpha and beta functions, but I have no idea on how to do that in UDK
    There's no equivalent max and min nodes that I know of, so you'll need to use an if node. Basically for Max: if A > B use A, and vice versa.
  • tharle
    Offline / Send Message
    tharle polycounter lvl 9
    pretty sure the arcos(x) doesnt equal 1/cos(x) either vailias. just try it for x=0.6:
    arcos(0.6) = 0.927
    1/cos(0.6) = 1.212

    the arcos of x should be thought of as "what do i have to cosine to get x" not "one minus" or "one divided by the cosine of x"

    so you'll have to either use a custom node or rewrite your equation in terms of normal functions (sin cos tan).
  • System
    Offline / Send Message
    System admin
    I know this might sound super noobish but whats the purpose of recreating the actual math when you could fake the effect for less instructions?
  • Ace-Angel
    Offline / Send Message
    Ace-Angel polycounter lvl 12
    Mind telling me how if you're so kind? ;P

    The closest I can think of is a Transformed Normal Map, multiplied by the Light Vector and Lerped with a Fresnel and using a copy of the Diffuse as a the control in all cases with an added Color for tint.

    Also, would like to thank all the peeps who helped me so far, but I think I will drop Oren for now, there is no way with my current abilities I would able to even get it working properly, so I think I will try hacky methods.
  • Gestalt
    Offline / Send Message
    Gestalt polycounter lvl 11
    I'm working on the material now but I can't find how to do the arccos. Basically I need the angles between the light and the normal as well as the camera and the normal, and the way to do that would be to take the arccos of the dot product of the vectors (the dot product gives you cos(θ) and the arccos of that gives the angle θ). Arccos isn't 1/cos.

    I've noticed the blue channel of the vectors appears to be the same as the dot product of the vectors with the normal. Does anyone know what the other channels (red and green) do for the light and camera vectors and if they'd be useful to find the angles the vectors make with the normals? If there is a way I'm missing to finding the angles please let me know.

    As for the max and min I'm using the 'If' node.
  • Ace-Angel
    Offline / Send Message
    Ace-Angel polycounter lvl 12
    You continuing? So. Much. AWESOME!

    I found this for arccos: http://wiki.beyondunreal.com/Legacy:Useful_Maths_Functions#arcCos_funtion
    static final function float ACos  ( float A ) 
    { 
    if (A>1||A<-1) //outside domain! 
        return 0; 
      if (A==0) //div by 0 check     
    return (Pi/2.0);   A=ATan(Sqrt(1.0-Square(A))/A); 
      if (A<0)     A+=Pi;   
    Return A;   }
    
    As for the Normals, I plug my Normal and Normal Map into a Lerp node and use a constant to control the harshness/softness of my normals, it could prove useful for the testing purposes.
  • Gestalt
    Offline / Send Message
    Gestalt polycounter lvl 11
    I should really learn HLSL :poly124:
    Do I just put this as is into a custom node or is there some more setup to it?
  • tharle
    Offline / Send Message
    tharle polycounter lvl 9
    Gestalt, unless i'm mistaken the red and green channels of the vectors contain the information for the binormal and tangent of the vector. if you imagine a set of axis at the centre of the face blue is the normal vector and red and green define the plane of the face. dont think they're very useful here as you want the angles between the light and camera vectors which are always using the normals from the face.

    edit: "I should really learn HLSL" - i was just thinking that this morning :D
  • Gestalt
    Offline / Send Message
    Gestalt polycounter lvl 11
    I found something sort of interesting. http://books.google.com/books?id=pCwwxlMuNycC&lpg=PR1&pg=PA140#v=onepage&q&f=false
    The alpha/beta part of the function was precomputed and basically made into a texture 'look-up table'. This greatly reduced the instruction count and made it so that inverse trig functions weren't needed.
  • Vailias
    Offline / Send Message
    Vailias polycounter lvl 18
    Tharle: oops yeah I must have been confused with something else.
  • tharle
    Offline / Send Message
    tharle polycounter lvl 9
    right here's my attempts. tried the wikipedia forumla first but it didnt seem to like it. i've left it in the material editor anyway incase someone can work out what's wrong with it but it looks like the tan function is breaking it. i've checked the publication and it's the right formula but i'm probably implementing it wrong.

    the second version from the link posted to start with seems to work alright though. the roughness definitely changes the falloff of the lighting although you can see where the two sin functions are interacting and creating banding, imo.

    hope that helps people - i've learned something from doing it, although i dont really see that it's useful enough to go through all this hassle still! if you want to update it to use a normal map then i think you just have to replace all the 0,0,1 vectors with the normal map you want. i'd be interested to see some comparisons if people do use it at all.

    cheers
  • Computron
    Offline / Send Message
    Computron polycounter lvl 7
    tharle wrote: »
    edit: "I should really learn HLSL" - i was just thinking that this morning :D

    I am this close |-| to learning Cg (with that new eat3d DVD) because I want to be all shader 1337.
  • LoTekK
    Offline / Send Message
    LoTekK polycounter lvl 17
    Computron wrote: »
    I am this close |-| to learning Cg (with that new eat3d DVD) because I want to be all shader 1337.

    You should totally get that DVD. It's very well-structured, and the various shader languages are quite similar, just some minor syntactical differences.
  • Vailias
    Offline / Send Message
    Vailias polycounter lvl 18
    Nice that there are DVD's now. :) Less slogging through Nvidia tech docs and MSDN and taking apart other peoples code to find what actually works.

    Also the packages here don't seem to show anything in my version of UDK, what release are you gents up to?

    Further: I built up a functional oren-nayar model. And I learned to be VERY VERY careful about order of operations when dealing with UDK nodes. :) no sloppy nodeing. I lost a good half hour or more just because I effectively had a few parenthesis in the wrong places. ha! Harder to see with node connections.


    OrenNayar_ShaderNetwork.jpg

    also here's the HLSL code listing, which if you put in a custom node, will do nearly the same thing with a few more instructions due to lack of optimization. There is a difference in the look between code and node based, but I haven't isolated where or why its occurring. :shrug: it is rather minor.
    //incoming variables are Light, Eye, Normal, Diffuse, and Sigma. 
    //Sigma is the Roughness value Squared.
    
    float NdotL, VdotN;
    
    NdotL = dot(Light, Normal);
    VdotN = dot(Eye, Normal);
    
    float A = 1- (0.5 * (Sigma / (Sigma + 0.33f)));
    float B = 0.45 * (Sigma / (Sigma+0.09f));
    
    float Temp1, Temp2;
    
    Temp1 = acos(NdotL);
    Temp2 = acos(VdotN);
    
    float Alpha = max(Temp1, Temp2);
    float Beta = min(Temp1, Temp2);
    
    
    float C = 0.0f;
    
    //this math assumes unit vectors
    
    float3 Vper = normalize(1 - (Normal * VdotN));
    float3 Lper = normalize(1 - (Normal * NdotL));
    
    C = dot(Vper, Lper);
    
    
    return (Diffuse *( NdotL*(A + B * sin(Alpha) * tan(Beta) * max(0.0f, C) ))) ;
    
    

    edit:
    Also here's an image.. see if the change is really worth the extra cost to you. :)
    Oren_Screenshot.jpg
  • Ace-Angel
    Offline / Send Message
    Ace-Angel polycounter lvl 12
    Hey Vailias, thanks alot for all the help, much appreciated, I do have a couple of questions if you don't mind answering (or if any other peeps could, that would be great to).

    -I noticed you didn't Power your Roughness Parameter, I was wondering if this is necessary or not.

    -I thought that Oren Nayar was limited to values of 1 and 0 for the Roughness, is that not the case?

    -For the custom node in ArcCos, is it written like this: acos(x) ? Is it really that simple? Is it the same with the Custom Sin node?

    -In the Formula, I noticed this part (which I still can't understand what it means); (...A+B* max(0,y) *sin(a)...)

    Cheers and thanks for everyone for helping, much appreciated.
  • LoTekK
    Offline / Send Message
    LoTekK polycounter lvl 17
    Vailias, that's sexy :D
    Ace-Angel wrote: »
    -In the Formula, I noticed this part (which I still can't understand what it means); (...A+B* max(0,y) *sin(a)...)

    max(x, y) means take the larger value of the two.

    In the case of max(0, y), it's basically keeping the expression to a minimum of 0 (ie, not negative).
  • equil
    -Nope. it's squared in the equation because it's the root mean square, but it's a unit in itself so there isn't any need to calcul(blabla it's just a superfluous multiplication).
    -Roughness goes from 0 to infinity. But anything over 1 might not make sense.
    -AVOID INVERSE TRIG. yes, that is how you do it (with all hlsl commands), but doing tan(acos(x)) and sin(acos(x)) is kind of terrible for performance and can be greatly simplified.
    -Just saturate that (since it's in the range of 0 to 1).

    I don't have udk installed but here is code for an exact solution without any trigonometric functions:
    (rms = roughness, v = view/camera, n = normal, nv = n.v, nl = n.l)
    float a = 0.285/(rms+0.57) + 0.5;
    float b = 0.45 * (form.a/(rms+0.09));
    float y = saturate(dot(v - n * nv, l - n * nl) );
    float c = sqrt( (1.0 - nv * nv) * (1.0 - nl * nl) ) / max(nv,nl);
    float abc = b * c * y + a;
    

    edit: you don't even need a custom lighting model for this, just multiply your diffuse texture by abc before plugging it into the diffuse slot.
  • Gestalt
    Offline / Send Message
    Gestalt polycounter lvl 11
    Vailias, awesome! Any idea about storing the alpha beta values in a 2d look-up? Acos isn't very lightweight, and precomputing a 2d look-up texture could reduce the instruction count a ton (I believe the link I linked above reduced it to 27 for the pixelshader). The texture lookup shouldn't change for the alpha-betas(you should only have to make the look-up once and store it) so it should be able to be reused for every use of oren-nayar.

    Edit: This could be helpful http://content.gpwiki.org/index.php/D3DBook:(Lighting)_Oren-Nayar
    he also uses a lookup

    Edit2: I just found this ( http://fgiesen.wordpress.com/2010/10/21/finish-your-derivations-please/ )which apparently gets rid of the need for the lookup.
    Did I mention angles? There’s one particular case of angle-mania that really pisses me off: Using inverse trigonometric functions immediately followed by sin / cos. atan2 / sin / cos: World’s most expensive 2D vector normalize. Using acos on the result of a dot product just to get the corresponding sin/tan? Time to brush up your trigonometric identities. A particularly bad offender can be found here – the relevant section from the simplified shader is this:
    float alpha = max( acos( dot( v, n ) ), acos( dot( l, n ) ) );
    float beta = min( acos( dot( v, n ) ), acos( dot( l, n ) ) );
    C = sin(alpha) * tan(beta);
    Ouch! If you use some trig identities and the fact that acos is monotonically decreasing over its domain, this reduces to:
    float vdotn = dot(v, n);
    float ldotn = dot(l, n);
    C = sqrt((1.0 - vdotn*vdotn) * (1.0 - ldotn*ldotn))
    / max(vdotn, ldotn);
    ..and suddenly there’s no need to use a lookup texture anymore (and by the way, this has way higher accuracy too). Come on, people! You don’t need to derive it by hand (although that’s not hard either), you don’t need to buy some formula collection, it’s all on Wikipedia – spend the two minutes and look it up!
  • Ace-Angel
    Offline / Send Message
    Ace-Angel polycounter lvl 12
    Thanks guys for all the information, it's all very interesting and amazingly well done if you don't mind me saying.
    equil wrote: »
    edit: you don't even need a custom lighting model for this, just multiply your diffuse texture by abc before plugging it into the diffuse slot.

    Really? That's interesting, say, it wouldn't be possible with an Half-Lambert, would it? I mean the part about not needing a custom lighting.
  • Gestalt
    Offline / Send Message
    Gestalt polycounter lvl 11
    I think what he means is that in the end you are multiplying by lambert, the NdotL, so you could do everything and plug it into the diffuse without doing the whole custom lighting thing. I think there are benefits to doing your own lambert though; I remember there was something that was off about the shading in UDK (it was mentioned in the environment 3dmotive series).
  • Vailias
    Offline / Send Message
    Vailias polycounter lvl 18
    Thanks for the followons guys. :) all good info.

    Yes this can and should be simplified for realtime use.
    As built this would not compile on SM2, and is expensive. It is built "by the book" for illustrative purposes mainly.

    One could use texture lookups for the alpha and beta values, indeed my reference material did just that. Personally I feel it's a waste of a texture lookup unless you're using this model on many assets. it WILL reduce the instruction count.

    No you do not need custom lighting for this. I've used multiple lighting models on a single physical model before and just plugged it into the diffuse slot. See the angel turnarounds on my youtube page. The lycra body suit is using a minnaert model. The lighting models effectively just create, well, areas of light and dark. You can combine them with arethmetic just like any other 0-1 value. I'm using custom lighting here, again primarily for illustrating the shader itself.
    Not sure about udk's shading being off. It looks damn lambertian to me. What can be a factor is light intensities greater than 1. May wash stuff out, especially with simple shading models

    Also yes the custom trig nodes are really that simple. Return Acos(IN); That's it.


    Thanks for the link on the trig identity refresh. I can never keep those things memorized and it will help me with finishing up my Marschner hair shader implementation.
  • Vailias
    Offline / Send Message
    Vailias polycounter lvl 18
    Oh also, the reason for no power on sigma. Since the function is in terms of roughness squared, the optimization is to treat the variable as already squared.
  • Ace-Angel
    Offline / Send Message
    Ace-Angel polycounter lvl 12
    Gestalt wrote: »
    I think what he means is that in the end you are multiplying by lambert, the NdotL, so you could do everything and plug it into the diffuse without doing the whole custom lighting thing. I think there are benefits to doing your own lambert though; I remember there was something that was off about the shading in UDK (it was mentioned in the environment 3dmotive series).

    Which is what has been driving me mad, most tutorials show a basic setup which still mimics the same 'issues' found in the material, the ones that try something 'new' (like eat3D's Shader DVD) end creating a 100% transmission based material for the lambert, which is still wrong, unless you apply it on a sphere model or plan on faking a very bad SSS.

    Also, Custom Materials in UDK still fight with Tanget Transform nodes, as well Transmission slots, it's pretty vexing, not to mention in some very finicky cases they break the Translucent material completely alongside the opacity, which is why I after my Oren Nayar and Half Lambert attempts, I'm trying to avoid custom materials in UDK.

    Vailias: Ah thanks for the info, much appreciated!
  • Vailias
    Offline / Send Message
    Vailias polycounter lvl 18
    I'm curious. What issues are you running into with what you want to create?

    Also what are you wanting to transform so much that you're having issues with? Do you need a lot of world space info things and vertex colors?

    There are likely some solutions to what you're looking for, just depends on what approach need to be taken.
  • Ace-Angel
    Offline / Send Message
    Ace-Angel polycounter lvl 12
    I'm guessing I'm just being stupid since most of the tutorials I watched are core HSLS video.

    HSLS in 3DS Max by Ben Cloward (CG Academy) and ShaderCGFX for Maya (eat3D) go through such basics and almost always end up NOT translating well for UDK.

    I was going to make a Strauss lighting model alongside Oren Nayar, but the fact that I was Transforming my Normal Map and Reflection nodes into a Transform - Tangent node which was creating a transmission effect because Tutorials X told me...well, lets say I'm not ready for any of that.
  • Vailias
    Offline / Send Message
    Vailias polycounter lvl 18
    Heh fair enough. Yeah you just need to get a handle on what space you're in. In the udk environment everything is already in tangent space.

    Straight hlsl stuff will require manually making all your data agree on the space it's in.
    Glad you're trying more stuff though. :)
  • Gestalt
    Offline / Send Message
    Gestalt polycounter lvl 11
    On the topic of HLSL does anyone know some good tutorials especially in regards to UDK. I'd like to make a custom node for the C term using the simplified formula, but I have no idea where to start.
  • Computron
    Offline / Send Message
    Computron polycounter lvl 7
    The Eat3d DVD teaches Cg (C for graphics) but it is nearly identical to HLSL. There is a chapter at the end just for UDK custom nodes.
  • Vailias
    Offline / Send Message
    Vailias polycounter lvl 18
    Tutorials are for chumps. :-P

    Seriously though, you may be better off with language reference than a tutorial. Search for HLSL on MSDN and you'll have a full function listing and syntax help etc.

    Cg is a subset of hlsl. Meaning everything you can do with Cg can be done in hlsl and more. The syntax is Identical.

    edit: ok quick thing to get you started.

    UDK custom nodes are equivalent to an HLSL function.

    The properties of the node are like its function name and associated variables. The return type, and variable types are set implicitly by UDK.

    You will need to return a value manually from the custom node though. Just use a return statement
    return ValuegoesHere;
    

    HLSL is a typed, curly bracket language. So you'll need to declare your variables.

    numbers come in INT and FLOAT flavors.
    Vectors come in FLOAT2, FLOAT3 and FLOAT4, for 2 3 and 4 component vectors.
    Matrices can be declared, but in my experience UDK doesn't play nice with them.


    So for the simplified c term, you'll need the Camera vector, normal vector, and light vector (or you could pass in the dot products as floats. Whatever.

    it should look like this
    //This custom node will need inputs named Normal, Light, and Camera. 
    //hook in the respective UDK nodes to the inputs
    float ndotl = dot(Normal, Light); 
    //dot(x,y) is the dot product function. returns a float.
    float vdotn = dot(Camera, Normal);
    
    float C = sqrt((1.0 - vdotn*vdotn) * (1.0 - ldotn*ldotn))
    / max(vdotn, ldotn); //yes the listing on the previous page was valid HLSL.
    
    return C;
    
  • Gestalt
    Offline / Send Message
    Gestalt polycounter lvl 11
    Thanks for the help :)
    @Computron I got and finished the dvd, and I thought it helped a lot so thanks!

    @Vailias That quick step-by-step helped a lot actually (clarified things about input); I set up a custom node and got things working, but for this case it turns out I can do things without a custom. I finally go oren-nayar set and without custom nodes! :)
  • Computron
    Offline / Send Message
    Computron polycounter lvl 7
    Wow, speedy. Guess I'll dive in when I get the time. I have never done any coding, I mean I did really basic C++, I love fiddling with the UDK node editor, would you say its good for beginners?
  • Gestalt
    Offline / Send Message
    Gestalt polycounter lvl 11
    Yeah I really never did coding either (never liked code much); I'd say the training's good for beginners. It goes from the very beginning and doesn't assume you know too much about coding, and although it goes over the basics very quickly, all of the files are provided with lots of comments. If you are familiar with setting up materials in the node editor then that helps a lot too; it's pretty much the same thing conceptually just more technical.
  • Vailias
    Offline / Send Message
    Vailias polycounter lvl 18
    It depends on how you learn best.
    Personally I highly encourage you to reverse engineer a sample material that comes with your dcc app. Grab an hlsl reference to check what stuff is that you can't intuit.
    And or slog through building your own blinn material. :)
    Actually this reminds me. I wrote a tutorial like 5 years ago on doing just that. Here. It's at ga
    http://www.gameartisans.org/forums/showthread.php?t=472
  • Computron
    Offline / Send Message
    Computron polycounter lvl 7
    Cool, I guess I'll get started tomorrow.

    I found this free app called Paragraf for my iPhone earlier this week, it lets you write GLSL code and preview it instantly with hardware acceleration using the iPhone's camera as input for textures. Had some fun reverse engineering the provided examples.
  • TheJamsh
    Hey chaps, sorry to bump such an old thread but I'm just getting into putting together an Oren-Nayar shader for in-game use. Valias mentioned above that his incarnation would require simplification for real-time use if I'm not mistaken?

    My shader is also going to have vertex-painted water, a wet/raining variation and additional ice as well, all modifying the specular and reflectivity of the surface too, so I need to save instructions wherever possible really!

    I found this shader recently which claims to use the Oren-Nayar model, I can indeed see similarities but it's much less expensive (and I assume, less accurate) than the versions posted and uses no HLSL. Anybody have any insight to offer on this?

    http://oliverm-h.blogspot.co.uk/2012/02/how-to-use-oren-nayar-lighting-for-ue3_13.html


    Edit: After building both versions, there is very little visual difference between the two with the added benefit of fewer instructions and no need for a custom lighting model.

    Also, *Facepalm*, I noticed that the article links to the same simplification article that somebody else did earlier in the thread. I guess that just makes it all too easy for me!

    One thing I am noticing however, I constantly have to clamp the output to prevent getting negative values at the materials master node, causing black spots. I guess it's good practice anyway, but is anybody the wiser about why this is?
  • Vailias
    Offline / Send Message
    Vailias polycounter lvl 18
    One thing, for what its worth, Oren Nayar is a lighting model. Hence the custom lighting approach. But as was mentioned, if you plug in the result to the diffuse node you're basically just pre-calculating the lighting, even though UDK will still run a lambertian model on whatever you put into the diffuse slot.


    I'm not sure where you mean you're getting negative values, but any dot product does range from -1 to +1. In some cases that doesn't matter, in others it may, and so you clamp it.

    Also, why an oren-nayar. Do you need the extra soft look it can give or are you building it as an exercise?
  • Ace-Angel
    Offline / Send Message
    Ace-Angel polycounter lvl 12
    Olivers solution is pretty neat, the only problem with it is that if you're using a ramp-edge-based solution (such as SSS, Fresnel, etc) in your Diffuse math, you will end up with a green-falloff, kinda like what Max pre 2011 had.

    You don't get that with the full ON math.
  • TheJamsh
    Vailias wrote: »
    Also, why an oren-nayar. Do you need the extra soft look it can give or are you building it as an exercise?

    The negative values might just be something else, but I was getting both black and white artefacts in the resulting material. I must have forgotten to clamp something somewhere...

    It's a bit of both really, I want to see if I can build one for real-time use that also has a lot of other functionality. I've also heard that it's notoriously good for rough surfaces. One of the surfaces in the game is one you'll be spending a lot of time around, so I figure I want to make it look as decent as possible, but at the same time not be a performance crusher.

    Ideally then, I would want to use the custom lighting model only, not UDK's in-built Lambert shader as well (which surely, would also add instructions too?)

    I'm still a little new to building shader models/materials, so pardon my ignorance all :)
  • mAlkAv!An
    Offline / Send Message
    mAlkAv!An polycounter lvl 5
    TheJamsh wrote: »
    Ideally then, I would want to use the custom lighting model only, not UDK's in-built Lambert shader as well (which surely, would also add instructions too?)

    Not sure if I understood correctly, but the lambertian term is part of the oren nayar formula. That's the only reason why it also works with MLM_Phong and not only a custom material.
    With a roughness parameter of 0 the whole oren-nayar term equals to one so what's left is the simple lambert diffuse. In case of a master material + instances the roughness should be a scalar parameter so you can easily switch to lambert (and cut off the extra instructions) for less important models, LoDs etc.


    Ace-Angel wrote: »
    the only problem with it is that if you're using a ramp-edge-based solution (such as SSS, Fresnel, etc) in your Diffuse math, you will end up with a green-falloff, kinda like what Max pre 2011 had.
    I wasn't aware of such issues. Do you have any sreenshots at hand showing that problem?
  • TheJamsh
    Maybe I'm misunderstanding but this is my grasp of it so far.

    if I plug anything into the 'Diffuse' slot on the master material node, I will get a Lambertian model applied to whatever is going into that node correct?

    So if I plug the Oren-Nayar output into it, I get Oren-Nayar + Lambert. If I plug the Oren-Nayer into 'Custom Lighting' and 'Custom Diffuse', I get Oren-Nayar only?

    Also, Oren-Nayar with a roughness of Zero is the same as Lambert, but more expensive.

    Next challenge, Oren-Nayar Cook-Torrence.
  • Vailias
    Offline / Send Message
    Vailias polycounter lvl 18
    What Malk says is correct: The lambertian term (l dot n) is a direct part of the simplified version of the Oren-Nayar shader, so if you do not include that final multiply, then plug it into the diffuse slot of the default material, it will give identical results as to having the full thing in a custom lighting slot.
  • Ace-Angel
    Offline / Send Message
    Ace-Angel polycounter lvl 12
    @Malk: Here you go:

    3Gxuwa6.jpg

    It's an Oren Nayar issue me thinks, not your implantation, since from what I remember, the lite version of the code that is around the web cuts out the the direct falloff rate and only keeps the light/eye direct math, hence why any kind of SSS solution that could use Oren Nayar as it's lighting term will cancel itself out.
  • mAlkAv!An
    Offline / Send Message
    mAlkAv!An polycounter lvl 5
    Thanks for the screens :)

    TheJamsh wrote: »
    Also, Oren-Nayar with a roughness of Zero is the same as Lambert, but more expensive.

    It's the exact same for me. I guess there has been done some optimizations for the material editor/shader compiler not that long ago. Using July 2012 build here cuts off all the extra instructions for a roughness of zero.
    I observed a similar behaviour for different setups, e.g. zero specularity does not cause any additional instructions.

    TheJamsh wrote: »
    Next challenge, Oren-Nayar Cook-Torrence.
    Good luck, though I guess you won't really need the full cook torrance functionality (it's quite heavy on instructions).
  • TheJamsh
    Interesting... I wonder if that'd an under-the-hood optimization of UDK that they've implemented more recently. I'm currently using verson 10246 (I'm not sure when that was released though I have a hunch that it's March 2012).
1
Sign In or Register to comment.