Skip to content

Instantly share code, notes, and snippets.

@aras-p
Last active April 27, 2020 11:13
Show Gist options
  • Star 7 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save aras-p/3d19b806d3fb7d386125 to your computer and use it in GitHub Desktop.
Save aras-p/3d19b806d3fb7d386125 to your computer and use it in GitHub Desktop.
Custom BRDFs in deferred shading/lighting in Unity

So, https://twitter.com/sunjammer/status/569925239989256192 and https://twitter.com/sunjammer/status/569983534368206848

Now, depends on whether you want custom BRDF in deferred on 1) all your objects (easy) or 2) only some of your objects (harder).

1. change BRDF for everything

That's fairly easy. The actual object shaders more or less just fill the g-buffer (and in Unity 4.x deferred lighting, combine textures with the lighting buffer in the final pass). The actual BRDF is in the "light shader". Start by copying the built-in light shader (4.x deferred lighting: Internal-PrePassLighting.shader; 5.0 deferred shading: Internal-DeferredShading.shader) into your project. In 4.x, put it into Resources folder so it's included into the build; in 5.0 point Unity to use that shader under Project Settings -> Graphics.

Change the shader to do different BRDF.

Profit.

2. Change BRDF for some objects only

This is harder, since when the lighting pass happens, it operates only on the g-buffer in screen space and light data - there's no knowledge of the objects at all. So to get different BRDFs, you'd have to somehow mark them in the g-buffer, and then branch based on that in the light shader.

In 5.0 deferred shading that should be fairly easy, since finding a bit or two in the g-buffer isn't hard. In 4.x deferred lighting it might be harder, since g-buffer is already tiny (32 bits and a Z buffer). Perhaps normals, instead of being in RGB channels, could be put into RG + one bit of B (for normal sign), and you'd use the rest of B bits to encode which BRDF to use.

And then in the light shader (everything from section 1 above) branch on that, and do one or another BRDF as needed.

"BRDF ramp material that will work with in deferred (for HDR)"

If all you need is HDR, then you don't need to use deferred, right? HDR works in Forward rendering fine in Unity. As far as I can tell :)

"Why is IN.viewDir different in forward & deferred?"

More context needed, I guess? I'll assume this is about surface shaders. I frankly don't remember, but it could be that in Unity 4.x in some cases the "space that vectors are in" was local object space. Generally, in surface shaders the various vectors you have (view, normal, reflection etc.) will all be in the same space, but you don't quite know which one. I think the graphics team changed that for Unity 5.0, where things are generally in world space. Not sure, would have to check.

@ArieLeo
Copy link

ArieLeo commented Oct 5, 2015

Hi aras, some question

  • is there an example for 2nd point in Unity5?
  • What is the best technique to mark an object to use custom brdf in unity, an additional MaterialID buffer?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment