This topic is 3409 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

hi. im using a vertex shader to generate different shapes (in this case a sphere) and trying to compute the normals aswell. what im doing is passing a grid mesh of size 100x100 (the plane coordinates are from 0.0 to 1.0) and in the shader i use the vertices to generate a sphere by this function:
float3 getSpherePoint( float u, float v )
{
float x = cos(v) * sin(u);
float y = sin(v) * sin(u);
float z = cos(u);
return float3( x, y, z );
}

vertexOutput VS_GoochySpecular( in vertexInput IN )
{
vertexOutput OUT = (vertexOutput)0;

float step = (1/100.0); // one step

float u = (IN.position.x) * TWOPI;
float v = (IN.position.y) * PI;

float3 pos = getSpherePoint( u, v );

// Compute tangents and normals
float3 tangent = getSpherePoint( u-(step/2), v ) - getSpherePoint( u+(step/2), v );
float3 bitangent = getSpherePoint( u, v-(step/2) ) - getSpherePoint( u, v+(step/2) );

float3 normal = normalize( cross( tangent, bitangent ) );

// scale sphere
pos *= a;

float4 Po = float4( pos, 1 );
OUT.position = mul( worldViewProj, Po );
float3 worldpos = mul(matWorld, Po).xyz;	// in "world" coordinates
float3 viewpos = mul(matView, float4(worldpos,1.0)).xyz;	// in "view" coordinates
OUT.worldPos = worldpos;

OUT.normal = normalize( mul((float3x3)matViewIT, normal) );
float3 L = viewL - (viewpos.xyz*lightPos.w);
OUT.lightVec = L;

OUT.viewVec = normalize( float3(matViewIT[0].w, matViewIT[1].w, matViewIT[2].w) - viewpos.xyz);

return OUT;
}

the problem is that the bottom hemisphere of the sphere has the lighting inverted. i have disabled face culling. when enabled i can see the normals are inverted. my question is why everything below y=0 inverts ? check this shot: best regards,

##### Share on other sites
Your getSpherePoint assumes u between 0 and PI and v between 0 and 2*PI.
Also, you don't have to compute a tangent vector and a bitangent vector to compute the normal of a sphere. The normal is simply getSpherePoint.

##### Share on other sites
thank you. i was so blind i didnt even see that.

as for the normals thing, im trying to find a way to compute vertex normals for distorted objects that can be generated at the vertex shader.

im not sure if this method will work. im hoping it does. would you know anything about that ?

##### Share on other sites
The method will work, but there's a better way to do it if you can.
Instead of sampling your function 5 times (once for position, 2 for the tangent and 2 for the bitangent), you can compute the normal by
n = cross(df/du, df/dv) (up to normalization),
where df/du and df/dv are the partial derivatives of your function (e.g. getSpherePoint) by u and v, resp.
df/du = ( cos(v)*cos(u), sin(v)*cos(u), -sin(u) )
df/dv = ( -sin(v)*sin(u), cos(v)*sin(u), 0 ),
so that
n = ( sin(u)*sin(u)*cos(v), sin(u)*sin(u)*sin(v), (cos(v)*cos(v) + sin(v)*sin(v))*cos(u)*sin(u) )
n = sin(u) * (cos(v) * sin(u), sin(u)*sin(v), cos(u))
n = sin(u) * getSpherePoint(u,v)
This even works for stuff like Perlin noise (which comes in very handy).

- Lutz

##### Share on other sites
hi lutz, i dont get that much on that derivative stuff.
are you telling me that

normal = sin(u) * getSpherePoint( u, v );

would give me correct normals for sphere mesh generated, and for perlin noise aswell ?

it looks too simple too me =)

##### Share on other sites
No, that was just an example to illustrate how it works. I used this example to verify what we already knew - that the normal direction for a sphere matches the direction to the point on the sphere. This way we could check that the calculations are correct.

In general, the normal direction is different from the direction to the point on the surface. For other objects like ellipsoids or Perlin noise you'll get other results. But the general way to compute the normal is the same. Let's say you write Perlin noise as function pos = f(u,v). Then the normal is given by normalize(cross(dfdu(u,v), dudv(u,v))), where you'll have to compute the partial derivatives dfdu and dfdv yourself.

##### Share on other sites
ok so it all depends on the formula. for example i am using a distorted version of a sphere formula here now:

float3 getSpherePoint( float u, float v )
{
// 0 <= u <= PI, 0 <= v <= TWOPI

float x = cos(v) * sin(u) + sin(20*u+count.x) * 0.075;
float y = sin(v) * sin(u) + cos(10*u+count.x) * 0.075;
float z = cos(u);

//r += sin(0.25*x * count.x + time + phase.x) * amount.x;
//r += cos(u*count.y + phase.y) * amount.y;

return float3( x*r, y*r, z*r );
}

i did not understand anything on the way you calculate the dfdu/dfdv. i would like to know if is there a general way to compute it for different functions, no matter what they are, ellipse, sphere, cone, perlin, etc

if its not, how would i compute it myself as you said? what would u recommend i should read/do to get myself working this out.

thanks

##### Share on other sites
Computing derivatives is done by applying some simple rules to general functions. I can't explain that in this post, it's nothing you can learn in one hour. If you really want to, I recommend you grab a book about calculus and learn how to do it.

##### Share on other sites
ok, thank you for your help.

1. 1
2. 2
3. 3
JoeJ
12
4. 4
5. 5
frob
11

• 12
• 16
• 13
• 20
• 12
• ### Forum Statistics

• Total Topics
632176
• Total Posts
3004593

×