首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Crytek算法OpenGL

Crytek算法OpenGL
EN

Stack Overflow用户
提问于 2017-06-02 20:32:43
回答 1查看 773关注 0票数 1

我试图实现Crytek的屏幕空间环境遮挡算法的简单变体。

就我所理解的算法而言;

  1. 对于像素,p,在视图空间中的球体中p附近的示例。
  2. 将采样点sp投影到屏幕空间。
  3. 将采样点的深度与当前像素的深度进行比较。

基本上应该是这样的。如果采样点的深度较高(它位于几何学之外),则不排除当前像素(、p、)。

代码语言:javascript
复制
float z = gl_FragCoord.z; // depth-buffer value for the current pixel
int occluding_points = 0;
vec4 fPosition = model_transformation * vec4(position, 1.0f); // Really from vertex shader
#ifdef CRYTEK_AO
    const int NUM_SAMPLES = 10;
    float R = 3.0f;
    const float[10] steps = float[](0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.6f, 0.7f, 0.8f, 0.9f, 1.0f);
    for (int sample_id = 0; sample_id < NUM_SAMPLES; sample_id++) {
        // 1. Generate sample point in world space.
        float ang = steps[sample_id];
        vec4 sample_point = vec4(R * cos(2 * M_PI * ang) * sin(M_PI * ang) + fPosition.x,
                                 R * sin(2 * M_PI * ang) * sin(M_PI * ang) + fPosition.y,
                                 R * sin(M_PI * ang) + fPosition.z,
                                 1.0f);
        // 2. Transform sample point from view space to screen space to get its depth value.
        sample_point = projection * camera_view * sample_point; // Clip space
        sample_point = sample_point / sample_point.w;           // Perspective division - Normalized device coordinate
        float sample_depth = 0.5f * (sample_point.z + 1.0f);    // Viewport transform for z - window space

        // 3. Check whether sample_point is behind current pixel depth.
        if (sample_depth > z) { occluding_points++; }
    }
    occlusion_factor = occluding_points / float(NUM_SAMPLES);
    // Diffuse, specular components removed
    total_light += vec3(ambient_intensity) * (1.0f - occlusion_factor); // Ambient factor
    outColor = total_light;
#endif

下面是一张截图。由于某种原因,工件只在向下看z轴时才会出现,这样转换就会有一些可疑之处,尽管在渲染对象和照相机等时工作很好。

当看基本上任何其他角度,它看起来像你期望从设置遮挡因子为0.5 (这将使你在所有的颜色通道灰色)。

结果意外整数除法固定为浮点数除法。

增加了一个闪烁的这里

有什么线索吗?

编辑:用四舍五入检测到一个问题。编辑:当沿着z轴移动时,添加了一个视频链接到工件上.

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-06-02 20:50:57

你的代码有两个可疑的地方。

整数除法

代码语言:javascript
复制
occlusion_factor = occluding_points / NUM_SAMPLES;

只需将occluding_points类型更改为浮动,就可以了。

采样

代码语言:javascript
复制
    vec4 sample_point = vec4(R * cos(2 * M_PI * ang) * sin(M_PI * ang) + fPosition.x,
                             R * sin(2 * M_PI * ang) * sin(M_PI * ang) + fPosition.y,
                             R * sin(M_PI * ang) + fPosition.z,
                             1.0f);

这给你样本从相同的螺旋世界坐标每一次,所以在正确的表面,你将得到工件取决于观察角度。这就是我认为,当你向下看z轴的时候,当它和上面的四舍五入误差成对的时候。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/44337017

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档