Search Unity

How to feed in arbitrary world space normals into a surface shader?

Discussion in 'Shaders' started by Skolstvo, Feb 28, 2017.

  1. Skolstvo

    Skolstvo

    Joined:
    Dec 21, 2015
    Posts:
    107
    I'm trying to write a surface shader where you can manually set the surface normal from a fixed3. These normals would be in world space. I specifically would like the shader to look like the standard shader.

    Is there any way to do this without having to write a custom lighting model?

    Essentially each pixel of the surface would just get a new arbitrary normal direction that would be transformed from world space to screen space completely ignoring the tangent direction.
     
  2. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,348
    Not even a custom lighting model would help here. Surface shaders always assume the normal set in the surf function is in tangent space and always transforms it from tangent space to world space before passing it to the lighting function.

    The only option is to use a fully custom vertex fragment shader. However this does not preclude you from using the standard shading model, or even from using a surface shader ... at least to start with. Basically you can write a surface shader, click on the "show generated code" button, and copy that code and remove the parts that do the tangent space transform. Surface shaders are just vertex fragment shader generators, so there isn't anything a surface shader can do that a vertex fragment shader can't, it's just a little more work. Alternatively you can transform your normals from world space into tangent space in the surf function, but that's kind of ugly.
     
  3. Skolstvo

    Skolstvo

    Joined:
    Dec 21, 2015
    Posts:
    107
    @bgolus

    Awesome advice as always. I haven't even though that you can simply change the compiled shader. Thank you very much.
     
  4. Skolstvo

    Skolstvo

    Joined:
    Dec 21, 2015
    Posts:
    107
    @bgolus

    Yeah, I looked at the compiled code and I'm fairly sure it gave me an aneurysm. Changing from world to tangent just to show world seems very dumb on the other hand, and I'm not too sure how to achieve that inside the surface function. Thanks for the help anyway.
     
    briank likes this.