Golgoth

06-23-2006, 02:11 PM

Hi guys!

I ve been trying to port this cg shader to glsl... relief mapping is one thing but the curved is another... I believe it is a must to understand and frankly... it is amazing... check this out:

http://fabio.policarpo.nom.br/docs/Curved_ReliefMapping.pdf

http://fabio.policarpo.nom.br/files/reliefmap4.zip

if anyone is interested in helping digging this out... fun is on its way! :)

here is what ShaderDesigner as to offer as a starter:

vert

uniform mat4 matWorldView;

uniform mat4 matView;

uniform mat4 matWorldViewProjection;

attribute vec3 tangent;

attribute vec3 binormal;

varying vec2 texCoord;

varying vec3 eyeSpaceVert;

varying vec3 eyeSpaceTangent;

varying vec3 eyeSpaceBinormal;

varying vec3 eyeSpaceNormal;

varying vec3 eyeSpaceLight;

void main(void)

{

eyeSpaceVert = (gl_ModelViewMatrix * gl_Vertex).xyz;

// eyeSpaceLight = (gl_ModelViewMatrix * vec4(gl_LightSource[0].position.xyz,1.0)).xyz;

eyeSpaceLight = vec4(gl_LightSource[0].position.xyz,1.0).xyz;

eyeSpaceTangent = gl_NormalMatrix * tangent;

eyeSpaceBinormal = gl_NormalMatrix * binormal;

eyeSpaceNormal = gl_NormalMatrix * gl_Normal;

texCoord = gl_MultiTexCoord0.xy;

gl_Position = ftransform();

}frag

uniform vec4 ambient;

uniform vec4 specular;

uniform vec4 diffuse;

uniform float shine;

uniform float depth;

uniform float tile;

uniform int linear_search_steps;

uniform int binary_search_steps;

varying vec2 texCoord;

varying vec3 eyeSpaceVert;

varying vec3 eyeSpaceTangent;

varying vec3 eyeSpaceBinormal;

varying vec3 eyeSpaceNormal;

varying vec3 eyeSpaceLight;

uniform sampler2D reliefmap;

uniform sampler2D texmap;

uniform sampler2D gloss;

float ray_intersect_rm(in vec2 dp,in vec2 ds);

void main(void)

{

vec4 t,c;

vec3 p,v,l,s;

vec2 dp,ds,uv;

float d,a;

// ray intersect in view direction

p = eyeSpaceVert;

v = normalize(p);

a = dot(eyeSpaceNormal,-v);

s = normalize(vec3(dot(v,eyeSpaceTangent),dot(v,eyeSpa ceBinormal),a));

s *= depth/a;

dp = texCoord*tile;

ds = s.xy;

d = ray_intersect_rm(dp,ds);

// get rm and color texture points

uv=dp+ds*d;

t=texture2D(reliefmap,uv);

c=texture2D(texmap,uv);

// expand normal from normal map in local polygon space

t.xy=t.xy*2.0-1.0;

t.z=sqrt(1.0-dot(t.xy,t.xy));

t.xyz=normalize(t.x*eyeSpaceTangent+t.y*eyeSpaceBi normal+t.z*eyeSpaceNormal);

// compute light direction

p += v*d*a;

l=normalize(p-eyeSpaceLight.xyz);

// ray intersect in light direction

dp+= ds*d;

a = dot(eyeSpaceNormal,-l);

s = normalize(vec3(dot(l,eyeSpaceTangent),dot(l,eyeSpa ceBinormal),a));

s *= depth/a;

ds = s.xy;

dp-= ds*d;

float dl = ray_intersect_rm(dp,s.xy);

float shadow = 1.0;

vec3 specular_shadow=specular.xyz;

if (dl<d-0.05) // if pixel in shadow

{

shadow=dot(ambient.xyz,vec3(1.0))*0.333333;

specular_shadow=vec3(0.0);

}

// compute diffuse and specular terms

float att=max(0.0,dot(-l,eyeSpaceNormal));

float diff=shadow*max(0.0,dot(-l,t.xyz));

float spec=max(0.0,dot(normalize(-l-v),t.xyz));

// compute final color

vec4 finalcolor;

finalcolor.xyz=ambient.xyz*c.xyz+

att*(c.xyz*diffuse.xyz*diff+specular_shadow*pow(sp ec,shine));

finalcolor.w=1.0;

gl_FragColor = vec4(finalcolor.rgb,1.0);

}

float ray_intersect_rm(in vec2 dp, in vec2 ds)

{

//const int linear_search_steps=20;

//const int binary_search_steps=5;

float depth_step=1.0/float(linear_search_steps);

// current size of search window

float size=depth_step;

// current depth position

float depth=0.0;

// best match found (starts with last position 1.0)

float best_depth=1.0;

// search front to back for first point inside object

for( int i=0;i<linear_search_steps-1;i++ )

{

depth+=size;

vec4 t=texture2D(reliefmap,dp+ds*depth);

if (best_depth>0.996) // if no depth found yet

if (depth>=t.w)

best_depth=depth; // store best depth

}

depth=best_depth;

// recurse around first point (depth) for closest match

for( int i=0;i<binary_search_steps;i++ )

{

size*=0.5;

vec4 t=texture2D(reliefmap,dp+ds*depth);

if (depth>=t.w)

{

best_depth=depth;

depth-=2.0*size;

}

depth+=size;

}

return best_depth;

}

