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
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

Extending surface info in surface shader

Discussion in 'Shaders' started by Relfos, Sep 23, 2015.

  1. Relfos

    Relfos

    Joined:
    Dec 27, 2011
    Posts:
    45
    I'm trying to write a custom illumination model for a surface shader.
    However I find no way to pass a custom value calculated in the "surf()" function to the custom illumination model.

    If it was possible to just extend the SurfaceOutput struct, then I could just add there the extra info I need, but I could not find out if this is possible.

    Note that I can't just use shader properties, since the value is calculated during the shader, in the surf() function.

    Right now I cheated by using the SurfaceOutput.alpha to store a float and then retrieve it in the illumination function. However later I want to make a transparent version of the shader, so I need to find a better solution.
     
  2. karp505

    karp505

    Joined:
    Jul 24, 2014
    Posts:
    18
  3. Relfos

    Relfos

    Joined:
    Dec 27, 2011
    Posts:
    45
    Thanks, but I've read that link before writing this thread :)

    Anyway, I've found a solution, which is actually very obvious...

    Any shader variable declared outside the surf() function can be used to calculate a value inside the surf(), store the result and read the result in the lighting function.
     
  4. karp505

    karp505

    Joined:
    Jul 24, 2014
    Posts:
    18
    Hey, I just looked over that page again and realized it didn't contain the snippet I thought it did. You can definitely declare a global variable, but you can (and probably should) also create a struct to pass into your custom lighting model, like so (only including the relevant code):

    Code (CSharp):
    1. #pragma surface surf Custom
    2.  
    3. struct SurfaceOutputCustom{
    4.     fixed3 Albedo;
    5.     fixed Alpha;
    6.     fixed3 Emissions;
    7.     fixed3 Normal;
    8.     fixed Specular;
    9.     fixed OtherVariable;
    10. };
    11.  
    12. void surf (Input IN, inout SurfaceOutputCustom o){
    13.     o.OtherVariable = 0.5;
    14. }
    15.  
    16. inline fixed4 LightingCustom(SurfaceOutputCustom s, half3 lightDir, half atten){
    17.     fixed4 c = fixed4(s.OtherVariable, 1.0, 1.0, 1.0);
    18.     return c;
    19. }
     
  5. Relfos

    Relfos

    Joined:
    Dec 27, 2011
    Posts:
    45
    Ahh, I see, very useful!!

    Weird that's something important as that seems missing from the documentation.

    Thanks :)