Phong Shader

Hi!



I found this Phong Shader on the net and attached it to a model in my scene. Unfortunately I don’t understand a lot of shaders.







Is it possible to use the shader with my texture (as shown on the right model)???



here are the programs:



!!ARBfp1.0
#simple phong lighting shader
#Declarations
TEMP tmp;
TEMP dif;
TEMP spec;
TEMP view;
ATTRIB tex = fragment.texcoord[0];
ATTRIB nrm = fragment.texcoord[1];
ATTRIB vDir = fragment.texcoord[2];
PARAM color = {0.2, 0.3, 1.0, 1.0};
PARAM const = {0.2, 0.2, 0.2, 32.0};
PARAM light = { 0.57735, 0.57735, 0.57735, 0.0};
OUTPUT out = result.color;

#Code
#Normalize the normal
DP3 tmp.a, nrm, nrm;
###reciprocal sqr root
RSQ tmp.a, tmp.a;
MUL tmp.rgb, nrm, tmp.a;
#normalize the view

DP3 view.a, vDir, vDir;
RSQ view.a, view.a;
MUL view.rgb, vDir, view.a;
#compute half angle vector
ADD spec.rgb, view, light;
DP3 spec.a, spec, spec;
RSQ spec.a, spec.a;
MUL spec.rgb, spec, spec.a;
#compute specular intensisty
### clamp before write
DP3_SAT spec.a, spec, tmp;
LG2 spec.a, spec.a;
MUL spec.a, spec.a, const.w;
EX2 spec.a, spec.a;
#compute diffuse illum
DP3_SAT dif, tmp, light;
ADD_SAT dif.rgb, dif, const;
#sum
MAD_SAT dif.rgb, color, dif,
spec.a;
MOV dif.a, color.a;
MOV out, dif;
END




!!ARBvp1.0
#Declarations
ATTRIB in = vertex.position;
ATTRIB nrm = vertex.normal;
ATTRIB tex = vertex.texcoord[0];
PARAM mvp[4] = { state.matrix.mvp };
PARAM mv[4] = { state.matrix.modelview };
OUTPUT out = result.position;
OUTPUT oTex = result.texcoord[0];
OUTPUT oNrm = result.texcoord[1];
OUTPUT vDir = result.texcoord[2];
TEMP tmp;

#Code
#transform the positions
DP4 out.x, in, mvp[0];
DP4 out.y, in, mvp[1];
DP4 out.z, in, mvp[2];
DP4 out.w, in, mvp[3];
#transform the position

DP4 tmp.x, in, mv[0];
DP4 tmp.y, in, mv[1];
DP4 tmp.z, in, mv[2];
DP4 tmp.w, in, mv[3];
#view direction
MOV vDir, -tmp;
#transfrom the normal to

DP3 oNrm.x, mv[0], nrm;
DP3 oNrm.y, mv[1], nrm;
DP3 oNrm.z, mv[2], nrm;
#output the texcoords
MOV oTex, tex;
END

In that you need in first to get texture[0] and if you use normal like me texture[1]:



TEMP diffuse, normal, temp, resColor;

PARAM ambient = state.lightmodel.ambient;



TEX diffuse, fragment.texcoord[0], texture[0], 2D;

TEX normal, fragment.texcoord[0], texture[1], 2D;



then



You need to normalize (in case of normal):



MAD normal, normal, 2.0, -1.0;

DP3 temp, normal, normal;

RSQ temp, temp.r;

MUL normal, normal, temp, bump, total;



Then process light direction:


normalize the light0 vector

DP3 temp, fragment.texcoord[1], fragment.texcoord[1];

RSQ temp, temp.x;

MUL light0tsvec, fragment.texcoord[1], temp;


normal dot lightdir 0

DP3 bump, normal, light0tsvec;

MUL_SAT total, bump, color0;


normalize the light1 vector

DP3 temp, fragment.texcoord[2], fragment.texcoord[2];

RSQ temp, temp.x;

MUL light1tsvec, fragment.texcoord[2], temp;


normal dot lightdir 1

DP3 bump, normal, light1tsvec;

MUL_SAT bump, bump, color1;

ADD_SAT total, total, bump;



to get scene globoal ambient light you need to add ambient:

ADD_SAT total, total, ambient;



Now you can apply the diffuse map to the total of processed normal with light:



MUL_SAT resColor, rgb, total;





Now you are ready to combine that part with your code in that way:



I keep tmp for using mesh light diffusion



#normalize the normal (global map)

DP3 tmp.a, nrm, nrm;

RSQ tmp.a, tmp.a;

MUL tmp.rgb, nrm, tmp.a;



#normalize the view (with normal)

DP3 view.a, normal, normal;

RSQ view.a, view.a;

