Kalir44

07-14-2015, 02:47 AM

Hey! First of all, sorry for the name of the topic, I have no idea how to call the problem I am having.

First of, here are my shaders because there's no way you'll understand without seeing them.

VertexShader:

attribute vec3 a_position; //attributes of vertex

attribute vec3 a_normal;

attribute vec2 a_texCoord0;

uniform mat4 u_worldTrans;

uniform mat4 u_projViewTrans; //some uniforms like transform of model, and camera matrix

uniform vec3 lightPos; //position of light

varying vec3 toCameraVector; //sending a toCameraVector to fragment shader (vector that points to camera)

varying vec2 v_texCoord0; //sending texCoords

varying vec3 normal; // sending Normal of vertex

varying vec3 toLightNormal; //sending toLightVector (vector that points to light)

void main() {

v_texCoord0 = a_texCoord0; //setting texCoords for fragment shader

vec4 worldTrans = u_worldTrans * vec4(a_position, 1.0); //calculate worldTransform of vertex

gl_Position = u_projViewTrans * worldTrans; //setting the position of vertex

normal = (u_worldTrans * vec4(a_normal, 0.0)).xyz; //setting the normal in worldCoords

toLightNormal = lightPos - worldTrans.xyz; // setting toLightVector

toCameraVector = (inverse(u_projViewTrans) * vec4(0.0, 0.0, 0.0, 1.0)).xyz - worldTrans.xyz; //setting toCameraVector

}

FragmentShader:

#ifdef GL_ES

precision mediump float; //have no idea what this does but it is needed I think

#endif

varying vec2 v_texCoord0; //getting all the info from vertexShader like texCoords, normal, and those 2 directional vectors

varying vec3 normal;

varying vec3 toLightNormal;

varying vec3 toCameraVector;

uniform sampler2D grass; //my textures. grass, dirt, path, flowers are than placed onto the mesh depending on the BlendMap color at corresponding pixel

uniform sampler2D dirt;

uniform sampler2D path;

uniform sampler2D flowers;

uniform sampler2D blendMap;

uniform sampler2D pathSpec; // specular map for path texture

uniform vec3 lightColour; //Colour of the light

float damper = 20; // some settings for customizable specular lighting

float reflectivity = 1;

void main() {

vec4 blendMapColour = texture(blendMap, v_texCoord0); //get the color of the blendMap at the corresponding pixel to vector

float grassColour = 1 - (blendMapColour.r + blendMapColour.g + blendMapColour.b); //I want to place grass when there is black color on the BlendMap so I create float that indicates that and then I will multiply grass texture with it.

vec2 texCoord = v_texCoord0 * 40; // multiply texCoords for tiling the texture

vec4 grassC = texture(grass, texCoord) * grassColour; //get all the textures at the corresponding pixel and then I multiply those by a color of the blendMap, basically, if there's black color I want to place grass, if red color I want to place //dirt texture and so on. You know, if there's no red color at the pixel of the Blendmap then the dirtTex.rgba are 0 so there's no dirt texture at all

vec4 dirtC = texture(dirt, texCoord) * blendMapColour.r;

vec4 pathC = texture(path, texCoord) * blendMapColour.b;

vec4 flowersC = texture(flowers, texCoord) * blendMapColour.g;

vec4 pathS = texture(pathSpec, texCoord) * blendMapColour.b;

vec4 finalColor = grassC + dirtC + pathC + flowersC; //mix all the textures together

vec3 UniteNormal = normalize(normal); //here the diffuse lighting calculations starts, no need to comment it I think

vec3 UnitLightNormal = normalize(toLightNormal);

float nDotl = dot(UniteNormal, UnitLightNormal);

float brightness = max(nDotl, 0.2);

vec3 diffuse = lightColour * brightness; //the diffuse lighting calculations ends

if (pathC.r > 0) { //if there is path texture at the corresponding pixel, I want to calculate the specular light of it so I do that here

vec3 UnitCameraVector = normalize(toCameraVector);

vec3 fromLightNormal = -UnitLightNormal;

vec3 reflectedVector = reflect(fromLightNormal, UniteNormal);

float SpecFactor = dot(reflectedVector, UnitCameraVector);

SpecFactor = max(SpecFactor, 0.0);

float Dumped = pow(SpecFactor, damper);

vec3 finalSpec = Dumped * reflectivity * lightColour;

gl_FragColor = vec4(diffuse, 1.0) * finalColor + vec4(finalSpec, 1.0) * pathS.r; // and now just apply the diffuse light, finalColor(which is now the path Texture basically) and specularlight onto the pixel

} else {

gl_FragColor = vec4(diffuse, 1.0) * finalColor; //if there is not path texture at the corresponding pixel but there's grass or whatever else, I dont do specular light.

}

}

Basically, my shaders are pretty advanced(they do diffuse lighting, specular lighting, multitexturing) and I noticed quite bad performance with it. The main problem occured when I wanted to optimize it. I tried to "profile" what slows it all down, so I tried to modify everything and found out that if I pass red(vec4(1,0,0,1)) or any other color to gl_FragColor(the color of pixel), so I dont draw the lighting and textures, everything works pretty good. What a weird thing? I still do all the light and multitexturing calculations in fragment Shader, but I dont draw them and FPS are good. This means, there is not any problem in calculations, but there's problem in displaying the result. Then I played around with it little more and found out that if I just mix all the textures together(without multiplying them by color of the blendMap) and pass it onto pixel color the performance is still good. but then if I multiply the result with diffuse vec. it starts to be worse and worse.

My question is, is this how it should work? I mean, I could understand that displaying the textures may slow down game, but as I mentioned, this doesn't..

