• Announcements

    • khawk

      Download the Game Design and Indie Game Marketing Freebook   07/19/17

      GameDev.net and CRC Press have teamed up to bring a free ebook of content curated from top titles published by CRC Press. The freebook, Practices of Game Design & Indie Game Marketing, includes chapters from The Art of Game Design: A Book of Lenses, A Practical Guide to Indie Game Marketing, and An Architectural Approach to Level Design. The GameDev.net FreeBook is relevant to game designers, developers, and those interested in learning more about the challenges in game development. We know game development can be a tough discipline and business, so we picked several chapters from CRC Press titles that we thought would be of interest to you, the GameDev.net audience, in your journey to design, develop, and market your next game. The free ebook is available through CRC Press by clicking here. The Curated Books The Art of Game Design: A Book of Lenses, Second Edition, by Jesse Schell Presents 100+ sets of questions, or different lenses, for viewing a game’s design, encompassing diverse fields such as psychology, architecture, music, film, software engineering, theme park design, mathematics, anthropology, and more. Written by one of the world's top game designers, this book describes the deepest and most fundamental principles of game design, demonstrating how tactics used in board, card, and athletic games also work in video games. It provides practical instruction on creating world-class games that will be played again and again. View it here. A Practical Guide to Indie Game Marketing, by Joel Dreskin Marketing is an essential but too frequently overlooked or minimized component of the release plan for indie games. A Practical Guide to Indie Game Marketing provides you with the tools needed to build visibility and sell your indie games. With special focus on those developers with small budgets and limited staff and resources, this book is packed with tangible recommendations and techniques that you can put to use immediately. As a seasoned professional of the indie game arena, author Joel Dreskin gives you insight into practical, real-world experiences of marketing numerous successful games and also provides stories of the failures. View it here. An Architectural Approach to Level Design This is one of the first books to integrate architectural and spatial design theory with the field of level design. The book presents architectural techniques and theories for level designers to use in their own work. It connects architecture and level design in different ways that address the practical elements of how designers construct space and the experiential elements of how and why humans interact with this space. Throughout the text, readers learn skills for spatial layout, evoking emotion through gamespaces, and creating better levels through architectural theory. View it here. Learn more and download the ebook by clicking here. Did you know? GameDev.net and CRC Press also recently teamed up to bring GDNet+ Members up to a 20% discount on all CRC Press books. Learn more about this and other benefits here.
Sign in to follow this  
Followers 0
Alexaroth

Phong shading issue in directx

9 posts in this topic

This has been bugging me for several days now and I can't really figure out if this is actually a problem or not!

 

This is a low poly sphere 

 

yDbXbF0.jpg

 

I'm using phong shading and the normals provided by blender when exporting the sphere object.

 

This is a higher poly count sphere:

 

Hjqn53Q.jpg

 

As you can notice, the edges are still visible and that is driving me insane. I'm using Blender's vertex normals so those values should be correct.  

 

The only thing left that could be wrong is the FX file, which again, should be okay.

 

Here is the code for it: 

 

VS_OUTPUT VS(float4 inPos : POSITION, float2 inTexCoord : TEXCOORD, float3 normal : NORMAL)
{
    VS_OUTPUT output;

    output.Pos = mul(inPos, WVP);	
    output.worldPos = mul(inPos, World);
    output.normal = mul(normal, World);
    output.TexCoord = inTexCoord;

    float4 worldPosition = mul(inPos, World);

    output.viewDirection = normalize(cameraPos - worldPosition);
	
    return output;
}

float4 PS(VS_OUTPUT input) : SV_TARGET
{
    float3 reflection;
    float4 specular;

    input.normal = normalize(input.normal);
	
    float4 tex = ObjTexture.Sample(ObjSamplerState, input.TexCoord);

    float3 finalColor = float3(0.0f, 0.0f, 0.0f);
    specular = float4(0.0f, 0.0f, 0.0f, 0.0f);
	
    //Create ambient
    float3 finalAmbient = tex * light.ambient;
	
    //Create the vector between light position and pixels position
    float3 lightToPixelVec = light.pos - input.worldPos;
		
    //Find the distance between the light pos and pixel pos
    float distance = length(lightToPixelVec);
	
    //If pixel is too far, return
    if( distance > light.range )
	return float4(finalAmbient, tex.a);
		


	//Turn lightToPixelVec into a unit length vector describing the pixels direction from the lights position
	lightToPixelVec /= distance; 
	
	//Calculate how much light the pixel gets by the angle in which the light strikes the pixels surfaec
	float howMuchLight = dot(input.normal, lightToPixelVec);
	
	
	reflection = normalize(2 * input.normal + lightToPixelVec); 
	specular = pow(saturate(dot(reflection, input.viewDirection)), light.specularPower);
	

	//If light is striking the front side of the pixel
	if( howMuchLight > 0.0f )
	{	

      	finalColor += howMuchLight * tex * light.diffuse + specular;		

        // falloff factor
	finalColor /= light.att[0] + (light.att[1] * distance) + (light.att[2] * (distance*distance));
	
	}	
	    
	finalColor = saturate(finalColor + finalAmbient);	
	return float4(finalColor, tex.a);
}

 

 

The code is simplified so that only the relevant light stuff is shown. Nothing too fancy, so I would immensely appreciate if someone could tell me why I simply can't get phong shading to work properly.

Edited by Alexaroth
0

Share this post


Link to post
Share on other sites

Are you sure that your vertex normals are smooth? Try just using vertex normal as the RGB values of the color returned by your pixel shader, and make sure that they look smooth.

