gpt4 book ai didi

java - 用于流体模拟的双边滤波器

转载 作者:行者123 更新时间:2023-11-30 11:10:31 26 4
gpt4 key购买 nike

所以我有一个流体模拟,我正在尝试应用双边过滤器,以便在保留边缘的同时模糊表面。我的方法基于此演示文稿(特别是幻灯片 26)http://developer.download.nvidia.com/presentations/2010/gdc/Direct3D_Effects.pdf

我遇到的问题是根本没有保留我的边缘。即使我渲染出单个粒子,它也会被模糊,正如您在下图中看到的那样,模糊是不正确的。

此外,如 pdf 中所述,虽然分离双边过滤器通常是 Not Acceptable ,但在流体的情况下这样做是合理的,因为只有轻微的伪影。这就是下面两个 pass 的原因,但这不应该导致边缘模糊。

模糊着色器:

#version 400

in vec2 coord;

uniform sampler2D depthMap;
uniform vec2 screenSize;
uniform mat4 projection;
uniform vec2 blurDir;

const float filterRadius = 10;
const float blurScale = .1;
const float blurDepthFalloff = 1000;

void main() {
float depth = texture(depthMap, coord).x;

float sum = 0.0f;
float wsum = 0.0f;

for (float x = -filterRadius; x <= filterRadius; x += 1.0f) {
float s = texture(depthMap, coord + x*blurDir).x;

float r = x * blurScale;
float w = exp(-r*r);

float r2 = (s - depth) * blurDepthFalloff;
float g = exp(-r2*r2);

sum += s * w * g;
wsum += w * g;
}

if (wsum > 0.0f) {
sum /= wsum;
}

gl_FragDepth = sum;
}

绘图代码:

//--------------------Particle Blur-------------------------
{
glUseProgram(blurShader.program);

//Vertical blur
glBindFramebuffer(GL_FRAMEBUFFER, blurShader.fboV);
glDrawBuffer(GL_NONE);
glReadBuffer(GL_NONE);

glClear(GL_DEPTH_BUFFER_BIT);

blurShader.blurDepthVAO();

glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, depthShader.tex);
glUniform1i(blurShader.depthMap, 0);

RenderUtility.setVector2(blurShader, screenSize, "screenSize");
RenderUtility.setMatrix(blurShader, projection, "projection");
RenderUtility.setVector2(blurShader, new Vector2(0.0f, 1.0f / screenSize.y), "blurDir");

glEnable(GL_DEPTH_TEST);

glBindVertexArray(blurShader.vao);

glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

//Horizontal Blur
glBindFramebuffer(GL_FRAMEBUFFER, blurShader.fboH);
glDrawBuffer(GL_NONE);
glReadBuffer(GL_NONE);

glClear(GL_DEPTH_BUFFER_BIT);

glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, blurShader.texV);
glUniform1i(blurShader.depthMap, 0);

RenderUtility.setVector2(blurShader, screenSize, "screenSize");
RenderUtility.setMatrix(blurShader, projection, "projection");
RenderUtility.setVector2(blurShader, new Vector2(1.0f / screenSize.x, 0.0f), "blurDir");

glEnable(GL_DEPTH_TEST);

glBindVertexArray(blurShader.vao);

glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
}

当前状态图: Depth rendered out to the screen after applying blur

最佳答案

终于明白了。缺少的部分是深度大于 .9999(或其他最大深度数)的像素需要被丢弃,这样您就不会试图模糊不属于模拟的像素。回想起来很明显,但我花了很长时间才意识到。

因此正确的着色器如下所示:

uniform sampler2D depthMap;
uniform vec2 screenSize;
uniform mat4 projection;
uniform vec2 blurDir;

const float filterRadius = 10;
const float blurScale = .1;
const float blurDepthFalloff = 1000;

void main() {
float depth = texture(depthMap, coord).x;
if (depth == 1.0f) {
discard;
}

float sum = 0.0f;
float wsum = 0.0f;

for (float x = -filterRadius; x <= filterRadius; x += 1.0f) {
float s = texture(depthMap, coord + x*blurDir).x;

float r = x * blurScale;
float w = exp(-r*r);

float r2 = (s - depth) * blurDepthFalloff;
float g = exp(-r2*r2);

sum += s * w * g;
wsum += w * g;
}

if (wsum > 0.0f) {
sum /= wsum;
}

gl_FragDepth = sum;
}

关于java - 用于流体模拟的双边滤波器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27662477/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com