Sign in to follow this  
razor1911

Shader performance

Recommended Posts

I'm running normal mapping with splatting on my terrain, but seems like when textures are sampled from the 2d array i get at least ~160fps loss.

Attached vert/frag shader,

how optimal is to sample normal/calculate from 2d array for each splat texture?







FRAG

[code]

#define USE_NORMALMAPPING

uniform sampler2D terrainSplat; //Splatting texture
uniform sampler2DArray terrainAtlas; //Colormap atlas
uniform sampler2DArray terrainNAtlas; //Colormap atlas


varying vec3 tnormal; //Normal from vertexs
varying vec2 uv_coords;

#ifdef USE_NORMALMAPPING


varying vec3 lightDir;
varying vec3 viewDir;
varying vec3 normal;

#endif



mat3 computeTangentFrame(vec3 normal, vec3 position, vec2 texCoord){
vec3 dpx = dFdx(position);
vec3 dpy = dFdy(position);
vec2 dtx = dFdx(texCoord);
vec2 dty = dFdy(texCoord);
vec3 tangent = normalize(dpy * dtx.t - dpx * dty.t);
vec3 binormal = cross(tangent, normal);
return mat3(tangent, binormal, normal);
}







void main()
{
vec4 Tb = texture2D(terrainSplat, uv_coords);


#ifdef USE_NORMALMAPPING

vec2 texCoord = vec2(uv_coords.x*100,uv_coords.y*100);
vec3 v = normalize(viewDir);
vec3 l = normalize(lightDir);
vec3 n = normalize(normal);
vec3 bump = normalize( texture2DArray(terrainNAtlas, vec3(texCoord.x,texCoord.y,0.0)).xyz * 2.0 - 1.0);
mat3 TBN = computeTangentFrame(n, v, texCoord);
n = normalize(TBN * bump);
float nDotL = clamp(dot(l, n), 0.0, 1.0);
vec4 ambient = gl_LightSource[0].ambient;
vec4 diffuse = gl_LightSource[0].diffuse * gl_FrontMaterial.diffuse * nDotL;
vec4 specular;
if (nDotL >= 0.0)
{

float nDotV = clamp(dot(reflect(-l, n), v), 0.0, 1.0);
specular = gl_LightSource[0].specular * gl_FrontMaterial.specular * pow(nDotV, gl_FrontMaterial.shininess);
}

vec4 t0 = (gl_FrontLightModelProduct.sceneColor + ambient + diffuse)* texture2DArray( terrainAtlas,vec3(texCoord.x,texCoord.y,0.0) ) + specular;




texCoord = vec2(uv_coords.x*110,uv_coords.y*110);
bump = normalize( texture2DArray(terrainNAtlas, vec3(texCoord.x,texCoord.y,1.0)).xyz * 2.0 - 1.0);
n = normalize(TBN * bump);
nDotL = clamp(dot(l, n), 0.0, 1.0);
diffuse = gl_LightSource[0].diffuse * gl_FrontMaterial.diffuse * nDotL;
if (nDotL >= 0.0)
{

float nDotV = clamp(dot(reflect(-l, n), v), 0.0, 1.0);
specular = gl_LightSource[0].specular * gl_FrontMaterial.specular * pow(nDotV, gl_FrontMaterial.shininess );

}
vec4 t1 = (gl_FrontLightModelProduct.sceneColor + ambient + diffuse)* texture2DArray( terrainAtlas,vec3(texCoord.x,texCoord.y,1.0) ) + specular;





texCoord = vec2(uv_coords.x*110,uv_coords.y*110);
bump = normalize( texture2DArray(terrainNAtlas, vec3(texCoord.x,texCoord.y,2.0)).xyz * 2.0 - 1.0);
n = normalize(TBN * bump);
nDotL = clamp(dot(l, n), 0.0, 1.0);
diffuse = gl_LightSource[0].diffuse * gl_FrontMaterial.diffuse * nDotL;
if (nDotL >= 0.0)
{

float nDotV = clamp(dot(reflect(-l, n), v), 0.0, 1.0);
specular = gl_LightSource[0].specular * gl_FrontMaterial.specular * pow(nDotV, gl_FrontMaterial.shininess );
}
vec4 t2 = (gl_FrontLightModelProduct.sceneColor + ambient + diffuse)* texture2DArray( terrainAtlas,vec3(texCoord.x,texCoord.y,2.0) ) + specular;





texCoord = vec2(uv_coords.x*160,uv_coords.y*160);
bump = normalize( texture2DArray(terrainNAtlas, vec3(texCoord.x,texCoord.y,3.0)).xyz * 2.0 - 1.0);
n = normalize(TBN * bump);
nDotL = clamp(dot(l, n), 0.0, 1.0);
diffuse = gl_LightSource[0].diffuse * gl_FrontMaterial.diffuse * nDotL;
if (nDotL >= 0.0)
{

float nDotV = clamp(dot(reflect(-l, n), v), 0.0, 1.0);
specular = gl_LightSource[0].specular * gl_FrontMaterial.specular * pow(nDotV, gl_FrontMaterial.shininess );
}
vec4 t3 = (gl_FrontLightModelProduct.sceneColor + ambient + diffuse)* texture2DArray( terrainAtlas,vec3(texCoord.x,texCoord.y,3.0) ) + specular;




texCoord = vec2(uv_coords.x*100,uv_coords.y*100);
bump = normalize( texture2DArray(terrainNAtlas, vec3(texCoord.x,texCoord.y,4.0)).xyz * 2.0 - 1.0);
n = normalize(TBN * bump);
nDotL = clamp(dot(l, n), 0.0, 1.0);
diffuse = gl_LightSource[0].diffuse * gl_FrontMaterial.diffuse * nDotL;
if (nDotL >= 0.0)
{

float nDotV = clamp(dot(reflect(-l, n), v), 0.0, 1.0);
specular = gl_LightSource[0].specular * gl_FrontMaterial.specular * pow(nDotV, gl_FrontMaterial.shininess );
}
vec4 t4 = (gl_FrontLightModelProduct.sceneColor + ambient + diffuse)* texture2DArray( terrainAtlas,vec3(texCoord.x,texCoord.y,4.0) ) + specular;



#else

vec4 t0=texture2DArray( terrainAtlas,vec3(uv_coords.x*100,uv_coords.y*100,0.0) );
vec4 t1=texture2DArray( terrainAtlas,vec3(uv_coords.x*110,uv_coords.y*110,1.0) );
vec4 t2=texture2DArray( terrainAtlas,vec3(uv_coords.x*110,uv_coords.y*110,2.0) );
vec4 t3=texture2DArray( terrainAtlas,vec3(uv_coords.x*160,uv_coords.y*160,3.0) );
vec4 t4=texture2DArray( terrainAtlas,vec3(uv_coords.x*100,uv_coords.y*100,4.0) );



#endif





vec4 splat;
vec4 color;

splat+=Tb.r*t2;
splat+=Tb.g*t0;
splat+=Tb.b*t3;
splat+=Tb.a*t4;




#ifdef USE_NORMALMAPPING
color= mix(splat,t1,1-tnormal.y);
#else
color= mix(splat,t1,1-tnormal.y)*gl_Color;
#endif



//Don't touch.
gl_FragColor = vec4(mix( color.rgb , gl_Fog.color.rgb ,gl_Color.a ),1);
gl_FragColor.a=1;



}





