我尝试基于此处的R5演示实现屏幕空间环境光遮挡(SSAO):http://blog.nextrevision.com/?p = 76
事实上,我尝试调整他们的SSAO - 线性着色器以适应我自己的小引擎.
1)我计算View Space曲面法线和线性深度值. 我使用以下着色器将它们存储在RGBA纹理中:
顶点:
varNormalVS = normalize(vec3(vmtInvTranspMatrix * vertexNormal));
depth = (modelViewMatrix * vertexPosition).z;
depth = (-depth-nearPlane)/(farPlane-nearPlane);
gl_Position = pvmtMatrix * vertexPosition;
Run Code Online (Sandbox Code Playgroud)
分段:
gl_FragColor = vec4(varNormalVS.x,varNormalVS.y,varNormalVS.z,depth)
Run Code Online (Sandbox Code Playgroud)
对于我的线性深度计算,我提到:http://www.gamerendering.com/2008/09/28/linear-depth-texture/
这是对的吗?纹理似乎是正确的,但也许不是吗?

2)实际的SSAO实施: 如上所述,原文可以在这里找到:http://blog.nextrevision.com/?p = 76
或更快:在pastebin http://pastebin.com/KaGEYexK上
与原始相比,我只使用2个输入纹理,因为我的一个纹理存储了两个,法线为RGB和线性Depht als Alpha.
我的第二个纹理,即随机正常纹理,如下所示:http: //www.gamerendering.com/wp-content/uploads/noise.png
我使用几乎完全相同的实现,但我的结果是错误的.
在详细介绍之前,我想首先澄清一些问题:
1)ssao着色器使用projectionMatrix和它的逆矩阵.
由于它是通过正投影渲染到对准四边形的屏幕上的后处理效果,因此投影矩阵是正交矩阵.正确还是错?
2)具有组合的法线和深度纹理而不是两个单独的纹理.
在我看来,这是R5实现和我的实现尝试之间的最大区别.我认为这不应该是一个大问题,但是,由于不同的深度纹理,这最有可能导致问题.
请注意,R5_clipRange看起来像这样
vec4 R5_clipRange = vec4(nearPlane, farPlane, nearPlane * farPlane, farPlane - nearPlane);
Run Code Online (Sandbox Code Playgroud)
原版的:
float GetDistance (in vec2 …Run Code Online (Sandbox Code Playgroud) 我坚持这个问题,一直在研究它,并研究它几个小时.
我正在尝试渲染我的场景,使用EffectComposer,这样我的背景对象就没有SSAO(在我的真实项目中,它是一个程序城市)和我的前景对象(在我的真实项目中我想要调用的两个建筑物) out和有不同的材料)有SSAO.
正如您在下面的小提琴中看到的那样,蓝色立方体(它是bg场景的一部分)由红色立方体的SSAO渲染(在FG场景中)覆盖.显然,这种效果是不可取的.
如何让它正常工作?
谢谢!
-亚当
http://jsfiddle.net/Lbddvnsp/1/
var renderTargetParameters, renderTarget, renderBackground, renderModel, clearMask, renderMask, depthMaterial, depthTarget, composer;
var container, camera, bgScene, fgScene, renderer;
init();
initSSAO();
addObjects();
animate();
function initSSAO() {
// Depth
var depthShader = THREE.ShaderLib[ "depthRGBA" ];
var depthUniforms = THREE.UniformsUtils.clone( depthShader.uniforms );
depthMaterial = new THREE.ShaderMaterial( { fragmentShader: depthShader.fragmentShader, vertexShader: depthShader.vertexShader, uniforms: depthUniforms } );
depthMaterial.blending = THREE.NoBlending;
// Post-processing
// create a custom render target with a stencil buffer
// the stencil buffer allows for masking …Run Code Online (Sandbox Code Playgroud) 我一直在尝试按照本教程的指示实现屏幕空间环境光遮挡.我一直在解决我的实施问题,因为我遇到过它们,但这一次让我感到难过.
我对该方法的理解如下.环境遮挡因子由从与给定片段的法线对齐的半球内取得的样本确定.为了确定样本是否有助于环境遮挡因子,我必须根据视图空间深度纹理(包含在此帖子图像的左下角)检查视图空间中的样本深度.所以我知道从深度纹理中取出哪些坐标,我必须将样本的坐标从视图空间转换为规范化设备坐标(在[-1,1]范围内),然后转换到范围[0 ,1],因此深度纹理有效地"映射"到视口.
下面的图像是我的场景中的环境遮挡.我知道环境遮挡本身有一个相当明显的问题(我假设半球的方向不正确),我会及时处理,但是目前我的好奇心是"闭塞"的外观是什么',表明我从视空间样本坐标移动到纹理坐标的操作是不正确的.

由于我缺少一个稳定的着色器调试器,我可以做的调试仅限于我可以渲染到屏幕上的内容.使用以下代码创建下一个图像,其中ndcs是给定样本的规范化设备坐标:
if (ndcs.x > 1.0f || ndcs.y > 1.0f || ndcs.x < -1.0f || ndcs.y < -1.0f)
{
gl_FragColor = vec4(1.0f, 0.0f, 0.0f, 1.0f);
}
else
{
gl_FragColor = vec4(vec3(1.0f), 1.0f);
}
Run Code Online (Sandbox Code Playgroud)

我希望图像完全是白色的(或者更确切地说,我正在使用这个着色器的位),但是它似乎表明我正在创建的NDC在[-1,1]范围之外,我相信一定是不正确的.它也不是屏幕的一致区域,如下图所示,相机非常接近表面:

我以前从未使用过这个程序来获取NDC,所以我确信我的逻辑在某处肯定是错的.我已经下载了教程提供的演示代码,但我无法看到代码的不同之处.我也在网上搜索过(包括在这个网站上)我似乎无法找到任何与我自己症状相同的人.
这是我的着色器的相关代码:
Vert Shader:
v_eye_space_position = u_mvpMatrix * a_position;
v_world_space_normal = normalize(u_rotationMatrix * a_normal);
v_eye_space_normal = normalize(u_mvpMatrix * a_normal);
gl_Position = v_eye_space_position;
Run Code Online (Sandbox Code Playgroud)
Frag Shader:
// --- SSAO Testing ---
// Convert from the noise texture back to [-1,1] range …Run Code Online (Sandbox Code Playgroud) 我按照学习 OpenGL中的教程来实现屏幕空间环境光遮挡。除了窗口顶部和底部有一个奇怪的工件之外,一切看起来都还不错。
当图像的顶部部分印在底部时,移动相机时问题会更加明显,反之亦然,如该视频所示。
当靠近墙壁站立并上下观察时,伪像会变得更糟,所以也许 Znear 值有所贡献?与其他演示相比,我的场景规模似乎很小,Znear 和 Zfar 为0.01f,1000并且所示走廊的宽度约为1.2f。
我已经阅读了常见的 SSAO 工件,但没有发现任何类似的内容。
#version 330 core
in vec2 TexCoords;
layout (location = 0) out vec3 FragColor;
uniform sampler2D MyTexture0; // Position
uniform sampler2D MyTexture1; // Normal
uniform sampler2D MyTexture2; // TexNoise
const int samples = 64;
const float radius = 0.25;
const float bias = 0.025;
uniform mat4 projectionMatrix;
uniform float screenWidth;
uniform float screenHeight;
void main()
{
//tile noise texture over …Run Code Online (Sandbox Code Playgroud) 我正在尝试使用SSAO后处理着色器渲染场景.没有任何错误,但我看不到使用和不使用SSAO传递渲染的场景之间的任何差异.我像这样初始化渲染器:
// Create WebGL Renderer
var renderParameters = { antialias: false, alpha: false, clearColor: 0xFFFFFF };
renderer = new THREE.WebGLRenderer(renderParameters);
renderer.autoClear = false;
renderer.setSize(viewportWidth, viewportHeight);
// Create render targets
renderTargetParametersRGB = { minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter, format: THREE.RGBFormat };
renderTargetParametersRGBA = { minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter, format: THREE.RGBAFormat };
depthTarget = new THREE.WebGLRenderTarget(width, height, renderTargetParametersRGBA);
colorTarget = new THREE.WebGLRenderTarget(width, height, renderTargetParametersRGB);
// The shader pass to draw the scene
var renderScenePass = new THREE.RenderPass(scene, camera);
// Copy to screen render …Run Code Online (Sandbox Code Playgroud) 我正在使用Oriented-Hemisphere渲染技术研究SSAO(屏幕空间环境遮挡)算法.
I)算法
该算法需要输入:
这是我使用的片段着色器源代码:
#version 400
/*
** Output color value.
*/
layout (location = 0) out vec4 FragColor;
/*
** Vertex inputs.
*/
in VertexData_VS
{
vec2 TexCoords;
} VertexData_IN;
/*
** Inverse Projection Matrix.
*/
uniform mat4 ProjMatrix;
/*
** GBuffer samplers.
*/
uniform sampler2D PositionSampler;
uniform sampler2D NormalSampler;
/*
** Noise sampler.
*/
uniform sampler2D NoiseSampler;
/*
** Noise texture viewport.
*/
uniform vec2 NoiseTexOffset;
/* …Run Code Online (Sandbox Code Playgroud)