Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice

Question Non-exposed parameters don't work?

Discussion in 'Shader Graph' started by dgoyette, Jun 14, 2020.

  1. dgoyette

    dgoyette

    Joined:
    Jul 1, 2016
    Posts:
    4,120
    In my graph, if I have a parameter that isn't exposed, it appears to not have a value. For example:

    upload_2020-6-14_15-46-23.png

    If I try to set either of these values into a node, such as Base Color, the result just just black. If I instead expose the parameter, it works.

    What's the point of non-exposed properties? This is in SG 7.4 with HDRP.
     
    Arnold_2013 likes this.
  2. LandonTownsend

    LandonTownsend

    Unity Technologies

    Joined:
    Aug 21, 2019
    Posts:
    35
    Because of the way properties work in shader code, un-exposed properties can not be initialized unless you do so through a script, which means they always have default values (identity matrix for matrices and zero vector for vectors, black for colors) in the materials. The purpose of unexposed properties is to set them through code, so if you don't plan on doing so, it's best to leave them exposed.
     
  3. dgoyette

    dgoyette

    Joined:
    Jul 1, 2016
    Posts:
    4,120
    Thanks for clarifying that. That definitely means I can't use unexposed properties as I'd hoped to.

    One thing I find fairly annoying about either Shader Graph, or the way things work in HDRP right now, is the way that material instances lock on to a value for an exposed properly, and don't change if the default changes in the shader unless I manually "Reset" the material. As a simple example, if I add a "Base Color" property to a shader, and choose a blue color for the default, materials instances will have blue as their default. But if I decide I really wanted red to be the default, and I change that in the Shader Graph, any materials that exist will not change to red. They'll keep their blue value.

    This is annoying because I usually want to drive values via properties on the shader, so it's natural to add those properties as soon as I see I'll need them. But as soon as I add a property, I've actually made it a lot more annoying to experiment on that shader, since now I need to go reset values on the materials that use that shader. Does that make sense?

    One thing I find missing about this process would be an approach like the way HDRP lets you override post-processing settings. For each property, you first opt-in to overriding it or not. If you don't override it, it uses the default value. Anyway, I'm not sure if there's currently any way to avoid the situation I often find myself in, where I want to edit the Shader, save it, and see the impact in the Scene view. I currently can't do that without having to reset the material's properties each time, assuming I'm tweaking a property. That's why I was hoping exposed properties would keep everything within the shader, so I can tweak everything in the shader, and only "expose" it once I'm ready for the material to lock to a single value.
     
    raaan127 likes this.
  4. nikefootbag

    nikefootbag

    Joined:
    Jun 13, 2017
    Posts:
    28
    So the default values set in the Shadergraph blackboard are only used if the property is exposed?
    Why aren't they all initialized per the blackboard defaults, and then simply hidden in the Inspector window when not exposed?
     
    abegue, Resonantmango and DevelolperD like this.
  5. DevelolperD

    DevelolperD

    Joined:
    Aug 14, 2019
    Posts:
    1
    I agree with @nikefootbag. All properties should be set to their default values regardless if it's tagged with "exposed" or "unexposed". Not doing so is confusing for the developer as it leads to unexpected behavior. For example, what we see in the shader graph Preview Window does not match what is seen for objects with the same material in game.

    "Unexposed" should mean that the shader doesn't required constant buffer storage and can copy a raw value into the shader code that get's compiled at the line the variable is declared. If a property is marked as "exposed", then the shader code can still set the default value where the variable is declared, but then later, in the generated code, read the property's new value from a constant buffer that stores values coming from inspector overrides.

    The fact that "Unexposed" is meant for setting values through script should not be our concern when authoring shaders in the shader graph.
     
    abegue and Resonantmango like this.
  6. Resonantmango

    Resonantmango

    Joined:
    May 28, 2017
    Posts:
    7
    Well this was frustrating and cumbersome to discover, not obvious whatsoever.

    If a property is exposed, I can't use a MaterialPropertyBlock. But if it is not exposed, I can't modify it's value in the GUI while building/testing. So I need to set all my properties to exposed while testing, then go back and uncheck all of them when I want to set through script... (and back and forth again if more testing is needed)

    It is also really frustrating that values 'latch' when setting them on the Material through the Inspector, so they can no longer be modified in the Shader....
     
  7. adrian_tut

    adrian_tut

    Joined:
    Dec 11, 2013
    Posts:
    1
    My workaround for that is to create a sub-graph with the internal variables I want to export, then add that subgraph to my shader and connect them whever I need.
    upload_2022-2-2_20-3-27.png

    then in the shader:
    upload_2022-2-2_20-4-24.png
     
  8. BOXOPHOBIC

    BOXOPHOBIC

    Joined:
    Jul 17, 2015
    Posts:
    481
    There is also this thingy, exposing properties while using them as Global variables, doesn't make sense at all, as exposed properties are always treated as per material properties.
    upload_2022-2-9_12-8-6.png
    upload_2022-2-9_12-13-12.png

    Non-exposed properties are always treated as global properties regardless of the declaration. Initially, I was thinking that this combination will use an [HideInInspector] attribute, but no.
    upload_2022-2-9_12-14-21.png

    This is with SG 10, not sure if anything changed.

    Amplify uses property types: Constant / Property (per material) / Global / Instanced and instead of the "Exposed" option, you have Attributes ([HideInInspector] for instance) with the ability to add your own if you want to create some custom drawers.

    upload_2022-2-9_12-10-16.png
     
    Last edited: Feb 9, 2022
  9. Kevin-VFX

    Kevin-VFX

    Joined:
    Apr 17, 2016
    Posts:
    54
    I don't understand why the Unity Shader Graph isn't following Unity's own property system. Within the generated shader, there are properties that use [HideInInspector] without issue. When making a property hidden (click off exposed), it removes it from the property list and just has a declaration in the pass. It doesn't utilize the HideInInspector. There's certainly a use case, but this doesn't seem to be the proper behavior nor is it communicated. At the moment, I don't see any way within the node system to just add the HideInInspector prefix.

    In my use case, I need a property hidden, with default values, and script editable. I believe most people trying to use this button need the same. Without the HideInInspector, the property isn't properly serializable which leads to it constantly forgetting values and complete lack of default values. So, now I need to expose a sensitive value because the functionality is broken otherwise.
     
  10. FredMoreau

    FredMoreau

    Unity Technologies

    Joined:
    May 27, 2019
    Posts:
    115
    Hi,

    thanks @Kevin-VFX for bringing this up again.
    We are looking into it, if you want to share more details on your use cases, we now have a card on the roadmap.
     
    TheMemorius likes this.