• 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
mynameisnafe

Check My Normal Calculations functions? Please?

11 posts in this topic

I'll just get down to it.. this is right, right?

 

/*
    Get Normals..
*/

class nVectorMath {
    //
    //
public:
    static void  Subtract( Vertex3D& ret, Vertex3D v1, Vertex3D v2 )
    {    
        ret.x = v1.x - v2.x;
        ret.y = v1.y - v2.y;
        ret.z = v1.z - v2.z;    
    }

    static void  Add( Vertex3D& ret, Vertex3D v )
    {
        ret.x += v.x;
        ret.y += v.y;
        ret.z += v.z;
    }

    //
    //

    static float Dot( Vertex3D v1, Vertex3D v2 )
    {
        return    v1.x * v2.x + v1.y * v2.y + v1.z * v2.z;
    }

    static void  Cross( Vertex3D& ret, Vertex3D v1, Vertex3D v2 )
    {    
        ret.x = v1.y* v2.z - v1.z* v2.y;
        ret.y = v1.z* v2.x - v1.x* v2.z;
        ret.z = v1.x* v2.y - v1.y* v2.x;    
    }

    //
    //

    static void  Normalize( Vertex3D& v )
    {
        float len = sqrtf(Dot(v,v));

        if(len==0)    return;
    
        float invL = 1.0f/len;

        v.x = v.x * invL;
        v.y = v.y * invL;
        v.z = v.z * invL;
    }

    static void  GetNormal( Vertex3D& n, Vertex3D a, Vertex3D b, Vertex3D c )
    {
        Vertex3D e1, e2;

        Subtract( e1, a, b );

        Subtract( e2, a, c );

        Cross( n, e1, e2 );

        Normalize( n );
    }
};
0

Share this post


Link to post
Share on other sites

The vector from a to b is b-a, but you're calculating a-b. Similarly for a and c. This will result in a negated normal.

1

Share this post


Link to post
Share on other sites

Okay!

 

So I just rewrite as..

 

 

    static void  GetNormal( Vertex3D& n, Vertex3D a, Vertex3D b, Vertex3D c )
    {
        Vertex3D e1, e2;

        Subtract( e1, b, a);

        Subtract( e2, c, a );

        Cross( n, e1, e2 );

        Normalize( n );
    }

 

?

 

Theres nothing else I need to change? And that's given vertices A, B, and C for some given triangle in a triangle list?

Edited by mynameisnafe
0

Share this post


Link to post
Share on other sites

Awesome news.. the bad news.. my shader must be bust. I can hardcode a colour but if I try any inverse-transposing specular and diffusing business my mesh comes out black.. and flat-shaded.:/

0

Share this post


Link to post
Share on other sites

Brother Bob seems to have covered your immediate query, but I wanted to mention that your use of a class containing only static functions is a little odd.

 

Usually one would use a namespace for this purpose, instead.

1

Share this post


Link to post
Share on other sites

Brother Bob seems to have covered your immediate query, but I wanted to mention that your use of a class containing only static functions is a little odd.

 

Usually one would use a namespace for this purpose, instead.

I know it's stupid.. not used namespaces in C++ before.. off I go searching.. all procrastination from my actual problems with .3ds..

It's been one of those weeks!

 

Thanks :)

1

Share this post


Link to post
Share on other sites

I know it's stupid.. not used namespaces in C++ before.. off I go searching..

 

Well that seems simple enough, sweet!

 

My loader now just holds an instance of an nVectorMath, now renamed VectorMagic lol

So if I'm generating these normals correctly, and I'm confident I'm putting them on the GPU correctly, and I've got one directional white light, and I set the colour of whatever is being shaded to bright green, what's the most likely cause of my completely black mesh?

 

Heres what happens / what I know for phong shading
 - vertex position and vertex normal are sent to the vertex shader

 - here they are transformed to world space and sent to the fragment shader

 - in the fragment shader work out all the lighting razzmataz

 - blend specular and diffuse colours, sum them, and output the final colour

 

So here we go, theres a lot of code here, which does the process above and gives me a black mesh..

 

Get the Inverse Transpose Model Matrix

 

glm::mat4 GLModel::GetInvTransModelMatrix()
{
    return glm::transpose( glm::inverse( modelMatrix ) );
}

 

