Home Technical Talk

(Solved) [Blender 2.8] Shader Editor: Is there a light direction input node?

polycounter lvl 6
Offline / Send Message
bitinn polycounter lvl 6
I am trying to get the lighting data to do a custom lighting shader, but couldn't find the node to read light data?

(Alternatively, if anyone can come up with a conversion from blinn-phong shininess/glossiness to BSDF roughness, I am all ears, aka this isn't possible without knowing the shader implementation details, tried a few conversion myself, not happy with the limited result.)

(If one just want toon shading, then there is Shader To RGB / Color Ramp node to make it doable, but light direction is still missing, hence I can't do simple blinn-phong shading)

Replies

  • Jekyll
    Offline / Send Message
    Jekyll polycounter lvl 6
    There is no node that gives you access to light direction. However, you can make your own using with the help of Drivers:

    Since light direction is basically the same as it's world space position, you just add a Combine XYZ node to hold the lights position vector and fill in the xyz values of the Light in the scene using Drivers - like in my screenshot below.


  • bitinn
    Offline / Send Message
    bitinn polycounter lvl 6
    Jekyll said:
    There is no node that gives you access to light direction. However, you can make your own using with the help of Drivers:

    Since light direction is basically the same as it's world space position, you just add a Combine XYZ node to hold the lights position vector and fill in the xyz values of the Light in the scene using Drivers - like in my screenshot below.


    Great suggestion! I completely forgot they exists.
  • bitinn
    Offline / Send Message
    bitinn polycounter lvl 6
    Actually this issue is a bit more complex than driver:

    - In my case, I would like to know the light direction, but we only know the rotation of this light.

    - Blender API doesn't provide a path for SunLight direction.

    - So I need to use expression to somehow calculate the actual direction from rotation.

    - But we can only access 1 property at a time...

    I don't think things should be this hard.
  • RN
    Offline / Send Message
    RN sublime tool
    What you're trying to do is called "NPR" (Non-Photorealistic Rendering), there's a dedicated website with some info on the subject: https://blendernpr.org/category/tutorial/

    The method @Jekyll told you is a cool way to get information that's not usually available in nodes, into nodes. You bind a Converter->Combine XYZ or Input->Value node to a driver, and in that driver you can add a scripted expression or sum of variables that come from scene objects or properties.
    The result of the driver will be sent to the driven node so you can access that value from within the node network and use it to affect the material in some way.

    The con of this method is that it doesn't show that well on the viewport: it doesn't update as the driver values change, you need to use the preview viewport rendering mode for that. But it's a small cost.

    If you can get the world-space position of your directional light (or empty or any other object) into a vector node, like Jekyll said, you can make a simple form of direct lighting (no shadowing, no occlusion) by calculating the lambert term, the famous "L dot N". This is a scalar value that you can plug into a Converter->ColorRamp node to translate lighting into color:



    This type of network can give these results:




  • Jekyll
    Offline / Send Message
    Jekyll polycounter lvl 6
    bitinn said:
    ...
    - In my case, I would like to know the light direction, but we only know the rotation of this light.

  • bitinn
    Offline / Send Message
    bitinn polycounter lvl 6
    @RN thx! I understand blinn-phong shading and NPR in general (can write shaders myself, also used shader graph a lot in Maya and Unity), and I think I understand how single-value drivers work in Blender.

    I see the suggestion is to using world-space position of an object (normalized) as light direction, that's a pretty clever hack, thx @Jekyll, it's not really the direction of SunLight, but I will take it :) (was replying to RN's explanation)

    (I believe it's not currently possible to read SunLight direction via driver, because it doesn't expose such information via python API)

    On a side-note, @RN, if you ever update https://gumroad.com/l/quick_node_access for blender 2.8, let me know, might come in handy if people want to expose shader properties (like material property in Unity).
  • RN
    Offline / Send Message
    RN sublime tool
    @bitinn good to know you're familiar with this, I hope I didn't offend with overexplaining (I only do it because other people might come here from a web search without knowing all this).

    If you use the world-space position, the light direction will go from the object position toward the world origin (0,0,0).
    I don't quite get how @Jekyll is using the light direction though, is the driver using the Local X rotation in a variable?

    PS: I don't know if I'll touch on that quick node access script, but I'll give it some thought.
  • Jekyll
    Offline / Send Message
    Jekyll polycounter lvl 6
    RN said:
    is the driver using the Local X rotation in a variable?
    Sort of.  Since directional light sources in Blender point usally in -Z direction (in their local space) you can use that,  normalized, as a direction vector. The "Edit Drivers" popup has the option to get location data either in world-space or local-space. 

    So, by rotating the Sun object, like you would normally do to adjust it's direction, it's local axis change accordingly and thats what I use in my example.
  • bitinn
    Offline / Send Message
    bitinn polycounter lvl 6
    Jekyll said:
    RN said:
    is the driver using the Local X rotation in a variable?
    Sort of.  Since directional light sources in Blender point usally in -Z direction (in their local space) you can use that,  normalized, as a direction vector. The "Edit Drivers" popup has the option to get location data either in world-space or local-space. 

    So, by rotating the Sun object, like you would normally do to adjust it's direction, it's local axis change accordingly and thats what I use in my example.
    OK I get it, so the local space position of this Light is essentially the "tip" we use to drag light direction, right? Hence we can use it with the default light direction to get actual light direction.

    But I find your math flawed here, usually we need Quaternion to properly rotation around an axis, so I can see your example breaks down in some cases:




    Also no worry about the explanation RN, always good to have a refresher :)
  • bitinn
    Offline / Send Message
    bitinn polycounter lvl 6
    Again I need more help on this: to compute specular term I need camera view direction and annoyingly the Camera Data node only provide view direction in Camera Space, not World Space, and I have see no model/view/projection/ matrix in Blender's shader editor (to be honest I don't even see a "matrix" node).

    Alternative is to pass in camera position and calculate view direction from there, but it's yet another hack: I want to shade in viewport (not active camera), there is no way I can drive the value as the viewport camera is not an object in the outliner...

    Basically I know what I need but Blende 2.8 EEVEE's shader nodes are pretty limited... (I don't think this was problem in 2.79 with Cycles?)

    UPDATE: wait, there is a vector transform node, maybe this can be saved....

    UPDATE2: answer is the vector transform node works, but camera data node doesn't pass in viewport camera information, only active camera. great...
  • bitinn
    Offline / Send Message
    bitinn polycounter lvl 6



    Here is my basic blinn-phong shader in Blender with normal/diffuse/specular support.

    What I find sourly lacking in Blender 2.8 Shader Editor:

    (1) Viewport Camera input: view direction, camera matrices;
    (2) Light Data input: light direction;
    (3) Math functions are spread across multiple nodes: Math node, Vector Math node and Mix node; too easy to use the wrong node.
    (4) Input data could be easier: using Combine Vector node with drivers as a vector input are just weird; what if you want to input a vector4? a matrix?

    So I end up hacking around these, I just driving all missing values by in scene object's world position...
  • RN
    Offline / Send Message
    RN sublime tool
    Two suggestions:
    1) Go back to 2.79, as the Blender Internal render engine supports the Blinn specular and is quite fast to render.
    There's also the Blender Game render engine that in some simple cases is fantastic (this is the 3D View):


    2) Go put in a vote so that GLSL PyNodes gets eventually committed to Eevee, it's a node that references your own Python script that defines a custom GLSL shader, for complete control over visuals.
  • bitinn
    Offline / Send Message
    bitinn polycounter lvl 6
    Side note: Viewport Camera Direction in World Space can be read from Geometry Node -> Incoming socket.

    It took me a lot of tries but I finally made an energy conserving blinn phong in Blender, to match my custom shader...




Sign In or Register to comment.