0

I have a problem with the following shader function in my android opengl project:

highp float calculateShadow(highp float cosTheta, highp vec4 shadowCoord)
{
    highp float bias = 0.005 * sqrt ( 1.0f - cosTheta * cosTheta   ) / cosTheta;
    bias = clamp(bias, 0.0 ,0.01);
    shadowCoord.z = shadowCoord.z - bias;
    return textureProjOffset(uTextureShadowMap, shadowCoord, ivec2(0,0));
}

This function is used to determine if a fragment is in shadow or not. The first parameter (cosTheta) is calculated in the following way:

float cosTheta = dot(theNormal, fragmentToSun);

So, cosTheta is the angle between the face's normal and the direction from the fragment to the sun. cosTheta is then used to shift the bias according to the face's slope - it kind of works quite well. I got it from opengl-tutorial.com.

But here's my problem:

On my Samsung Galaxy S7 with Exynos-CPU I have no shadow acne, but on devices with a Snapdragon 600 or 855 chipsets I get a lot of acne.

Why is there a difference? The shader function should calculate roughly the same values for the bias - no matter what the chipset is. How can I get the same results on almost all devices?

(I tried glPolygonOffset before, but this is implemented differently on almost every chipset)

BDL
  • 21,052
  • 22
  • 49
  • 55
AudioGuy
  • 413
  • 5
  • 18
  • 1
    cosTheta is the cosine of the angle between face normal and sun direction. Not the angle itself. (not related to the actual problem) – BDL Sep 18 '19 at 08:42
  • 1
    Possibly the difference is the format of the depth buffer. The format of the depth buffer may vary in the number of bite, dependent on the hardware. If the depth buffer has less bits per value, then you've to increment the bias. Note shadow acne is cause by equal depths in the depth buffer and the equality depends on the precision (number of bits) per value. – Rabbid76 Sep 18 '19 at 14:09
  • @BDL you're right thank you!! – AudioGuy Sep 19 '19 at 09:22
  • @Rabbid76 you mean a depth buffer of 24bit ist not always 24bit? Even if I set it to glDepthComponent24? – AudioGuy Sep 19 '19 at 14:30

1 Answers1

1

The problem may come from the resolution of your others devices. If they have a lower resolution, the shadow map texture will have a lower resolution too if you define it's resolution depending of the device resolution. Try to define the shadow map texture size with a constant value in your program.

  • This pointed me in the right direction: the shadow map resolution is now always 1024x1024, and the depth buffer is always 24bit. Biggest fault: the cosTheta float in the shader was lowp! All this combined with the fact that some devices have different aspect ratios resulted in different outcomes. Switching cosTheta to highp already fixed it by a lot. Thank you very much! – AudioGuy Sep 19 '19 at 14:28