SSLR 跟踪不正确(屏幕 Space 局部反射)
Incorrect tracing with SSLR (Screen Space Local Reflections)
在实施 SSLR 时,我 运行 遇到了对象显示不正确的问题:它们被无限投影 "down" 并且在镜子中根本没有显示。我在下面给出代码和截图。
片段 SSLR 着色器:
#version 330 core
uniform sampler2D normalMap; // in view space
uniform sampler2D depthMap; // in view space
uniform sampler2D colorMap;
uniform sampler2D reflectionStrengthMap;
uniform mat4 projection;
uniform mat4 inv_projection;
in vec2 texCoord;
layout (location = 0) out vec4 fragColor;
vec3 calcViewPosition(in vec2 texCoord) {
// Combine UV & depth into XY & Z (NDC)
vec3 rawPosition = vec3(texCoord, texture(depthMap, texCoord).r);
// Convert from (0, 1) range to (-1, 1)
vec4 ScreenSpacePosition = vec4(rawPosition * 2 - 1, 1);
// Undo Perspective transformation to bring into view space
vec4 ViewPosition = inv_projection * ScreenSpacePosition;
// Perform perspective divide and return
return ViewPosition.xyz / ViewPosition.w;
}
vec2 rayCast(vec3 dir, inout vec3 hitCoord, out float dDepth) {
dir *= 0.25f;
for (int i = 0; i < 20; i++) {
hitCoord += dir;
vec4 projectedCoord = projection * vec4(hitCoord, 1.0);
projectedCoord.xy /= projectedCoord.w;
projectedCoord.xy = projectedCoord.xy * 0.5 + 0.5;
float depth = calcViewPosition(projectedCoord.xy).z;
dDepth = hitCoord.z - depth;
if(dDepth < 0.0) return projectedCoord.xy;
}
return vec2(-1.0);
}
void main() {
vec3 normal = texture(normalMap, texCoord).xyz * 2.0 - 1.0;
vec3 viewPos = calcViewPosition(texCoord);
// Reflection vector
vec3 reflected = normalize(reflect(normalize(viewPos), normalize(normal)));
// Ray cast
vec3 hitPos = viewPos;
float dDepth;
float minRayStep = 0.1f;
vec2 coords = rayCast(reflected * max(minRayStep, -viewPos.z), hitPos, dDepth);
if (coords != vec2(-1.0)) fragColor = mix(texture(colorMap, texCoord), texture(colorMap, coords), texture(reflectionStrengthMap, texCoord).r);
else fragColor = texture(colorMap, texCoord);
}
截图:
此外,lamp根本没有反映
我将不胜感激
更新:
colorMap
:
normalMap
:
depthMap
:
更新:我解决了反射错误的问题,但是还是有问题。
我是这样解决的:ViewPosition.y *= -1
现在,正如您在屏幕截图中看到的那样,由于某种原因,对象的下半部分没有反映出来。
问题仍然悬而未决。
我也在努力争取一个好的ssr。我发现了两件事可以提供帮助。
要获得视图 space 法线,您必须仅保留相机的旋转并移除平移,因为如果不这样做,您将法线拉伸到相反的方向相机移动,即使你再次标准化它们也不再有正确的方向,对于列主要 mat4 你可以这样做:
mat4 viewNoTranslation = 视图;
viewNoTranslation[3] = vec4(0.0, 0.0, 0.0, 1.0);
深度图像的深度采样是对数的,如果对其进行线性化,您确实会得到从 0 到 1 的值,但它们在所需精度方面会不准确。我试图直接从顶点着色器获取深度值:
gl_Position = ubo.projection * ubo.view * ubo.model * inPos;
深度 = gl_Position.z;
不知道对不对,现在深度更准确了
如果有进步,欢迎更新:)
在实施 SSLR 时,我 运行 遇到了对象显示不正确的问题:它们被无限投影 "down" 并且在镜子中根本没有显示。我在下面给出代码和截图。
片段 SSLR 着色器:
#version 330 core
uniform sampler2D normalMap; // in view space
uniform sampler2D depthMap; // in view space
uniform sampler2D colorMap;
uniform sampler2D reflectionStrengthMap;
uniform mat4 projection;
uniform mat4 inv_projection;
in vec2 texCoord;
layout (location = 0) out vec4 fragColor;
vec3 calcViewPosition(in vec2 texCoord) {
// Combine UV & depth into XY & Z (NDC)
vec3 rawPosition = vec3(texCoord, texture(depthMap, texCoord).r);
// Convert from (0, 1) range to (-1, 1)
vec4 ScreenSpacePosition = vec4(rawPosition * 2 - 1, 1);
// Undo Perspective transformation to bring into view space
vec4 ViewPosition = inv_projection * ScreenSpacePosition;
// Perform perspective divide and return
return ViewPosition.xyz / ViewPosition.w;
}
vec2 rayCast(vec3 dir, inout vec3 hitCoord, out float dDepth) {
dir *= 0.25f;
for (int i = 0; i < 20; i++) {
hitCoord += dir;
vec4 projectedCoord = projection * vec4(hitCoord, 1.0);
projectedCoord.xy /= projectedCoord.w;
projectedCoord.xy = projectedCoord.xy * 0.5 + 0.5;
float depth = calcViewPosition(projectedCoord.xy).z;
dDepth = hitCoord.z - depth;
if(dDepth < 0.0) return projectedCoord.xy;
}
return vec2(-1.0);
}
void main() {
vec3 normal = texture(normalMap, texCoord).xyz * 2.0 - 1.0;
vec3 viewPos = calcViewPosition(texCoord);
// Reflection vector
vec3 reflected = normalize(reflect(normalize(viewPos), normalize(normal)));
// Ray cast
vec3 hitPos = viewPos;
float dDepth;
float minRayStep = 0.1f;
vec2 coords = rayCast(reflected * max(minRayStep, -viewPos.z), hitPos, dDepth);
if (coords != vec2(-1.0)) fragColor = mix(texture(colorMap, texCoord), texture(colorMap, coords), texture(reflectionStrengthMap, texCoord).r);
else fragColor = texture(colorMap, texCoord);
}
截图:
此外,lamp根本没有反映
我将不胜感激
更新:
colorMap
:
normalMap
:
depthMap
:
更新:我解决了反射错误的问题,但是还是有问题。
我是这样解决的:ViewPosition.y *= -1
现在,正如您在屏幕截图中看到的那样,由于某种原因,对象的下半部分没有反映出来。
问题仍然悬而未决。
我也在努力争取一个好的ssr。我发现了两件事可以提供帮助。
要获得视图 space 法线,您必须仅保留相机的旋转并移除平移,因为如果不这样做,您将法线拉伸到相反的方向相机移动,即使你再次标准化它们也不再有正确的方向,对于列主要 mat4 你可以这样做:
mat4 viewNoTranslation = 视图; viewNoTranslation[3] = vec4(0.0, 0.0, 0.0, 1.0);
深度图像的深度采样是对数的,如果对其进行线性化,您确实会得到从 0 到 1 的值,但它们在所需精度方面会不准确。我试图直接从顶点着色器获取深度值:
gl_Position = ubo.projection * ubo.view * ubo.model * inPos; 深度 = gl_Position.z;
不知道对不对,现在深度更准确了
如果有进步,欢迎更新:)