Forum

Normals in shader

Hallo
I am following the tutorial on ((tutorial effects normals)) for basic normals calculation but i see that normals need to go through the same math function that I am using to generate the mesh… any hint, tutorial?
tx
S.

- define pi 3.14
 
float2 Scale = 1;
float2 Offset = 0;
 
float3 Cone(float2 uv)
{
 
     uv *= Scale;
     uv += Offset;
 
    float u = uv.x * 2*pi;
    float v = uv.y;
 
    float3 newPos;
    newPos.x = 1.2*(1 -v/(2*pi))*cos(3*v)*(1 + cos(u)) + 3*cos(3*v);
    newPos.y = 9*v/(2*pi) + 1.2*(1 - v/(2*pi))*sin(u);
    newPos.z = 1.2*(1 -v/(2*pi))*sin(3*v)*(1 + cos(u)) + 3*sin(3*v);
 
    return newPos;
}
 
float NeighbourOffset = 0.001;
 
vs2ps VS(
    float4 PosO  : POSITION,
    float4 TexCd : TEXCOORD0)
{
    //declare output struct
    vs2ps Out;
 
    //calc new position
    float3 p = Cone(PosO.xy);
 
    //calc neighbour pos in u direction
    float3 n1 = Cone(PosO.xy + float2(NeighbourOffset, 0));
 
    //calc neighbour pos in v direction
    float3 n2 = Cone(PosO.xy + float2(0, NeighbourOffset));
 
    //get tangent vector 1
    float3 t1 = p - n1;
 
    //get tangent vector 2
    float3 t2 = p - n2;
 
    //get normal
    float3 NormO = cross(t1, t2);
 
    //set new pos
    PosO.xyz = p;
 
    //put normal in view space and normalize it
    Out.NormV = normalize(mul(NormO, tWV));
 
    //inverse light direction in view space
    Out.LightDirV = normalize(-mul(lDir, tV));
 
    //inverse view dir in view space
    Out.ViewDirV = -normalize(mul(PosO, tWV));
 
    //transform position (projected)
    Out.Pos = mul(PosO, tWVP);
 
    //transform texturecoordinates
    Out.TexCd = mul(TexCd, tTex);
 
    return Out;
}

You can use the out keyword for it, like:

float3 Cone(float2 uv, out float3 normal)
{
 
     uv *= Scale;
     uv += Offset;
 
    float u = uv.x * 2*pi;
    float v = uv.y;
 
    float3 newPos;
    newPos.x = 1.2*(1 -v/(2*pi))*cos(3*v)*(1 + cos(u)) + 3*cos(3*v);
    newPos.y = 9*v/(2*pi) + 1.2*(1 - v/(2*pi))*sin(u);
    newPos.z = 1.2*(1 -v/(2*pi))*sin(3*v)*(1 + cos(u)) + 3*sin(3*v);

    normal = //Calculate you normal here
   
    return newPos;
}

where is the problem exactly? you use the mesh function 3 times, that gives you a small triangle on the surface, like in the code. then you use the 3 points to get a normal vector with the cross product… it looks correct…

you would use the solution from vux if you know the derivative of your function and want to calculate the normal directly.

@tonfilm: the normals do not look correct at all, i tried with the cull node to fix it but the object looks “weird”

could you post a screenshot or patch?

math.zip (5.3 kB)

Yeah that’s a common problem when doing parametric surfaces, Some triangles can have their normals pointing to the opposite direction once transformed.

Using partial derivatives is more efficient indeed (saves a lot of sin/cos), but yeah quite more cumbersome (had some functions like that and some softwares like mathematica comes in handy), and you still end up with the same “reverse normals” problem.

I go completely blank after :

normal = //Calculate you normal here

hints?
S.

hey that was fun, i recreated the same object but with the CPU method, still something weird with normals…
S.

math.zip (8.4 kB)

Hi io
nice blinking effect!

Anyway setting the dbuffer format of the renderer in your previous patch the mesh looks ok.

Just to contribute, maybe I don’t understand the problem… I’m a newbie
Bye

math2.zip (5.1 kB)

ok that was dumb …really dumb … anyway, i am attaching the latest patch where I am trying to calculate the normals in CPU, how do I make the cross product in a patch ?
S.

math.zip (9.3 kB)

Cross Product??? I just discover this on wiki, interesting, but I can’t help you… I’m studying addition at http://www.khanacademy.org/

do you know the Normals (EX9.Geometry Mesh) node?

and * (3d cross) is also a node… :)

Hi,
i´ve made a change in the shader, now the scale only works on X to avoid the overlapping on Y,
nice shader btw ;)

Ari

math3.rar (5.2 kB)

@tonfilm: i am not used to work with shaders so I haven t noticed it before, just the Normals help patch … and yes I ve found out yesterday night the cross product node …

Hi,
if I have an mesh with computed normals (the normals node) what would be a good way to display or highlight or something like that only the parts of the mesh that create a plane surface (a desk, table, sheet of paper, …) that is the polygons with normals in the same direction.
how could that be done?

you could input a vector which is normal to your plane in the mesh and compare the normals to this vector (using the dot product). if the value of the dot product is above a certain threshold, you can consider this vector as part of the plane and give it another color…