Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/150.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 当相机接近模型时,SSAO样本内核会导致性能下降?_C++_Opengl - Fatal编程技术网

C++ 当相机接近模型时,SSAO样本内核会导致性能下降?

C++ 当相机接近模型时,SSAO样本内核会导致性能下降?,c++,opengl,C++,Opengl,我有一个问题,当相机靠近模型时,性能会下降 我发现ssao示例内核是要做的,但我似乎无法理解为什么这些内核在接近网格时会导致性能问题 当我注释掉ssao渲染代码中的samples for循环时,性能又回到了应该的状态,所以这个for循环显然是导致问题的原因。我最初认为这可能是一个着色器问题,但我也找不到任何问题 有什么想法吗?以下是您需要的所有代码 SSAO设置代码 // Create two frame buffers, one for ssao colour and another for

我有一个问题,当相机靠近模型时,性能会下降

我发现ssao示例内核是要做的,但我似乎无法理解为什么这些内核在接近网格时会导致性能问题

当我注释掉ssao渲染代码中的samples for循环时,性能又回到了应该的状态,所以这个for循环显然是导致问题的原因。我最初认为这可能是一个着色器问题,但我也找不到任何问题

有什么想法吗?以下是您需要的所有代码

SSAO设置代码

// Create two frame buffers, one for ssao colour and another for ssao blur
_fbos.push_back(new Fbo(width, height, { new FboAttachment(width, height, GL_RED, GL_RGB, GL_FLOAT, GL_COLOR_ATTACHMENT0) }, false));
_fbos.push_back(new Fbo(width, height, { new FboAttachment(width, height, GL_RED, GL_RGB, GL_FLOAT, GL_COLOR_ATTACHMENT0) }, false));
//////////////////////////////////////////////////////////////////////////////////////////////////////////

std::uniform_real_distribution<GLfloat> rand_floats(0.0f, 1.0f);    // Generate random floats between 0.0 and 1.0
std::default_random_engine rand_generator;  // A generator for randomising floats

// Create temp iterator var
for (unsigned int i = 0; i < 64; ++i)   // Iterate through each sample...
{
    glm::vec3 sample(rand_floats(rand_generator) * 2.0f - 1.0f, rand_floats(rand_generator) * 2.0f - 1.0f, rand_floats(rand_generator)); // the third parameter was wrong on this line

    sample = glm::normalize(sample);    // Normalise the sample
    sample *= rand_floats(rand_generator);  // Seed the randomisation

    float scale = static_cast<float>(i) / 64.0f;    // Get pixel position in NDC about the resolution size

    scale = Math::lerpf(0.1f, 1.0f, scale * scale);     // Interpolate the scale
    sample *= scale;    // Scale the s and t values

    _ssao_kernals.push_back(sample);    // Assign sample to the kernal array

    _u_samples.push_back(glGetUniformLocation(shader_programs[0], ("samples[" + std::to_string(i) + "]").c_str()));     // Get each sample uniform location
}

for (unsigned int i = 0; i < 16; i++)       // For each sample / 4...
{
    glm::vec3 noise(rand_floats(rand_generator) * 2.0f - 1.0f, rand_floats(rand_generator) * 2.0f - 1.0f, 0.0f);    // Randomly generate a noise pixel
    _ssao_noise.push_back(noise);   // Assign noise pixel to noise array
}

