Clen up, exposingthe level of obscurance

This commit is contained in:
samcake 2016-01-06 13:16:16 -04:00
parent 12ad08560f
commit 7e2cf741c0
8 changed files with 68 additions and 41 deletions

View file

@ -52,7 +52,7 @@ var overlaysCounter = new CounterWidget(panel, "Overlays", Render.overlay3D);
var resizing = false; var resizing = false;
var previousMode = Settings.getValue(SETTINGS_KEY, -1); var previousMode = Settings.getValue(SETTINGS_KEY, -1);
previousMode = 4; // FIXME: just for debug purpose previousMode = 1; // FIXME: just for debug purpose
Menu.addActionGroup(MENU, ACTIONS, ACTIONS[previousMode + 1]); Menu.addActionGroup(MENU, ACTIONS, ACTIONS[previousMode + 1]);
Render.deferredDebugMode = previousMode; Render.deferredDebugMode = previousMode;
Render.deferredDebugSize = { x: 0.0, y: -1.0, z: 1.0, w: 1.0 }; // Reset to default size Render.deferredDebugSize = { x: 0.0, y: -1.0, z: 1.0, w: 1.0 }; // Reset to default size
@ -104,6 +104,11 @@ panel.newSlider("Ambient Occlusion Radius", 0.0, 2.0,
function() { return Render.ambientOcclusion.radius; }, function() { return Render.ambientOcclusion.radius; },
function (value) { return (value); }); function (value) { return (value); });
panel.newSlider("Ambient Occlusion Level", 0.0, 1.0,
function (value) { Render.ambientOcclusion.level = value; },
function() { return Render.ambientOcclusion.level; },
function (value) { return (value); });
var tickTackPeriod = 500; var tickTackPeriod = 500;
function updateCounters() { function updateCounters() {

View file

@ -154,14 +154,27 @@ const gpu::PipelinePointer& AmbientOcclusionEffect::getVBlurPipeline() {
} }
void AmbientOcclusionEffect::setClipInfo(float nearZ, float farZ) { void AmbientOcclusionEffect::setDepthInfo(float nearZ, float farZ) {
_parametersBuffer.edit<Parameters>()._clipInfo = glm::vec4(nearZ*farZ, farZ -nearZ, -farZ, 0.0f); _parametersBuffer.edit<Parameters>()._depthInfo = glm::vec4(nearZ*farZ, farZ -nearZ, -farZ, 0.0f);
} }
void AmbientOcclusionEffect::setRadius(float radius) { void AmbientOcclusionEffect::setRadius(float radius) {
radius = std::max(0.01f, radius); radius = std::max(0.01f, radius);
_parametersBuffer.edit<Parameters>()._radius_radius2_InvRadius6_s2 = glm::vec4(radius, radius * radius, 1.0f / pow(radius, 6.0f), 0.0f); if (radius != getRadius()) {
auto& current = _parametersBuffer.edit<Parameters>()._radiusInfo;
current.x = radius;
current.y = radius * radius;
current.z = 1.0f / pow(radius, 6.0f);
}
}
void AmbientOcclusionEffect::setLevel(float level) {
level = std::max(0.01f, level);
if (level != getLevel()) {
auto& current = _parametersBuffer.edit<Parameters>()._radiusInfo;
current.w = level;
}
} }
void AmbientOcclusionEffect::updateDeferredTransformBuffer(const render::RenderContextPointer& renderContext) { void AmbientOcclusionEffect::updateDeferredTransformBuffer(const render::RenderContextPointer& renderContext) {
@ -290,8 +303,8 @@ void AmbientOcclusionEffect::run(const render::SceneContextPointer& sceneContext
mat4 monoProjMat; mat4 monoProjMat;
args->_viewFrustum->evalProjectionMatrix(monoProjMat); args->_viewFrustum->evalProjectionMatrix(monoProjMat);
setClipInfo(args->_viewFrustum->getNearClip(), args->_viewFrustum->getFarClip()); setDepthInfo(args->_viewFrustum->getNearClip(), args->_viewFrustum->getFarClip());
_parametersBuffer.edit<Parameters>()._projection = monoProjMat; _parametersBuffer.edit<Parameters>()._projection[0] = monoProjMat;
_parametersBuffer.edit<Parameters>()._pixelInfo = args->_viewport; _parametersBuffer.edit<Parameters>()._pixelInfo = args->_viewport;
auto pyramidPipeline = getPyramidPipeline(); auto pyramidPipeline = getPyramidPipeline();

View file

@ -25,20 +25,28 @@ public:
typedef render::Job::Model<AmbientOcclusionEffect> JobModel; typedef render::Job::Model<AmbientOcclusionEffect> JobModel;
void setRadius(float radius); void setRadius(float radius);
float getRadius() const { return _parametersBuffer.get<Parameters>()._radius_radius2_InvRadius6_s2.x; } float getRadius() const { return _parametersBuffer.get<Parameters>()._radiusInfo.x; }
// Obscurance level which intensify or dim down the obscurance effect
void setLevel(float level);
float getLevel() const { return _parametersBuffer.get<Parameters>()._radiusInfo.w; }
private: private:
void setClipInfo(float nearZ, float farZ); void setDepthInfo(float nearZ, float farZ);
// Class describing the uniform buffer with all the parameters common to the AO shaders // Class describing the uniform buffer with all the parameters common to the AO shaders
class Parameters { class Parameters {
public: public:
// radius info is { R, R^2, 1 / R^6, ObscuranceScale}
glm::vec4 _radiusInfo{ 0.5, 0.5 * 0.5, 1.0 / (0.25 * 0.25 * 0.25), 1.0 };
// Pixel info is { viemport width height and stereo on off}
glm::vec4 _pixelInfo; glm::vec4 _pixelInfo;
glm::vec4 _clipInfo; // Depth info is { n.f, f - n, -f}
glm::mat4 _projection; glm::vec4 _depthInfo;
glm::vec4 _radius_radius2_InvRadius6_s2{ 0.5, 0.5 * 0.5, 1.0 / (0.25 * 0.25 * 0.25), 0.0 }; // Mono proj matrix or Left and Right proj matrix going from Mono Eye space to side clip space
glm::mat4 _projection[2];
Parameters() {} Parameters() {}
}; };
typedef gpu::BufferView UniformBufferView; typedef gpu::BufferView UniformBufferView;

View file

@ -160,6 +160,7 @@ void RenderDeferredTask::run(const SceneContextPointer& sceneContext, const Rend
setOcclusionStatus(renderContext->getOcclusionStatus()); setOcclusionStatus(renderContext->getOcclusionStatus());
if (_occlusionJobIndex >= 0) { if (_occlusionJobIndex >= 0) {
_jobs[_occlusionJobIndex].edit<AmbientOcclusionEffect>().setRadius(renderContext->getAmbientOcclusion().radius); _jobs[_occlusionJobIndex].edit<AmbientOcclusionEffect>().setRadius(renderContext->getAmbientOcclusion().radius);
_jobs[_occlusionJobIndex].edit<AmbientOcclusionEffect>().setLevel(renderContext->getAmbientOcclusion().level);
} }
setAntialiasingStatus(renderContext->getFxaaStatus()); setAntialiasingStatus(renderContext->getFxaaStatus());

View file

@ -71,6 +71,7 @@ namespace RenderScripting {
public: public:
Q_PROPERTY(float radius MEMBER radius) Q_PROPERTY(float radius MEMBER radius)
Q_PROPERTY(float level MEMBER level)
}; };
using AmbientOcclusionPointer = std::unique_ptr<AmbientOcclusion>; using AmbientOcclusionPointer = std::unique_ptr<AmbientOcclusion>;
}; };

View file

@ -32,10 +32,10 @@ vec2 unpackOcclusionDepth(vec3 raw) {
<@func declareAmbientOcclusion()@> <@func declareAmbientOcclusion()@>
struct AmbientOcclusionParams { struct AmbientOcclusionParams {
vec4 _radiusInfo;
vec4 _pixelInfo; vec4 _pixelInfo;
vec4 _clipInfo; vec4 _depthInfo;
mat4 _projection; mat4 _projection[2];
vec4 _radius_radius2_InvRadius6_s2;
}; };
uniform ambientOcclusionParamsBuffer { uniform ambientOcclusionParamsBuffer {
@ -46,28 +46,34 @@ vec2 getWidthHeight() {
return params._pixelInfo.zw; return params._pixelInfo.zw;
} }
float getProjScale() { float getProjScale() {
return getWidthHeight().y * params._projection[1][1] * 0.5; return getWidthHeight().y * params._projection[0][1][1] * 0.5;
}
mat4 getProjection(int side) {
return params._projection[side];
} }
float getRadius() { float getRadius() {
return params._radius_radius2_InvRadius6_s2.x; return params._radiusInfo.x;
} }
float getRadius2() { float getRadius2() {
return params._radius_radius2_InvRadius6_s2.y; return params._radiusInfo.y;
} }
float getInvRadius6() { float getInvRadius6() {
return params._radius_radius2_InvRadius6_s2.z; return params._radiusInfo.z;
}
float getObscuranceScaling() {
return params._radiusInfo.z * params._radiusInfo.w;
} }
float evalZeyeFromZdb(float depth) { float evalZeyeFromZdb(float depth) {
return params._clipInfo.x / (depth * params._clipInfo.y + params._clipInfo.z); return params._depthInfo.x / (depth * params._depthInfo.y + params._depthInfo.z);
} }
vec3 evalEyePositionFromZeye(float Zeye, vec2 texcoord) { vec3 evalEyePositionFromZeye(float Zeye, vec2 texcoord) {
// compute the view space position using the depth // compute the view space position using the depth
// basically manually pick the proj matrix components to do the inverse // basically manually pick the proj matrix components to do the inverse
float Xe = (-Zeye * (texcoord.x * 2.0 - 1.0) - Zeye * params._projection[2][0] - params._projection[3][0]) / params._projection[0][0]; float Xe = (-Zeye * (texcoord.x * 2.0 - 1.0) - Zeye * params._projection[0][2][0] - params._projection[0][3][0]) / params._projection[0][0][0];
float Ye = (-Zeye * (texcoord.y * 2.0 - 1.0) - Zeye * params._projection[2][1] - params._projection[3][1]) / params._projection[1][1]; float Ye = (-Zeye * (texcoord.y * 2.0 - 1.0) - Zeye * params._projection[0][2][1] - params._projection[0][3][1]) / params._projection[0][1][1];
return vec3(Xe, Ye, Zeye); return vec3(Xe, Ye, Zeye);
} }
@ -96,15 +102,14 @@ vec2 fetchOcclusionDepth(ivec2 coords) {
const int BLUR_RADIUS = 4; const int BLUR_RADIUS = 4;
const int RADIUS_SCALE = 2; const int RADIUS_SCALE = 3;
const float EDGE_SHARPNESS = 1.0; const float EDGE_SHARPNESS = 1.0;
const float gaussian[BLUR_RADIUS + 1] = const float gaussian[BLUR_RADIUS + 1] =
// float[](0.356642, 0.239400, 0.072410, 0.009869); // R = 2 // float[](0.356642, 0.239400, 0.072410, 0.009869);
// float[](0.398943, 0.241971, 0.053991, 0.004432, 0.000134); // R = 3 // float[](0.398943, 0.241971, 0.053991, 0.004432, 0.000134); // stddev = 1.0
float[](0.153170, 0.144893, 0.122649, 0.092902, 0.062970); // R = 4 float[](0.153170, 0.144893, 0.122649, 0.092902, 0.062970); // stddev = 2.0
// float[](0.111220, 0.107798, 0.098151, 0.083953, 0.067458, 0.050920, 0.036108); // R = 5.0 // float[](0.111220, 0.107798, 0.098151, 0.083953, 0.067458, 0.050920, 0.036108); // stddev = 3.0
vec3 getBlurredOcclusion(vec2 coord) { vec3 getBlurredOcclusion(vec2 coord) {
ivec2 ssC = ivec2(coord); ivec2 ssC = ivec2(coord);

View file

@ -85,15 +85,8 @@ float sampleAO(in ivec2 ssC, in vec3 C, in vec3 n_C, in float ssDiskRadius, in i
// return float(vv < radius2) * max((vn - bias) / (epsilon + vv), 0.0) * radius2 * 0.6; // return float(vv < radius2) * max((vn - bias) / (epsilon + vv), 0.0) * radius2 * 0.6;
// B: Smoother transition to zero (lowers contrast, smoothing out corners). [Recommended] // B: Smoother transition to zero (lowers contrast, smoothing out corners). [Recommended]
float f = max(radius2 - vv, 0.0); return f * f * f * max((vn - bias) / (epsilon + vv), 0.0); float f = max(radius2 - vv, 0.0);
return f * f * f * max((vn - bias) / (epsilon + vv), 0.0);
// C: Medium contrast (which looks better at high radii), no division. Note that the
// contribution still falls off with radius^2, but we've adjusted the rate in a way that is
// more computationally efficient and happens to be aesthetically pleasing.
// return 4.0 * max(1.0 - vv * invRadius2, 0.0) * max(vn - bias, 0.0);
// D: Low contrast, no division operation
// return 2.0 * float(vv < radius * radius) * max(vn - bias, 0.0);
} }
vec3 debugValue(float f, float scale) { vec3 debugValue(float f, float scale) {
@ -125,16 +118,16 @@ void main(void) {
sum += sampleAO(ssC, Cp, Cn, ssDiskRadius, i, randomPatternRotationAngle); sum += sampleAO(ssC, Cp, Cn, ssDiskRadius, i, randomPatternRotationAngle);
} }
float A = max(0.0, 1.0 - sum * getInvRadius6() * 5.0 * INV_NUM_SAMPLES); float A = max(0.0, 1.0 - sum * getObscuranceScaling() * 5.0 * INV_NUM_SAMPLES);
// Bilateral box-filter over a quad for free, respecting depth edges // Bilateral box-filter over a quad for free, respecting depth edges
// (the difference that this makes is subtle) // (the difference that this makes is subtle)
/*if (abs(dFdx(Cp.z)) < 0.02) { if (abs(dFdx(Cp.z)) < 0.02) {
A -= dFdx(A) * ((ssC.x & 1) - 0.5); A -= dFdx(A) * ((ssC.x & 1) - 0.5);
} }
if (abs(dFdy(Cp.z)) < 0.02) { if (abs(dFdy(Cp.z)) < 0.02) {
A -= dFdy(A) * ((ssC.y & 1) - 0.5); A -= dFdy(A) * ((ssC.y & 1) - 0.5);
}*/ }
outFragColor = vec4(packOcclusionDepth(A, CSZToDephtKey(Cp.z)), 1.0); outFragColor = vec4(packOcclusionDepth(A, CSZToDephtKey(Cp.z)), 1.0);
//outFragColor = vec4(0.5 * (Cn + vec3(1.0)), A); //outFragColor = vec4(0.5 * (Cn + vec3(1.0)), A);

View file

@ -79,7 +79,8 @@ public:
class AmbientOcclusion { class AmbientOcclusion {
public: public:
float radius = 0.5; // radius in meters of the AO effect float radius = 0.5f; // radius in meters of the AO effect
float level = 0.5f; // Level of the obscrance value
}; };
RenderContext(ItemsConfig items, Tone tone, AmbientOcclusion ao, int drawStatus, bool drawHitEffect, glm::vec4 deferredDebugSize, int deferredDebugMode); RenderContext(ItemsConfig items, Tone tone, AmbientOcclusion ao, int drawStatus, bool drawHitEffect, glm::vec4 deferredDebugSize, int deferredDebugMode);