screen space reflections vatten och dämpad motion blur på skärnor

This commit is contained in:
2026-11-01 21:46:25 +01:00
parent a7207086b2
commit cb5070dc1c
19 changed files with 480 additions and 55 deletions

View File

@@ -27,7 +27,9 @@ uniform vec3 uLightDirections[2];
uniform vec3 uLightColors[2];
uniform float uLightFlux[2];
uniform float uTime;
out vec4 fragColor;
layout(location=0) out vec4 fragColor;
layout(location=1) out vec4 reflectionNormal;
layout(location=2) out vec4 reflectionFallback;
const float PI=3.14159265359;
vec3 toLocal(vec3 v) { return vec3(dot(v,uAxisX),dot(v,uAxisY),dot(v,uAxisZ)); }
vec3 toWorld(vec3 v) { return uAxisX*v.x+uAxisY*v.y+uAxisZ*v.z; }
@@ -98,25 +100,9 @@ vec3 skyReflection(vec3 direction,vec3 up) {
}
return sky*(.006+daylight*1.35);
}
vec3 screenReflection(vec3 position,vec3 direction,vec3 fallback) {
vec3 world=toWorld(position-vec3(0,uCameraHeight,0));
vec3 reflected=toWorld(direction);
float stepSize=3.0;
for(int i=0;i<9;i++) {
vec3 q=world+reflected*stepSize;
float z=dot(q,uForward);
if(z>.1) {
vec2 uv=.5+vec2(dot(q,uRight)/(uAspect*uTanHalfFov),dot(q,uUp)/uTanHalfFov)/(2.0*z);
if(all(greaterThan(uv,vec2(.015))) && all(lessThan(uv,vec2(.985)))) {
float depth=exp2(texture(uDepth,uv).r*log2(uFar+1.0))-1.0;
if(z>depth && z-depth<max(1.0,stepSize*.09))return texture(uScene,uv).rgb;
}
}
stepSize*=1.9;
}
return fallback;
}
void main() {
// Premultiplied-alpha MRT blending preserves earlier ocean planets outside this one's silhouette.
reflectionNormal=vec4(0); reflectionFallback=vec4(0);
vec3 scene=texture(uScene,vUv).rgb;
float originalDepth=texture(uDepth,vUv).r;
gl_FragDepth=originalDepth;
@@ -167,7 +153,6 @@ void main() {
vec3 reflectionDirection=reflect(rd,n);
vec3 reflected=skyReflection(reflectionDirection,up);
reflected=cloudReflection(toWorld(p-ro),toWorld(reflectionDirection),reflected);
if(t<1500.0 && !underwater)reflected=screenReflection(p,reflectionDirection,reflected);
vec2 refractUv=clamp(vUv+vec2(dot(toWorld(n),uRight),dot(toWorld(n),uUp))*uWaterOptics.z/(1.0+t*.012),vec2(.001),vec2(.999));
float floorDistance=sceneDistance(refractUv,cameraRay(refractUv));
float thickness=max(.0,min(400.0,floorDistance-t));
@@ -204,5 +189,8 @@ void main() {
color=color*through+uShallowColor*(1.0-through)*.5;
}
fragColor=vec4(max(color,vec3(0)),1);
float reflectance=underwater?0.0:fresnel*uWaterOptics.y*(1.0-foam);
reflectionNormal=vec4(toWorld(n)*reflectance,1);
reflectionFallback=vec4(reflected*reflectance,1);
gl_FragDepth=clamp(log2(1.0+t*max(.001,dot(worldRay,uForward)))/log2(uFar+1.0),0.0,1.0);
}