1

I still didn't get rid of some annoying bugs in my glsl shader (GL 2.0)... I searched for a solution of this problem for over 3 weeks now, but I didn't get any. There are many examples and explanations on google, but none of them really works.

First of all, here is my fragmentshader code. After that I will explain what exactly the problem is:

//fragmentshader
const int MAX_POINT_LIGHTS = LL.MAX_POINT_LIGHTS;
const int MAX_DIR_LIGHTS = LL.MAX_DIR_LIGHTS;
const int MAX_TEXTURES = LL.MAX_TEXTURES;
//float-precision
precision mediump float;
//varyings
varying vec2 texcoord;
varying vec3 normal;
varying vec3 position;
varying float depth;
//pointlights
uniform float pl_range[MAX_POINT_LIGHTS];
uniform vec3 pl_position[MAX_POINT_LIGHTS];
uniform vec3 pl_color[MAX_POINT_LIGHTS];
uniform vec3 pl_specular[MAX_POINT_LIGHTS];
//dirlights
uniform vec3 dl_direction[MAX_DIR_LIGHTS];
uniform vec3 dl_position[MAX_DIR_LIGHTS];
uniform vec3 dl_color[MAX_DIR_LIGHTS];
uniform vec3 dl_specular[MAX_POINT_LIGHTS];
//cameras
uniform vec3 camera;
//fog
uniform vec4 uVecFog;
uniform float uFogNear;
uniform float uFogFar;
//material
uniform vec3 mat_diff;
uniform vec3 mat_spec;
uniform float mat_shine;
uniform float mat_elum;
//texture
uniform sampler2D uTexture;
//ambientlight
vec4 ambient = vec4(0.0,0.0,0.0,0.0);

void main() {

    vec3 N = normalize(normal);
    vec3 V = normalize(camera - position);
    vec4 diff  = vec4(0.0,0.0,0.0,0.0);
    vec4 spec = vec4(0.0,0.0,0.0,0.0);
    //dirlights
    for(int i=0;i<MAX_DIR_LIGHTS;i++) {
        vec3 L = -normalize(dl_direction[i]);
        vec3 R = -normalize(reflect(L,N));
        float RV = max(dot(R,V),0.0);
        float S = pow(max(dot(R,V),0.0),mat_shine);
        float F = clamp(dot(L,N),0.0,1.0);
        diff += vec4(F * mat_diff * dl_color[i],1.0);
        spec = vec4(S * mat_spec * dl_specular[i],1.0);
    }

    //pointlights
    for(int i=0;i<MAX_POINT_LIGHTS;i++) {
        vec3 L = normalize(pl_position[i] - position);
        vec3 R = -normalize(reflect(L,N));
        float D = distance(pl_position[i],position);
        float DF = clamp(1.0 - D/pl_range[i],0.0,1.0);
        float S = pow(max(dot(R,V),0.0),mat_shine);
        float F = clamp(DF * max(dot(L,N),0.0),0.0,1.0);
        diff += vec4(F * mat_diff * pl_color[i],1.0);
        spec += vec4(DF * S * mat_spec * pl_specular[i],1.0);
    }
    //fog
    float fogDensity = 0.0;
    if (depth > uFogFar) {
        fogDensity = 1.0;
    } else if(depth > uFogNear) {
        float newDepth = depth-uFogNear;
        fogDensity = newDepth/(uFogFar-uFogNear);
    } else if (depth < uFogNear) {
        fogDensity = 0.0;
    }
    vec4 vecFog = uVecFog * fogDensity;
    //texturecolor
    vec4 colortex = texture2D(uTexture,vec2(texcoord.x,-texcoord.y));
    //final fragmentcolor
    gl_FragColor = mix((ambient + colortex * (diff + vec4(mat_diff * mat_elum,1.0)) + spec),vecFog,fogDensity);
}

There are give following variable-values, where:

  • pl_ are pointlightvalues,
  • dl_ are directionallightvalues,
  • mat_diff is the diffuse-value for the material,
  • also mat_spec, mat_elum, mat_shine for material specular, elumination and shininess,
  • N = Normal,
  • V = View-Vector to Vertex,
  • L = Light-Vector to Vertex,
  • R = Reflection Vector,
  • D = Lightdistance,
  • DF = Distancefactor for blending light,
  • S = Calculated Specularityfactor,
  • F = Dotproduct from L,N
  • and diff, spec vectorsum of the calculated diffuse/spec-vectors.

Now there occures following problem: Pointlights themself run perfect. Directionallights themself run perfect, too. But together they won't work very well. I'll precise the problem: I've got 4 Pointlights and 4 Directionallights for maximum. For testing i've used 4 Pointlights and 1 Directionallight.

  • If i commented out the for-loop calculation the directionallights, i got following result: Directionallights are disable, pointlights enabled
  • If i commented out the for-loop for pointlights, i got following result: Pointlights are disabled, directionallights enabled instead
  • If i enabled both for-loops, following happens: Both lightsource types are anabled

The directionallight seems to be ignored completly. The car is lighted only by the pointlights instead.

So, what I found out: If I change the order of the for-loops, pointlights -> directionallights, instead of dirlights -> pointlights, the effect swaps: pointlights are ignored, directionallight is computed.

What I found out too, this problem must be up to: pow() function or dividing by zero, but: If I comment out follwing lines of code:

spec = vec4(S * mat_spec * dl_specular[i],1.0);
spec += vec4(DF * S * mat_spec * pl_specular[i],1.0);

i can get following result:

spec += lines commented out

-> The diffuse color is computed normally for point AND directionallights!

So I thought of how to eliminate this problem, because I thought about 0 powered by 0 leads to a math error. Dividing by zero, too.... How can I avoid values that are undefined?

isnan() or isinf() functions seem not to exist in android-glsl.

Andy solutions or tipps what I could do better, that this will work? I would be glad about any answer if it could help a little bit. This makes me mad since 3 weeks. Thanks so much for helpers! :)

More information about the code: https://github.com/Chrise55/Llama3D

Chrise

Aziz Shaikh
  • 16,245
  • 11
  • 62
  • 79
TheWhiteLlama
  • 1,276
  • 1
  • 18
  • 31
  • 1
    can you try to change every 0 to 0.0000001 in your shader? I am preety sure that your shader failed at design stage and there is no simple way to outtake divide/0 or pow0 problem – ZZZ Jun 13 '12 at 07:51
  • when I reimplement the pintlights I'll do that! That's a good idea :) But is there any problem with float precision at this time? Because the values could still grow too big, couldn't they? – TheWhiteLlama Jun 13 '12 at 07:59
  • 1
    yes they can, and in es 2.0 there is only mediump available in glsl so if your shader is based on normal gl shader this may be point of failure. The idea of 0.00001 is stupid but its the way you will now in with place error occurs. – ZZZ Jun 14 '12 at 19:30
  • so there isn't any change, when I write highp or lowp in my shaders? – TheWhiteLlama Jun 15 '12 at 00:09

0 Answers0