0
\$\begingroup\$

While reading on shading, I came across a section in which the artist provides 2 different kinds of fragment shading:

Coloring using model space and eye space.

The result is as illustrated in the following image:

enter image description here

The author goes on with a brief explanation claiming that the image on the left is a result of shading in model space coordinates because the stripes follow the vx value running from the tip of the spout to the handle while the image on the right is based in eye space coordinates, with the stripes following the vx value from right to left.

My questions are as follow:

I have been spending hours trying to understand why and how the effects would be different in both cases (why are the stripes different in both cases?). In addition, is there any particular case when we need to perform shading in the model space coordinates and likewise only in eye space coordinates?

Thanks.

\$\endgroup\$
2
\$\begingroup\$

First, you are misunderstanding the point of the article; these are not two different kinds of fragment shading. This is just an illustration two different coordinate systems.

Which one you use will depend upon which one is more convenient for whatever operations you're doing.

Let's take some simple examples:

Texture Mapping

If you're just doing regular texture mapping, you don't need to think about any of this at all; your fragment shader doesn't need to know where a fragment is in space; just the coordinate to use to sample from a texture map.

Lighting

The simplest form of lighting calculation is float lightAmount = clamp(0,1,dot( -light_direction, surface_normal ));, where 'light_direction' and 'surface_normal' tell you the direction the light is shining and the direction the surface faces.

It doesn't actually matter whether you express these directions in object local space, in world space, or in view space; the math works out exactly the same, as long as both vectors are in the same coordinate system.

In practice, it's awkward to convert the light direction into every object's local space, and so people don't tend to do that. But if you wanted to, you totally could, and there'd be no visible difference.

Folks on the Internet seem to have mostly settled on doing lighting calculations in view space (that is, relative to the camera), so that's mostly what you'll see in online tutorials. But for certain projects it may be simpler to do them in world space. Feel free to do whichever is simpler, or makes more sense for your program.

Uniform Fog

Simple (i.e.: uniform) fog is implemented by simply blending a fragment's color toward some constant value, based upon the distance from that fragment to the camera.

As above, you can do fog calculations in object-local space, in world-space, or in view-space; just take the camera's position in that coordinate system, subtract the fragment's position in that same coordinate system, and find the length of the resulting vector.

Of course, the same problem as with Lighting happens here; converting the camera position into object-local space for every object you render is a pain, so nobody actually does that. But you could, if you really wanted to.

Nobody does fog calculations in world-space, either, even though it'd be easy to do. No, everybody does fog calculations in view-space for one simple reason; in view-space, the camera is, by definition, located at coordinate (0,0,0). And so if you're doing the fog calculation in view-space, you don't have to subtract the camera position from the fragment position, because the camera position is 0; you can just use the fragment position in the fog calculation directly.

But if you really wanted to do your fog calculations in object-local space, or in world-space, you totally could, and it'd work, and nobody would be able to tell you weren't doing it the conventional way unless they actually read your shader code.

That's really all that's going on in that article. Pointing out that there are these different coordinate systems available to you, and you can use whichever ones you like depending upon which is most convenient for whatever you're trying to do. And it isn't about different "kinds" of fragment shading which you must make a hard decision between; it's not unusual to use each of these different coordinate spaces in different parts of a single shader.

\$\endgroup\$
1
\$\begingroup\$

The use of 'shading' here is a bit off from the typical renderer meaning. The author appears to talk about how texture coordinates are computed.

In the first case, texture coordinates are assigned based on the model space positions of the mesh.

In the second case, texture coordinates are computed from the position of the vertices in eye space.

In a realtime renderer, you tend to always have your artist-authored texture coordinates fixed as vertex attributes up-front. Specialist modes like view/world-sourced texture coordinates don't really occur, unless such an effect is explicitly designed into a shader.

\$\endgroup\$
  • \$\begingroup\$ I'm no expert on the matter; but I can imagine that an example of such effect would be a reflectionmap that uses world coordinates? So the diffuse map is in model coordinates but a metallic effect could use world coordinates and a generic metallic texture? \$\endgroup\$ – Felsir Nov 3 '16 at 10:18
  • \$\begingroup\$ Other words, should one always, or for most of the cases, send vertex coordinates to the fragment shader to compute color? I would like to know when we would use one set of coordinates over the other as fas as effects and usage is concerned. \$\endgroup\$ – Unheilig Nov 4 '16 at 2:18
0
\$\begingroup\$

What this looks to me is just sampling form a texture using texcoords.xy and then texcoords.yx or using world space coords like worldpos.xz or worldpos.xy.

worldpos.xz will make the strips go horizontal and worldpos.xy will make them go vertical.

I do this for my triplaner mapping and blend mapping:

float Blend = BlendMap.Sample(colorSampler, input.WSPosition.xz / 2500).r; //flat ground
float Blend2 = BlendMap.Sample(colorSampler, input.WSPosition.yx / 6000).r; // hills


float2 coord1 = float2(input.WSPosition.zy / 400);
float2 coord2 = float2(input.WSPosition.zx / 75);
float2 coord3 = float2(input.WSPosition.xy /400);
\$\endgroup\$
  • \$\begingroup\$ Thanks for input; the author did mention that the stripes were generated and then applied on the teapot using procedural texture rather than using an image as a texture. \$\endgroup\$ – Unheilig Nov 4 '16 at 0:13
  • \$\begingroup\$ could the procedural texture take object space or eye space coords as input to define the direction of the stripes? \$\endgroup\$ – Justin William Stanley Bryant Nov 4 '16 at 0:19
  • \$\begingroup\$ The images are created using model space (left) and eye space (right), respectively. The author only mentions the difference using the above images but did not mention why and how the location and placement of the stripes are different using 2 sets of coordinate space (i.e., model and eye). Thanks. \$\endgroup\$ – Unheilig Nov 4 '16 at 0:21
  • \$\begingroup\$ could the eyespace be horizontal because it only has xy value but for object space its getting the xz value? \$\endgroup\$ – Justin William Stanley Bryant Nov 4 '16 at 0:26
  • \$\begingroup\$ It is mentioned that the stripes on both cases are generated parallel to the YZ plate. \$\endgroup\$ – Unheilig Nov 4 '16 at 0:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.