/*
* Create a noise texture to remove any banding from the ssao
*/
glGenTextures(1, &_noise_texture); // generate the texture
glBindTexture(GL_TEXTURE_2D, _noise_texture); // bind data
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32F, 4, 4, 0, GL_RGB, GL_FLOAT, &_ssao_noise[0]); // set texture data
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); // texture filtering
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); // texture filtering
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); // texture filtering 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); // texture filtering
//创建两个帧缓冲区,一个用于ssao颜色,另一个用于ssao模糊
_fbos.push_back(新Fbo(宽度,高度,{新FboAttachment(宽度,高度,GL_红色,GL_RGB,GL_浮动,GL_颜色_附件0)),false);
_fbos.push_back(新Fbo(宽度,高度,{新FboAttachment(宽度,高度,GL_红色,GL_RGB,GL_浮动,GL_颜色_附件0)),false);
//////////////////////////////////////////////////////////////////////////////////////////////////////////
标准::均匀实分布随机浮动(0.0f,1.0f);//生成介于0.0和1.0之间的随机浮点
std::默认随机引擎和生成器;//用于随机浮动的生成器
//创建临时迭代器变量
for(unsigned int i=0;i<64;++i)//遍历每个样本。。。
{
glm::vec3示例(随机浮点数(随机生成器)*2.0f-1.0f,随机浮点数(随机生成器)*2.0f-1.0f,随机浮点数(随机生成器));//此行的第三个参数错误
sample=glm::normalize(sample);//使样本正常化
sample*=rand_floats(rand_生成器);//为随机化设定种子
float scale=static_cast(i)/64.0f;//获取NDC中关于分辨率大小的像素位置
scale=Math::lerpf(0.1f,1.0f,scale*scale);//插值比例
sample*=scale;//缩放s和t值
_ssao_内核。push_back(sample);//将sample分配给内核数组
_u_samples.push_back(glGetUniformLocation(着色器程序[0],(“samples[“+std::to_string(i)+“])));//获取每个样本的统一位置
}
for(unsigned int i=0;i<16;i++)//对于每个样本/4。。。
{
glm::vec3噪波(随机浮点数(随机生成器)*2.0f-1.0f,随机浮点数(随机生成器)*2.0f-1.0f,0.0f);//随机生成一个噪波像素
_ssao_noise.push_back(noise);//将noise像素指定给noise数组
}
/*
*创建噪波纹理以删除ssao中的任何带状
*/
glGenTextures(1,&_noise_texture);//生成纹理
glBindTexture(GL_纹理_2D,_噪波_纹理);//绑定数据
glTexImage2D(GL_纹理2D,0,GL_RGB32F,4,4,0,GL_RGB,GL_浮点,和_ssao_噪波[0]);//设置纹理数据
glTexParameteri(GL_纹理_2D,GL_纹理_最小_过滤器,GL_最近);//纹理过滤
glTexParameteri(GL_纹理_2D,GL_纹理_贴图过滤器,GL_最近);//纹理过滤
glTexParameteri(GL_纹理_2D,GL_纹理_包裹,GL_重复);//纹理过滤
glTexParameteri(GL_纹理_2D,GL_纹理_包裹,GL_重复);//纹理过滤
SSAO渲染功能

\u fbos[0]->Bind();//绑定ssao纹理
glClear(GL_颜色_缓冲区_位);//在屏幕上清除颜色数据
glUseProgram(_shader_programs[0]);//使用第一个着色器过程
for(unsigned int i=0;iGetCamera()->GetProjectionMatrix());//指定摄影机投影均匀数据
玻璃纹理(GL_纹理0);//将活动纹理设置为索引0
glBindTexture(GL_TEXTURE_2D,_g_buffer_data->GetAttachments()[0]->_TEXTURE);//绑定位置
玻璃纹理(GL_纹理1);//将活动纹理设置为索引1
glBindTexture(GL_TEXTURE_2D,_g_buffer_data->GetAttachments()[1]->_TEXTURE);//绑定法线
玻璃纹理(GL_纹理2);//将活动纹理设置为索引2
glBindTexture(GL_纹理_2D,_噪波_纹理);//绑定噪波纹理
_屏幕校正->渲染(1);//渲染到屏幕矩形
//模糊ssao纹理
_fbos[1]->Bind();
glClear(GLU颜色缓冲位);
glUseProgram(_shader_programs[1]);//使用第二个着色器过程
玻璃纹理(GL_纹理0);//将活动纹理绑定到索引0
glBindTexture(GL_纹理_2D,_fbos[0]->GetAttachments()[0]->_纹理);//定色
_屏幕校正->渲染(1);//渲染到屏幕矩形
SSAO片段着色器

#版本330核心
外浮彩色;
在vec2_texcoord;
均匀采样二维定位;
一致性;
均匀采样噪声;
均匀vec3样品[64];
int-kernelSize=64;
浮动半径=0.3;
浮动偏差=0.025;
const vec2 noiseScale=vec2(1920.0/4.0、1080.0/4.0);
统一mat4项目;
void main()
{
vec3 fragPos=纹理(gPosition,_texcoord).xyz;
vec3 normal=normalize(纹理(gNormal,_texcoord).rgb);
vec3 randomVec=规格化(纹理(texNoise,_texcoord*noiseScale).xyz);
vec3切线=规格化(随机向量-法线*点(随机向量,法线));
vec3双切线=交叉(法线、切线);
mat3 TBN=mat3(切线、双切线、法线);
浮动闭塞=0.0;
for(int i=0;i_fbos[0]->Bind(); // bind ssao texture

        glClear(GL_COLOR_BUFFER_BIT); // clear colour data on the screen

        glUseProgram(_shader_programs[0]); // Use the first shader pass

        for (unsigned int i = 0; i < SSAO_SAMPLE_RESOLUTION; ++i)   // For each ssao sample...
            glUniform3fv(_u_samples[i], 1, glm::value_ptr(_ssao_kernals[i]));   // Assign kernal uniform data

        glUniformMatrix4fv(_u_projection, 1, GL_FALSE, glm::value_ptr(Content::_map->GetCamera()->GetProjectionMatrix()));  // Assign camera projection uniform data

        glActiveTexture(GL_TEXTURE0);   // Set active texture to index 0
        glBindTexture(GL_TEXTURE_2D, _g_buffer_data->GetAttachments()[0]->_texture);    // Bind positions
        glActiveTexture(GL_TEXTURE1);   // Set active texture to index 1
        glBindTexture(GL_TEXTURE_2D, _g_buffer_data->GetAttachments()[1]->_texture);    // Bind normals
        glActiveTexture(GL_TEXTURE2);   // Set active texture to index 2
        glBindTexture(GL_TEXTURE_2D, _noise_texture);   // Bind the noise texture

        _screen_rect->Render(1);        // Render to screen rectangle

        // Blur ssao texture
        _fbos[1]->Bind();

        glClear(GL_COLOR_BUFFER_BIT);

        glUseProgram(_shader_programs[1]);  // Use the second shader pass

        glActiveTexture(GL_TEXTURE0);   // Bind active texture to index 0
        glBindTexture(GL_TEXTURE_2D, _fbos[0]->GetAttachments()[0]->_texture);  // Bind the final colour

        _screen_rect->Render(1);        // Render to screen rectangle
#version 330 core

out float FragColor;

in vec2 _texcoord;

uniform sampler2D gPosition;
uniform sampler2D gNormal;
uniform sampler2D texNoise;

uniform vec3 samples[64];

int kernelSize = 64;
float radius = 0.3;
float bias = 0.025;

const vec2 noiseScale = vec2(1920.0 / 4.0, 1080.0 / 4.0); 

uniform mat4 proj;

void main()
{
    vec3 fragPos = texture(gPosition, _texcoord).xyz;
    vec3 normal = normalize(texture(gNormal, _texcoord).rgb);
    vec3 randomVec = normalize(texture(texNoise, _texcoord * noiseScale).xyz);

    vec3 tangent = normalize(randomVec - normal * dot(randomVec, normal));
    vec3 bitangent = cross(normal, tangent);
    mat3 TBN = mat3(tangent, bitangent, normal);

    float occlusion = 0.0;
    for(int i = 0; i < kernelSize; ++i)
    {
        // get sample position
        vec3 sample = TBN * samples[i]; // from tangent to view-space
        sample = fragPos + sample * radius; 

        // project sample position (to sample texture) (to get position on screen/texture)
        vec4 offset = vec4(sample, 1.0);
        offset = proj * offset; // from view to clip-space
        offset.xyz /= offset.w; // perspective divide
        offset.xyz = offset.xyz * 0.5 + 0.5; // transform to range 0.0 - 1.0

        // get sample depth
        float sampleDepth = texture(gPosition, offset.xy).z; // get depth value of kernel sample

        // range check & accumulate
        float rangeCheck = smoothstep(0.0, 1.0, radius / abs(fragPos.z - sampleDepth));
        occlusion += (sampleDepth >= sample.z + bias ? 1.0 : 0.0) * rangeCheck;           
    }

    occlusion = 1.0 - (occlusion / kernelSize);  
    FragColor = pow(occlusion, 3.0);
}