Procedural shape with Lighting.j3md Material (self made normals)

hey there,

what i am doing is using an object from blender to iterate over its triangles an create every triangle for itself. It works fine with a solid Material

The problem is that i want no solid color but a shaded. Therefore I need to set normals, right?

That should not be that hard, because the normal is the normal auf the triangle

[java]

Triangle t1 = new Triangle();

//extracts the triangle data from the mesh and stores the data in t1

getTriangle(t1.get1(), t1.get2(), t1.get3());

//Normal:

t1.getNormal();

[/java]

Using a raycast i can check wheter the normal of the triangle points inside or outside my model (if the result is 0 it points outside, else inside)

[java] Vector3f[] normals = new Vector3f[3];

// 1. Reset results list.

CollisionResults results = new CollisionResults();

// 2. Aim the ray from cam loc to cam direction.

Ray ray = new Ray(t1.getCenter(),t1.getNormal());

parentCity.getParent().collideWith(ray, results);

if(results.size() == 0){

normals[0] = new Vector3f(t1.getNormal());

normals[1] = new Vector3f(t1.getNormal());

normals[2] = new Vector3f(t1.getNormal());

} else {

normals[0] = new Vector3f(t1.getNormal().mult(-1));

normals[1] = new Vector3f(t1.getNormal().mult(-1));

normals[2] = new Vector3f(t1.getNormal().mult(-1));

}

mesh.setBuffer(Type.Normal,3,BufferUtils.createFloatBuffer(normals));

[/java]

Now i use the shaded Material:

[java] TangentBinormalGenerator.generate(mesh, true);

Material mat_lit = new Material(ClientMain.app.getAssetManager(), “Common/MatDefs/Light/Lighting.j3md”);

mat_lit.setTexture(“DiffuseMap”,

ClientMain.app.getAssetManager().loadTexture(“Textures/brown.png”));

mat_lit.setTexture(“NormalMap”,

ClientMain.app.getAssetManager().loadTexture(“Textures/brown.png”));

mat_lit.setTexture(“SpecularMap”,

ClientMain.app.getAssetManager().loadTexture(“Textures/brown.png”));

mat_lit.setFloat(“Shininess”, 2.21f); // [0,128]

setMaterial(mat_lit); [/java]

but the result doenst look the way i exspected it

http://i.imgur.com/gYndv.jpg

please help :slight_smile:

There are a few problems I see right off the bat…



[java]

CollisionResults results = new CollisionResults();

// 2. Aim the ray from cam loc to cam direction.

Ray ray = new Ray(t1.getCenter(),t1.getNormal());

parentCity.getParent().collideWith(ray, results);

[/java]



This will not do what you think. For any non-simple shape, it is quite likely that a ray cast from the center in the direction of the surface normal will not intersect that particular face. It entirely depends on where that face is. For example, just imagine a capsule. Every face on the capsule ends would fail this test.



You’d have better results creating a vector from the center to one of the triangle vertexes and doing a dot product with the triangle normal. This will only work for convex shapes. Concave shapes will trivially fail on lots of faces. (Your shape is concave, by the way.) The only proper check is to compare the normal to the vertex winding. This involves comparing the normal to a cross product of two of the triangle’s edges.



But really, have you tried just using the normals as they are?



Another problem is that you are setting the same material for both diffuse and normal map… this will never be right. The diffuse map is for the coloring of your mesh. The normal map is a bunch of encoded vectors. If you don’t have a normal map, just don’t set it. It’s for simulating bumps in the material with shading. Get the other stuff working first.



Leave specular map off as well. That shouldn’t be the same either.