... Everything gets put into the pipleline..

    glm::vec4 cPos = glm::vec4( mainCam->GetPosition(), 1.0 );

    glm::vec4 slDir( 0.0f, 1.0f, 0.0f, 0.0f );
    glm::vec4 slDif( 1.0f, 1.0f, 1.0f, 1.0f );
    glm::vec4 slSpe( 0.07f, 0.8f, 0.9f, 1.0f );
                                                                  // cam, direction, diffuse, specular, falloff/attenuation, inverse transpose model matrix
    theBeast->m_Shader.SetLightUniforms( cPos, slDir, slDif, slSpe, 0.8f, theBeast->GetInvTransModelMatrix() );
                                 // world mx,          view mx,                                proj mx,                                   scale,      viewmode
    theBeast->Render( glm::mat4(1.0), mainCam->GetViewMatrix(), m_ogl->GetProjectionMatrix(), 0.07f, GetViewMode() ); // for wireframe and what not. Using fill mode atm
 

 

then in the vertex shader..

 

#version 330

uniform mat4  worldMx;
uniform mat4  viewMx;
uniform mat4  projMx;

uniform mat4  modelMatrix;
uniform mat4  invtrans_modelMatrix;

uniform float scale_xyz;
 
layout (location=0) in vec4 vertexPos;
layout (location=1) in vec3 vertexNormal;

out vec3 colour;
out vec3 normalWorld;
out vec4 positWorld;

void main(void)
{
    vec4 v = vertexPos;

    v.x *= scale_xyz;
    v.y *= scale_xyz;
    v.z *= scale_xyz;

    //-----------------------------------------------

    colour = vec3( 0.3, 0.4, 0.7 ); // pale blue

    // vertex position in world coordinate space - for fragment shader
    positWorld = modelMatrix * v;

    // normal transformed to world coordinate space - again for fragment shader
    normalWorld = ( invtrans_modelMatrix * vec4(vertexNormal, 0.0) ).xyz;

    gl_Position = projMx * viewMx * worldMx * modelMatrix * v;
}

 

And finally the Pixel shader..

 

#version 330

uniform vec4  cameraPos;
uniform vec4  lightDirection;
uniform vec4  lightDiffuse;
uniform vec4  lightSpecular;
uniform float lightFalloff;

in vec3 colour;
in vec3 normalWorld;
in vec4 positWorld;

layout (location=0) out vec4 fragColour;

void main(void)
{
    // make sure light direction vector is unit length (store in L)
    
    vec4 L = normalize( lightDirection );
    
    // important to normalise length of normal otherwise shading artefacts occur
    
    vec3 N = normalize( normalWorld );
    
    // calculate lambertian term
    
    float lambertian = clamp( dot( L.xyz, N ), 0.0, 1.0 );

    //
    // calculate diffuse light colour
    //

    vec3 diffuseColour = colour.rgb * lightDiffuse.rgb * lambertian; // input colour actually diffuse colour
    
    //
    // calculate specular light colour
    //

    // vector from point on object surface in world coords to camera

    vec3 E = cameraPos.xyz - positWorld.xyz;

    E = normalize(E);    
    
    // reflected light vector about normal N
    vec3 R = reflect(-L.xyz, N);                    

    float specularIntensity = pow( max( dot(R, E), 0.0 ), lightFalloff );
    vec3  specularColour = vec3(1.0f, 1.0f, 1.0f) * lightSpecular.rgb * specularIntensity * lambertian;

    //
    // combine colour components to get final pixel / fragment colour
    //
    
    vec3 rgbColour = diffuseColour + specularColour;

    // output final colour to framebuffer

    fragColour = vec4( rgbColour, 1.0 );
//    fragColour = vec4( colour, 1.0 );
}
 
0

Share this post


Link to post
Share on other sites

im a lazy guy, so i haven't read the entire code section, but if stuff turns up black when it shouldn't, go slow at first.