MUL view.rgb, normal, view.a;



#Adding mesh and normal light:

ADD normals, view, tmp;



Getting correct ligth position (here i have some problem if anyone can solve)

I use lightPos - FragPos to get light by direction, but maybe is a bad fake, that i move lightPos to lightVec and use ligth direction at the moment…



#pointing to light0

DP4 light0pos, normals, state.light[0].position;

SUB light0vec, light0pos, fragment.position;

#Try to comment the line below:

MOV light0vec, state.light[0].position;



#pointing to light1

DP4 light1pos, normals, state.light[1].position;

SUB light1vec, light1pos, fragment.position;

#Try to comment the line below:

MOV light1vec, state.light[1].position;





#compute half angle vector for light 1

ADD spec0.rgb, normals, light0vec;

DP3 spec0.a, spec0, spec0;

RSQ spec0.a, spec0.a;

MUL spec0.rgb, spec0, spec0.a;

#compute specular intensity

DP3_SAT spec0.a, spec0, normals;

LG2 spec0.a, spec0.a;

MUL spec0.a, spec0.a, resColor;

EX2 spec0.a, spec0.a;



#compute half angle vector for light 2

ADD spec1.rgb, normals, light1vec;

DP3 spec1.a, spec1, spec1;

RSQ spec1.a, spec1.a;

MUL spec1.rgb, spec1, spec1.a;

#compute specular intensity

DP3_SAT spec1.a, spec1, normals;

LG2 spec1.a, spec1.a;

MUL spec1.a, spec1.a, resColor;

EX2 spec1.a, spec1.a;



#compute specular lights

MUL specColor0, spec0.a, state.light[0].diffuse;

MUL specColor1, spec1.a, state.light[1].diffuse;

ADD totalSpecs, specColor0, specColor1;

#here i use a param passed during shaders load process ( PARAM specIntensity = {0.5, 0.5, 0.5, 1}; or program.local[0]; )

MUL intensityRes, resColor, specIntensity;

MUL totalSpecs, totalSpecs, intensityRes;



#getting correct colors and textures with global ambient light:

DP3_SAT dif, normals, resColor;

ADD_SAT dif.rgb, dif, ambient;



#sum

MAD_SAT dif.rgb, resColor, dif, totalSpecs;

MOV result.color, dif;



END



Then, that are a simple play i made with your code and getting normal example from parallax example shader.

The vertex program are the same and my complete code like i write above is that:



!!ARBfp1.0

TEMP tmp;
TEMP dif;
TEMP spec0, spec1;
TEMP specColor0, specColor1;
TEMP view;
TEMP totalSpecs;

TEMP eyevects, eyevec;
TEMP rgb, normal, height, temp, bump, total;
TEMP normals;
TEMP light0tsvec, light1tsvec;
TEMP newtexcoord;
TEMP resColor;
TEMP intensityRes;

TEMP light0pos, light0vec;
TEMP light1pos, light1vec;

ATTRIB tex = fragment.texcoord[0];
ATTRIB nrm = fragment.texcoord[1];
PARAM color0 = state.light[0].diffuse;
PARAM color1 = state.light[1].diffuse;
PARAM specIntensity =  program.local[0];
PARAM ambient = state.lightmodel.ambient;

#Code

DP3 temp, fragment.texcoord[3], fragment.texcoord[3];
RSQ temp, temp.x;
MUL eyevects, fragment.texcoord[3], temp;

# get texture data
TEX rgb, fragment.texcoord[0], texture[0], 2D;
TEX normal, fragment.texcoord[0], texture[1], 2D;

# remove scale and bias from the normal map
MAD normal, normal, 2.0, -1.0;

# normalize the normal map
DP3 temp, normal, normal;
RSQ temp, temp.r;
MUL normal, normal, temp;

# add ambient lighting
ADD_SAT total, total, ambient;

# normalize the light0 vector
DP3 temp, fragment.texcoord[1], fragment.texcoord[1];
RSQ temp, temp.x;
MUL light0tsvec, fragment.texcoord[1], temp;

# normal dot lightdir 1
DP3 bump, normal, light0tsvec;
MUL_SAT total, bump, color0;

# normalize the light1 vector
DP3 temp, fragment.texcoord[2], fragment.texcoord[2];
RSQ temp, temp.x;
MUL light1tsvec, fragment.texcoord[2], temp;

# normal dot lightdir 2
DP3 bump, normal, light1tsvec;
MUL_SAT bump, bump, color1;
ADD_SAT total, total, bump;

# add ambient lighting
ADD_SAT total, total, ambient;

# multiply by regular texture map color
MUL_SAT resColor, rgb, total;

