summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
authorDave Parks <davep@lindenlab.com>2010-11-24 03:36:41 -0600
committerDave Parks <davep@lindenlab.com>2010-11-24 03:36:41 -0600
commit894dd833f7351ead340047bd5d6f9950a5cecbeb (patch)
tree10e6539c2d3cdafc2b74238063d0293d774e92c5 /indra
parent2915715ec4a9bb7978c4a0db0afc26b73ab8b2fb (diff)
Depth of Field whenever "Lighting and Shadows" is enabled and global-illumination is not (experimental).
Diffstat (limited to 'indra')
-rwxr-xr-xindra/newview/app_settings/settings.xml40
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/postDeferredF.glsl172
-rw-r--r--indra/newview/lldrawpoolalpha.cpp45
-rw-r--r--indra/newview/llviewerwindow.cpp20
-rw-r--r--indra/newview/pipeline.cpp60
5 files changed, 282 insertions, 55 deletions
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 5cc8c34cd5..4efb8edd63 100755
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -1332,7 +1332,45 @@
<key>Value</key>
<integer>0</integer>
</map>
- <key>CertStore</key>
+
+ <key>CameraFNumber</key>
+ <map>
+ <key>Comment</key>
+ <string>Camera f-number value for DoF effect</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>F32</string>
+ <key>Value</key>
+ <real>2.8</real>
+ </map>
+
+ <key>CameraFocalLength</key>
+ <map>
+ <key>Comment</key>
+ <string>Camera focal length for DoF effect (in millimeters)</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>F32</string>
+ <key>Value</key>
+ <real>50</real>
+ </map>
+
+ <key>CameraCoC</key>
+ <map>
+ <key>Comment</key>
+ <string>Camera circle of confusion for DoF effect (in millimeters)</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>F32</string>
+ <key>Value</key>
+ <real>0.5</real>
+ </map>
+
+
+ <key>CertStore</key>
<map>
<key>Comment</key>
<string>Specifies the Certificate Store for certificate trust verification</string>
diff --git a/indra/newview/app_settings/shaders/class1/deferred/postDeferredF.glsl b/indra/newview/app_settings/shaders/class1/deferred/postDeferredF.glsl
index 03c2e63fb1..eec44d9d42 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/postDeferredF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/postDeferredF.glsl
@@ -17,6 +17,8 @@ uniform sampler2D bloomMap;
uniform float depth_cutoff;
uniform float norm_cutoff;
+uniform float near_focal_distance;
+uniform float far_focal_distance;
uniform mat4 inv_proj;
uniform vec2 screen_res;
@@ -32,55 +34,149 @@ float getDepth(vec2 pos_screen)
return p.z/p.w;
}
+void dofSample(inout vec4 diff, inout float w, float fd, float x, float y)
+{
+ vec2 tc = vary_fragcoord.xy+vec2(x,y);
+ float d = getDepth(tc);
+
+ if (d < fd)
+ {
+ diff += texture2DRect(diffuseRect, tc);
+ w += 1.0;
+ }
+}
+
+void dofSampleNear(inout vec4 diff, inout float w, float x, float y)
+{
+ vec2 tc = vary_fragcoord.xy+vec2(x,y);
+
+ diff += texture2DRect(diffuseRect, tc);
+ w += 1.0;
+}
+
void main()
{
vec3 norm = texture2DRect(normalMap, vary_fragcoord.xy).xyz;
norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm
- float depth = getDepth(vary_fragcoord.xy);
+
vec2 tc = vary_fragcoord.xy;
float sc = 0.75;
- vec2 de;
- de.x = (depth-getDepth(tc+vec2(sc, sc))) + (depth-getDepth(tc+vec2(-sc, -sc)));
- de.y = (depth-getDepth(tc+vec2(-sc, sc))) + (depth-getDepth(tc+vec2(sc, -sc)));
- de /= depth;
- de *= de;
- de = step(depth_cutoff, de);
-
- vec2 ne;
- vec3 nexnorm = texture2DRect(normalMap, tc+vec2(-sc,-sc)).rgb;
- nexnorm = vec3((nexnorm.xy-0.5)*2.0,nexnorm.z); // unpack norm
- ne.x = dot(nexnorm, norm);
- vec3 neynorm = texture2DRect(normalMap, tc+vec2(sc,sc)).rgb;
- neynorm = vec3((neynorm.xy-0.5)*2.0,neynorm.z); // unpack norm
- ne.y = dot(neynorm, norm);
-
- ne = 1.0-ne;
-
- ne = step(norm_cutoff, ne);
-
- float edge_weight = clamp(dot(de,de)+dot(ne,ne), 0.0, 1.0);
- //edge_weight *= 0.0;
-
- vec4 bloom = texture2D(bloomMap, vary_fragcoord.xy/screen_res);
+ float depth[5];
+ depth[0] = getDepth(tc);
+
vec4 diff = texture2DRect(diffuseRect, vary_fragcoord.xy);
- diff += texture2DRect(diffuseRect, vary_fragcoord.xy+vec2(1,1))*edge_weight;
- diff += texture2DRect(diffuseRect, vary_fragcoord.xy+vec2(-1,-1))*edge_weight;
- diff += texture2DRect(diffuseRect, vary_fragcoord.xy+vec2(-1,1))*edge_weight;
- diff += texture2DRect(diffuseRect, vary_fragcoord.xy+vec2(1,-1))*edge_weight;
- diff += texture2DRect(diffuseRect, vary_fragcoord.xy+vec2(-1,0))*edge_weight;
- diff += texture2DRect(diffuseRect, vary_fragcoord.xy+vec2(1,0))*edge_weight;
- diff += texture2DRect(diffuseRect, vary_fragcoord.xy+vec2(0,1))*edge_weight;
- diff += texture2DRect(diffuseRect, vary_fragcoord.xy+vec2(0,-1))*edge_weight;
-
- diff /= 1.0+edge_weight*8.0;
+ bool do_aa = true;
- vec4 blur = texture2DRect(edgeMap, vary_fragcoord.xy);
-
- //gl_FragColor = vec4(edge_weight,edge_weight,edge_weight, 1.0);
+ if (depth[0] < far_focal_distance)
+ { //pixel is behind far focal plane
+ float w = 1.0;
+
+ float fd = far_focal_distance;
+ float sc = clamp(depth[0]/fd, 0.0, -8.0/fd);
+ sc = min(sc, 8.0);
+
+ //fd = depth[0]*0.5;
+
+ while (sc > 1.0)
+ {
+ do_aa = false;
+ dofSample(diff,w, fd, sc,sc);
+ dofSample(diff,w, fd, -sc,sc);
+ dofSample(diff,w, fd, sc,-sc);
+ dofSample(diff,w, fd, -sc,-sc);
+
+ sc -= 0.5;
+ float sc2 = sc*1.414;
+ dofSample(diff,w, fd, 0,sc2);
+ dofSample(diff,w, fd, 0,-sc2);
+ dofSample(diff,w, fd, -sc2,0);
+ dofSample(diff,w, fd, sc2,0);
+ sc -= 0.5;
+ }
+ diff /= w;
+ }
+ else
+ {
+ float fd = near_focal_distance;
+
+ if (depth[0] > fd)
+ { //pixel is in front of near focal plane
+ //diff.r = 1.0;
+ float w = 1.0;
+ float sc = depth[0] - fd;
+ sc = min(-sc/fd*16.0, 8.0);
+
+ fd = depth[0];
+ while (sc > 1.0)
+ {
+ do_aa = false;
+ dofSampleNear(diff,w, sc,sc);
+ dofSampleNear(diff,w, -sc,sc);
+ dofSampleNear(diff,w, sc,-sc);
+ dofSampleNear(diff,w, -sc,-sc);
+
+ sc -= 0.5;
+ float sc2 = sc*1.414;
+ dofSampleNear(diff,w, 0,sc2);
+ dofSampleNear(diff,w, 0,-sc2);
+ dofSampleNear(diff,w, -sc2,0);
+ dofSampleNear(diff,w, sc2,0);
+ sc -= 0.5;
+ }
+ diff /= w;
+ }
+
+ if (do_aa)
+ {
+ depth[1] = getDepth(tc+vec2(sc,sc));
+ depth[2] = getDepth(tc+vec2(-sc,-sc));
+ depth[3] = getDepth(tc+vec2(-sc,sc));
+ depth[4] = getDepth(tc+vec2(sc, -sc));
+
+
+ vec2 de;
+ de.x = (depth[0]-depth[1]) + (depth[0]-depth[2]);
+ de.y = (depth[0]-depth[3]) + (depth[0]-depth[4]);
+ de /= depth[0];
+ de *= de;
+ de = step(depth_cutoff, de);
+
+ vec2 ne;
+ vec3 nexnorm = texture2DRect(normalMap, tc+vec2(-sc,-sc)).rgb;
+ nexnorm = vec3((nexnorm.xy-0.5)*2.0,nexnorm.z); // unpack norm
+ ne.x = dot(nexnorm, norm);
+ vec3 neynorm = texture2DRect(normalMap, tc+vec2(sc,sc)).rgb;
+ neynorm = vec3((neynorm.xy-0.5)*2.0,neynorm.z); // unpack norm
+ ne.y = dot(neynorm, norm);
+
+ ne = 1.0-ne;
+
+ ne = step(norm_cutoff, ne);
+
+ float edge_weight = clamp(dot(de,de)+dot(ne,ne), 0.0, 1.0);
+ //edge_weight *= 0.0;
+
+ //diff.r = edge_weight;
+
+ if (edge_weight > 0.0)
+ {
+ diff += texture2DRect(diffuseRect, vary_fragcoord.xy+vec2(1,1))*edge_weight;
+ diff += texture2DRect(diffuseRect, vary_fragcoord.xy+vec2(-1,-1))*edge_weight;
+ diff += texture2DRect(diffuseRect, vary_fragcoord.xy+vec2(-1,1))*edge_weight;
+ diff += texture2DRect(diffuseRect, vary_fragcoord.xy+vec2(1,-1))*edge_weight;
+ diff += texture2DRect(diffuseRect, vary_fragcoord.xy+vec2(-1,0))*edge_weight;
+ diff += texture2DRect(diffuseRect, vary_fragcoord.xy+vec2(1,0))*edge_weight;
+ diff += texture2DRect(diffuseRect, vary_fragcoord.xy+vec2(0,1))*edge_weight;
+ diff += texture2DRect(diffuseRect, vary_fragcoord.xy+vec2(0,-1))*edge_weight;
+ diff /= 1.0+edge_weight*8.0;
+ }
+ }
+ }
+
+ vec4 bloom = texture2D(bloomMap, vary_fragcoord.xy/screen_res);
gl_FragColor = diff + bloom;
- //gl_FragColor.r = edge_weight;
}
diff --git a/indra/newview/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp
index a2428d2de0..2519d0297c 100644
--- a/indra/newview/lldrawpoolalpha.cpp
+++ b/indra/newview/lldrawpoolalpha.cpp
@@ -103,16 +103,29 @@ void LLDrawPoolAlpha::renderDeferred(S32 pass)
S32 LLDrawPoolAlpha::getNumPostDeferredPasses()
{
- return 1;
+ return 2;
}
void LLDrawPoolAlpha::beginPostDeferredPass(S32 pass)
{
LLFastTimer t(FTM_RENDER_ALPHA);
- simple_shader = &gDeferredAlphaProgram;
- fullbright_shader = &gDeferredFullbrightProgram;
-
+ if (pass == 0)
+ {
+ simple_shader = &gDeferredAlphaProgram;
+ fullbright_shader = &gDeferredFullbrightProgram;
+ }
+ else
+ {
+ //update depth buffer sampler
+ gPipeline.mScreen.flush();
+ gPipeline.mDeferredDepth.copyContents(gPipeline.mDeferredScreen, 0, 0, gPipeline.mDeferredScreen.getWidth(), gPipeline.mDeferredScreen.getHeight(),
+ 0, 0, gPipeline.mDeferredDepth.getWidth(), gPipeline.mDeferredDepth.getHeight(), GL_DEPTH_BUFFER_BIT, GL_NEAREST);
+ gPipeline.mDeferredDepth.bindTarget();
+ simple_shader = NULL;
+ fullbright_shader = NULL;
+ }
+
deferred_render = TRUE;
if (mVertexShaderLevel > 0)
{
@@ -124,6 +137,8 @@ void LLDrawPoolAlpha::beginPostDeferredPass(S32 pass)
void LLDrawPoolAlpha::endPostDeferredPass(S32 pass)
{
+ gPipeline.mDeferredDepth.flush();
+ gPipeline.mScreen.bindTarget();
deferred_render = FALSE;
endRenderPass(pass);
}
@@ -174,7 +189,14 @@ void LLDrawPoolAlpha::render(S32 pass)
LLGLSPipelineAlpha gls_pipeline_alpha;
- gGL.setColorMask(true, true);
+ if (deferred_render && pass == 1)
+ { //depth only
+ gGL.setColorMask(false, false);
+ }
+ else
+ {
+ gGL.setColorMask(true, true);
+ }
if (LLPipeline::sAutoMaskAlphaNonDeferred && !deferred_render)
{
@@ -206,7 +228,13 @@ void LLDrawPoolAlpha::render(S32 pass)
gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT);
}
- LLGLDepthTest depth(GL_TRUE, LLDrawPoolWater::sSkipScreenCopy ? GL_TRUE : GL_FALSE);
+ LLGLDepthTest depth(GL_TRUE, LLDrawPoolWater::sSkipScreenCopy ||
+ (deferred_render && pass == 1) ? GL_TRUE : GL_FALSE);
+
+ if (deferred_render && pass == 1)
+ {
+ gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.33f);
+ }
mColorSFactor = LLRender::BF_SOURCE_ALPHA; // } regular alpha blend
mColorDFactor = LLRender::BF_ONE_MINUS_SOURCE_ALPHA; // }
@@ -218,6 +246,11 @@ void LLDrawPoolAlpha::render(S32 pass)
gGL.setColorMask(true, false);
+ if (deferred_render && pass == 1)
+ {
+ gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT);
+ }
+
if (deferred_render && current_shader != NULL)
{
gPipeline.unbindDeferredShader(*current_shader);
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index 972c9c255e..20d9f49a3e 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -3549,6 +3549,8 @@ LLViewerObject* LLViewerWindow::cursorIntersect(S32 mouse_x, S32 mouse_y, F32 de
LLVector3 mouse_world_start = mouse_point_global;
LLVector3 mouse_world_end = mouse_point_global + mouse_direction_global * depth;
+ //gDebugRaycastIntersection = mouse_world_end;
+
if (start)
{
*start = mouse_world_start;
@@ -3570,8 +3572,7 @@ LLViewerObject* LLViewerWindow::cursorIntersect(S32 mouse_x, S32 mouse_y, F32 de
{
found = this_object;
}
- }
-
+ }
else // is a world object
{
if (this_object->lineSegmentIntersect(mouse_world_start, mouse_world_end, this_face, pick_transparent,
@@ -3579,21 +3580,22 @@ LLViewerObject* LLViewerWindow::cursorIntersect(S32 mouse_x, S32 mouse_y, F32 de
{
found = this_object;
}
- }
- }
-
+ }
+ }
else // check ALL objects
- {
+ {
found = gPipeline.lineSegmentIntersectInHUD(mouse_hud_start, mouse_hud_end, pick_transparent,
face_hit, intersection, uv, normal, binormal);
if (!found) // if not found in HUD, look in world:
-
- {
+ {
found = gPipeline.lineSegmentIntersectInWorld(mouse_world_start, mouse_world_end, pick_transparent,
face_hit, intersection, uv, normal, binormal);
+ if (found)
+ {
+ gDebugRaycastIntersection = *intersection;
}
-
+ }
}
return found;
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index 4007d9d8f3..a189d17dc8 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -6253,14 +6253,71 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield)
{
shader = &gDeferredGIFinalProgram;
}
-
+
LLGLDisable blend(GL_BLEND);
bindDeferredShader(*shader);
+
+ //depth of field focal plane calculations
+
+ F32 subject_distance = 16.f;
+ if (LLViewerJoystick::getInstance()->getOverrideCamera())
+ {
+ //flycam mode, use mouse cursor as focus point
+ LLVector3 eye = LLViewerCamera::getInstance()->getOrigin();
+ subject_distance = (eye-gDebugRaycastIntersection).magVec();
+ }
+ else
+ {
+ LLViewerObject* obj = gAgentCamera.getFocusObject();
+ if (obj)
+ {
+ LLVector3 focus = LLVector3(gAgentCamera.getFocusGlobal()-gAgent.getRegion()->getOriginGlobal());
+ LLVector3 eye = LLViewerCamera::getInstance()->getOrigin();
+ subject_distance = (focus-eye).magVec();
+ }
+ }
+
+ //convert to mm
+ subject_distance *= 1000.f;
+ F32 fnumber = gSavedSettings.getF32("CameraFNumber");
+ F32 focal_length = gSavedSettings.getF32("CameraFocalLength");
+ F32 coc = gSavedSettings.getF32("CameraCoC");
+
+
+ F32 hyperfocal_distance = (focal_length*focal_length)/(fnumber*coc);
+
+ subject_distance = llmin(hyperfocal_distance, subject_distance);
+
+ //adjust focal length for subject distance
+ focal_length = llmax(focal_length, 1.f/(1.f/focal_length - 1.f/subject_distance));
+
+ //adjust focal length for zoom
+ F32 fov = LLViewerCamera::getInstance()->getView();
+ F32 default_fov = LLViewerCamera::getInstance()->getDefaultFOV();
+ focal_length *= default_fov/fov;
+
+ F32 near_focal_distance = hyperfocal_distance*subject_distance/(hyperfocal_distance+subject_distance);
+
+ //beyond far clip plane is effectively infinity
+ F32 far_focal_distance = 4096.f;
+
+ if (subject_distance < hyperfocal_distance)
+ {
+ far_focal_distance = hyperfocal_distance*subject_distance/(hyperfocal_distance-subject_distance);
+ far_focal_distance /= 1000.f;
+ }
+
+ near_focal_distance /= 1000.f;
+
+ shader->uniform1f("far_focal_distance", -far_focal_distance);
+ shader->uniform1f("near_focal_distance", -near_focal_distance);
+
S32 channel = shader->enableTexture(LLViewerShaderMgr::DEFERRED_DIFFUSE, LLTexUnit::TT_RECT_TEXTURE);
if (channel > -1)
{
mScreen.bindTexture(0, channel);
+ gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
}
gGL.begin(LLRender::TRIANGLE_STRIP);
@@ -6753,6 +6810,7 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index, LLRen
shader.uniform2f("proj_shadow_res", mShadow[4].getWidth(), mShadow[4].getHeight());
shader.uniform1f("depth_cutoff", gSavedSettings.getF32("RenderEdgeDepthCutoff"));
shader.uniform1f("norm_cutoff", gSavedSettings.getF32("RenderEdgeNormCutoff"));
+
if (shader.getUniformLocation("norm_mat") >= 0)
{