Lafortune shading tests

Hi all,
before I begin to code the anisotropic shading of my Lafortune shader, I do some tests with it, for fun :slight_smile:

On each render, left is Phong, vs Lafortune on the right…

I’m satisfied with the results :smiley: As you can see, the Lafortune shader describes the specular highlights, especially at grazing angles, better than Phong. It allows to simulate Fresnel effect, it encompasses the Phong shader (since it’s a generalization of it), can simulate retro-reflection, non-lambertian diffusion, and anisotropy… I’ll explain later how to use it (for those who want, you can check the thread I opened in the development section, and take a look at the original paper. I also posted a patch + a vista build). Before documenting it, I’ll try’n code the anisotropy.

Have fun !

How do you write these shaders, I’ve been trying to get answers for this question for a while now, please help!

Also it looks fantastic!

It depends. You can write them using a PyNode, it will be runned like a python script, and will be slower but easier and more flexible. Or you can choose to write it directly in the code of Blender, in C, and then compile.

I’ll tell you which files to modify to have a new shader, if you want :slight_smile:

Yea, that would be great! Also if you could direct me to any links or guides on how to write shaders for Blender, or where to get started, that would be awesome. I already know a decent amount of Python from before I started with Blender, and I have been learning C, so I don’t need help there, but just in general the theory behind making them.

Thanks a bunch mate!

that looks fantastic

THE LAFORTUNE ONE stands out slight more than the phong ones just a tinybit

The effect is biggest on the soccer ball, the material just looks a little more real with LaFortune.

Good work, now get it in patch form and let’s see it in Blender 2.5.

Thanks for the replies all.
@blenderrenegade : that’s true. The difference are only subtle, and can be observed in extreme cases, e.g, the 2 perfect spheres, were we see the weaknesses of the Phong shader. But still, it’s cool to code it :slight_smile: When the anisotropy is coded, I’ll submit a patch I think (as an answer to cyborgdragon)

@sebbonaparte : ok, so, let’s start : to add my shader, I modified “buttons_shading.c” to add buttons in the interface, “DNA_material_types.h” (don’t remember what I modified there :D), “Material.c”, and “Shadeoutput.c” (it’s here THE function is coded)
It’s quite simple to know where you have to add a line : just use the Search function, looking for files containing “Phong” for example, go to the right line in the source code, and add the useful things :slight_smile:
For example, if you see something like this :

else if (ma->spec_shader==MA_SPEC_BLINN)

else if …
else if…

Then, it’s quite easy to guess that you have to add something… I hope you know what I mean. :slight_smile:

For a guide, see here, but I prefer to warn you, it is out of date. But it can help.

Thanks a ton mate! I appreciate it!

By the way, I’ve got a question (for those who readed the paper entirely, and who understand quite well the meaning of Cxy and Cz )

What would you write in the tooltips for Cxy and Cz ? :smiley: I just wrote something like “sets the Cz coefficient. See documentation to understand its meaning”…

[edit] sebbonaparte, you’re welcome :slight_smile: I would have liked someone could have told me exactly what files to modify for my shader, so, there was no reason not to tell you.

Sebbonaparte : there are 2 “material.c” files. In “Material.c” in Blender\Blenderkernel\Intern, you can give a default value to the parameters you create (it’s where materials are initialized, e.g, hardness is told to be at 50 at start). In “material.c” (without a big “m”), in Blender\python\api2_2x, you give Blender others information, for example the min and max values of the parameters you created.
By the way, in those files, do not Search “Phong”, but rather “rms” or “hard”, “roughness”, that kind of stuff.
[edit] you’ll also need to modify readfile.c. I forgot it in my builds, and it didn’t seem to makes problems appear…

Pixelvore, the recent addition of Ward Anisotropic Shader may be useful…

Yep, Broken also linked me this patch. It will be useful I think, since I also need to get the tangent vectors for the anisotropy :slight_smile:

Thanks for that last tip Pixelvore :slight_smile:

Also I found this guide on writing shaders using pynodes… might be useful to some people, so I figured I would post a link here.

If you are going to code even the anisotropy,this can be a really good shader for blender,keep it up!

