Opengl 是否有任何方法可以偏移从深度纹理读取的深度?

Opengl 是否有任何方法可以偏移从深度纹理读取的深度?,opengl,shadow,depth-buffer,Opengl,Shadow,Depth Buffer,我正在为我的游戏在一个大场景上做阴影贴图。问题是,作为一个大场景,最近对象的深度约为0.999,因此碎片的颜色乘以深度比较结果得到的颜色几乎相同,因此阴影不明显。是否有任何方法或技术可以使用(最好是简单的)使整个纹理的值偏移 我曾考虑过在纹理的最大值和最小值之间进行偏移(某种规格化),但这需要知道这两个值,我真的不知道如何获取它们,或者获取它们是否非常昂贵(我怀疑这会) 这是我在片段着色器中用来计算阴影值的代码,以防它有用 #version 440 core out vec4 glFragCo

我正在为我的游戏在一个大场景上做阴影贴图。问题是,作为一个大场景,最近对象的深度约为0.999,因此碎片的颜色乘以深度比较结果得到的颜色几乎相同,因此阴影不明显。是否有任何方法或技术可以使用(最好是简单的)使整个纹理的值偏移

我曾考虑过在纹理的最大值和最小值之间进行偏移(某种规格化),但这需要知道这两个值,我真的不知道如何获取它们,或者获取它们是否非常昂贵(我怀疑这会)

这是我在片段着色器中用来计算阴影值的代码,以防它有用

#version 440 core

out vec4 glFragColor;

uniform sampler2D texture_diffuse1;
uniform sampler2D texture_specular1;
uniform sampler2D shadowMap;

in vec2 TexCoord;
in vec3 fragPos;
in vec3 norm;
in vec4 posCamSpace;
in vec4 posLightSpace;

uniform vec3 ambient;
uniform int shouldRender;

uniform float exposure;

struct Light
{
  vec3 position;
  vec3 diffuseColour;
  vec3 specularColour;

  vec3 dir;

  int shininess;

  float ambientStrength;
  float diffuseStrength;
  float specularStrength;

  float linear;
  float quadratic;
  float cosInner;
  float cosOuter;
  float falloff;
};

struct fogProperties
{
  vec4 color;
  float density;

  int equation;
  int isEnabled;
};

uniform Light light;
uniform fogProperties fogProps;
uniform vec3 viewPos;

subroutine vec3 lightType(void);
subroutine uniform lightType computeLight;

float ShadowCalculations()
{
  float bias = 0;

  float currentDepth = (posLightSpace.z + bias) / posLightSpace.w;

  //perspective division
  vec3 newfragPos = (posLightSpace.xyz / posLightSpace.w);

  //compute Uvs from position
  vec2 UVshadowPos = newfragPos.xy * 0.5 + 0.5;

  float shadow = 0.0;

  //compute offset
  vec2 texelSize = 1.0 / textureSize(shadowMap, 0);

  int count = 0;

  float pcfDepth = texture(shadowMap, UVshadowPos).r;
  shadow =  pcfDepth  - currentDepth > 0.0 ? 1.0 : 0.0;

  return shadow;
}

subroutine(lightType)
vec3 computeDirectionalLight()
{
  float ambientStrength = light.ambientStrength;
  float diffuseStrength = light.diffuseStrength;
  float specularStrength = light.specularStrength;
  vec3 tex = texture(texture_diffuse1, TexCoord).rgb;
  vec3 texspecular = texture(texture_specular1, TexCoord).rgb;


  vec3 normal = normalize(norm);
  vec3 lightDir = normalize(-light.dir);
  float diff = max(dot(normal, lightDir), 0.0f);
  vec3 diffuse = diffuseStrength * light.diffuseColour * diff * tex * ShadowCalculations();


  vec3 viewDir = normalize(-fragPos);
  vec3 reflectDir = reflect(-lightDir, normal);
  float spec = pow(max(dot(viewDir, reflectDir), 0.0f), light.shininess);
  vec3 specular = specularStrength * spec * light.specularColour * texspecular * ShadowCalculations();

  vec3 result = (ambientStrength * ambient * tex) + (diffuse + specular);

  return result;
}

float getFogFactor(fogProperties params, float fogCoordinate)
{
  float result = 0.0;

  result = exp(-pow(params.density * fogCoordinate, 2.0));

  result = 1.0 - clamp(result, 0.0, 1.0);

  return result;
}

void main()
{
  if(shouldRender == 1)
  {
    glFragColor = vec4(computeLight(), 1.0);

    if(fogProps.isEnabled == 1)
    {
        float fogCoordinate = abs(posCamSpace.z / posCamSpace.w);
        glFragColor = mix(glFragColor, fogProps.color, getFogFactor(fogProps, fogCoordinate));
    }
  }

  if(shouldRender == 0)
      discard;
}
这是深度纹理的屏幕截图,最接近对象的深度值显示在右下角:

这是一个游戏的尖叫,以vec4(阴影,0,0,1)的形式输出阴影计算值作为颜色:

这是最终渲染过程的屏幕截图,显示阴影不会影响最终颜色:


正如你在第二幅图像中所看到的,中间的较小岩石的颜色应该是黑色的,这是因为在第一幅图像中它们被大岩石所隐藏。如果我得到它们的颜色值(它应该表示阴影计算的输出),它是(1,0,0)。

“片段颜色乘以阴影值”这不是阴影映射的方式。如果您使用的是
shadow
采样器,并且正在这样做,那么您没有读取“shadow值”;您正在阅读深度比较的结果。那么您的实际代码是什么呢?深度比较的结果就是我的意思。对不起,误会了。如果我将比较结果输出为颜色,我几乎得到1。“深度比较的结果就是我的意思。”但深度比较的结果绝不基于深度缓冲区中的绝对距离。它产生一个值,表示比较是否通过(或通过比较的百分比)。所以你说“最近物体的深度约为0.999”是完全不相干的,因为深度比较并不关心深度的绝对值。很有可能代码中的其他地方有问题,并且您误判了实际问题。@NicolBolas我将发布片段着色器代码和更多信息,以使我的观点更清楚。