HLSL - Flat Shading

  • (2 Pages)
  • +
  • 1
  • 2

24 Replies - 4946 Views - Last Post: 31 August 2012 - 07:49 AM Rate Topic: -----

#16 stayscrisp  Icon User is offline

  • フカユ
  • member icon

Reputation: 1000
  • View blog
  • Posts: 4,181
  • Joined: 14-February 08

Re: HLSL - Flat Shading

Posted 30 August 2012 - 08:58 AM

Nice work, but I really wouldn't be doing per-pixel lighting on blocks like you have. If you look at the example I gave it uses per-vertex lighting which is a lot faster. When doing per-vertex lighting you cut the amount of processes needed dramatically and you will not even notice a dip in quality for flat surfaces such as yours.

Per-pixel lighting is usually done only if you are also doing another effect with it such as bump mapping. Bear this in mind, there are 3 vertices in a triangle yet how many pixels in between?
Was This Post Helpful? 0
  • +
  • -

#17 ichkanns  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 13
  • Joined: 24-August 12

Re: HLSL - Flat Shading

Posted 30 August 2012 - 09:08 AM

View Poststayscrisp, on 30 August 2012 - 08:58 AM, said:

Nice work, but I really wouldn't be doing per-pixel lighting on blocks like you have. If you look at the example I gave it uses per-vertex lighting which is a lot faster. When doing per-vertex lighting you cut the amount of processes needed dramatically and you will not even notice a dip in quality for flat surfaces such as yours.

Per-pixel lighting is usually done only if you are also doing another effect with it such as bump mapping. Bear this in mind, there are 3 vertices in a triangle yet how many pixels in between?


Indeed, but I don't think I have a choice. I tried your shader and it didn't work. I need the surface normals, but unfortunately I'm only given the vertex normals which mean I have to calculate the surface normals. Since a vertex is dealing with the intersection of surfaces I can't really single one out in the vertex shader, thus it needs to be done in the pixel shader. If there were some way that I could only calculate the lighting once for every face, that would be awesome, but I've found no way of doing that.

Thanks for the help though!
Was This Post Helpful? 0
  • +
  • -

#18 stayscrisp  Icon User is offline

  • フカユ
  • member icon

Reputation: 1000
  • View blog
  • Posts: 4,181
  • Joined: 14-February 08

Re: HLSL - Flat Shading

Posted 30 August 2012 - 09:21 AM

You don't single one out, you calculate the lighting for each vertex in the triangle and then linearly interpolate the colour across the pixels. What did the shader example I posted do?
Was This Post Helpful? 0
  • +
  • -

#19 ichkanns  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 13
  • Joined: 24-August 12

Re: HLSL - Flat Shading

Posted 30 August 2012 - 09:31 AM

View Poststayscrisp, on 30 August 2012 - 09:21 AM, said:

You don't single one out, you calculate the lighting for each vertex in the triangle and then linearly interpolate the colour across the pixels. What did the shader example I posted do?


That's what I'm saying I don't want it to do. I don't want it to do any interpolation. I just want a surface to be a single shade of light across the whole surface. You're shader did exactly what my shader did when I tried the same thing and that is that it diffused the light across each block, making the shade interpolate across the block. Which would be fine if I wanted it to look like there are rounded edges, but I don't. I want a flat surface to look flat.
Was This Post Helpful? 0
  • +
  • -

#20 BBeck  Icon User is offline

  • Here to help.
  • member icon


Reputation: 580
  • View blog
  • Posts: 1,287
  • Joined: 24-April 12

Re: HLSL - Flat Shading

Posted 30 August 2012 - 02:10 PM

So far, I've only had a couple of ideas. The first is to go into the model file (.fbx or whatever) and set all the normals to face in the upward or downward direction. I think that "might" work.

Another idea that I had was to calculate the face normal externally and pass it in as a parameter, resetting it every time you move to a new face. You would probably still end up passing it in for every vertex multiple times, but it could be seperate from the vertex normal. Maybe that's a lot easier said then done. I'm not even sure exactly how you would do that.

But if I were going to write this game, I would probably not use models. I would probably create the "cubes" procedurally and just make them planes, or flat panels. That would avoid having geometry for the non-visable parts of the cubes. Then they would be planes and you could easily define all the normals pointing in the same direction. And it might greatly reduce the amount of drawing you're doing if you're drawing a lot of cube parts that aren't actually visable.

I'm currently doing this with my floor tiles in my current project. Each floor tile quad is a mesh of exactly two triangles. They touch at all their edges, with no gap, and so they appear to be one piece. The lighting lights across the entire surface because they all have their normals pointing straight up. So, as you move the specular highlight moves across the floor. You could take it one step further and draw quads for the visible sides of the cubes as well.

But by breaking the cube up into 6 planes, you can define 3 different normals for every facing of each vertex.

It seems to me that there has to be a way to do what you are wanting in the shader, but I still haven't figured out how to do it. But I can say that making a cube out of 6 planes allows you to put seperate textures on each surface and it also allows you to take the four vertices and point them all in the same direction; every plane can have all the normals on that plane facing the same direction.

I'm pretty sure that would work for you. I don't know if you want to do that or not. I was a little worried about how it would affect performance, making every quad a seperate mesh rather then having the entire floor as a single mesh, but haven't noticed any perforance issues so far.

I worked on someone else's project that had the exact same issue this week, where the normals were causing it to draw unevenly across the face of a cube. That was using the built in BasicEffect. So, I think this is really an issue of the normals rather than the fact that it's a custom shader.

Flat shading seems to really have fallen out of vogue. I haven't really even seen any discussion of it in the books I'm reading.

