Search Unity

A Couple Questions.

Discussion in 'Shaders' started by LittleRainGames, Sep 11, 2017.

  1. LittleRainGames

    LittleRainGames

    Joined:
    Apr 7, 2016
    Posts:
    97
    1: How can I get the Light Position.


    2: To get the Screen Position, would I use ComputeGrabScreenPos(float4 pos), or ComputeScreenPos(float4 pos), and what goes in the pos?

    I need to know how to do this in the fragment shader, I'm trying to avoid the surface side of things.
     
  2. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,352
    _WorldSpaceLightPos0
    For the ForwardBase pass this is always the directional light's direction and not it's position. The only way to get it's position is with a custom script passing the data manually. For ForwardAdd passes it could be either a directional light direction or point / spot light position. See this:
    https://docs.unity3d.com/Manual/SL-UnityShaderVariables.html

    Probably ComputeScreenPos(). The clip space position, i.e.: the value you're assigning to the variable using the SV_POSITION semantic.
    https://docs.unity3d.com/Manual/SL-BuiltinFunctions.html
     
    LittleRainGames likes this.
  3. LittleRainGames

    LittleRainGames

    Joined:
    Apr 7, 2016
    Posts:
    97
    Ah I was looking for docs like that. Thank you.
    So how would I get all the, lets say point lights color/position data, would I have to use a custom script to pass that data?
    And would I be sending it to a property or how would you send data from a custom script?

    Another little question is what are these doing? #pragma shader_feature _PARALLAXMAP
    I kind of understand that its reusing code from another script, but I'm not really sure what it is referencing.
     
  4. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,352
    The first four "non-important" lights are passed to the ForwardBase pass, or you can get the first 8 lights if using vertex lighting, as per the documentation. If you want all of the lights you would have to pass that data manually.

    Not exactly.
    https://docs.unity3d.com/Manual/SL-MultipleProgramVariants.html

    The multi_compile and shader_feature lines are telling the shader compiler to produce multiple versions of the shader with those keywords enabled and disabled. Those are the shader variants. Elsewhere in the shader you'll see #if lines with that keyword. Those are bits of code that will only be included in the final compiled variant. This allows the game to enable and disable specific features at runtime and not pay the cost for rendering them when not needed while still using "one shader" for several objects. The standard shader for example has tens of thousands of potential variants depending on which texture slots you use, what kinds of lights exist in the scene, if you're using light mapping (and each type of light mapping), and what graphics card you have.

    Now that particular shader_feature line is likely from the standard shader and is enabling something in another file. Those files are included via the #include lines, and those files might have their own #include lines (and those files again, etc.). You can think of the #include line as meaning "take everything in this file and copy / paste it into this file here". The standard shader is a deep rabbit hole to crawl into with all the include files; its several thousand lines of code.
     
  5. LittleRainGames

    LittleRainGames

    Joined:
    Apr 7, 2016
    Posts:
    97
    Ahh ok thanks a lot. I think I'm starting to understand.

    Just to clarify though, the 4/8 lights is for forward only? So is deferred any different?
    And what would the actual code look like? Like how do I pass it to the vertex shader?
     
  6. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,352
    The deferred pass gets no lights at all, apart from what's baked into the ambient SH (ie: the lighting from static lights and GI). This is kind of the whole point of deferred in that the deferred pass for each object needs to know (almost) nothing about lighting. Almost all of the lighting is deferred until later, hence the name.

    If you were to pass the light positions manually?
    https://docs.unity3d.com/ScriptReference/Material.SetVectorArray.html

    Search around for that function. You'll find examples.
     
  7. LittleRainGames

    LittleRainGames

    Joined:
    Apr 7, 2016
    Posts:
    97
    Ahh ok, I'm reading a book called the The CG Tutorial, everything was going good until I got to the lighting.
    Just found out that my shader was all black because I was passing the LightPos/Color to a function in a cginc I wrote. For some reason it works when its just in the shader itself which kind of puzzles me though. Thought I might be getting the lights the wrong way, looking through Unitys cginc files there seems to be a few different functions/variables for the lights.

    Ok yes I am quite familiar with the Material.Set.... I made/am working on an editor tool that uses that extensively. Thought there might be a different way to pass it to the shader then using a hidden property. Never used the arrays though. The shaders in the book are quite different then how you do things in Unity, kind of fun to figure out how to convert them.

    Ok just want to thank you for all your help! I will quit bugging you now. I just want you to know I really appreciate everything!

    Edit: Oh Man, really sorry, just one last question, how do I declare a vector array in the Properties???

    Edit: Ok I figured it out, no need to create a hidden property. But for some reason it does not want to update the shader, although when you Get the array the new value will be there. For some reason a regular color, non array will update the shader though. No need to help, just sayin.
     
    Last edited: Sep 13, 2017