Jump to content

Cook Torrance shader code help pls


kensonuken

Recommended Posts

Hello friends,

Ive been looking for developing cook torrance shader in Renderman can anybody give me the code of it... tried alot but couldnt find it.... please help me...

thanks,

Ken

I wrote it once based on wiki and some Blender code, which I can't find now. Don't expect too much, please! I have no idea if this is a valid or decent implementation, most probably neither of these. I haven't use it for a while and never actually seriously. Maybe this could be a good starting point for you, specially after Mario's corrections ;).

Hope that helps,

sy.

#include  <math.h>

vector  
cooktorrance(vector nN; vector nV; float eta; float m) {

	vector Ct = 0;
	vector H = 0;
	float  NH = 0;
	vector nL = 0;
	float  alpha = 0;
	float NV = 0;
	float NL = 0;
	float HV = 0;
	float b, c, d, g;
	float _d = 0;
	float Kr = 0;
	float Kt = 0;


	illuminance(P) {

		nL = normalize(L);
		H = normalize(nV + nL);
		NH = dot(nN, H);
		alpha = acos(NH);
		NV = dot(nN, nV);
		NL = dot(nN, nL);
		HV = dot(nV, H);

		// Geometric attenuation term:
		b = (2 * NH * NV) / HV;
		c = (2 * NH * NL) / HV;		
		g = min(set(1, b, c));

		// Beckmann distribution factor:
		_d = tan(alpha) / m;
		d = exp( - (_d*_d) ) / (4.0 * m * m * pow(cos(alpha), 4.0));

		// Fresnel:
		fresnel(normalize(I), nN, eta, Kr, Kt);

		// Cook Torrance:
		 shadow(Cl);
		Ct += Cl * ( d * Kr * g  /  NV  );

	}

	return Ct;	

}


surface
ct_skk(vector spec	= 0.9;
	   vector diff	= 0.8;
	   float  eta	 = 0.8;
	   float  m	   = 0.8;)

{

	vector nN = normalize(N);
		  nN = normalize(frontface(N, I));
	vector nV = normalize(-I);

	Cf = diff * diffuse(nN) + spec * cooktorrance(nN, nV, eta, m);

}

Edited by SYmek
Link to comment
Share on other sites

Thx freind

i was refereing to this pages too for creating my RSL code but i'm still learning shading launguage.

but their is alot dicussion on Cooktorrance and more adv simulation will be to have a cooktorrance with a three lobes.

Link to comment
Share on other sites

Thx freind

i was refereing to this pages too for creating my RSL code but i'm still learning shading launguage.

but their is alot dicussion on Cooktorrance and more adv simulation will be to have a cooktorrance with a three lobes.

Unfortunately I wasn't interested too much in this topic and I didn't see any papers. So, if you can share some links or files, I would be happy to take a look on it ;)

cheers,

sy.

Link to comment
Share on other sites

  • 2 weeks later...

hello symek,

Can you please tell me whats the renderman shader code for this?

I tried to compile this with renderman equivalent shader attributes but im getting few errors like at

UNdefined set function

Invalid number of arguments for min and shadow functions

can you please give me renderman shader code please....

thanks,

Ken

Link to comment
Share on other sites

hello symek,

Can you please tell me whats the renderman shader code for this?

I tried to compile this with renderman equivalent shader attributes but im getting few errors like at

UNdefined set function

Invalid number of arguments for min and shadow functions

can you please give me renderman shader code please....

thanks,

Ken

Well, you're lucky, I didn't have this code until yesterday although I'm pretty sure it's available in Internet. Yesterday I was provided this by Przemyslaw Koprowski as a notes to his lectures. I hope he doesn't mind if I put it here. Please note, that I still haven't checked if this code is equal to VEX version above.

Cook-Torrance
//Cook-Torrance illumiantion model
//N, V, Ks, Kd, roughness - usual meaning
//eta index of refraction
//Cdiff - diffuse color (usually Cs)
//Cspec - specular color (us. Cs or 1)
color LocIllumCookTorrance(normal N; vector V;
		float Ks, Kd, eta, roughness;
		color Cdiff, Cspec;)
{
		extern point P;
		color Ct = 0;
		float m2= roughness*roughness;
		//First normalize every vector
		vector Vn = normalize(V);
		vector Nn = faceforward(normalize(N), -V);
	illuminance ( P, Nn, PI/2 ) {
				extern vector L;
				vector Ln = normalize (L);
				vector Hn = normalize (Vn + Ln);
				//Cook-Torrance parmeters
				float t = Hn.Nn;
				float t2 = t*t; //t squared
				float v = Vn.Nn;
				float vp= Ln.Nn;
				float u = Hn.Vn;
2
			 //Now BRDF
			 float D = 0.5/(m2*t2*t2) * exp( (t2-1)/(m2*t2) );
			 float G = min(1 , 2*min(t*v/u, t*vp/u) );
			 float Kr, Kt;
			 fresnel(Ln, Nn, eta, Kr, Kt);
			 Ct += Cl * ( Cdiff*Kd + Cspec*Ks*Kr*D*G/(vp*v) ) * Nn.Ln;
  }
  return Ct;
}