this means:

  • first, directly output all your inputs as color (in this case, esp. the normals) and check if they have sane values (represented as colors in the framebuffer) you might want to pack them before outputting them (something like (normal+1)/*0,5), so you get the full range.
  • after that, output every step of your lighting, and do a check if it is as expected
  • also, don't forget to check constants, that can mess up things too
  • have a very simple model handy for this, where results are easily predictable (i use cubes and spheres)

you can also always use something like nsight or so for error checking, but i got kinda used not to use those, because they don't like me and have more issues with my code than me (especially with stream output/transform feedback, they love failing on those).

 

hope this helps,

    tasche

1

Share this post


Link to post
Share on other sites

im a lazy guy, so i haven't read the entire code section, but if stuff turns up black when it shouldn't, go slow at first.

this means:

  • first, directly output all your inputs as color (in this case, esp. the normals) and check if they have sane values (represented as colors in the framebuffer) you might want to pack them before outputting them (something like (normal+1)/*0,5), so you get the full range.
  • after that, output every step of your lighting, and do a check if it is as expected
  • also, don't forget to check constants, that can mess up things too
  • have a very simple model handy for this, where results are easily predictable (i use cubes and spheres)

you can also always use something like nsight or so for error checking, but i got kinda used not to use those, because they don't like me and have more issues with my code than me (especially with stream output/transform feedback, they love failing on those).

 

hope this helps,

    tasche

 

Thats some pretty sound advice dude, ta muchly. :) However you lost me a bit with "first, directly output all your inputs as color (in this case, esp. the normals) and check if they have sane values (represented as colors in the framebuffer) you might want to pack them before outputting them
(something like (normal+1)/*0,5), so you get the full range."

 

So you mean use my normals as colours? frag_colour = normal.xyz?

 

Also, what's this doing ( x) / * 0  ?

 

Thanks again dude :)

0

Share this post


Link to post
Share on other sites

im a lazy guy, so i haven't read the entire code section, but if stuff turns up black when it shouldn't, go slow at first.

this means:

  • first, directly output all your inputs as color (in this case, esp. the normals) and check if they have sane values (represented as colors in the framebuffer) you might want to pack them before outputting them (something like (normal+1)/*0,5), so you get the full range.
  • after that, output every step of your lighting, and do a check if it is as expected
  • also, don't forget to check constants, that can mess up things too
  • have a very simple model handy for this, where results are easily predictable (i use cubes and spheres)

you can also always use something like nsight or so for error checking, but i got kinda used not to use those, because they don't like me and have more issues with my code than me (especially with stream output/transform feedback, they love failing on those).

 

hope this helps,

    tasche

 

Thats some pretty sound advice dude, ta muchly. smile.png However you lost me a bit with "first, directly output all your inputs as color (in this case, esp. the normals) and check if they have sane values (represented as colors in the framebuffer) you might want to pack them before outputting them
(something like (normal+1)/*0,5), so you get the full range."

 

So you mean use my normals as colours? frag_colour = normal.xyz?

 

Also, what's this doing ( x) / * 0  ?

 

Thanks again dude smile.png

yep, exactly. something along the lines of:

cbuffer 
{
     float4 something;
}

struct vsIn
{
     float4 position;
     float4 normal;
     float2 tex;
}

struct psIn 
{ 
    float4 position; 
    float4 normal; 
    float2 tex;
} 

psIn vsmain(vsIn input)
{
    psIn output;
    ...some vertex manipulations...
    output.position = finalPos;
    output.normal = rotatedNormal;
    output.tex = input.tex;
}

float4 psmain : SV_TARGET
{
    float4 ret;
    ...some cool lighting done here...
    return ret;
}

now just before you 'return ret;' you insert:

ret = input.normal;

for example. if that is already messed up, pass the normal from the vertex shader untouched (may have to add an extra var using the texcoord semantic in psIn), and output that first.

psIn vsmain(vsIn input)
{
    psIn output;
    ...some vertex manipulations...
    output.position = finalPos;
    output.normal = input.normal;     //<----change to this
    output.tex = input.tex;
}

use this for quick and dirty 'judged-by-eye' tests

 

Also, what's this doing ( x) / * 0  ?

that was just another way to show you how typos work. was meant to be (normal+1)*0.5. this moves normal component values from -1,1 range to 0,1 which can be viewed as rgb.

 

good luck finding your errors!

Edited by Tasche
0

Share this post


Link to post
Share on other sites

good luck finding your errors!

 

Thanks :)

I agree I should be doing this in DirectX ;)

 

that was just another way to show you how typos work. was meant to be (normal+1)*0.5. this moves normal component values from -1,1 range to 0,1 which can be viewed as rgb.

 

I see :)

 

Okay, onwards!

 

Thanks again :)

0

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