I really appreciate any advice. Thanks in advance!

First of, here are my shaders because there's no way you'll understand without seeing them.

VertexShader:

attribute vec3 a_position; //attributes of vertex

attribute vec3 a_normal;

attribute vec2 a_texCoord0;

uniform mat4 u_worldTrans;

uniform mat4 u_projViewTrans; //some uniforms like transform of model, and camera matrix

uniform vec3 lightPos; //position of light

varying vec3 toCameraVector; //sending a toCameraVector to fragment shader (vector that points to camera)

varying vec2 v_texCoord0; //sending texCoords

varying vec3 normal; // sending Normal of vertex

varying vec3 toLightNormal; //sending toLightVector (vector that points to light)

void main() {

v_texCoord0 = a_texCoord0; //setting texCoords for fragment shader

vec4 worldTrans = u_worldTrans * vec4(a_position, 1.0); //calculate worldTransform of vertex

gl_Position = u_projViewTrans * worldTrans; //setting the position of vertex

normal = (u_worldTrans * vec4(a_normal, 0.0)).xyz; //setting the normal in worldCoords

toLightNormal = lightPos - worldTrans.xyz; // setting toLightVector

toCameraVector = (inverse(u_projViewTrans) * vec4(0.0, 0.0, 0.0, 1.0)).xyz - worldTrans.xyz; //setting toCameraVector

}

FragmentShader:

#ifdef GL_ES

precision mediump float; //have no idea what this does but it is needed I think

#endif

varying vec2 v_texCoord0; //getting all the info from vertexShader like texCoords, normal, and those 2 directional vectors

varying vec3 normal;

varying vec3 toLightNormal;

varying vec3 toCameraVector;

uniform sampler2D grass; //my textures. grass, dirt, path, flowers are than placed onto the mesh depending on the BlendMap color at corresponding pixel

uniform sampler2D dirt;

uniform sampler2D path;

uniform sampler2D flowers;

uniform sampler2D blendMap;

uniform sampler2D pathSpec; // specular map for path texture

uniform vec3 lightColour; //Colour of the light

float damper = 20; // some settings for customizable specular lighting

float reflectivity = 1;

void main() {

vec4 blendMapColour = texture(blendMap, v_texCoord0); //get the color of the blendMap at the corresponding pixel to vector

float grassColour = 1 - (blendMapColour.r + blendMapColour.g + blendMapColour.b); //I want to place grass when there is black color on the BlendMap so I create float that indicates that and then I will multiply grass texture with it.

vec2 texCoord = v_texCoord0 * 40; // multiply texCoords for tiling the texture

vec4 grassC = texture(grass, texCoord) * grassColour; //get all the textures at the corresponding pixel and then I multiply those by a color of the blendMap, basically, if there's black color I want to place grass, if red color I want to place //dirt texture and so on. You know, if there's no red color at the pixel of the Blendmap then the dirtTex.rgba are 0 so there's no dirt texture at all

vec4 dirtC = texture(dirt, texCoord) * blendMapColour.r;

vec4 pathC = texture(path, texCoord) * blendMapColour.b;

vec4 flowersC = texture(flowers, texCoord) * blendMapColour.g;

vec4 pathS = texture(pathSpec, texCoord) * blendMapColour.b;

vec4 finalColor = grassC + dirtC + pathC + flowersC; //mix all the textures together

vec3 UniteNormal = normalize(normal); //here the diffuse lighting calculations starts, no need to comment it I think

vec3 UnitLightNormal = normalize(toLightNormal);

float nDotl = dot(UniteNormal, UnitLightNormal);

float brightness = max(nDotl, 0.2);

vec3 diffuse = lightColour * brightness; //the diffuse lighting calculations ends

if (pathC.r > 0) { //if there is path texture at the corresponding pixel, I want to calculate the specular light of it so I do that here

vec3 UnitCameraVector = normalize(toCameraVector);

vec3 fromLightNormal = -UnitLightNormal;

vec3 reflectedVector = reflect(fromLightNormal, UniteNormal);

float SpecFactor = dot(reflectedVector, UnitCameraVector);

SpecFactor = max(SpecFactor, 0.0);

float Dumped = pow(SpecFactor, damper);

vec3 finalSpec = Dumped * reflectivity * lightColour;

gl_FragColor = vec4(diffuse, 1.0) * finalColor + vec4(finalSpec, 1.0) * pathS.r; // and now just apply the diffuse light, finalColor(which is now the path Texture basically) and specularlight onto the pixel

} else {

gl_FragColor = vec4(diffuse, 1.0) * finalColor; //if there is not path texture at the corresponding pixel but there's grass or whatever else, I dont do specular light.

}

}

Basically, my shaders are pretty advanced(they do diffuse lighting, specular lighting, multitexturing) and I noticed quite bad performance with it. The main problem occured when I wanted to optimize it. I tried to "profile" what slows it all down, so I tried to modify everything and found out that if I pass red(vec4(1,0,0,1)) or any other color to gl_FragColor(the color of pixel), so I dont draw the lighting and textures, everything works pretty good. What a weird thing? I still do all the light and multitexturing calculations in fragment Shader, but I dont draw them and FPS are good. This means, there is not any problem in calculations, but there's problem in displaying the result. Then I played around with it little more and found out that if I just mix all the textures together(without multiplying them by color of the blendMap) and pass it onto pixel color the performance is still good. but then if I multiply the result with diffuse vec. it starts to be worse and worse.

My question is, is this how it should work? I mean, I could understand that displaying the textures may slow down game, but as I mentioned, this doesn't..

I really appreciate any advice. Thanks in advance!