[/code]




VERT




[code]

#define USE_NORMALMAPPING

varying vec3 tnormal;
varying vec2 uv_coords;


#ifdef USE_NORMALMAPPING

varying vec3 lightDir;
varying vec3 viewDir;
varying vec3 normal;
#endif








void main()
{



#ifndef USE_NORMALMAPPING




vec3 normal, lightDir;
vec4 diffuse, ambient, globalAmbient;
float NdotL;

normal = normalize(gl_NormalMatrix * gl_Normal);

lightDir = normalize(vec3(gl_LightSource[0].position));
NdotL = max(dot(normal, lightDir), 0.0);


diffuse = gl_FrontMaterial.diffuse * gl_LightSource[0].diffuse;
ambient = gl_FrontMaterial.ambient * gl_LightSource[0].ambient;
globalAmbient = gl_LightModel.ambient * gl_FrontMaterial.ambient;

gl_FrontColor = NdotL * diffuse + globalAmbient + ambient;
#else


normal = normalize(gl_NormalMatrix * gl_Normal);
lightDir = normalize(gl_LightSource[0].position.xyz);
vec3 eyeVec = vec3(gl_ModelViewMatrix * gl_Vertex);
viewDir = normalize(-eyeVec);



#endif



gl_Position = ftransform();
tnormal=gl_Normal;
gl_FrontColor.a = clamp( ( gl_Position.z-gl_Fog.start ) / ( gl_Fog.end - gl_Fog.start ) , 0.0 , 1.0 );
uv_coords = gl_MultiTexCoord7.st;

}


[/code]







Share this post


Link to post
Share on other sites
For starters, why are you messing with the TBN in the pixel shader, The TBN matrix gives you a normal representing in another space( texture relative to model). When doing phong you interpolate the normals in the vertex shader, here again you should be interpolating the normal. Just because it is in a new space doesnt mean it should be done in the pixel shader.

Share this post


Link to post
Share on other sites
I would have to agree. Your computeTangentFrame function is unnecessary. Look at some other people normal mapping examples. Check out RenderMonkey if you wish.
Also, your fragment program look rather heavy.
I can also recommend to stop using deprecated stuff like
gl_LightSource but that is really your decision.

Share this post


Link to post
Share on other sites
[quote name='donmof' timestamp='1298310759' post='4777125'] i get at least ~160fps loss.[/quote]This statement is [b]completely meaningless[/b]. It tells us [b]absolutely nothing [/b]about the performance loss.

Lets say you started out at 2000fps and lost 160 -- That's a loss of 0.04ms.
On the other hand, if you started at 161fps and lost 160, then that's a loss of 993ms.
2000fps = 0.5ms per frame.
1840fps (2000 - 160) = 0.54ms per frame.
161fps = 6.21ms per frame.
1fps = 1000ms per frame.

So did you lose a fraction of a millisecond, or did you lost most of a second?[quote name='dpadam450' timestamp='1298313989' post='4777157']
You should take my original advice and get rid of the #ifdefs and write all separate cases as a different shader because it is going to get harder to read and debug.[/quote]It's fairly common for shaders to have a [i]lot[/i] more compile-time branches than that in them ;)
The lack of readability is made up for in the reduced duplication of code.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this