#normalize the normal (global map)
DP3 tmp.a, nrm, nrm;
RSQ tmp.a, tmp.a;
MUL tmp.rgb, nrm, tmp.a;

#normalize the view
DP3 view.a, normal, normal;
RSQ view.a, view.a;
MUL view.rgb, normal, view.a;

ADD normals, view, tmp;

#pointing to light0
DP4 light0pos, normals, state.light[0].position;
SUB light0vec, light0pos, fragment.position;
MOV light0vec, state.light[0].position;

#pointing to light1
DP4 light1pos, normals, state.light[1].position;
SUB light1vec, light1pos, fragment.position;
MOV light1vec, state.light[1].position;

#compute half angle vector for light 1
ADD spec0.rgb, normals, light0vec;
DP3 spec0.a, spec0, spec0;
RSQ spec0.a, spec0.a;
MUL spec0.rgb, spec0, spec0.a;
#compute specular intensisty
DP3_SAT spec0.a, spec0, normals;
LG2 spec0.a, spec0.a;
MUL spec0.a, spec0.a, resColor;
EX2 spec0.a, spec0.a;

#compute half angle vector for light 2
ADD spec1.rgb, normals, light1vec;
DP3 spec1.a, spec1, spec1;
RSQ spec1.a, spec1.a;
MUL spec1.rgb, spec1, spec1.a;
#compute specular intensisty
DP3_SAT spec1.a, spec1, normals;
LG2 spec1.a, spec1.a;
MUL spec1.a, spec1.a, resColor;
EX2 spec1.a, spec1.a;

#copmute specular lights
MUL specColor0, spec0.a, state.light[0].diffuse;
MUL specColor1, spec1.a, state.light[1].diffuse;
ADD totalSpecs, specColor0, specColor1;
MUL intensityRes, resColor, specIntensity;
MUL totalSpecs, totalSpecs, intensityRes;

#compute ambient light
DP3_SAT dif, normals, resColor;
ADD_SAT dif.rgb, dif, ambient;

#sum
MAD_SAT dif.rgb, resColor, dif, totalSpecs;
MOV result.color, dif;

END

Here is the code mixing up HeightMap too:



!!ARBfp1.0

TEMP tmp;
TEMP dif;
TEMP spec0, spec1;
TEMP specColor0, specColor1;
TEMP view;
TEMP totalSpecs;

TEMP eyevects;
TEMP rgb, normal, height, temp, bump, total;
TEMP normals;
TEMP light0tsvec, light1tsvec;
TEMP newtexcoord;
TEMP resColor;
TEMP intensityRes;

ATTRIB tex = fragment.texcoord[0];
ATTRIB nrm = fragment.texcoord[1];
PARAM light0 = state.light[0].position;
PARAM light1 = state.light[1].position;
PARAM color0 = state.light[0].diffuse;
PARAM color1 = state.light[1].diffuse;
PARAM specIntensity =  program.local[0];
PARAM ambient = state.lightmodel.ambient;

#Code

# normalize tangent space eye vector
DP3 temp, fragment.texcoord[3], fragment.texcoord[3];
RSQ temp, temp.x;
MUL eyevects, fragment.texcoord[3], temp;

# calculate offset and new texture coordinate
TEX height, fragment.texcoord[0], texture[2], 2D;
MAD height, height, 0.04, -0.02;  # scale and bias
MAD newtexcoord, height, eyevects, fragment.texcoord[0];

# get texture data
TEX rgb, newtexcoord, texture[0], 2D;
TEX normal, newtexcoord, texture[1], 2D;

# remove scale and bias from the normal map
MAD normal, normal, 2.0, -1.0;

# normalize the normal map
DP3 temp, normal, normal;
RSQ temp, temp.r;
MUL normal, normal, temp;

# add ambient lighting
ADD_SAT total, total, ambient;

# normalize the light0 vector
DP3 temp, fragment.texcoord[1], fragment.texcoord[1];
RSQ temp, temp.x;
MUL light0tsvec, fragment.texcoord[1], temp;

# normal dot lightdir
DP3 bump, normal, light0tsvec;

# add light0 color
MUL_SAT total, bump, state.light[0].diffuse;

# normalize the light1 vector
DP3 temp, fragment.texcoord[2], fragment.texcoord[2];
RSQ temp, temp.x;
MUL light1tsvec, fragment.texcoord[2], temp;

# normal dot lightdir
DP3 bump, normal, light1tsvec;

# add light1 color
MUL_SAT bump, bump, state.light[1].diffuse;
ADD_SAT total, total, bump;

# add ambient lighting
ADD_SAT total, total, ambient;

# multiply by regular texture map color
MUL_SAT resColor, rgb, total;

###reciprocal sqr root
DP3 tmp.a, nrm, nrm;
RSQ tmp.a, tmp.a;
MUL tmp.rgb, nrm, tmp.a;

