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