Link to comment
Share on other sites

I written the main shader function but this doesnt work...

////////////////////////////////////////////////////////////////////////////////////////////

//Cook-Torrance

//Cook-Torrance illumiantion model

//N, V, Ks, Kd, roughness - usual meaning

//eta index of refraction

//Cdiff - diffuse color (usually Cs)

//Cspec - specular color (us. Cs or 1)

color LocIllumCookTorrance(normal N; vector V;

float Ks, Kd, eta, roughness;

color Cdiff, Cspec;)

{

extern point P;

color Ct = 0;

float m2= roughness*roughness;

//First normalize every vector

vector Vn = normalize(V);

vector Nn = faceforward(normalize(N), -V);

illuminance ( P, Nn, PI/2 ) {

extern vector L;

vector Ln = normalize (L);

vector Hn = normalize (Vn + Ln);

//Cook-Torrance parmeters

float t = Hn.Nn;

float t2 = t*t; //t squared

float v = Vn.Nn;

float vp= Ln.Nn;

float u = Hn.Vn;

//2

//Now BRDF

float D = 0.5/(m2*t2*t2) * exp( (t2-1)/(m2*t2) );

float G = min(1 , 2*min(t*v/u, t*vp/u) );

float Kr, Kt;

fresnel(Ln, Nn, eta, Kr, Kt);

Ct += Cl * ( Cdiff*Kd + Cspec*Ks*Kr*D*G/(vp*v) ) * Nn.Ln;

}

return Ct;

}

surface CT(

float Ka = 1;

float Ks = .5;

float Kd = .5;

float eta = 1;

float roughness = .1;

color Cdiff = (1,.3,.5);

color Cspec = 1; )

{

normal Nf = faceforward( normalize(N), I );

vector V = - normalize( I );

color spec = LocIllumCookTorrance(Nf, -normalize(I), eta, roughness,Kd, Ks, Cdiff, Cspec);

Oi = Os;

Ci = ( Cs * (Ka * ambient() + Kd * diffuse(Nf)) +

Cspec * Ks * spec);

Ci *= Oi;

}

/////////////////////////////////////////////////////////////////////////////////

Can anybody please help me with the right working code... please....

the above code compiles but it doesnt work.

can anybody help me with the working rsl code... please....

thanks,

Ken

Link to comment
Share on other sites

Easy fix. Try this.

////////////////////////////////////////////////////////////////////////////////////////////
//Cook-Torrance
//Cook-Torrance illumiantion model
//N, V, Ks, Kd, roughness - usual meaning
//eta index of refraction
//Cdiff - diffuse color (usually Cs)
//Cspec - specular color (us. Cs or 1)
color LocIllumCookTorrance(normal N; vector V;
float Ks, Kd, eta, roughness;
color Cdiff, Cspec;)
{
extern point P;
color Ct = 0;
float m2= roughness*roughness;
//First normalize every vector
vector Vn = normalize(V);
vector Nn = faceforward(normalize(N), -V);
illuminance ( P, Nn, PI/2 ) {
extern vector L;
vector Ln = normalize (L);
vector Hn = normalize (Vn + Ln);
//Cook-Torrance parmeters
float t = Hn.Nn;
float t2 = t*t; //t squared
float v = Vn.Nn;
float vp= Ln.Nn;
float u = Hn.Vn;
//2
//Now BRDF
float D = 0.5/(m2*t2*t2) * exp( (t2-1)/(m2*t2) );
float G = min(1 , 2*min(t*v/u, t*vp/u) );
float Kr, Kt;
fresnel(Ln, Nn, eta, Kr, Kt);
Ct += Cl * ( Cdiff*Kd + Cspec*Ks*Kr*D*G/(vp*v) ) * Nn.Ln;

}
return Ct;
}

surface CT(
float Ka = 1;
float Ks = .5;
float Kd = .5;
float eta = 1;
float roughness = .1;
color Cdiff = (1,.3,.5);
color Cspec = 1; )
{
normal Nf = faceforward( normalize(N), I );
vector V = -normalize( I );
color spec = LocIllumCookTorrance(Nf, V, Ks, Kd, eta, roughness, Cdiff, Cspec);
Oi = Os;
Ci = ( Cs * (Ka * ambient() + Kd * diffuse(Nf)) +
Cspec * Ks * spec);

Ci *= Oi;
}

