Fix the curvature issue in stereo by evaluating in the mono clip space, not stereo. INtegrate the scattering in simple ambient without IBL

This commit is contained in:
samcake 2016-06-28 13:47:55 -07:00
parent 197d49fc03
commit d128af48db
17 changed files with 231 additions and 28 deletions

View file

@ -36,13 +36,12 @@ void DeferredFrameTransform::update(RenderArgs* args) {
cameraTransform.getMatrix(frameTransformBuffer.invView);
cameraTransform.getInverseMatrix(frameTransformBuffer.view);
args->getViewFrustum().evalProjectionMatrix(frameTransformBuffer.projectionMono);
// Running in stero ?
bool isStereo = args->_context->isStereo();
if (!isStereo) {
// Eval the mono projection
mat4 monoProjMat;
args->getViewFrustum().evalProjectionMatrix(monoProjMat);
frameTransformBuffer.projection[0] = monoProjMat;
frameTransformBuffer.projection[0] = frameTransformBuffer.projectionMono;
frameTransformBuffer.stereoInfo = glm::vec4(0.0f, (float)args->_viewport.z, 0.0f, 0.0f);
frameTransformBuffer.invpixelInfo = glm::vec4(1.0f / args->_viewport.z, 1.0f / args->_viewport.w, 0.0f, 0.0f);
} else {

View file

@ -45,6 +45,8 @@ protected:
glm::vec4 stereoInfo{ 0.0 };
// Mono proj matrix or Left and Right proj matrix going from Mono Eye space to side clip space
glm::mat4 projection[2];
// THe mono projection for sure
glm::mat4 projectionMono;
// Inv View matrix from eye space (mono) to world space
glm::mat4 invView;
// View matrix from world space to eye space (mono)

View file

@ -110,6 +110,99 @@ vec3 evalAmbientSphereGlobalColor(mat4 invViewMat, float shadowAttenuation, floa
}
<@endfunc@>
<@func declareEvalAmbientSphereGlobalColorScattering()@>
<$declareDeferredCurvature()$>
<@include SubsurfaceScattering.slh@>
<$declareSubsurfaceScatteringResource()$>
<!<$declareEvalGlobalSpecularIrradiance(1, 0, 0)$>!>
vec3 evalAmbientSphereGlobalColorScattering(mat4 invViewMat, float shadowAttenuation, float obscurance, vec3 position, vec3 normal, vec3 albedo, vec4 blurredCurvature, vec4 diffusedCurvature, float roughness) {
// prepareGlobalLight
// Transform directions to worldspace
vec3 fragNormal = vec3((normal));
vec3 fragEyeVector = vec3(invViewMat * vec4(-position, 0.0));
vec3 fragEyeDir = normalize(fragEyeVector);
// Get light
Light light = getLight();
vec3 fresnel = vec3(0.028); // Default Di-electric fresnel value for skin
float metallic = 0.0;
vec3 fragLightDir = -normalize(getLightDirection(light));
vec3 bentNormalHigh = normalize((blurredCurvature.xyz - 0.5f) * 2.0f);
vec3 bentNormalLow = normalize((diffusedCurvature.xyz - 0.5f) * 2.0f);
float curvature = unpackCurvature(diffusedCurvature.w);
if (showDiffusedNormal()) {
return diffusedCurvature.xyz;
return bentNormalLow * 0.5 + vec3(0.5);
}
if (showCurvature()) {
float curvatureSigned = unpackCurvatureSigned(diffusedCurvature.w);
return (curvatureSigned > 0 ? vec3(curvatureSigned, 0.0, 0.0) : vec3(0.0, 0.0, -curvatureSigned));
}
vec3 rS = bentNormalHigh;
vec3 bendFactorSpectrum = getBendFactor();
// vec3 rN = normalize(mix(normal, bentNormalLow, bendFactorSpectrum.x));
vec3 rN = normalize(mix(bentNormalHigh, bentNormalLow, bendFactorSpectrum.x));
vec3 gN = normalize(mix(bentNormalHigh, bentNormalLow, bendFactorSpectrum.y));
vec3 bN = normalize(mix(bentNormalHigh, bentNormalLow, bendFactorSpectrum.z));
vec3 NdotLSpectrum = vec3(dot(rN, fragLightDir), dot(gN, fragLightDir), dot(bN, fragLightDir));
//return 0.5 * (NdotLSpectrum + vec3(1.0));
// --> Look up the pre-integrated curvature-dependent BDRF textures
vec3 brdf = fetchBRDFSpectrum(NdotLSpectrum, curvature);
// The position of the pixel fragment in Eye space then in world space
float scatteringLevel = getScatteringLevel();
vec4 shading;
float standardDiffuse = clamp(dot(normal, fragLightDir), 0.0, 1.0);
{ // Key Sun Lighting
// Diffuse Lighting
//float diffuse = clamp(dot(normal, fragLightDir), 0.0, 1.0);
// Specular Lighting
vec3 halfDir = normalize(fragEyeDir + fragLightDir);
vec3 fresnelColor = fresnelSchlick(fresnel, fragLightDir, halfDir);
float power = specularDistribution(roughness, fragNormal, halfDir);
vec3 specular = power * fresnelColor * standardDiffuse;
shading = vec4(specular, (1 - fresnelColor.x));
}
if (scatteringLevel < 0.1) {
brdf = vec3(standardDiffuse);
}
vec3 color = vec3(albedo * vec3(brdf.xyz) * shading.w + shading.rgb) * getLightColor(light) * getLightIntensity(light);
// Diffuse from ambient
// color += albedo * evalSphericalLight(getLightAmbientSphere(light), bentNormalHigh).xyz *getLightAmbientIntensity(light);
// Specular highlight from ambient
vec3 specularLighting = evalGlobalSpecularIrradiance(light, fragEyeDir, fragNormal, roughness, fresnel, 1.0);
// color += specularLighting;
if (showBRDF())
return brdf;
//vec3 debugNdotL = 0.5 * (NdotLSpectrum + vec3(1.0));
//return vec3(debugNdotL.z, curvature, 0.0 );
return vec3(color);
}
<@endfunc@>
<@func declareEvalSkyboxGlobalColor()@>
<$declareEvalGlobalSpecularIrradiance(0, 1, 0)$>
@ -169,7 +262,7 @@ vec3 evalSkyboxGlobalColorScattering(mat4 invViewMat, float shadowAttenuation, f
// Get light
Light light = getLight();
vec3 fresnel = vec3(0.03); // Default Di-electric fresnel value
vec3 fresnel = vec3(0.028); // Default Di-electric fresnel value for skin
float metallic = 0.0;
vec3 fragLightDir = -normalize(getLightDirection(light));
@ -178,6 +271,14 @@ vec3 evalSkyboxGlobalColorScattering(mat4 invViewMat, float shadowAttenuation, f
vec3 bentNormalLow = normalize( (diffusedCurvature.xyz - 0.5f) * 2.0f );
float curvature = unpackCurvature(diffusedCurvature.w);
if (showDiffusedNormal()) {
return diffusedCurvature.xyz;
return bentNormalLow * 0.5 + vec3(0.5);
}
if (showCurvature()) {
float curvatureSigned = unpackCurvatureSigned(diffusedCurvature.w);
return (curvatureSigned > 0 ? vec3(curvatureSigned, 0.0, 0.0) : vec3(0.0, 0.0, -curvatureSigned));
}
vec3 rS = bentNormalHigh;
vec3 bendFactorSpectrum = getBendFactor();

View file

@ -626,6 +626,8 @@ void RenderDeferred::configure(const Config& config) {
_subsurfaceScatteringResource->setLevel((float)config.enableScattering);
_subsurfaceScatteringResource->setShowBRDF(config.showScatteringBRDF);
_subsurfaceScatteringResource->setShowCurvature(config.showCurvature);
_subsurfaceScatteringResource->setShowDiffusedNormal(config.showDiffusedNormal);
_enablePointLights = config.enablePointLights;
_enableSpotLights = config.enableSpotLights;

View file

@ -148,6 +148,8 @@ class RenderDeferredConfig : public render::Job::Config {
Q_PROPERTY(bool enableScattering MEMBER enableScattering NOTIFY dirty)
Q_PROPERTY(bool showScatteringBRDF MEMBER showScatteringBRDF NOTIFY dirty)
Q_PROPERTY(bool showCurvature MEMBER showCurvature NOTIFY dirty)
Q_PROPERTY(bool showDiffusedNormal MEMBER showDiffusedNormal NOTIFY dirty)
Q_PROPERTY(bool enablePointLights MEMBER enablePointLights NOTIFY dirty)
Q_PROPERTY(bool enableSpotLights MEMBER enableSpotLights NOTIFY dirty)
@ -162,10 +164,12 @@ public:
float bentScale{ 1.5f };
float curvatureOffset{ 0.08f };
float curvatureScale{ 0.8f };
float curvatureScale{ 0.9f };
bool enableScattering{ true };
bool showScatteringBRDF{ true };
bool showScatteringBRDF{ false };
bool showCurvature{ false };
bool showDiffusedNormal{ false };
bool enablePointLights{ true };
bool enableSpotLights{ true };

View file

@ -19,6 +19,7 @@ struct DeferredFrameTransform {
vec4 _depthInfo;
vec4 _stereoInfo;
mat4 _projection[2];
mat4 _projectionMono;
mat4 _viewInverse;
mat4 _view;
};
@ -49,6 +50,9 @@ float getProjScale(int resolutionLevel) {
mat4 getProjection(int side) {
return frameTransform._projection[side];
}
mat4 getProjectionMono() {
return frameTransform._projectionMono;
}
// positive near distance of the projection
float getProjectionNear() {

View file

@ -84,6 +84,23 @@ bool SubsurfaceScatteringResource::isShowBRDF() const {
return (bool)_parametersBuffer.get<Parameters>().showBRDF;
}
void SubsurfaceScatteringResource::setShowCurvature(bool show) {
if (show != isShowCurvature()) {
_parametersBuffer.edit<Parameters>().showCurvature = show;
}
}
bool SubsurfaceScatteringResource::isShowCurvature() const {
return (bool)_parametersBuffer.get<Parameters>().showCurvature;
}
void SubsurfaceScatteringResource::setShowDiffusedNormal(bool show) {
if (show != isShowDiffusedNormal()) {
_parametersBuffer.edit<Parameters>().showDiffusedNormal = show;
}
}
bool SubsurfaceScatteringResource::isShowDiffusedNormal() const {
return (bool)_parametersBuffer.get<Parameters>().showDiffusedNormal;
}
void SubsurfaceScatteringResource::generateScatteringTable(RenderArgs* args) {
if (!_scatteringProfile) {

View file

@ -35,7 +35,10 @@ public:
void setShowBRDF(bool show);
bool isShowBRDF() const;
void setShowCurvature(bool show);
bool isShowCurvature() const;
void setShowDiffusedNormal(bool show);
bool isShowDiffusedNormal() const;
UniformBufferView getParametersBuffer() const { return _parametersBuffer; }
@ -56,7 +59,12 @@ protected:
glm::vec4 normalBentInfo{ 1.5f, 0.8f, 0.3f, 1.5f };
glm::vec2 curvatureInfo{ 0.08f, 0.8f };
float level{ 1.0f };
float showBRDF{ 1.0f };
float showBRDF{ 0.0f };
float showCurvature{ 0.0f };
float showDiffusedNormal{ 0.0f };
float spare1{ 0.0f };
float spare2{ 0.0f };
Parameters() {}
};
@ -96,8 +104,8 @@ public:
float curvatureOffset{ 0.08f };
float curvatureScale{ 0.8f };
bool showProfile{ true };
bool showLUT{ true };
bool showProfile{ false };
bool showLUT{ false };
signals:
void dirty();

View file

@ -117,6 +117,7 @@ vec3 fetchBRDFSpectrum(vec3 LdotNSpectrum, float curvature) {
struct ScatteringParameters {
vec4 normalBendInfo; // R, G, B, factor
vec4 curvatureInfo;// Offset, Scale, level
vec4 debugFlags;
};
uniform subsurfaceScatteringParametersBuffer {
@ -135,6 +136,16 @@ bool showBRDF() {
return parameters.curvatureInfo.w > 0.0;
}
bool showCurvature() {
return parameters.debugFlags.x > 0.0;
}
bool showDiffusedNormal() {
return parameters.debugFlags.y > 0.0;
}
float unpackCurvatureSigned(float packedCurvature) {
return (packedCurvature * 2 - 1) * parameters.curvatureInfo.y + parameters.curvatureInfo.x;
}
float unpackCurvature(float packedCurvature) {
return abs(packedCurvature * 2 - 1) * parameters.curvatureInfo.y + parameters.curvatureInfo.x;
}

View file

@ -26,7 +26,7 @@ class SurfaceGeometryPassConfig : public render::Job::Config {
public:
SurfaceGeometryPassConfig() : render::Job::Config(true) {}
float depthThreshold{ 0.033f };
float depthThreshold{ 0.02f }; // meters
float basisScale{ 1.0f };
float curvatureScale{ 10.0f };

View file

@ -17,6 +17,8 @@
<$declareEvalLightmappedColor()$>
<$declareEvalAmbientSphereGlobalColor()$>
<$declareEvalAmbientSphereGlobalColorScattering()$>
in vec2 _texCoord0;
out vec4 _fragColor;
@ -38,6 +40,22 @@ void main(void) {
frag.diffuse,
frag.specularVal.xyz);
_fragColor = vec4(color, 1.0);
} else if (frag.mode == FRAG_MODE_SCATTERING) {
vec4 blurredCurvature = fetchCurvature(_texCoord0);
vec4 diffusedCurvature = fetchDiffusedCurvature(_texCoord0);
vec3 color = evalAmbientSphereGlobalColorScattering(
getViewInverse(),
shadowAttenuation,
frag.obscurance,
frag.position.xyz,
frag.normal,
frag.diffuse,
blurredCurvature,
diffusedCurvature,
frag.roughness);
_fragColor = vec4(color, 1.0);
} else {
vec3 color = evalAmbientSphereGlobalColor(
getViewInverse(),

View file

@ -112,6 +112,14 @@ void main(void) {
// The position of the pixel fragment in Eye space then in world space
vec3 eyePos = evalEyePositionFromZeye(stereoSide.x, Zeye, texcoordPos);
vec3 worldPos = (frameTransform._viewInverse * vec4(eyePos, 1.0)).xyz;
if (texcoordPos.y > 0.5) {
outFragColor = vec4(fract(10.0 * worldPos.xyz), 1.0);
} else {
outFragColor = vec4(fract(10.0 * eyePos.xyz), 1.0);
}
// return;
// Calculate the perspective scale.
// Clamp to 0.5
@ -142,14 +150,14 @@ void main(void) {
vec4 py = vec4(eyePos + ay, 0.0);
vec4 pz = vec4(eyePos + az, 0.0);
/*
if (texcoordPos.y > 0.5) {
outFragColor = vec4(fract(px.xyz), 1.0);
} else {
outFragColor = vec4(fract(eyePos.xyz), 1.0);
}
return;
*/
// return;
/* IN case the axis end point goes behind mid way near plane, this shouldn't happen
if (px.z >= -nearPlaneScale) {
@ -165,11 +173,13 @@ void main(void) {
// Project px, py pz to homogeneous clip space
mat4 viewProj = getProjection(stereoSide.x);
// mat4 viewProj = getProjection(stereoSide.x);
mat4 viewProj = getProjectionMono();
px = viewProj * px;
py = viewProj * py;
pz = viewProj * pz;
// then to normalized clip space
px.xy /= px.w;
py.xy /= py.w;
@ -177,20 +187,37 @@ void main(void) {
vec2 nclipPos = (texcoordPos - 0.5) * 2.0;
/*
//vec4 clipPos = frameTransform._projection[stereoSide.x] * vec4(eyePos, 1.0);
vec4 clipPos = getProjectionMono() * vec4(eyePos, 1.0);
nclipPos = clipPos.xy / clipPos.w;
if (texcoordPos.y > 0.5) {
outFragColor = vec4(px.xy * 0.5 + 0.5, 0.0, 1.0);
// outFragColor = vec4(fract(10.0 * worldPos.xyz), 1.0);
outFragColor = vec4(fract(10.0 * (nclipPos)), 0.0, 1.0);
} else {
outFragColor = vec4(nclipPos * 0.5 + 0.5, 0.0, 1.0);
outFragColor = vec4(fract(10.0 * (clipPos.xy / clipPos.w)), 0.0, 1.0);
// outFragColor = vec4(nclipPos * 0.5 + 0.5, 0.0, 1.0);
}
return;
*/
//return;
float pixPerspectiveScaleInv = 1.0 / (perspectiveScale);
px.xy = (px.xy - nclipPos) * pixPerspectiveScaleInv;
py.xy = (py.xy - nclipPos) * pixPerspectiveScaleInv;
pz.xy = (pz.xy - nclipPos) * pixPerspectiveScaleInv;
if (texcoordPos.y > 0.5) {
// outFragColor = vec4(fract(10.0 * worldPos.xyz), 1.0);
outFragColor = vec4(fract(10.0 * (px.xy)), 0.0, 1.0);
} else {
outFragColor = vec4(fract(10.0 * (py.xy)), 0.0, 1.0);
// outFragColor = vec4(nclipPos * 0.5 + 0.5, 0.0, 1.0);
}
// return;
// Calculate dF/dx, dF/dy and dF/dz using chain rule
vec4 dFdx = dFdu * px.x + dFdv * px.y;
vec4 dFdy = dFdu * py.x + dFdv * py.y;

View file

@ -79,7 +79,7 @@ public:
BlurGaussianConfig() : Job::Config(true) {}
float filterScale{ 1.2f };
float filterScale{ 0.2f };
signals :
void dirty();

View file

@ -99,7 +99,7 @@ vec4 pixelShaderGaussianDepthAware(vec2 texcoord, vec2 direction, vec2 pixelStep
float filterScale = getFilterScale();
float scale = distanceToProjectionWindow / sampleDepth;
vec2 finalStep = filterScale * scale * direction * pixelStep; // *1000.0;
vec2 finalStep = filterScale * scale * direction * pixelStep;
// Accumulate the center sample
vec4 srcBlurred = gaussianDistributionCurve[0] * sampleCenter;
@ -112,7 +112,7 @@ vec4 pixelShaderGaussianDepthAware(vec2 texcoord, vec2 direction, vec2 pixelStep
// If the difference in depth is huge, we lerp color back.
float s = clamp(/*depthThreshold */12.0 * distanceToProjectionWindow * filterScale * abs(srcDepth - sampleDepth), 0.0, 1.0);
float s = clamp(depthThreshold * distanceToProjectionWindow * filterScale * abs(srcDepth - sampleDepth), 0.0, 1.0);
// float s = clamp(depthThreshold * distanceToProjectionWindow * filterScale * abs(srcDepth - sampleDepth), 0.0, 1.0);
srcSample = mix(srcSample, sampleCenter, s);

View file

@ -13,8 +13,8 @@ var qml = Script.resolvePath('deferredLighting.qml');
var window = new OverlayWindow({
title: 'Deferred Lighting Pass',
source: qml,
width: 400, height: 400,
width: 400, height: 350,
});
window.setPosition(250, 750);
window.setPosition(250, 800);
window.closed.connect(function() { Script.stop(); });

View file

@ -13,8 +13,8 @@ var qml = Script.resolvePath('surfaceGeometryPass.qml');
var window = new OverlayWindow({
title: 'Surface Geometry Pass',
source: qml,
width: 400, height: 400,
width: 400, height: 300,
});
window.setPosition(250, 500);
window.setPosition(250, 400);
window.closed.connect(function() { Script.stop(); });

View file

@ -40,6 +40,16 @@ Column {
checked: Render.getConfig("RenderDeferred").showScatteringBRDF
onCheckedChanged: { Render.getConfig("RenderDeferred").showScatteringBRDF = checked }
}
CheckBox {
text: "Show Curvature"
checked: Render.getConfig("RenderDeferred").showCurvature
onCheckedChanged: { Render.getConfig("RenderDeferred").showCurvature = checked }
}
CheckBox {
text: "Show Diffused Normal"
checked: Render.getConfig("RenderDeferred").showDiffusedNormal
onCheckedChanged: { Render.getConfig("RenderDeferred").showDiffusedNormal = checked }
}
Repeater {
model: [ "Scattering Bent Red:RenderDeferred:bentRed:2.0",
"Scattering Bent Green:RenderDeferred:bentGreen:2.0",