1

Share this post


Link to post
Share on other sites

Are you sure that your vertex normals are smooth? Try just using vertex normal as the RGB values of the color returned by your pixel shader, and make sure that they look smooth.

 

Indeed it seems the FX file is okay...

 

 

I decided to try a hack and set all the normals to the value of the actual x y and z position (which for a centred sphere they also represent the smoothest possible normals)

 

HAgYl8W.jpg

 

 

Surprise, surprise.... 

 

Well, now I am down to the normals... I need to change them in the model loader, but what do I need to do to them? Is blender at fault for this?


In the .obj file each vertex has it's own normal so what could I possible do to them further?

0

Share this post


Link to post
Share on other sites

Also, tried your suggestion (previous 'broken' normals as RGB). I'm not sure on how to interpret this (what should I be looking for?)

 

knXf5iM.jpg

0

Share this post


Link to post
Share on other sites

The banding in the image tells you the normals aren't completely smooth, there should be no banding other then that of the monitor on a sphere, loook at the arrows in the linked image those ridges shouldn't be there. Anyway for any sphere in space the easiest way to calculate the normal is the direction from the center point of the sphere to the vertex itself and then normalise that vector.

 

Also when rendering out normals red means the normal is directed mostly in the x-axis, green is y-axis and blue is z-axis, so if there are bands in that or extreme color shifts you know that the normal over that surface isn't smooth. These normals seem mostly smooth with some edges in it.

 

As a side note rendering out uv's should give you gradients from black to green, black to red, and then to yellow.

Edited by NightCreature83
1

Share this post


Link to post
Share on other sites

The banding in the image tells you the normals aren't completely smooth, there should be no banding other then that of the monitor on a sphere, loook at the arrows in the linked image those ridges shouldn't be there. Anyway for any sphere in space the easiest way to calculate the normal is the direction from the center point of the sphere to the vertex itself and then normalise that vector.

 

Also when rendering out normals red means the normal is directed mostly in the x-axis, green is y-axis and blue is z-axis, so if there are bands in that or extreme color shifts you know that the normal over that surface isn't smooth. These normals seem mostly smooth with some edges in it.

 

As a side note rendering out uv's should give you gradients from black to green, black to red, and then to yellow.

 

Thanks for the answer, so does that mean that the normals from Blender are not correct? Is there a way to fix that somehow? 

0

Share this post


Link to post
Share on other sites

No it doesn't mean that they are wrong, the reason your sphere goes completely smooth when you use the position for the normal for that vertex on a sphere is because you just moved to a mathematical representation of your sphere instead of a geometric one. What you are seeing is probably unwelded edges in the geometry and thus you have two verts in the same position with a slightly different normal and that will create the interpolation difference you see when rendering them out. The vertex positions however are exactly the same in this case, and the error is probably due to the normal calculation and normalisation and floating point errors in blender.

 

What you want to do is weld these verts together so that they are using the same vert and normal in all faces they are in.

Edited by NightCreature83
1

Share this post


Link to post
Share on other sites

No it doesn't mean that they are wrong, the reason your sphere goes completely smooth when you use the position for the normal for that vertex on a sphere is because you just moved to a mathematical representation of your sphere instead of a geometric one. What you are seeing is probably unwelded edges in the geometry and thus you have two verts in the same position with a slightly different normal and that will create the interpolation difference you see when rendering them out. The vertex positions however are exactly the same in this case, and the error is probably due to the normal calculation and normalisation and floating point errors in blender.

 

What you want to do is weld these verts together so that they are using the same vert and normal in all faces they are in.

 

Again, thanks for the answer and sorry to bother you with my noobness. I know what you are talking about and it was indeed blender's fault. Actually, my fault; I was using metaball instead of NURBS sphere when exporting the .obj. 

 

Sorry again for the trouble and thanks for the help, at least I learned testing normals via RGB now :) 

 

Cheers

0

Share this post


Link to post
Share on other sites

No it doesn't mean that they are wrong, the reason your sphere goes completely smooth when you use the position for the normal for that vertex on a sphere is because you just moved to a mathematical representation of your sphere instead of a geometric one. What you are seeing is probably unwelded edges in the geometry and thus you have two verts in the same position with a slightly different normal and that will create the interpolation difference you see when rendering them out. The vertex positions however are exactly the same in this case, and the error is probably due to the normal calculation and normalisation and floating point errors in blender.

 

What you want to do is weld these verts together so that they are using the same vert and normal in all faces they are in.

 

Again, thanks for the answer and sorry to bother you with my noobness. I know what you are talking about and it was indeed blender's fault. Actually, my fault; I was using metaball instead of NURBS sphere when exporting the .obj. 

 

Sorry again for the trouble and thanks for the help, at least I learned testing normals via RGB now smile.png

 

Cheers

Btw normals can come out black, when their components are negative they come out as a black color, especially when you use the "saturate" function to output your color.

0

Share this post


Link to post
Share on other sites
One can overcome this with a so-called wrapped lighting, e.g. (fully wrapped):
    float NdL = dot(normal, lightDirection) * 0.5 + 0.5;
Edit
Small nitpick. This
    output.normal = mul(normal, World);
is not correct for a general World transformation. E.g. for non-uniform scaling one needs to use the inverse transpose of the world matrix. For a uniformely scaling, non-skewed arbitrary (pure) rotation this does not matter, though.
Also, for normals one can grab the rotational part only with a cast (doesn't make a difference but should prevent some compiler warnings):
    output.normal = mul(normal, (float3x3)World);
1

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0