Anyway, I'm still reading up on HLSL. I'll let you know if I come up with any more crazy schemes. ;-)

This post has been edited by BBeck: 30 August 2012 - 02:12 PM

Was This Post Helpful? 1
  • +
  • -

#21 ichkanns  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 13
  • Joined: 24-August 12

Re: HLSL - Flat Shading

Posted 30 August 2012 - 02:18 PM

View PostBBeck, on 30 August 2012 - 02:10 PM, said:

So far, I've only had a couple of ideas. The first is to go into the model file (.fbx or whatever) and set all the normals to face in the upward or downward direction. I think that "might" work.

Another idea that I had was to calculate the face normal externally and pass it in as a parameter, resetting it every time you move to a new face. You would probably still end up passing it in for every vertex multiple times, but it could be seperate from the vertex normal. Maybe that's a lot easier said then done. I'm not even sure exactly how you would do that.

But if I were going to write this game, I would probably not use models. I would probably create the "cubes" procedurally and just make them planes, or flat panels. That would avoid having geometry for the non-visable parts of the cubes. Then they would be planes and you could easily define all the normals pointing in the same direction. And it might greatly reduce the amount of drawing you're doing if you're drawing a lot of cube parts that aren't actually visable.

I'm currently doing this with my floor tiles in my current project. Each floor tile quad is a mesh of exactly two triangles. They touch at all their edges, with no gap, and so they appear to be one piece. The lighting lights across the entire surface because they all have their normals pointing straight up. So, as you move the specular highlight moves across the floor. You could take it one step further and draw quads for the visible sides of the cubes as well.

But by breaking the cube up into 6 planes, you can define 3 different normals for every facing of each vertex.

It seems to me that there has to be a way to do what you are wanting in the shader, but I still haven't figured out how to do it. But I can say that making a cube out of 6 planes allows you to put seperate textures on each surface and it also allows you to take the four vertices and point them all in the same direction; every plane can have all the normals on that plane facing the same direction.

I'm pretty sure that would work for you. I don't know if you want to do that or not. I was a little worried about how it would affect performance, making every quad a seperate mesh rather then having the entire floor as a single mesh, but haven't noticed any perforance issues so far.

I worked on someone else's project that had the exact same issue this week, where the normals were causing it to draw unevenly across the face of a cube. That was using the built in BasicEffect. So, I think this is really an issue of the normals rather than the fact that it's a custom shader.

Flat shading seems to really have fallen out of vogue. I haven't really even seen any discussion of it in the books I'm reading.

Anyway, I'm still reading up on HLSL. I'll let you know if I come up with any more crazy schemes. ;-)


Well I do know that the shader I posted works. So if you want to use it for that project feel free. You can see the picture attached to it so see how it's shading the whole side equally. Thanks for all the help. The discussion has helped a lot. I'm still open to suggestions on how it can be accomplished in the vertex shader if anyone has any thoughts.
Was This Post Helpful? 0
  • +
  • -

#22 BBeck  Icon User is offline

  • Here to help.
  • member icon


Reputation: 580
  • View blog
  • Posts: 1,287
  • Joined: 24-April 12

Re: HLSL - Flat Shading

Posted 30 August 2012 - 02:29 PM

I missed the post where you solved it. Sorry.

Anyway, cool! Glad you figured it out.

I'm going to go read through your code and see what you did.
Was This Post Helpful? 0
  • +
  • -

#23 stayscrisp  Icon User is offline

  • フカユ
  • member icon

Reputation: 1000
  • View blog
  • Posts: 4,181
  • Joined: 14-February 08

Re: HLSL - Flat Shading

Posted 31 August 2012 - 06:13 AM

View Postichkanns, on 30 August 2012 - 05:31 PM, said:

That's what I'm saying I don't want it to do. I don't want it to do any interpolation. I just want a surface to be a single shade of light across the whole surface.


Ah, I guess I misunderstood. In that case you can just pass in ShadeMode = Flat;


pass Pass1
{
    ShadeMode = Flat;
    VertexShader = compile vs_3_0 VertexShaderFunction();
    PixelShader = compile ps_3_0 PixelShaderFunction();
}


Was This Post Helpful? 0
  • +
  • -

#24 ichkanns  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 13
  • Joined: 24-August 12

Re: HLSL - Flat Shading

Posted 31 August 2012 - 07:22 AM

View Poststayscrisp, on 31 August 2012 - 06:13 AM, said:

View Postichkanns, on 30 August 2012 - 05:31 PM, said:

That's what I'm saying I don't want it to do. I don't want it to do any interpolation. I just want a surface to be a single shade of light across the whole surface.


Ah, I guess I misunderstood. In that case you can just pass in ShadeMode = Flat;


pass Pass1
{
    ShadeMode = Flat;
    VertexShader = compile vs_3_0 VertexShaderFunction();
    PixelShader = compile ps_3_0 PixelShaderFunction();
}


One of the first things I tried. Apparently it is out of use and when you try to compile it simply says it's obsolete and no longer in use. I wish it were that simple... I thought it was at first. But no...
Was This Post Helpful? 0
  • +
  • -

#25 stayscrisp  Icon User is offline

  • フカユ
  • member icon

Reputation: 1000
  • View blog
  • Posts: 4,181
  • Joined: 14-February 08

Re: HLSL - Flat Shading

Posted 31 August 2012 - 07:49 AM

Ah, didn't realise it was deprecated. Maybe you now have to set it in the application, there used to be a choice. It should still exist though somewhere. But hey, you got it working anyway, it's just a thought for any possible future performance issues :)
Was This Post Helpful? 1
  • +
  • -

  • (2 Pages)
  • +
  • 1
  • 2