More SSR.
This commit is contained in:
parent
63be820f91
commit
35ddb29f8a
|
@ -41,6 +41,7 @@ in vec3 eyeDir;
|
|||
in mat3 TBN;
|
||||
#else
|
||||
in vec3 normal;
|
||||
// in vec3 vnormal;
|
||||
#endif
|
||||
|
||||
void main() {
|
||||
|
@ -50,6 +51,7 @@ void main() {
|
|||
n = normalize(TBN * normalize(n));
|
||||
#else
|
||||
vec3 n = normalize(normal);
|
||||
// vec3 vn = normalize(vnormal);
|
||||
#endif
|
||||
|
||||
#ifdef _AMTex
|
||||
|
@ -84,4 +86,5 @@ void main() {
|
|||
gl_FragData[0] = vec4(n.xyz, depth);
|
||||
gl_FragData[1] = vec4(position.xyz, roughness);
|
||||
gl_FragData[2] = vec4(baseColor.rgb, metalness);
|
||||
// gl_FragData[3] = vec4(vn.rgb, 1.0);
|
||||
}
|
||||
|
|
|
@ -29,6 +29,7 @@ in vec3 off;
|
|||
|
||||
uniform mat4 M;
|
||||
uniform mat4 NM;
|
||||
// uniform mat4 VNM;
|
||||
uniform mat4 V;
|
||||
uniform mat4 P;
|
||||
uniform mat4 LMVP;
|
||||
|
@ -52,6 +53,7 @@ out vec3 eyeDir;
|
|||
out mat3 TBN;
|
||||
#else
|
||||
out vec3 normal;
|
||||
out vec3 vnormal;
|
||||
#endif
|
||||
|
||||
#ifdef _Skinning
|
||||
|
@ -122,6 +124,7 @@ void main() {
|
|||
vec3 _normal = normalize(mat3(NM) * (nor * skinningMatVec));
|
||||
#else
|
||||
vec3 _normal = normalize(mat3(NM) * nor);
|
||||
// vec3 _vnormal = normalize(mat3(VNM) * nor);
|
||||
#endif
|
||||
|
||||
matColor = albedo_color;
|
||||
|
@ -141,8 +144,7 @@ void main() {
|
|||
vec3 bitangent = normalize(cross(_normal, tangent));
|
||||
TBN = mat3(tangent, bitangent, _normal);
|
||||
#else
|
||||
// vec4 n = V * vec4(_normal, 1.0);
|
||||
// normal = n.xyz;
|
||||
normal = _normal;
|
||||
// vnormal = _vnormal;
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -10,236 +10,173 @@ uniform sampler2D gbuffer1; // Position, roughness
|
|||
uniform sampler2D gbuffer2;
|
||||
uniform mat4 P;
|
||||
uniform mat4 V;
|
||||
uniform mat4 tiV;
|
||||
uniform vec3 eye;
|
||||
|
||||
const int maxSteps = 20;
|
||||
const int numBinarySearchSteps = 5;
|
||||
|
||||
const float rayStep = 0.25;
|
||||
const float minRayStep = 0.1;
|
||||
const float maxSteps = 20;
|
||||
const float searchDist = 5;
|
||||
const float searchDistInv = 0.2;
|
||||
const int numBinarySearchSteps = 5;
|
||||
const float maxDDepth = 1.0;
|
||||
const float maxDDepthInv = 1.0;
|
||||
const float reflectionSpecularFalloffExponent = 3.0;
|
||||
// uniform float rayStep;
|
||||
// uniform float minRayStep;
|
||||
// uniform float searchDist;
|
||||
|
||||
const float falloffExp = 3.0;
|
||||
const float zNear = 1.0;
|
||||
const float zFar = 100.0;
|
||||
|
||||
in vec2 texCoord;
|
||||
|
||||
vec3 hitCoord;
|
||||
float dDepth;
|
||||
float depth;
|
||||
|
||||
vec3 binarySearch(vec3 dir) {
|
||||
float depth;
|
||||
vec4 projectedCoord;
|
||||
// float rand(vec2 co) { // Unreliable
|
||||
// return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453);
|
||||
// }
|
||||
|
||||
vec4 getProjectedCoord(vec3 hitCoord) {
|
||||
vec4 projectedCoord = P * vec4(hitCoord, 1.0);
|
||||
projectedCoord.xy /= projectedCoord.w;
|
||||
projectedCoord.xy = projectedCoord.xy * 0.5 + 0.5;
|
||||
return projectedCoord;
|
||||
}
|
||||
|
||||
float getDeltaDepth(vec3 hitCoord) {
|
||||
// depth = texture(gbuffer0, getProjectedCoord(hitCoord).xy).a;
|
||||
// depth = (2.0 * zNear) / (zFar + zNear - depth * (zFar - zNear));
|
||||
// depth *= zFar;
|
||||
vec4 viewPos = vec4(texture(gbuffer1, getProjectedCoord(hitCoord).xy).rgb, 1.0);
|
||||
viewPos = V * viewPos;
|
||||
float depth = viewPos.z;
|
||||
|
||||
// for (int i = 0; i < numBinarySearchSteps; i++) {
|
||||
projectedCoord = P * vec4(hitCoord, 1.0);
|
||||
projectedCoord.xy /= projectedCoord.w;
|
||||
projectedCoord.xy = projectedCoord.xy * 0.5 + 0.5;
|
||||
depth = texture(gbuffer0, projectedCoord.xy).a;
|
||||
dDepth = hitCoord.z - depth;
|
||||
if (dDepth > 0.0) {
|
||||
hitCoord += dir;
|
||||
}
|
||||
dir *= 0.5;
|
||||
hitCoord -= dir;
|
||||
|
||||
projectedCoord = P * vec4(hitCoord, 1.0);
|
||||
projectedCoord.xy /= projectedCoord.w;
|
||||
projectedCoord.xy = projectedCoord.xy * 0.5 + 0.5;
|
||||
depth = texture(gbuffer0, projectedCoord.xy).a;
|
||||
dDepth = hitCoord.z - depth;
|
||||
if (dDepth > 0.0) {
|
||||
hitCoord += dir;
|
||||
}
|
||||
dir *= 0.5;
|
||||
hitCoord -= dir;
|
||||
|
||||
projectedCoord = P * vec4(hitCoord, 1.0);
|
||||
projectedCoord.xy /= projectedCoord.w;
|
||||
projectedCoord.xy = projectedCoord.xy * 0.5 + 0.5;
|
||||
depth = texture(gbuffer0, projectedCoord.xy).a;
|
||||
dDepth = hitCoord.z - depth;
|
||||
if (dDepth > 0.0) {
|
||||
hitCoord += dir;
|
||||
}
|
||||
dir *= 0.5;
|
||||
hitCoord -= dir;
|
||||
|
||||
projectedCoord = P * vec4(hitCoord, 1.0);
|
||||
projectedCoord.xy /= projectedCoord.w;
|
||||
projectedCoord.xy = projectedCoord.xy * 0.5 + 0.5;
|
||||
depth = texture(gbuffer0, projectedCoord.xy).a;
|
||||
dDepth = hitCoord.z - depth;
|
||||
if (dDepth > 0.0) {
|
||||
hitCoord += dir;
|
||||
}
|
||||
dir *= 0.5;
|
||||
hitCoord -= dir;
|
||||
|
||||
projectedCoord = P * vec4(hitCoord, 1.0);
|
||||
projectedCoord.xy /= projectedCoord.w;
|
||||
projectedCoord.xy = projectedCoord.xy * 0.5 + 0.5;
|
||||
depth = texture(gbuffer0, projectedCoord.xy).a;
|
||||
dDepth = hitCoord.z - depth;
|
||||
if (dDepth > 0.0) {
|
||||
hitCoord += dir;
|
||||
}
|
||||
dir *= 0.5;
|
||||
hitCoord -= dir;
|
||||
// }
|
||||
return hitCoord.z - depth;
|
||||
}
|
||||
|
||||
projectedCoord = P * vec4(hitCoord, 1.0);
|
||||
projectedCoord.xy /= projectedCoord.w;
|
||||
projectedCoord.xy = projectedCoord.xy * 0.5 + 0.5;
|
||||
return vec3(projectedCoord.xy, depth);
|
||||
vec3 binarySearch(vec3 dir) {
|
||||
// for (int i = 0; i < numBinarySearchSteps; i++) {
|
||||
dir *= 0.5;
|
||||
hitCoord += dir;
|
||||
if (getDeltaDepth(hitCoord) > 0.0) hitCoord -= dir;
|
||||
|
||||
dir *= 0.5;
|
||||
hitCoord += dir;
|
||||
if (getDeltaDepth(hitCoord) > 0.0) hitCoord -= dir;
|
||||
|
||||
dir *= 0.5;
|
||||
hitCoord += dir;
|
||||
if (getDeltaDepth(hitCoord) > 0.0) hitCoord -= dir;
|
||||
|
||||
dir *= 0.5;
|
||||
hitCoord += dir;
|
||||
if (getDeltaDepth(hitCoord) > 0.0) hitCoord -= dir;
|
||||
|
||||
dir *= 0.5;
|
||||
hitCoord += dir;
|
||||
if (getDeltaDepth(hitCoord) > 0.0) hitCoord -= dir;
|
||||
// }
|
||||
return vec3(getProjectedCoord(hitCoord).xy, depth);
|
||||
}
|
||||
|
||||
vec4 rayCast(vec3 dir) {
|
||||
dir *= rayStep;
|
||||
float depth;
|
||||
dir *= rayStep;
|
||||
|
||||
// for (int i = 0; i < maxSteps; i++) {
|
||||
hitCoord += dir;
|
||||
vec4 projectedCoord = P * vec4(hitCoord, 1.0);
|
||||
projectedCoord.xy /= projectedCoord.w;
|
||||
projectedCoord.xy = projectedCoord.xy * 0.5 + 0.5;
|
||||
depth = texture(gbuffer0, projectedCoord.xy).a;
|
||||
dDepth = hitCoord.z - depth;
|
||||
if (dDepth < 0.0) {
|
||||
return vec4(binarySearch(dir), 1.0);
|
||||
}
|
||||
hitCoord -= dir;
|
||||
if (getDeltaDepth(hitCoord) < 0.0) return vec4(binarySearch(dir), 1.0);
|
||||
|
||||
hitCoord += dir;
|
||||
projectedCoord = P * vec4(hitCoord, 1.0);
|
||||
projectedCoord.xy /= projectedCoord.w;
|
||||
projectedCoord.xy = projectedCoord.xy * 0.5 + 0.5;
|
||||
depth = texture(gbuffer0, projectedCoord.xy).a;
|
||||
dDepth = hitCoord.z - depth;
|
||||
if (dDepth < 0.0) {
|
||||
return vec4(binarySearch(dir), 1.0);
|
||||
}
|
||||
hitCoord -= dir;
|
||||
if (getDeltaDepth(hitCoord) < 0.0) return vec4(binarySearch(dir), 1.0);
|
||||
|
||||
hitCoord += dir;
|
||||
projectedCoord = P * vec4(hitCoord, 1.0);
|
||||
projectedCoord.xy /= projectedCoord.w;
|
||||
projectedCoord.xy = projectedCoord.xy * 0.5 + 0.5;
|
||||
depth = texture(gbuffer0, projectedCoord.xy).a;
|
||||
dDepth = hitCoord.z - depth;
|
||||
if (dDepth < 0.0) {
|
||||
return vec4(binarySearch(dir), 1.0);
|
||||
}
|
||||
hitCoord -= dir;
|
||||
if (getDeltaDepth(hitCoord) < 0.0) return vec4(binarySearch(dir), 1.0);
|
||||
|
||||
hitCoord += dir;
|
||||
projectedCoord = P * vec4(hitCoord, 1.0);
|
||||
projectedCoord.xy /= projectedCoord.w;
|
||||
projectedCoord.xy = projectedCoord.xy * 0.5 + 0.5;
|
||||
depth = texture(gbuffer0, projectedCoord.xy).a;
|
||||
dDepth = hitCoord.z - depth;
|
||||
if (dDepth < 0.0) {
|
||||
return vec4(binarySearch(dir), 1.0);
|
||||
}
|
||||
hitCoord -= dir;
|
||||
if (getDeltaDepth(hitCoord) < 0.0) return vec4(binarySearch(dir), 1.0);
|
||||
|
||||
hitCoord += dir;
|
||||
projectedCoord = P * vec4(hitCoord, 1.0);
|
||||
projectedCoord.xy /= projectedCoord.w;
|
||||
projectedCoord.xy = projectedCoord.xy * 0.5 + 0.5;
|
||||
depth = texture(gbuffer0, projectedCoord.xy).a;
|
||||
dDepth = hitCoord.z - depth;
|
||||
if (dDepth < 0.0) {
|
||||
return vec4(binarySearch(dir), 1.0);
|
||||
}
|
||||
hitCoord -= dir;
|
||||
if (getDeltaDepth(hitCoord) < 0.0) return vec4(binarySearch(dir), 1.0);
|
||||
|
||||
hitCoord += dir;
|
||||
projectedCoord = P * vec4(hitCoord, 1.0);
|
||||
projectedCoord.xy /= projectedCoord.w;
|
||||
projectedCoord.xy = projectedCoord.xy * 0.5 + 0.5;
|
||||
depth = texture(gbuffer0, projectedCoord.xy).a;
|
||||
dDepth = hitCoord.z - depth;
|
||||
if (dDepth < 0.0) {
|
||||
return vec4(binarySearch(dir), 1.0);
|
||||
}
|
||||
hitCoord -= dir;
|
||||
if (getDeltaDepth(hitCoord) < 0.0) return vec4(binarySearch(dir), 1.0);
|
||||
|
||||
hitCoord += dir;
|
||||
projectedCoord = P * vec4(hitCoord, 1.0);
|
||||
projectedCoord.xy /= projectedCoord.w;
|
||||
projectedCoord.xy = projectedCoord.xy * 0.5 + 0.5;
|
||||
depth = texture(gbuffer0, projectedCoord.xy).a;
|
||||
dDepth = hitCoord.z - depth;
|
||||
if (dDepth < 0.0) {
|
||||
return vec4(binarySearch(dir), 1.0);
|
||||
}
|
||||
hitCoord -= dir;
|
||||
if (getDeltaDepth(hitCoord) < 0.0) return vec4(binarySearch(dir), 1.0);
|
||||
|
||||
hitCoord += dir;
|
||||
projectedCoord = P * vec4(hitCoord, 1.0);
|
||||
projectedCoord.xy /= projectedCoord.w;
|
||||
projectedCoord.xy = projectedCoord.xy * 0.5 + 0.5;
|
||||
depth = texture(gbuffer0, projectedCoord.xy).a;
|
||||
dDepth = hitCoord.z - depth;
|
||||
if (dDepth < 0.0) {
|
||||
return vec4(binarySearch(dir), 1.0);
|
||||
}
|
||||
hitCoord -= dir;
|
||||
if (getDeltaDepth(hitCoord) < 0.0) return vec4(binarySearch(dir), 1.0);
|
||||
|
||||
hitCoord += dir;
|
||||
projectedCoord = P * vec4(hitCoord, 1.0);
|
||||
projectedCoord.xy /= projectedCoord.w;
|
||||
projectedCoord.xy = projectedCoord.xy * 0.5 + 0.5;
|
||||
depth = texture(gbuffer0, projectedCoord.xy).a;
|
||||
dDepth = hitCoord.z - depth;
|
||||
if (dDepth < 0.0) {
|
||||
return vec4(binarySearch(dir), 1.0);
|
||||
}
|
||||
hitCoord -= dir;
|
||||
if (getDeltaDepth(hitCoord) < 0.0) return vec4(binarySearch(dir), 1.0);
|
||||
|
||||
hitCoord += dir;
|
||||
projectedCoord = P * vec4(hitCoord, 1.0);
|
||||
projectedCoord.xy /= projectedCoord.w;
|
||||
projectedCoord.xy = projectedCoord.xy * 0.5 + 0.5;
|
||||
depth = texture(gbuffer0, projectedCoord.xy).a;
|
||||
dDepth = hitCoord.z - depth;
|
||||
if (dDepth < 0.0) {
|
||||
return vec4(binarySearch(dir), 1.0);
|
||||
}
|
||||
hitCoord -= dir;
|
||||
if (getDeltaDepth(hitCoord) < 0.0) return vec4(binarySearch(dir), 1.0);
|
||||
|
||||
hitCoord -= dir;
|
||||
if (getDeltaDepth(hitCoord) < 0.0) return vec4(binarySearch(dir), 1.0);
|
||||
|
||||
hitCoord -= dir;
|
||||
if (getDeltaDepth(hitCoord) < 0.0) return vec4(binarySearch(dir), 1.0);
|
||||
|
||||
hitCoord -= dir;
|
||||
if (getDeltaDepth(hitCoord) < 0.0) return vec4(binarySearch(dir), 1.0);
|
||||
|
||||
hitCoord -= dir;
|
||||
if (getDeltaDepth(hitCoord) < 0.0) return vec4(binarySearch(dir), 1.0);
|
||||
|
||||
hitCoord -= dir;
|
||||
if (getDeltaDepth(hitCoord) < 0.0) return vec4(binarySearch(dir), 1.0);
|
||||
|
||||
hitCoord -= dir;
|
||||
if (getDeltaDepth(hitCoord) < 0.0) return vec4(binarySearch(dir), 1.0);
|
||||
|
||||
hitCoord -= dir;
|
||||
if (getDeltaDepth(hitCoord) < 0.0) return vec4(binarySearch(dir), 1.0);
|
||||
|
||||
hitCoord -= dir;
|
||||
if (getDeltaDepth(hitCoord) < 0.0) return vec4(binarySearch(dir), 1.0);
|
||||
|
||||
hitCoord -= dir;
|
||||
if (getDeltaDepth(hitCoord) < 0.0) return vec4(binarySearch(dir), 1.0);
|
||||
|
||||
hitCoord -= dir;
|
||||
if (getDeltaDepth(hitCoord) < 0.0) return vec4(binarySearch(dir), 1.0);
|
||||
// }
|
||||
|
||||
return vec4(0.0, 0.0, 0.0, 0.0);
|
||||
}
|
||||
|
||||
void main() {
|
||||
// vec2 gTexCoord = gl_FragCoord.xy * gTexSizeInv;
|
||||
// Samples
|
||||
float roughness = texture(gbuffer1, texCoord).a;
|
||||
float specular = 1.0 - roughness;
|
||||
if (specular == 0.0) {
|
||||
float reflectivity = 1.0 - roughness;
|
||||
if (reflectivity == 0.0) {
|
||||
vec4 texColor = texture(tex, texCoord);
|
||||
gl_FragColor = texColor;
|
||||
// gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0);
|
||||
return;
|
||||
return;
|
||||
}
|
||||
|
||||
vec4 viewNormal = vec4(texture(gbuffer0, texCoord).rgb, 1.0);
|
||||
viewNormal = V * viewNormal;
|
||||
viewNormal /= viewNormal.w;
|
||||
|
||||
vec4 viewPos = vec4(texture(gbuffer1, texCoord).rgb, 1.0);
|
||||
vec4 viewNormal = vec4(texture(gbuffer0, texCoord).rgb, 1.0);
|
||||
viewNormal = tiV * viewNormal;
|
||||
// viewNormal /= viewNormal.w;
|
||||
|
||||
vec4 viewPos = vec4(texture(gbuffer1, texCoord).rgb, 1.0);
|
||||
viewPos = V * viewPos;
|
||||
viewPos /= viewPos.w;
|
||||
|
||||
// Reflection vector
|
||||
vec3 reflected = normalize(reflect(normalize(viewPos.xyz), normalize(viewNormal.xyz)));
|
||||
|
||||
// Ray cast
|
||||
hitCoord = viewPos.xyz;
|
||||
dDepth = 0.0;
|
||||
//viewPos /= viewPos.w;
|
||||
|
||||
vec4 coords = rayCast(reflected * max(minRayStep, -viewPos.z));
|
||||
vec2 dCoords = abs(vec2(0.5, 0.5) - coords.xy);
|
||||
|
||||
float screenEdgeFactor = clamp(1.0 - (dCoords.x + dCoords.y), 0.0, 1.0);
|
||||
|
||||
float intensity = pow(specular, reflectionSpecularFalloffExponent) *
|
||||
screenEdgeFactor * clamp(-reflected.z, 0.0, 1.0) *
|
||||
clamp((searchDist - length(viewPos.xyz - hitCoord)) * searchDistInv, 0.0, 1.0) * coords.w;
|
||||
|
||||
vec4 reflCol = vec4(texture(tex, coords.xy).rgb, 1.0);
|
||||
vec3 reflected = normalize(reflect(normalize(viewPos.xyz), normalize(viewNormal.xyz)));
|
||||
hitCoord = viewPos.xyz;
|
||||
|
||||
vec3 dir = reflected * max(minRayStep, -viewPos.z);// * (1.0 - rand(texCoord) * 0.7);
|
||||
vec4 coords = rayCast(dir);
|
||||
|
||||
vec2 deltaCoords = abs(vec2(0.5, 0.5) - coords.xy);
|
||||
float screenEdgeFactor = clamp(1.0 - (deltaCoords.x + deltaCoords.y), 0.0, 1.0);
|
||||
|
||||
float intensity = pow(reflectivity, falloffExp) *
|
||||
screenEdgeFactor * clamp(-reflected.z, 0.0, 1.0) *
|
||||
clamp((searchDist - length(viewPos.xyz - hitCoord)) * (1.0 / searchDist), 0.0, 1.0) * coords.w;
|
||||
|
||||
vec4 texColor = texture(tex, texCoord);
|
||||
vec4 reflCol = vec4(texture(tex, coords.xy).rgb, 1.0);
|
||||
gl_FragColor = texColor * (1.0 - intensity) + reflCol * intensity;
|
||||
}
|
||||
|
|
|
@ -32,6 +32,10 @@
|
|||
{
|
||||
"id": "V",
|
||||
"link": "_viewMatrix"
|
||||
},
|
||||
{
|
||||
"id": "tiV",
|
||||
"link": "_transposeInverseViewMatrix"
|
||||
}
|
||||
],
|
||||
"texture_params": [],
|
||||
|
|
264
raw/ssr_pass/ssr_pass_kode.frag.glsl
Normal file
264
raw/ssr_pass/ssr_pass_kode.frag.glsl
Normal file
|
@ -0,0 +1,264 @@
|
|||
// SSR based on implementation by Ben Hopkins
|
||||
// Work in progress
|
||||
#version 450
|
||||
|
||||
#ifdef GL_ES
|
||||
precision mediump float;
|
||||
#endif
|
||||
|
||||
uniform sampler2D tex;
|
||||
uniform sampler2D gbuffer0; // Normal, depth
|
||||
uniform sampler2D gbuffer1; // Position, roughness
|
||||
uniform sampler2D gbuffer2;
|
||||
uniform mat4 P;
|
||||
uniform mat4 invP;
|
||||
uniform mat4 V;
|
||||
uniform vec3 eye;
|
||||
|
||||
in vec2 texCoord;
|
||||
in vec3 cameraRay;
|
||||
|
||||
vec3 ScreenSpaceToViewSpace(vec3 cameraRay, float depth) {
|
||||
return (cameraRay * depth);
|
||||
}
|
||||
|
||||
// void swapIfBigger(inout float aa, inout float bb) {
|
||||
// if( aa > bb) {
|
||||
// float tmp = aa;
|
||||
// aa = bb;
|
||||
// bb = tmp;
|
||||
// }
|
||||
// }
|
||||
|
||||
// Projection params: x is 1.0 (or –1.0 if currently rendering with a flipped projection matrix), y is the camera’s near plane, z is the camera’s far plane and w is 1/FarPlane.
|
||||
|
||||
// Linear01Depth: Z buffer to linear 0..1 depth (0 at eye, 1 at far plane) inline float Linear01Depth( float z ) { } // Z buffer to linear depth inline float
|
||||
float Linear01Depth(float z) {
|
||||
// return 1.0 / (_ZBufferParams.x * z + _ZBufferParams.y);
|
||||
return z;
|
||||
// x = 1 - 100/0.1 = -999
|
||||
// y = 100/0.1 = 1000
|
||||
// 1 / (-999 * 200 + 1000)
|
||||
}
|
||||
|
||||
// double zc0, zc1;
|
||||
// // OpenGL would be this:
|
||||
// // zc0 = (1.0 - m_FarClip / m_NearClip) / 2.0;
|
||||
// // zc1 = (1.0 + m_FarClip / m_NearClip) / 2.0;
|
||||
// // D3D is this:
|
||||
// zc0 = 1.0 - m_FarClip / m_NearClip;
|
||||
// zc1 = m_FarClip / m_NearClip;
|
||||
// // now set _ZBufferParams with (zc0, zc1, zc0/m_FarClip, zc1/m_FarClip);
|
||||
|
||||
// // Values used to linearize the Z buffer (http://www.humus.name/temp/Linearize%20depth.txt)
|
||||
// // x = 1-far/near
|
||||
// // y = far/near
|
||||
// // z = x/far
|
||||
// // w = y/far
|
||||
// uniform float4 _ZBufferParams;
|
||||
|
||||
bool rayIntersectsDepthBF(float zA, float zB, vec2 uv) {
|
||||
// vec4 uv4 = vec4(uv, 0.0, 0.0);
|
||||
vec2 uv4 = uv;
|
||||
float cameraZ = Linear01Depth(texture(gbuffer0, uv4).a) * - 100.0;//_ProjectionParams.z;
|
||||
float backZ = texture(_BackFaceDepthTex, uv4).r * - 100;//_ProjectionParams.z;
|
||||
|
||||
return zB <= cameraZ && zA >= backZ - _PixelZSize;
|
||||
}
|
||||
|
||||
float distanceSquared( vec2 a, vec2 b) { a -= b; return dot(a, a); }
|
||||
|
||||
|
||||
// Trace a ray in screenspace from rayOrigin (in camera space) pointing in rayDirection (in camera space)
|
||||
// using jitter to offset the ray based on (jitter * _PixelStride).
|
||||
//
|
||||
// Returns true if the ray hits a pixel in the depth buffer
|
||||
// and outputs the hitPixel (in UV space), the hitPoint (in camera space) and the number
|
||||
// of iterations it took to get there.
|
||||
bool traceScreenSpaceRay( vec3 rayOrigin,
|
||||
vec3 rayDirection,
|
||||
float jitter,
|
||||
out vec2 hitPixel,
|
||||
out vec3 hitPoint,
|
||||
out float iterationCount, bool debugHalf) {
|
||||
// Clip to the near plane
|
||||
float rayLength = ((rayOrigin.z + rayDirection.z * _MaxRayDistance) > -_ProjectionParams.y) ?
|
||||
(-_ProjectionParams.y - rayOrigin.z) / rayDirection.z : _MaxRayDistance;
|
||||
vec3 rayEnd = rayOrigin + rayDirection * rayLength;
|
||||
|
||||
// Project into homogeneous clip space
|
||||
vec4 H0 = P * vec4( rayOrigin, 1.0);
|
||||
vec4 H1 = P * vec4( rayEnd, 1.0);
|
||||
|
||||
float k0 = 1.0 / H0.w, k1 = 1.0 / H1.w;
|
||||
|
||||
// The interpolated homogeneous version of the camera-space points
|
||||
vec3 Q0 = rayOrigin * k0, Q1 = rayEnd * k1;
|
||||
|
||||
// Screen-space endpoints
|
||||
vec2 P0 = H0.xy * k0, P1 = H1.xy * k1;
|
||||
|
||||
// If the line is degenerate, make it cover at least one pixel
|
||||
// to avoid handling zero-pixel extent as a special case later
|
||||
P1 += (distanceSquared(P0, P1) < 0.0001) ? 0.01 : 0.0;
|
||||
|
||||
vec2 delta = P1 - P0;
|
||||
|
||||
// Permute so that the primary iteration is in x to collapse
|
||||
// all quadrant-specific DDA cases later
|
||||
bool permute = false;
|
||||
if (abs(delta.x) < abs(delta.y)) {
|
||||
// This is a more-vertical line
|
||||
permute = true; delta = delta.yx; P0 = P0.yx; P1 = P1.yx;
|
||||
}
|
||||
|
||||
float stepDir = sign(delta.x);
|
||||
float invdx = stepDir / delta.x;
|
||||
|
||||
// Track the derivatives of Q and k
|
||||
vec3 dQ = (Q1 - Q0) * invdx;
|
||||
float dk = (k1 - k0) * invdx;
|
||||
vec2 dP = vec2(stepDir, delta.y * invdx);
|
||||
|
||||
// Calculate pixel stride based on distance of ray origin from camera.
|
||||
// Since perspective means distant objects will be smaller in screen space
|
||||
// we can use this to have higher quality reflections for far away objects
|
||||
// while still using a large pixel stride for near objects (and increase performance)
|
||||
// this also helps mitigate artifacts on distant reflections when we use a large
|
||||
// pixel stride.
|
||||
float strideScaler = 1.0 - min( 1.0, -rayOrigin.z / _PixelStrideZCuttoff);
|
||||
float pixelStride = 1.0 + strideScaler * _PixelStride;
|
||||
|
||||
// Scale derivatives by the desired pixel stride and then
|
||||
// offset the starting values by the jitter fraction
|
||||
dP *= pixelStride; dQ *= pixelStride; dk *= pixelStride;
|
||||
P0 += dP * jitter; Q0 += dQ * jitter; k0 += dk * jitter;
|
||||
|
||||
float i, zA = 0.0, zB = 0.0;
|
||||
|
||||
// Track ray step and derivatives in a float4 to parallelize
|
||||
float4 pqk = float4( P0, Q0.z, k0);
|
||||
float4 dPQK = float4( dP, dQ.z, dk);
|
||||
bool intersect = false;
|
||||
|
||||
for( i=0; i<_Iterations && intersect == false; i++) {
|
||||
pqk += dPQK;
|
||||
|
||||
zA = zB;
|
||||
zB = (dPQK.z * 0.5 + pqk.z) / (dPQK.w * 0.5 + pqk.w);
|
||||
swapIfBigger( zB, zA);
|
||||
|
||||
hitPixel = permute ? pqk.yx : pqk.xy;
|
||||
hitPixel *= _OneDividedByRenderBufferSize;
|
||||
|
||||
intersect = rayIntersectsDepthBF( zA, zB, hitPixel);
|
||||
}
|
||||
|
||||
// Binary search refinement
|
||||
if( pixelStride > 1.0 && intersect) {
|
||||
pqk -= dPQK;
|
||||
dPQK /= pixelStride;
|
||||
|
||||
float originalStride = pixelStride * 0.5;
|
||||
float stride = originalStride;
|
||||
|
||||
zA = pqk.z / pqk.w;
|
||||
zB = zA;
|
||||
|
||||
for( float j=0; j<_BinarySearchIterations; j++)
|
||||
{
|
||||
pqk += dPQK * stride;
|
||||
|
||||
zA = zB;
|
||||
zB = (dPQK.z * -0.5 + pqk.z) / (dPQK.w * -0.5 + pqk.w);
|
||||
swapIfBigger( zB, zA);
|
||||
|
||||
hitPixel = permute ? pqk.yx : pqk.xy;
|
||||
hitPixel *= _OneDividedByRenderBufferSize;
|
||||
|
||||
originalStride *= 0.5;
|
||||
stride = rayIntersectsDepthBF( zA, zB, hitPixel) ? -originalStride : originalStride;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Q0.xy += dQ.xy * i;
|
||||
Q0.z = pqk.z;
|
||||
hitPoint = Q0 / pqk.w;
|
||||
iterationCount = i;
|
||||
|
||||
return intersect;
|
||||
}
|
||||
|
||||
float calculateAlphaForIntersection( bool intersect,
|
||||
float iterationCount,
|
||||
float specularStrength,
|
||||
vec2 hitPixel,
|
||||
vec3 hitPoint,
|
||||
vec3 vsRayOrigin,
|
||||
vec3 vsRayDirection) {
|
||||
float alpha = min( 1.0, specularStrength * 1.0);
|
||||
|
||||
// Fade ray hits that approach the maximum iterations
|
||||
alpha *= 1.0 - (iterationCount / _Iterations);
|
||||
|
||||
// Fade ray hits that approach the screen edge
|
||||
float screenFade = _ScreenEdgeFadeStart;
|
||||
vec2 hitPixelNDC = (hitPixel * 2.0 - 1.0);
|
||||
float maxDimension = min( 1.0, max( abs( hitPixelNDC.x), abs( hitPixelNDC.y)));
|
||||
alpha *= 1.0 - (max( 0.0, maxDimension - screenFade) / (1.0 - screenFade));
|
||||
|
||||
// Fade ray hits base on how much they face the camera
|
||||
float eyeFadeStart = _EyeFadeStart;
|
||||
float eyeFadeEnd = _EyeFadeEnd;
|
||||
swapIfBigger( eyeFadeStart, eyeFadeEnd);
|
||||
|
||||
float eyeDirection = clamp( vsRayDirection.z, eyeFadeStart, eyeFadeEnd);
|
||||
alpha *= 1.0 - ((eyeDirection - eyeFadeStart) / (eyeFadeEnd - eyeFadeStart));
|
||||
|
||||
// Fade ray hits based on distance from ray origin
|
||||
alpha *= 1.0 - clamp( distance( vsRayOrigin, hitPoint) / _MaxRayDistance, 0.0, 1.0);
|
||||
|
||||
alpha *= intersect;
|
||||
|
||||
return alpha;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void main() {
|
||||
|
||||
vec4 specRoughPixel = texture(_CameraGBufferTexture1, texCoord);
|
||||
vec3 specularStrength = specRoughPixel.a;
|
||||
|
||||
float decodedDepth = Linear01Depth(texture(_CameraDepthTexture, texCoord).r);
|
||||
|
||||
vec3 vsRayOrigin = ScreenSpaceToViewSpace(cameraRay, decodedDepth);
|
||||
|
||||
vec3 decodedNormal = (texture( _CameraGBufferTexture2, texCoord)).rgb * 2.0 - 1.0;
|
||||
decodedNormal = mul( (mat3)_NormalMatrix, decodedNormal);
|
||||
|
||||
vec3 vsRayDirection = normalize( reflect( normalize( vsRayOrigin), normalize(decodedNormal)));
|
||||
|
||||
vec2 hitPixel;
|
||||
vec3 hitPoint;
|
||||
float iterationCount;
|
||||
|
||||
vec2 uv2 = texCoord * _RenderBufferSize;
|
||||
float c = (uv2.x + uv2.y) * 0.25;
|
||||
float jitter = fmod( c, 1.0);
|
||||
|
||||
bool intersect = traceScreenSpaceRay( vsRayOrigin, vsRayDirection, jitter, hitPixel, hitPoint, iterationCount, texCoord.x > 0.5);
|
||||
float alpha = calculateAlphaForIntersection( intersect, iterationCount, specularStrength, hitPixel, hitPoint, vsRayOrigin, vsRayDirection);
|
||||
hitPixel = lerp( texCoord, hitPixel, intersect);
|
||||
|
||||
// Comment out the line below to get faked specular,
|
||||
// in no way physically correct but will tint based
|
||||
// on spec. Physically correct handling of spec is coming...
|
||||
specRoughPixel = vec4( 1.0, 1.0, 1.0, 1.0);
|
||||
|
||||
return vec4( (texture( _MainTex, hitPixel)).rgb * specRoughPixel.rgb, alpha);
|
||||
|
||||
// vec4 texColor = texture(tex, texCoord);
|
||||
// gl_FragColor = texColor * (1.0 - intensity) + reflCol * intensity;
|
||||
}
|
25
raw/ssr_pass/ssr_pass_kode.vert.glsl
Normal file
25
raw/ssr_pass/ssr_pass_kode.vert.glsl
Normal file
|
@ -0,0 +1,25 @@
|
|||
#version 450
|
||||
|
||||
#ifdef GL_ES
|
||||
precision highp float;
|
||||
#endif
|
||||
|
||||
in vec2 pos;
|
||||
|
||||
out vec2 texCoord;
|
||||
out vec3 cameraRay;
|
||||
|
||||
uniform mat4 invP;
|
||||
|
||||
const vec2 madd = vec2(0.5, 0.5);
|
||||
|
||||
void main() {
|
||||
// Scale vertex attribute to [0-1] range
|
||||
texCoord = pos.xy * madd + madd;
|
||||
|
||||
vec4 ray = vec4(texcoord * 2.0 - 1.0, 1.0, 1.0);
|
||||
ray = invP * ray;
|
||||
cameraRay = ray.xyz / ray.w;
|
||||
|
||||
gl_Position = vec4(pos.xy, 0.0, 1.0);
|
||||
}
|
Loading…
Reference in a new issue