Edited by Alanw
Link to comment
Share on other sites

Also, here is a different implementation of the Cook-Torrance shading model found in the "Renderman Shading Language Guide".

float distro( normal Nn;
			  vector H;
			  float m; )

{
	float ndoth = Nn.H;
	float beta = acos( ndoth );
	float tanbeta = tan( beta );
	float tanbeta_over_m = tanbeta/m;
	float D = exp(-(tanbeta_over_m*tanbeta_over_m));
	D /= 4*m*m*pow(ndoth,4);
	return D;
}//distro();

// geometric attenuation factor
float geom( normal Nn;
			vector H;
			vector L;
			vector V )

{
	float ndoth = Nn.H;
	float ndotv = Nn.V;
	float ndotl = Nn.L;
	float vdoth = V.H;

	float masking = 2*ndoth*ndotv/vdoth;
	float shadowing = 2*ndoth*ndotl/vdoth;
	return min(1, min(masking, shadowing));
}//geom();

float LocIllumCookTorrance(
normal N; vector V;
float eta, m;)
{
	extern vector I;
	extern point P;
	normal Nf, Nn;

	Nn = normalize(N);
	Nf = faceforward(Nn, I);

	float cook = 0;
	illuminance( P, Nf, PI/2 )
		{
			vector Ln = normalize(L);
			vector H = normalize(Ln+V);
			float D = distro(Nf, H, m);
			float G = geom(Nf, H, Ln, V);
			float F, Kt;
			//float F = fresnel_hack(Nf, V, IndexOfRefraction);
			fresnel(V, Nf, eta, F, Kt);

			cook += D*G*F;
		}
	float vdotn = V.Nf;
	cook /= vdotn;
	//normalize - preserves conservation of energy
	cook /= PI;

	return cook;
}

surface cookTorrance(
float Ka = 1;
float Ks = .5;
float Kd = .5;
float eta = 1;
float m = .1;
color Cdiff = (1,.3,.5);
color Cspec = 1; )
{
normal Nf = faceforward( normalize(N), I );
vector V = -normalize( I );
color diffusecolor = Kd * diffuse(Nf);
color spec = LocIllumCookTorrance(Nf, V, eta, m);
Oi = Os;
Ci = ( Cs * (Ka * ambient() + diffusecolor * Cdiff) +
Cspec * Ks * spec);

Ci *= Oi;
}

Link to comment
Share on other sites

I have been playing with this a little bit. Added reflections, and environment map options to the shader I posted earlier.

surface cookTorrance(
float Ka = 1;
float Ks = .5;
float Kd = .5;
float Kr = .6;
float eta = 1;
float m = .1;
float samples = 1;
string mapname = "raytrace";
color Cdiff = (1,.3,.5);
color Cspec = 1; )
{

//locals
float depth, s;
color env = 0;
vector Ntmp, D;
vector Nr;

rayinfo("depth", depth);
s = (depth == 0) ? samples: 1;

Nr = faceforward(normalize(N), -I);
Ntmp = Nr;

normal Nf = faceforward( normalize(N), I );
vector V = -normalize( I );
color diffusecolor = Kd * diffuse(Nf);
color spec = LocIllumCookTorrance(Nf, V, eta, m);

//map
if(mapname != "raytrace") {
		D = reflect(-V, Ntmp);
		D = vtransform("world", D);
		env += environment(mapname, D);
		}
 else if (mapname == "raytrace") {
	normal Nn = normalize(N);
	vector In = normalize(I);
	vector reflDir = reflect(In,Nn);
	env = environment(mapname, reflDir, "samples", s);
} else {
	env = 0;
}


Oi = Os;
Ci = Oi * ( Cs * (Ka * ambient() + diffusecolor * Cdiff) +
Cspec * Ks * spec) + env * Kr;
}

post-3205-1207587999_thumb.jpg

Link to comment
Share on other sites

Also, here is a different implementation of the Cook-Torrance shading model found in the "Renderman Shading Language Guide".

(...)

O yes, this is a version with some computations in tangent space, I found it also in Blender code but got rid of it since I couldn't fit in to the Wiki info.

Link to comment
Share on other sites

hey Mario,

I mean to say that when intensity of light increases the specs changes its color so as it gets out of control in certain situations so the specular lobes are very nice but the color of the spec changes. That would be disturbing some times.

Yeah Im thinking of first desaturating that what ever the spec it comes and the multiply with a new component color that would probably fit my requirement.

thanks,

Ken

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...