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

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.

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.

@bgolus

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

@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.

1 Like