I ve been trying to port this cg shader to glsl... relief mapping is one thing but the curved is another... I believe it is a must to understand and frankly... it is amazing... check this out:

http://fabio.policarpo.nom.br/docs/Curved_ReliefMapping.pdf

http://fabio.policarpo.nom.br/files/reliefmap4.zip

if anyone is interested in helping digging this out... fun is on its way! :)

here is what ShaderDesigner as to offer as a starter:

vert

uniform mat4 matWorldView;

uniform mat4 matView;

uniform mat4 matWorldViewProjection;

attribute vec3 tangent;

attribute vec3 binormal;

varying vec2 texCoord;

varying vec3 eyeSpaceVert;

varying vec3 eyeSpaceTangent;

varying vec3 eyeSpaceBinormal;

varying vec3 eyeSpaceNormal;

varying vec3 eyeSpaceLight;

void main(void)

{

eyeSpaceVert = (gl_ModelViewMatrix * gl_Vertex).xyz;

// eyeSpaceLight = (gl_ModelViewMatrix * vec4(gl_LightSource[0].position.xyz,1.0)).xyz;

eyeSpaceLight = vec4(gl_LightSource[0].position.xyz,1.0).xyz;

eyeSpaceTangent = gl_NormalMatrix * tangent;

eyeSpaceBinormal = gl_NormalMatrix * binormal;

eyeSpaceNormal = gl_NormalMatrix * gl_Normal;

texCoord = gl_MultiTexCoord0.xy;

gl_Position = ftransform();

}frag

uniform vec4 ambient;

uniform vec4 specular;

uniform vec4 diffuse;

uniform float shine;

uniform float depth;

uniform float tile;

uniform int linear_search_steps;

uniform int binary_search_steps;

varying vec2 texCoord;

varying vec3 eyeSpaceVert;

varying vec3 eyeSpaceTangent;

varying vec3 eyeSpaceBinormal;

varying vec3 eyeSpaceNormal;

varying vec3 eyeSpaceLight;

uniform sampler2D reliefmap;

uniform sampler2D texmap;

uniform sampler2D gloss;

float ray_intersect_rm(in vec2 dp,in vec2 ds);

void main(void)

{

vec4 t,c;

vec3 p,v,l,s;

vec2 dp,ds,uv;

float d,a;

// ray intersect in view direction

p = eyeSpaceVert;

v = normalize(p);

a = dot(eyeSpaceNormal,-v);

s = normalize(vec3(dot(v,eyeSpaceTangent),dot(v,eyeSpa ceBinormal),a));

s *= depth/a;

dp = texCoord*tile;

ds = s.xy;

d = ray_intersect_rm(dp,ds);

// get rm and color texture points

uv=dp+ds*d;

t=texture2D(reliefmap,uv);

c=texture2D(texmap,uv);

// expand normal from normal map in local polygon space

t.xy=t.xy*2.0-1.0;

t.z=sqrt(1.0-dot(t.xy,t.xy));

t.xyz=normalize(t.x*eyeSpaceTangent+t.y*eyeSpaceBi normal+t.z*eyeSpaceNormal);

// compute light direction

p += v*d*a;

l=normalize(p-eyeSpaceLight.xyz);

// ray intersect in light direction

dp+= ds*d;

a = dot(eyeSpaceNormal,-l);

s = normalize(vec3(dot(l,eyeSpaceTangent),dot(l,eyeSpa ceBinormal),a));

s *= depth/a;

ds = s.xy;

dp-= ds*d;

float dl = ray_intersect_rm(dp,s.xy);

float shadow = 1.0;

vec3 specular_shadow=specular.xyz;

if (dl<d-0.05) // if pixel in shadow

{

shadow=dot(ambient.xyz,vec3(1.0))*0.333333;

specular_shadow=vec3(0.0);

}

// compute diffuse and specular terms

float att=max(0.0,dot(-l,eyeSpaceNormal));

float diff=shadow*max(0.0,dot(-l,t.xyz));

float spec=max(0.0,dot(normalize(-l-v),t.xyz));

// compute final color

vec4 finalcolor;

finalcolor.xyz=ambient.xyz*c.xyz+

att*(c.xyz*diffuse.xyz*diff+specular_shadow*pow(sp ec,shine));

finalcolor.w=1.0;

gl_FragColor = vec4(finalcolor.rgb,1.0);

}

float ray_intersect_rm(in vec2 dp, in vec2 ds)

{

//const int linear_search_steps=20;

//const int binary_search_steps=5;

float depth_step=1.0/float(linear_search_steps);

// current size of search window

float size=depth_step;

// current depth position

float depth=0.0;

// best match found (starts with last position 1.0)

float best_depth=1.0;

// search front to back for first point inside object

for( int i=0;i<linear_search_steps-1;i++ )

{

depth+=size;

vec4 t=texture2D(reliefmap,dp+ds*depth);

if (best_depth>0.996) // if no depth found yet

if (depth>=t.w)

best_depth=depth; // store best depth

}

depth=best_depth;

// recurse around first point (depth) for closest match

for( int i=0;i<binary_search_steps;i++ )

{

size*=0.5;

vec4 t=texture2D(reliefmap,dp+ds*depth);

if (depth>=t.w)

{

best_depth=depth;

depth-=2.0*size;

}

depth+=size;

}

return best_depth;

}