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. Dismiss Notice

How do I make all my normals the same in Shader ?

Discussion in 'Shaders' started by JonnyHilly, Jun 21, 2016.

  1. JonnyHilly

    JonnyHilly

    Joined:
    Sep 4, 2009
    Posts:
    742
    I'm trying to modify the normal for lighting within a shader ( learning cg ) but while experimenting just writing 2 simple lines of code produces confusing output, can you help me understand please.

    I put my shader on a sphere... then did this in the pixel shader ...
    o.Albedo = .5; //grey This turns the color grey
    o.Normal = 1; // make all pixel normals the same...
    But this still produces lighting that looks like a ball... why ?
    if I put o.Normal=0 I get black ball, which makes sense...
    please explain why ball is still lit, round looking ? thanks

    I actually need the normals in Vertex shader for some vertex shader processing, but then I want it to ignore the vertex normals when doing lighting in pixel shader, and just use the warped normals I am generating from my own texture.
    I think that Unity uses the vertex normals in the lighting model, and combines with the normals output from pixel shader... (my guess) How can I make it ignore the vertex normals, but still use the pixel shader normals ?
    Cheers
     
  2. MSplitz-PsychoK

    MSplitz-PsychoK

    Joined:
    May 16, 2015
    Posts:
    1,278
    I honestly have no idea what "o.Normal = 1;" does, a Normal should be a float3 with a length of 1. If your shader has a shader Fallback, especially if the fallback is a lit shader (like diffuse or vertextLit), the shadows and lighting often come from the callback, so you could try commenting that out.

    Set o.Normal to whatever you want Unity to use for lighting, and use a separate register (I recommend the first free TEXCOORD register) to send your custom normals from the vertex shader to your frag shader.

    If you want more specific help, please post your shader code
     
  3. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,209
    If you're using o.Normal I assume you're using a surface shader. Surface shaders are expecting a tangent space normal set as o.Normal, which is to say a half3 vector direction normals that offset the existing mesh's vertex normals. If you want to force the normals do be a direction that's in world space or object space and ignores the vertex normal from the pixel shader you cannot use surface shaders.
     
  4. JonnyHilly

    JonnyHilly

    Joined:
    Sep 4, 2009
    Posts:
    742
    @gambit, sorry, I also tried normalize(float3(1,1,1)) for the output with the same result.

    the code is a jumbled mess of experimentation currently... I'll try to tidy it up and post it tonight if I don't make progress.
     
    Last edited: Jun 21, 2016
  5. JonnyHilly

    JonnyHilly

    Joined:
    Sep 4, 2009
    Posts:
    742
    Thanks for reply. yes, using vertex and pixel shader. I need the vertex normals for my calculation in vertex shader, but then I want unity to ignore them in the lighting in the pixel shader... I want to only send pre pixel / screen space normals, but with the normals from vertices ignored (as if all are facing directly at the camera)

    So it seems like I cannot do what I want to do, only way would be to hack the vertex normals on the geometry to all point towards the camera.
     
    Last edited: Jun 22, 2016
  6. JonnyHilly

    JonnyHilly

    Joined:
    Sep 4, 2009
    Posts:
    742
    here is the gist of it...with code below I got a screen overlay texture (that will eventually be a normal map)
    I figured out how to map it onto objects on the screen (parallel projection)
    I need the normals of the objects for a separate render,
    but in this shader, I need the vertex normals to be ignored (as if they are all facing the camera)
    but it still needs to do lighting in the surface shader, based on o.Normal

    Currently I'm just trying to get it to render a sphere, without the lighting so it looks like a flat color circle... but it still getting lit as a round object.

    another way to put it... I wand fragment pixel lighting, but with it ignoring the vertex normals somehow ?


    //get the screen space position, so I can use it as a UV into my screen space normal map texture
    void vert (inout appdata_full v, out Input o)
    {
    UNITY_INITIALIZE_OUTPUT(Input,o);
    o.locPos=mul(UNITY_MATRIX_MVP,v.vertex);
    o.locPos = ComputeScreenPos(o.locPos);

    }

    void surf (Input IN, inout SurfaceOutput o)
    {
    //map the screen space to our texture
    float2 uv_Map.xy= (IN.locPos.xy/IN.locPos.w);
    uv_Map.y *= aspect;
    float4 texcol = tex2D(_MetaMap, uv_Map);

    //test flat lighting
    //o.Albedo = texcol.rgb;
    o.Albedo = .5; //grey
    o.Normal=normalize(float3(1,1,1));
    o.Alpha = 1;
    }
     
  7. JonnyHilly

    JonnyHilly

    Joined:
    Sep 4, 2009
    Posts:
    742
    isn't there a way to specify an Unlit pixel shader, then do my own lighting code in the pixel shader ? I tried "Lighting Off" but that had no effect
     
    Last edited: Jun 22, 2016
  8. Peter77

    Peter77

    QA Jesus

    Joined:
    Jun 12, 2013
    Posts:
    6,405
    Did you find the Vertex and Fragment Shader Examples page already?
     
  9. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,209
    A surface shader is essentially a vertex / fragment shader generator. It assumes some common functionality, like tangent space normals.

    However there's no reason you can't do it all in a custom vertex / fragment shader, again that's all a surface shader really is in the end. You can try modifying the generated shader by selecting the surface shader and clicking on show generated code.

    Alternatively you can write your own from scratch.
    http://docs.unity3d.com/Manual/SL-VertexFragmentShaderExamples.html

    Or you could keep using the surface shader and replace the vertex normal and tangent with ones aligned with the screen after you've done what you need with them.

    I highly recommend this tutorial:
    http://www.alanzucconi.com/2015/06/10/a-gentle-introduction-to-shaders-in-unity3d/
     
  10. JonnyHilly

    JonnyHilly

    Joined:
    Sep 4, 2009
    Posts:
    742
    Thanks for help,
    I used to write quite a bit of hlsl shaders from scratch (it felt a lot simpler without all the various options available in unity shader coding for some reason)

    yep I've looked through tutorials a couple of times. When writing from scratch, things are not very obvious with shaders though... I figure out a plan first ... but then trying to figure out how to implement that shader code is the hard part, as there are these hidden restrictions, or things you learn on the way (like not being able to alter the vertex normals in the vertex shader)
    getting closer to goal though.. thanks for help, I'll checkout those links also