Full BSDF
This commit is contained in:
@ -11,6 +11,7 @@ uniform sampler2D gbuffer1; // basecol, spec
|
||||
uniform mat4 P;
|
||||
uniform mat3 V3;
|
||||
uniform vec2 cameraProj;
|
||||
uniform vec2 screenSize;
|
||||
|
||||
#ifdef _CPostprocess
|
||||
uniform vec3 PPComp9;
|
||||
@ -24,8 +25,8 @@ out vec4 fragColor;
|
||||
vec3 hitCoord;
|
||||
float depth;
|
||||
|
||||
const int numBinarySearchSteps = 7;
|
||||
const int maxSteps = int(ceil(1.0 / ssrRayStep) * ssrSearchDist);
|
||||
const int numBinarySearchSteps = 8;
|
||||
const int maxSteps = 50;
|
||||
|
||||
vec2 getProjectedCoord(const vec3 hit) {
|
||||
vec4 projectedCoord = P * vec4(hit, 1.0);
|
||||
@ -38,44 +39,58 @@ vec2 getProjectedCoord(const vec3 hit) {
|
||||
}
|
||||
|
||||
float getDeltaDepth(const vec3 hit) {
|
||||
depth = textureLod(gbufferD, getProjectedCoord(hit), 0.0).r * 2.0 - 1.0;
|
||||
vec2 tc = getProjectedCoord(hit);
|
||||
if (tc.x < 0.0 || tc.x > 1.0 || tc.y < 0.0 || tc.y > 1.0)
|
||||
return -1.0;
|
||||
depth = textureLod(gbufferD, tc, 0.0).r * 2.0 - 1.0;
|
||||
vec3 viewPos = getPosView(viewRay, depth, cameraProj);
|
||||
return viewPos.z - hit.z;
|
||||
}
|
||||
|
||||
vec4 binarySearch(vec3 dir) {
|
||||
vec4 binarySearch(vec3 dir, float stepSize) {
|
||||
float ddepth;
|
||||
for (int i = 0; i < numBinarySearchSteps; i++) {
|
||||
dir *= 0.5;
|
||||
hitCoord -= dir;
|
||||
stepSize *= 0.5;
|
||||
hitCoord -= dir * stepSize;
|
||||
ddepth = getDeltaDepth(hitCoord);
|
||||
if (ddepth < 0.0) hitCoord += dir;
|
||||
if (ddepth < 0.0) hitCoord += dir * stepSize;
|
||||
}
|
||||
// Ugly discard of hits too far away
|
||||
#ifdef _CPostprocess
|
||||
if (abs(ddepth) > PPComp9.z / 500) return vec4(0.0);
|
||||
float maxDist = PPComp9.z;
|
||||
#else
|
||||
if (abs(ddepth) > ssrSearchDist / 500) return vec4(0.0);
|
||||
float maxDist = ssrSearchDist;
|
||||
#endif
|
||||
return vec4(getProjectedCoord(hitCoord), 0.0, 1.0);
|
||||
if (abs(ddepth) > maxDist * 0.005) return vec4(0.0);
|
||||
vec2 hitTC = getProjectedCoord(hitCoord);
|
||||
if (hitTC.x < 0.0 || hitTC.x > 1.0 || hitTC.y < 0.0 || hitTC.y > 1.0)
|
||||
return vec4(0.0);
|
||||
return vec4(hitTC, 0.0, 1.0);
|
||||
}
|
||||
|
||||
vec4 rayCast(vec3 dir) {
|
||||
#ifdef _CPostprocess
|
||||
dir *= PPComp9.x;
|
||||
float baseStep = PPComp9.x;
|
||||
float maxDist = PPComp9.z;
|
||||
#else
|
||||
dir *= ssrRayStep;
|
||||
float baseStep = ssrRayStep;
|
||||
float maxDist = ssrSearchDist;
|
||||
#endif
|
||||
float stepSize = baseStep * max(1.0, -viewRay.z * 0.1);
|
||||
vec3 startPos = hitCoord;
|
||||
for (int i = 0; i < maxSteps; i++) {
|
||||
hitCoord += dir;
|
||||
if (getDeltaDepth(hitCoord) > 0.0) return binarySearch(dir);
|
||||
hitCoord += dir * stepSize;
|
||||
float dist = length(hitCoord - startPos);
|
||||
if (dist > maxDist) break;
|
||||
float ddepth = getDeltaDepth(hitCoord);
|
||||
if (ddepth > 0.0) return binarySearch(dir, stepSize);
|
||||
stepSize *= 1.03;
|
||||
}
|
||||
return vec4(0.0);
|
||||
}
|
||||
|
||||
void main() {
|
||||
vec4 g0 = textureLod(gbuffer0, texCoord, 0.0);
|
||||
float roughness = unpackFloat(g0.b).y;
|
||||
float roughness = g0.b;
|
||||
if (roughness == 1.0) { fragColor.rgb = vec3(0.0); return; }
|
||||
|
||||
float spec = fract(textureLod(gbuffer1, texCoord, 0.0).a);
|
||||
@ -92,30 +107,54 @@ void main() {
|
||||
|
||||
vec3 viewNormal = V3 * n;
|
||||
vec3 viewPos = getPosView(viewRay, d, cameraProj);
|
||||
vec3 reflected = reflect(viewPos, viewNormal);
|
||||
float NdotV = clamp(dot(viewNormal, -normalize(viewPos)), 0.0, 1.0);
|
||||
vec3 reflected = reflect(normalize(viewPos), viewNormal);
|
||||
hitCoord = viewPos;
|
||||
|
||||
#ifdef _CPostprocess
|
||||
vec3 dir = reflected * (1.0 - rand(texCoord) * PPComp10.y * roughness) * 2.0;
|
||||
#else
|
||||
vec3 dir = reflected * (1.0 - rand(texCoord) * ssrJitter * roughness) * 2.0;
|
||||
#endif
|
||||
vec3 dir = reflected;
|
||||
|
||||
// * max(ssrMinRayStep, -viewPos.z)
|
||||
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);
|
||||
if (coords.w <= 0.0) {
|
||||
fragColor.rgb = vec3(0.0);
|
||||
return;
|
||||
}
|
||||
|
||||
vec2 deltaCoords = abs(vec2(0.5, 0.5) - coords.xy);
|
||||
float screenEdgeFactor = smoothstep(0.5, 0.15, deltaCoords.x)
|
||||
* smoothstep(0.5, 0.15, deltaCoords.y);
|
||||
screenEdgeFactor = max(screenEdgeFactor, 0.15);
|
||||
|
||||
float hitDepth = textureLod(gbufferD, coords.xy, 0.0).r * 2.0 - 1.0;
|
||||
vec3 hitViewPos = getPosView(viewRay, hitDepth, cameraProj);
|
||||
vec3 hitDir = normalize(hitViewPos - viewPos);
|
||||
float hitNdotV = clamp(dot(viewNormal, -hitDir), 0.0, 1.0);
|
||||
float hitBackFace = smoothstep(-0.15, 0.3, hitNdotV);
|
||||
|
||||
float reflectivity = 1.0 - roughness;
|
||||
#ifdef _CPostprocess
|
||||
float intensity = pow(reflectivity, PPComp10.x) * screenEdgeFactor * clamp(-reflected.z, 0.0, 1.0) * clamp((PPComp9.z - length(viewPos - hitCoord)) * (1.0 / PPComp9.z), 0.0, 1.0) * coords.w;
|
||||
float falloffExp = PPComp10.x;
|
||||
float maxDist = PPComp9.z;
|
||||
#else
|
||||
float intensity = pow(reflectivity, ssrFalloffExp) * screenEdgeFactor * clamp(-reflected.z, 0.0, 1.0) * clamp((ssrSearchDist - length(viewPos - hitCoord)) * (1.0 / ssrSearchDist), 0.0, 1.0) * coords.w;
|
||||
float falloffExp = ssrFalloffExp;
|
||||
float maxDist = ssrSearchDist;
|
||||
#endif
|
||||
|
||||
float distAttenuation = 1.0 - clamp(length(viewPos - hitCoord) / maxDist, 0.0, 1.0);
|
||||
distAttenuation = pow(distAttenuation, 1.5);
|
||||
|
||||
float fresnel = pow(1.0 - NdotV, 5.0);
|
||||
fresnel = mix(0.04, 1.0, fresnel);
|
||||
|
||||
float intensity = pow(reflectivity, falloffExp) * screenEdgeFactor
|
||||
* smoothstep(0.0, 0.1, -reflected.z)
|
||||
* distAttenuation
|
||||
* hitBackFace
|
||||
* coords.w;
|
||||
|
||||
intensity = clamp(intensity, 0.0, 1.0);
|
||||
|
||||
vec3 reflCol = textureLod(tex, coords.xy, 0.0).rgb;
|
||||
reflCol = clamp(reflCol, 0.0, 1.0);
|
||||
fragColor.rgb = reflCol * intensity * 0.5;
|
||||
fragColor.rgb = reflCol * intensity * mix(0.5, 1.0, fresnel);
|
||||
}
|
||||
|
||||
@ -22,6 +22,10 @@
|
||||
"name": "cameraProj",
|
||||
"link": "_cameraPlaneProj"
|
||||
},
|
||||
{
|
||||
"name": "screenSize",
|
||||
"link": "_screenSize"
|
||||
},
|
||||
{
|
||||
"name": "PPComp9",
|
||||
"link": "_PPComp9",
|
||||
|
||||
Reference in New Issue
Block a user