Jump to content


Reflections - environment mapping


  • You cannot reply to this topic
10 replies to this topic

#1 Xcrypt

    New Member

  • Members
  • PipPipPip
  • 132 posts
  • LocationBelgium

Posted 20 November 2011 - 12:43 AM

I'm playing around a bit with shaders atm and I'm not sure how I have to display certain stuff realistically, how does reflection work, how does ambient and emissive work, and how do they add up?

//1
float3 col = m_ColEmissive * m_TexDiffuse.Sample(m_Sampler, input.tex);

//An object could possibly have an emissive colour. I supposed this also lights up the diffuse colour, is this correct?

//2
col += input.lighting.x * m_TexDiffuse.Sample(m_Sampler, input.tex);

//Diffuse texture gets lit by the diffuse lighting, and adds to the previous colour

//3
col += input.lighting.y * m_TexSpecular.Sample(m_Sampler, input.tex);

//Specular texture gets lit by the specular lighting and adds to the previous colour

//4
col += lerp(m_ColAmbient,m_CubeMap.Sample(m_SamplerCube, input.vReflected)*m_ReflectionAmount , m_AmbientReflectionLerp);

//I'm especially hesitant about this part.
I'm not sure if ambient light is supposed to be multiplied with the diffuse color or add to it. Same with the environment mapping(cubemap) reflection, is it supposed to add to the previous colour, or act as additional light, aka multiplying the diffuse colour with the reflection?

#2 Reedbeta

    DevMaster Staff

  • Administrators
  • 4974 posts
  • LocationBellevue, WA

Posted 20 November 2011 - 07:12 AM

1. I'd probably have a separate texture for the emissive color. This will let you do things like make part of an object emissive and other parts not, like a neon sign for example.
2. 3. I'm assuming the "input.lighting" vector includes the actual diffuse and specular light formulas.
4. The ambient light should be multiplied by the diffuse texture, and the reflection should be multiplied by the specular texture; these should both be added to the other forms of light.

Basically, think of the ambient term as diffuse reflection of everything in the scene but the light sources (e.g. sky, indirect illumination etc.); and the environment map as specular reflection of everything in the scene but the light sources.

You might want to read the presentations here: http://renderwonk.co...shading-course/ (at least the two by Naty Hoffman). I've been recommending these to everyone who asks about how shaders work. :) In my opinion, physically based lighting/shading is extremely important for nailing the "realistic" look...there is a lot of material to learn, though, and it's not always intuitive.
reedbeta.com - developer blog, OpenGL demos, and other projects

#3 Xcrypt

    New Member

  • Members
  • PipPipPip
  • 132 posts
  • LocationBelgium

Posted 20 November 2011 - 12:02 PM

Oh that's totally awesome, thanks!

EDIT: Tough material though, indeed :p I wish I had the knowledge necessary to understand all of it.

#4 Xcrypt

    New Member

  • Members
  • PipPipPip
  • 132 posts
  • LocationBelgium

Posted 23 January 2012 - 08:26 PM

Reedbeta, I have a question about specular maps that follow from IRL observation:

Why do we separate a specular map from an environment map? This really confuses me, since you first posted this.
It seems to belong together, I mean, "specular" is just reflection right? The reason it lights up a little is just because of the light travelling and bouncing off the surface, and has nothing to do with the position of the viewer (except when the model of the viewer occludes the lightsource in a specific direction), or am I wrong about that?

I guess my question could be quite simply put by: What exactly is "specular"? I read through most parts of those presentations but I still don't quite get it

#5 Reedbeta

    DevMaster Staff

  • Administrators
  • 4974 posts
  • LocationBellevue, WA

Posted 23 January 2012 - 10:32 PM

Physically, specular and reflection are exactly the same thing. What we usually call "specular" in rendering is just the reflected image of a light source, typically a point light. In theory, you could do it all with an environment map, if it's HDR, since you could just render all the lights into the cubemap and, (assuming that you have correct filtering on the environment map) then they'd be reflected correctly along with the rest of the environment.

Specular reflection depends on the position of the viewer because when light reflects off a surface it sends different amounts of light in different directions. So depending on where you are, you see more or less of the specular reflection. In fact this could be considered a definition of specular: that part of the BRDF that is view-dependent (the view-independent component being the diffuse).