Hi renderdemon, now, it’s done :slight_smile:

1- I got rid of all the heresy done by Blender for the tangent shading (i.e, replacing the normal vectors by the tangent vectors, etc). This means, all lines like this…

if(ma->mode & MA_TANGENT_V)

… were replaced by something like this :

if((ma->mode & MA_TANGENT_V)&&(ma->spec_shader != MA_SPEC_LAFORTUNE))

in order for the shader not to be concerned bythose modifications.
2- I replaced Cxy by Cx and Cy, added buttons in the interface, etc…
3- I changed the shading function itself : instead of choosing the x local axis arbitrary, I set x to be aligned to the tangent vector, and y is perpendicular to both x and n (cross product). And I replaced Cxy in the formula by Cx and Cy.

With those explanations, no need to show the code :slight_smile: Moreover, it is very similar to the WardAniso patch.

Here’s the patch :
And here’s a vista build (without quicktime)

Now I’m gonna work on allowing to rotate the directions of anisotropy, just like in the Aniso patch. (btw, there is something weird in the ward anisotropic patch… The Ward shader is still called “WardIso” whereas it is anisotropic, by now…)

Have fun ! :smiley:

[edit] btw, now it’s necessary to turn on the [tangentV] button.

Hey you might want to contact Broken for the development of anistropic rotation maps, he had some initial work on raytrace nodes and this was one of the things it allowed you to do.

Basically it allows you to render things like circular brushed metal with just a texture, white would be a rotation of 0 degrees and black would be 360 degrees.

Yep, the rotation is easy, the code for it in that wardiso patch is here:

Crossf(x, n, tangent);      // bitangent
VECCOPY(y, tangent);

if (rot > 0.0f && rot < 1.0f) {
	float angle = rot*(float)M_PI*2.f;
	float cosa = cosf(angle);
	float sina = sinf(angle);

	x[0] = cosa*x[0] + sina*y[0];
	x[1] = cosa*x[1] + sina*y[1];
	x[2] = cosa*x[2] + sina*y[2];
	Crossf(y, x, n);

this gives you perpendicular vectors x and y aligned to the tangent plane, rotated by rot, where rot is 0.0 (0 degrees) to 1.0 (360 degrees). This allows you to texture the rotation quite easily.

I’m not all that familiar with what those lafortune parameters actually do, but also one thing I was poking mfoxdogg to work on next is, rather than having separate parameters with the X factor, Y factor, etc that take a lot of fiddling, I think it’s much nicer and simpler to have just one slider- ‘anisotropy’ that ranges from 0.0 (perfectly round, phong-like) to 1.0 (fully stretched). I suppose this can be done internally pretty easily by just using the anisotropy parameter to create a ratio between the X and Y factors.

PS. really nice work! :slight_smile:

CybordDragon & Broken, those are really nice ideas :slight_smile: (I mean, texturing the anisotropy).

@broken : for the Cx/Cy ratio instead of Cx and Cy apart : I think it’s just a matter of taste :slight_smile: Personally, I prefer to have Cx and Cy separed. Because using a slider with the Cy/Cy ratio would lead to 2 buttons anyway : when you have Cx = -1 and Cy = -1, it doesn’t give the same result than Cx=-2 and Cy=-2 (vectors are more stretched, and the resulting specular highlight is bigger). So, you would have the ratio between them =1, but next to the ratio button, you would need to chose Cx for example. That’s why I prefer to use Cx and Cy appart.

Concerning the texturing of the directions of anisotropy : it’s a great idea. By now, my rotation angle is expressed in radians and ranges from -pi/2 to pi/2, but it isn’t a problem to make it belong to the [0,1] interval. (dunno where to compute this however. If I do the conversion inside the shading function, it will be made for each rendered pixel having a lafortune shader). And I also don’t know anything about how to use textures in the blender code. But if it becomes possible to texture the directions of anisotropy, it can be really really cool (some people on french forums were asking me whether it would still be necessary to specify the directions of anisotropy with uv mapping, and the answer would be “no” :slight_smile: )

And here’s a screenshot of the varying AniRot parameter :