More SSR.

This commit is contained in:
Lubos Lenco 2016-03-31 21:06:53 +02:00
parent 63be820f91
commit 35ddb29f8a
6 changed files with 429 additions and 194 deletions

View file

@ -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);
}

View file

@ -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
}

View file

@ -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;
}

View file

@ -32,6 +32,10 @@
{
"id": "V",
"link": "_viewMatrix"
},
{
"id": "tiV",
"link": "_transposeInverseViewMatrix"
}
],
"texture_params": [],

View 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 cameras near plane, z is the cameras 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;
}

View 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);
}