In practice, we often separate things into "light sources" (done with specular equations in the shader) and "everything else" (done with a cubemap). There are three reasons for this, as I see it. First, historically (and even sometimes today) the cubemap was not HDR and so could not include the lights with a high enough brightness. Second, a cubemap is technically only valid for one point, so when it's applied to surfaces away from the point where it was captured, it's incorrect to a greater or lesser extent. When you calculate the light sources analytically you don't have this problem, so you get correct parallax and placement of the specular highlights relative to the lights. Third, it's actually hard to filter on a cubemap in a way that's consistent with sophisticated BRDF models like Cook-Torrance, since the necessary filtering would be view-dependent. Most people approximate by just using Phong filtering on cubemaps (pre-blurring the cubemap by a cosine power filter). This approximation isn't necessary for point lights, where you can actually evaluate the full BRDF and get better quality results.

It's kind of a tradeoff between the complexity of the lighting environment vs the complexity of the BRDF. Doing both at full complexity is hard, so we compromise by combining simplified lighting and full, complex BRDF (specular lighting), or simplified BRDF and full, complex lighting (Phong-filtered cubemap). Both approximations are useful for different things, namely the former for small, very bright objects (light sources) and the latter for most everything else.
reedbeta.com - developer blog, OpenGL demos, and other projects

#6 Xcrypt

    New Member

  • Members
  • PipPipPip
  • 132 posts
  • LocationBelgium

Posted 24 January 2012 - 01:25 AM

Thanks a lot for clarifying :)
I hope in the future we can use full complexity for both!

By the way, another question, if you don't mind: since you're a graphics programmer, you're probably familiar with shader models such as "Ward anisotropic distribution" and so on. Now, these shader models all really interest me, but when I get a (in my opinion) complex formula like this: http://upload.wikime...ae4d51eaffe.png
I just get confused like fuck (sorry :P)

I 'understand' easier models like phong and blinn-phong, but I think that's about all.
In my current studies, they teach us how to implement shaders like these (most complex so far was Cook Torrance),
but we're not supposed to actually understand them, which is the lamest thing ever (again, in my opinion)

I really want to understand these formulas, but I don't know where to start when I get a formula like that.

I first thought of studying Comp Sci, but then again I'm not really sure if that's going to help, it's not like they teach you advanced math (or am I wrong about that?).
I enjoy low(er)-level programming, messing around with formulas and learning new theories, but I'm only a bit above average at math and physics (maybe because I never cared before, idk?).
There's also very little time for self-study in a game-dev course, everything is utter chaos and bullshit workload all the time (not that I have a problem with working hard, it's what we actually do that annoys me). Their philosophy seems to be: "As long as my code is working, I'm happy about it. I don't give a damn about the rest". I'm quite sure that this is not the road I want to follow...

You seem to understand most of these formulas that I seem to struggle so hard with,
so could you point me in the right direction?
Should I take a math course and do self-study on CS, or the other way around?

EDIT: btw, sorry if I'm asking too many questions. I'm just curious as to how stuff works, and these are questions I can't ask my teachers, because they don't know that either...

#7 Reedbeta

    DevMaster Staff

  • Administrators
  • 4974 posts
  • LocationBellevue, WA

Posted 24 January 2012 - 01:59 AM

What are you asking for help with - the mechanics of the formula (what does the notation mean, what are the variables supposed to be, etc.) or understanding it conceptually? As far as conceptual stuff goes, these shaders are typically based on microfacet theory, and the Naty Hoffman papers I linked to above really give the most accessible explanation of microfacet theory that I've seen. If you have specific questions about something in those papers or some specific BRDF you've found I can try to answer those too.
reedbeta.com - developer blog, OpenGL demos, and other projects

#8 Xcrypt

    New Member

  • Members
  • PipPipPip
  • 132 posts
  • LocationBelgium

Posted 24 January 2012 - 02:26 AM

I understand the microfacet theory. It's the formulas that don't seem to make sense to me.
I don't always know the notation, but that's not really a problem, I can look that up. The problem is that I can't seem to make anything of the (more complex) formula as a whole, eg the way the parameters get combined, and why