#normalize the view
DP3 view.a, normal, normal;
RSQ view.a, view.a;
MUL view.rgb, normal, view.a;

ADD normals, view, tmp;

#compute half angle vector for light 1
ADD spec0.rgb, normals, state.light[0].position;
DP3 spec0.a, spec0, spec0;
RSQ spec0.a, spec0.a;
MUL spec0.rgb, spec0, spec0.a;
#compute specular intensisty
DP3_SAT spec0.a, spec0, normals;
LG2 spec0.a, spec0.a;
MUL spec0.a, spec0.a, resColor; #state.light[0].specular;
EX2 spec0.a, spec0.a;

#compute half angle vector for light 2
ADD spec1.rgb, normals, state.light[1].position;
DP3 spec1.a, spec1, spec1;
RSQ spec1.a, spec1.a;
MUL spec1.rgb, spec1, spec1.a;
#compute specular intensisty
DP3_SAT spec1.a, spec1, normals;
LG2 spec1.a, spec1.a;
MUL spec1.a, spec1.a, resColor; #state.light[1].specular;
EX2 spec1.a, spec1.a;

#copmute specular lights
MUL specColor0, spec0.a, state.light[0].diffuse;
MUL specColor1, spec1.a, state.light[1].diffuse;
ADD totalSpecs, specColor0, specColor1;
MUL intensityRes, resColor, specIntensity;
MUL totalSpecs, totalSpecs, intensityRes;

#compute ambient light
DP3_SAT dif, normals, resColor;
ADD_SAT dif.rgb, dif, ambient;

#sum
MAD_SAT dif.rgb, resColor, dif, totalSpecs;
MOV result.color, dif;

END

And that is using only a texture:



!!ARBfp1.0

TEMP tmp;#, temp;
TEMP dif;
TEMP spec0, spec1;
TEMP specColor0, specColor1;
TEMP view;
TEMP rgb;
TEMP total;

TEMP light0pos, light0vec;
TEMP light1pos, light1vec;

ATTRIB tex = fragment.texcoord[0];
ATTRIB normal = fragment.texcoord[1];
PARAM specIntensity =  program.local[0];

#Code
#get diffuse texture
TEX rgb, tex, texture[0], 2D;

#normalize the view
DP3 view.a, normal, normal;
RSQ view.a, view.a;
MUL view.rgb, normal, view.a;

#pointing to light0
DP4 light0pos, view.a, state.light[0].position;
SUB light0vec, light0pos, fragment.position;
MOV light0vec, state.light[0].position;

#pointing to light1
DP4 light1pos, view.a, state.light[1].position;
SUB light1vec, light1pos, fragment.position;
MOV light1vec, state.light[1].position;

#compute half angle vector for light 1
ADD spec0.rgb, view, light0vec;
DP3 spec0.a, spec0, spec0;
RSQ spec0.a, spec0.a;
MUL spec0.rgb, spec0, spec0.a;
#compute specular intensisty
DP3_SAT spec0.a, spec0, view;
LG2 spec0.a, spec0.a;
EX2 spec0.a, spec0.a;
MUL spec0.a, spec0.a, rgb;

#compute half angle vector for light 2
ADD spec1.rgb, view, light1vec;
DP3 spec1.a, spec1, spec1;
RSQ spec1.a, spec1.a;
MUL spec1.rgb, spec1, spec1.a;
#compute specular intensisty
DP3_SAT spec1.a, spec1, view;
LG2 spec1.a, spec1.a;
EX2 spec1.a, spec1.a;
MUL spec1.a, spec1.a, rgb;

#copmute specular lights
MUL specColor0, spec0.a, state.light[0].diffuse;
MUL specColor1, spec1.a, state.light[1].diffuse;
ADD total, specColor0, specColor1;
MUL total, total, specIntensity;

#compute ambient light
DP3_SAT dif, view, rgb;
ADD_SAT dif.rgb, dif, state.lightmodel.ambient;

#sum
MAD_SAT dif.rgb, rgb, dif, total;
MOV result.color, dif;

END

And then some shots:



Diffuse:





Normal:





Parallax:

Very cool!



Could you post the Java test code you used to generate those cool images?

Can anyone else NOT see the images?  I'd sure like to.  Any chance of a repost or hosting them somewhere else.  I've tried from work and at home - no luck.

Oh, strange…

You can't get my host?



http://www.g32.it

Achilleterzo said:

Oh, strange...
You can't get my host?

http://www.g32.it


Comes up dead for me both at work and at home.

I see the images fine, in Taunton MA USA.

I don't know, maybe some dns problem?

Worked tonight from home.  Must've been screwy last night.  That's great work, those images look awesome.