But the maybe most important question here is what do you think I should study, in order to achieve this?
It's not that I want to go "full math", but I want to be able to understand the mathematical and physical side of computer science

#9 Reedbeta

    DevMaster Staff

  • Administrators
  • 4974 posts
  • LocationBellevue, WA

Posted 24 January 2012 - 07:07 AM

Hmm, I'm not sure I see just where the hang-up is. BRDFs are just a quantitative expression of microfacet theory and other bits and pieces of optics (e.g. Fresnel). If you're looking for derivations of the BRDF equations, you'll probably have to read the papers that introduced them. These papers are often very dense and hard to understand, so it's a good idea to skim it first to get a high-level overview of what they're doing, then reread carefully, one sentence at a time, relating everything to what the paper said previously. There will probably be some parts you can't understand immediately because they're not explained clearly enough or they assume some background knowledge you don't have, but sometimes you can come back and understand more on a second or third reading.

Naty Hoffman's Crafting Physically-Motivated Shading Models paper also includes a pretty step-by-step explanation of how the Cook-Torrance BRDF is built up, factor by factor, with diagrams showing the effect of each part. It's on pages 4-10, roughly, of that paper. If you read that carefully you should have a fairly good understanding of that BRDF.

Most others that you'll find out there are a variation on Cook-Torrance in some way. For example, that Ward BRDF you posted looks very similar to a Cook-Torrance BRDF where the distribution function (the D(h) function in Naty Hoffman's paper) is a Gaussian distribution (the exp(stuff) in the Ward function) based on comparing the h vector (half-angle) vector to two tangent vectors (X and Y) with two roughness values (a_x and a_y). Setting a_x and a_y to different values causes the specular highlights to spread more along one direction than another, which gives you the asymmetrical highlights that you see on hair, brushed metal, and things like that. The Ward function is missing a Fresnel factor (maybe with good reason) and has some different factors out front (the 1/sqrt(stuff) and 1/ (4 a_x a_y)), which is probably some combination of normalization of the Gaussian, and the Cook-Torrance geometry factors, but you'd have to check Ward's original paper to be sure.
reedbeta.com - developer blog, OpenGL demos, and other projects

#10 Stainless

    Member

  • Members
  • PipPipPip
  • 275 posts
  • LocationIckleford

Posted 24 January 2012 - 10:23 AM

I often have to "read" equations like that, and at first it's just a mess of rubbish. Looks like an ant stepped in some ink and went for a walk on a piece of paper.

The only way I have found to understand these equations is to break them down slowly.

Start with the bits you do recognise. N.L you should be well familiar with now. Same for N.R so you know what they are.

Rewrite the equations with the bits you do understand replaced by a descriptive word. Replace all constants with a single variable C and look at it again.

Then pick one of the terms you do not understand and research it, this can be the difficult part as entering an equation into google doesn't produce good results, but usually the equations are in a scientific paper and you can flip through it until you find the relevant passage. When you get your head around that term rewrite the equation again.

Rinse and repeat.

Eventually you will end up with a bunch of known terms and some constants. Then it's just a case of looking at whats left and making sense of it.

(something)/sqrt(something else) usually can be thought of as a kind of normalisation, products can be thought of as blends, (1-t)*something +t*something else is a proportional blend, etc.

The more you do it the quicker you get a feel for the equations.

Does make your head hurt sometimes though. :D

If that doesn't work, then the only way I have found of dealing with it is to write a shader using the equations, making sure that each of the terms is in a separate variable. Then vary the terms you don't understand and see what happens.

Often this makes something obvious that was beyond your knowledge when you started

#11 Xcrypt

    New Member

  • Members
  • PipPipPip
  • 132 posts
  • LocationBelgium

Posted 24 January 2012 - 10:56 AM

Ok, I'll try all that, thanks to both.
Sadly I don't really have much time for it now, but I'll do so first day I get "vacation", and probably take some online courses about mathematics and physics too.

Because really, what is being able to program something, when you don't even understand the problem you just solved.

It's like most of the dudes in my class are like "oooooh, that shader is damn shiny!" without realising what they actually did =3





1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users