QT With OpenGL(延时着色法)(Deferred Shading)

2023-10-27

1.创建G-Buffer帧缓存

//G-Buffer
    //  位置
    G_Buffer = new QOpenGLFramebufferObject(size(),QOpenGLFramebufferObject::CombinedDepthStencil,GL_TEXTURE_2D,GL_RGBA16F);
    //  法向量
    G_Buffer->addColorAttachment(size(),GL_RGBA);
    //  颜色(HDR)+镜面颜色
    G_Buffer->addColorAttachment(size(),GL_RGBA16F);
    //  高光图(只计算光源物体)
    G_Buffer->addColorAttachment(size(),GL_RGBA16F);
    //  设置着色器渲染纹理路径
    G_Buffer->bind();
    GLenum buffers2[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2 };
    core->glDrawBuffers(3, buffers2);
    G_Buffer->release();

2.修改各类型物体的着色器

vert不用变

#version 450 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aNormal;
layout (location = 2) in vec2 aTexCoords;

out vec3 Normal;
out vec3 FragPos;
out vec2 TexCoords;

uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;

void main()
{
        Normal = mat3(transpose(inverse(model))) * aNormal;
        TexCoords = aTexCoords;
        FragPos = vec3(model * vec4(aPos,1.0));
        gl_Position = projection * view * model * vec4(aPos,1.0);
}

frag去除光照部分

#version 450 core

//输出
layout (location = 0) out vec3 gPosition;
layout (location = 1) out vec3 gNormal;
layout (location = 2) out vec4 gAlbedoSpec;
layout (location = 3) out vec4 BrightColor;

struct Material {
    vec3 color;
    //float shiness;
};


//顶点信息
in vec3 Normal;
in vec3 FragPos;
in vec2 TexCoords;

uniform Material material;
uniform bool islight;


void main()
{
    // 存储第一个G缓冲纹理中的片段位置向量
    gPosition = FragPos;
    // 同样存储对每个逐片段法线到G缓冲中
    gNormal = normalize(Normal);
    // 和漫反射对每个逐片段颜色
    gAlbedoSpec.rgb = material.color;
    // 存储镜面强度到gAlbedoSpec的alpha分量
    gAlbedoSpec.a = 0.3;

    // 高光项存储在BrightColor
    if(islight){
        BrightColor = vec4(material.color, 1.0);
    }
    else BrightColor = vec4(0,0,0, 1.0);

}

3. 测试G_Buffer

    glViewport(0,height()/2,width()/2,height()/2);
    showShadow(G_Buffer->textures().at(0));
    glViewport(width()/2,height()/2,width()/2,height()/2);
    showShadow(G_Buffer->textures().at(1));
    glViewport(0,0,width()/2,height()/2);
    showShadow(G_Buffer->textures().at(2));
    glViewport(width()/2,0,width()/2,height()/2);
    showShadow(G_Buffer->textures().at(3));
    return;

在这里插入图片描述
gPosition = FragPos;改为 gPosition = FragPos/(FragPos+vec3(100,100,100)); 获得更好的视觉效果
在这里插入图片描述

4. 使用G_Buffer生成场景

着色器frag:

#version 450 core

//输出
layout (location = 0) out vec4 FragColor;
in vec2 TexCoords;

struct DirLight {
    bool Activated;
    vec3 direction;

    vec3 ambient;
    vec3 diffuse;
    vec3 specular;
    //阴影
    sampler2D shadowMap;
    mat4 lightSpaceMatrix;

};

struct PointLight {
    vec3 position;
    vec3 lightnormal;

    vec3 ambient;
    vec3 diffuse;
    vec3 specular;

    float constant;
    float linear;
    float quadratic;

    //阴影
    sampler2D shadowMap;
    mat4 lightSpaceMatrix;
    float width;
};

//视点
uniform vec3 viewPos;
//平行光
uniform DirLight dirLight;

//点光源
uniform PointLight pointLights[16];
uniform int numPointLights;

//材质
uniform float shiness;

//传入参数
uniform sampler2D gPosition;
uniform sampler2D gNormal;
uniform sampler2D gAlbedoSpec;
//光照
uniform bool blinn;
//色调映射
uniform float toneMapping;
//gamma
uniform bool gamma;


//输入信息
vec3 Normal;
vec3 FragPos;
vec3 diffusecolor;
vec3 specularcolor;


//常量
const float PI = 3.141592653589793;
const float PI2 = 6.283185307179586;
float near_plane = 0.5f;
float far_plane = 100.5f;

//采样数
const int NUM_SAMPLES = 30;

//采样圈数
const int NUM_RINGS = 10;

//函数申明
vec3 CalcDirLight(DirLight light, vec3 normal, vec3 viewDir);
vec3 CalcPointLight(PointLight light,vec3 normal, vec3 fragPos,vec3 viewDir);
float PCF(vec3 projCoords,int r,sampler2D shadowMap);
float PCSS(vec3 projCoords,sampler2D shadowMap,float weightOfLight);
float averageBlockDep(vec3 projCoords,vec2 texelSize,sampler2D shadowMap);
void poissonDiskSamples(const in vec2 randomSeed);


float LinearizeDepth(float depth)
{
    float z = depth * 2.0 - 1.0; // Back to NDC
    return (2.0 * near_plane * far_plane) / (far_plane + near_plane - z * (far_plane - near_plane))/far_plane;
}

//全局参数
vec2 poissonDisk[NUM_SAMPLES];

highp float rand_2to1(vec2 uv ) {//传入一个二维数,传出一个假随机数。
    // 0 - 1
    const highp float a = 12.9898, b = 78.233, c = 43758.5453;
    highp float dt = dot( uv.xy, vec2( a,b ) );
    highp float sn = mod( dt, PI );
    return fract(sin(sn) * c);//只取小数部分(取值范围0~1,若为负+1)
}

void poissonDiskSamples(const in vec2 randomSeed){
    float ANGLE_STEP = PI2 * float(NUM_RINGS)/float( NUM_SAMPLES);//角位移大小
    float INV_NUM_SAMPLES = 1.0 / float(NUM_SAMPLES); //采样数的倒数

    float angle = rand_2to1(randomSeed) * PI2;//初始角度(弧度)
    float radius = INV_NUM_SAMPLES;//初始半径
    float radiusStep = radius;     //半径增量

    for( int i = 0; i < NUM_SAMPLES; i ++ ) {
      poissonDisk[i] = vec2( cos( angle ), sin( angle ) ) * pow( radius, 0.75 );
      radius += radiusStep;//半径增加
      angle += ANGLE_STEP;//弧度增加
    }
}

void main()
{
       //FragColor = vec4(1,1,1,0);
       //return ;
        //获取G—Buffer信息
       Normal = texture2D(gNormal,TexCoords).rgb;
       FragPos = texture2D(gPosition,TexCoords).rgb;
       diffusecolor = texture2D(gAlbedoSpec,TexCoords).rgb;
       specularcolor = diffusecolor * texture2D(gAlbedoSpec,TexCoords).a;

       //反gamma矫正
       diffusecolor = pow(diffusecolor, vec3(2.2));
       specularcolor = pow(specularcolor , vec3(2.2));

       // 属性
       vec3 norm = normalize(Normal);
       vec3 viewDir = normalize(viewPos - FragPos);
       vec3 result = vec3(0,0,0);
       // 平行光
       if(dirLight.Activated){
            result += CalcDirLight(dirLight, norm, viewDir);
       }
       // 点光源
       for(int i = 0; i < numPointLights; i++){
            result += CalcPointLight(pointLights[i], norm, FragPos, viewDir);
       }
       //色调映射
       if(toneMapping>0.0f){
           //result.rgb = result.rgb /(result.rgb+ vec3(1.0));
           result.rgb = vec3(1.0) - exp(-result.rgb * toneMapping);
       }


       //gamma矫正
       float gamma_ = 2.2;
       if(gamma){
           result.rgb = pow(result.rgb, vec3(1.0/gamma_));
       }

       FragColor = vec4(result,1.0);

//       //检查该像素亮度是否高于阈值
//       float brightness = dot(FragColor.rgb, vec3(0.2126, 0.7152, 0.0722));
//       //if(brightness > 1.0) BrightColor = vec4(FragColor.rgb, 1.0);
//       //else
//       BrightColor = vec4(0,0,0, 1.0);
//       //BrightColor = vec4(1.0,1.0,1.0, 1.0);
}

float averageBlockDep(vec3 projCoords,vec2 texelSize,sampler2D shadowMap){
    float blockerZ = 0.0;//遮挡物总深度
    int count = 0;
    int r=5;

    poissonDiskSamples(projCoords.xy+vec2(0.1314,0.351));
    for(int i=0;i<NUM_SAMPLES;++i){
        float depth = texture(shadowMap, projCoords.xy + r * poissonDisk[i] * texelSize).r;
        if(depth < projCoords.z){//如果为遮挡物
            count++;
            blockerZ +=depth;
        }
    }


    if(count == 0||count==(r*2+1)*(r*2+1))return 1.0f;
    return blockerZ / count;
}

float PCSS(vec3 projCoords,sampler2D shadowMap,float weightOfLight){

    // 取得最近点的深度(使用[0,1]范围下的fragPosLight当坐标)
    float closestDepth = texture(shadowMap, projCoords.xy).r;
    // 取得当前片段在光源视角下的深度
    float currentDepth = projCoords.z;
    // 检查当前片段是否在阴影中
    //float bias = max(0.05 * (1.0 - dot(Normal, -dirLight.direction)), 0.005);
    //每像素偏移距离
    vec2 texelSize = 1.0 / textureSize(shadowMap, 0);

    //PCSS核心算法
    float visibility = 0.0;
    //第一步计算平均遮挡物深度
    float averBlocker = averageBlockDep(projCoords,texelSize,shadowMap);
    //第二步,计算半影半径
    float penumbra = (projCoords.z - averBlocker) * weightOfLight / averBlocker;
    //第三步 PCF
    visibility = PCF(projCoords,int(penumbra),shadowMap);

    return visibility;
}

float PCF(vec3 projCoords,int r,sampler2D shadowMap)
{
    // 取得最近点的深度(使用[0,1]范围下的fragPosLight当坐标)
    float closestDepth = texture(shadowMap, projCoords.xy).r;
    // 取得当前片段在光源视角下的深度
    float currentDepth = projCoords.z;
    // 检查当前片段是否在阴影中
    float bias = max(0.05 * (1.0 - dot(Normal, -dirLight.direction)), 0.005);

    //PCF
    float shadow = 0.0;
    vec2 texelSize = 1.0 / textureSize(shadowMap, 0);//每像素偏移距离

    poissonDiskSamples(projCoords.xy);
    for(int i=0;i<NUM_SAMPLES;i++){
        float pcfDepth = texture(shadowMap, projCoords.xy + r * poissonDisk[i] * texelSize).r;
        shadow += currentDepth - bias > pcfDepth ? 1.0 : 0.0;
    }
    shadow /= float(NUM_SAMPLES);

    //远平面矫正
    if(projCoords.z > 1.0) shadow = 0.0;

    return shadow;
}

//计算平行光源
vec3 CalcDirLight(DirLight light, vec3 normal, vec3 viewDir){
        vec3 lightDir = normalize(-light.direction);//平行光反方向
        float diff = max(dot(lightDir,normal),0.0);//cos衰减系数
        float spec = 0.0;//反射系数
        if(blinn){
            vec3 halfwayDir = normalize(viewDir+lightDir);//半程向量
            spec = pow(max(dot(normal,halfwayDir),0.0),shiness*4);
        }
        else{
            vec3 reflectDir = reflect(-lightDir,normal); //反射方向
            spec = pow(max(dot(viewDir,reflectDir),0.0),shiness);//计算镜面反射系数
        }

        vec3 ambient = light.ambient * diffusecolor;
        vec3 diffuse = light.diffuse * diff * diffusecolor;
        vec3 specular = light.specular * spec * specularcolor;

        //阴影计算
        float shadow = 0.0;
        {
            //光视角的点位置
            vec4 FragPosLightSpace = light.lightSpaceMatrix * vec4(FragPos, 1.0);
            // 执行透视除法
            vec3 projCoords = FragPosLightSpace.xyz / FragPosLightSpace.w;
            // 变换到[0,1]的范围
            projCoords = projCoords * 0.5 + 0.5;
            // 计算阴影
            shadow = PCSS(projCoords,light.shadowMap,5);
            //shadow = PCF(projCoords,1,light.shadowMap);
        }

        vec3 lighting = (ambient + (1.0 - shadow) * (diffuse + specular));
        return lighting;
}

vec3 CalcPointLight(PointLight light,vec3 normal, vec3 fragPos,vec3 viewDir){
        vec3 lightDir = normalize(light.position - fragPos);//片元指向光源

        float angleDecay = 0.0f;
        if(any(notEqual(light.lightnormal,vec3(0,0,0)))){//不是(0,0,0)
            angleDecay = max(dot(-lightDir,normalize(light.lightnormal)),0.0f);
        }

        float diff = max(dot(lightDir,normal),0.0);
        float spec = 0.0;//反射系数
        if(blinn){
            vec3 halfwayDir = normalize(viewDir+lightDir);//半程向量
            spec = pow(max(dot(normal,halfwayDir),0.0),shiness*4);
        }
        else{
            vec3 reflectDir = reflect(-lightDir,normal); //反射方向
            spec = pow(max(dot(viewDir,reflectDir),0.0),shiness);//计算镜面反射系数
        }

        float distance = length(light.position - fragPos);
        float attenuation = 1.0/(light.constant + light.linear * distance + light.quadratic * (distance * distance));

        vec3 ambient = light.ambient * diffusecolor;
        vec3 diffuse = light.diffuse * diff * diffusecolor;
        vec3 specular = light.specular * spec * specularcolor;

        ambient *= attenuation;
        diffuse *= attenuation;
        specular *= attenuation;

        diffuse *= angleDecay;
        specular *= angleDecay;

        //阴影计算
        float shadow = 0.0;
        {
            //光视角的点位置
            vec4 FragPosLightSpace = light.lightSpaceMatrix * vec4(FragPos, 1.0);
            // 执行透视除法
            vec3 projCoords = FragPosLightSpace.xyz / FragPosLightSpace.w;
            // 变换到[0,1]的范围
            projCoords = projCoords * 0.5 + 0.5;
            //转化为线性深度
            projCoords.z = LinearizeDepth(projCoords.z);

            // 计算阴影
            shadow = PCSS(projCoords,light.shadowMap,light.width);
            //shadow = PCF(projCoords,1,light.shadowMap);
        }

        vec3 lighting = (ambient + (1.0 - shadow) * (diffuse + specular));

        return lighting;
}

Uniform绑定

G_BufferShader->bind();
    // G_Buffer输入
    G_BufferShader->setUniformValue("gPosition",0);
    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D,G_Buffer->textures().at(0));
    G_BufferShader->setUniformValue("gNormal",1);
    glActiveTexture(GL_TEXTURE1);
    glBindTexture(GL_TEXTURE_2D,G_Buffer->textures().at(1));
    G_BufferShader->setUniformValue("gAlbedoSpec",2);
    glActiveTexture(GL_TEXTURE2);
    glBindTexture(GL_TEXTURE_2D,G_Buffer->textures().at(2));
    // 光照信息输入
    glActiveTexture(GL_TEXTURE3);
    scene.dirlight->setShaderPara(G_BufferShader);
    int numPointLight = pointLight.size();
    G_BufferShader->setUniformValue("numPointLights",numPointLight);
    for(int i=0;i<pointLight.length();++i){
        glActiveTexture(GL_TEXTURE4+i);
        pointLight.at(i)->setShaderPara(G_BufferShader,i);
    }
    // 其他信息
    G_BufferShader->setUniformValue("viewPos",maincamera.getCameraPos());
    G_BufferShader->setUniformValue("shiness",64.0f);
    // 调试参数
    G_BufferShader->setUniformValue("gamma",gamma);
    G_BufferShader->setUniformValue("blinn",blinn);
    G_BufferShader->setUniformValue("toneMapping",toneMapping);
    renderQuad();

结果
在这里插入图片描述

5. 添加高光项

(1)如果为光源物体,则不进行光照结果计算

    if(islight) {
        gAlbedoSpec = vec4(0,0,0,0.1);
        BrightColor = vec4(color, 1.0);
    }
    else{
        gAlbedoSpec = vec4(color,0.1);
        BrightColor = vec4(0,0,0, 1.0);
    }

在这里插入图片描述

(2)对高光项进行高斯模糊

unsigned int ID = gaussBlur->getGaussBlurPhoto(G_Buffer->textures().at(3),width(),height(),15);

在这里插入图片描述

(3)泛光合成

Uniform绑定

    G_BufferShader->setUniformValue("gBrightColor",3);
    glActiveTexture(GL_TEXTURE3);
    glBindTexture(GL_TEXTURE_2D,ID);

Shader

       //泛光
       result += texture2D(gBrightColor,TexCoords).rgb;

在这里插入图片描述

更多

光体积(Light Volumes)

延迟渲染一直被称赞的原因就是它能够渲染大量的光源而不消耗大量的性能。然而,延迟渲染它本身并不能支持非常大量的光源,因为我们仍然必须要对场景中每一个光源计算每一个片段的光照分量。真正让大量光源成为可能的是我们能够对延迟渲染管线引用的一个非常棒的优化:光体积(Light Volumes)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

QT With OpenGL(延时着色法)(Deferred Shading) 的相关文章

  • 将 jstring 转换为 QString

    我正在调用一个返回字符串的 Java 函数 QAndroidJniObject obj QAndroidJniObject callStaticObjectMethod
  • Qt 嵌入式触摸屏 QMouseEvents 在收到 MouseButtonRelease 之前未收到

    我在带有触摸屏的小型 ARM 嵌入式 Linux 设备上使用 Qt 4 8 3 我的触摸屏配置了 tslib 并对其进行了校准 因此 etc 中有一个 pointcal 文件 我的触摸事件的位置工作得很好 但无论如何我都会在鼠标按下或鼠标释
  • glTranslatef 不在 glBegin .. glEnd 中工作

    我正在尝试并排绘制不同颜色的两个方块 我的问题是我无法让 glTranslatef 将第二个方块向右移动 第二个方块只是绘制在第一个方块上 void display void glClear GL COLOR BUFFER BIT glMa
  • 是否有 Qt 小部件可以浏览应用程序中小部件的层次结构(类似于 Spy++)?

    我们有一个具有复杂的小部件层次结构的应用程序 我希望能够以与 Spy 类似的方式浏览此层次结构 查看和编辑属性 例如大小 如果有一个小部件可以显示此信息 则它不需要在外部应用程序中运行 那么问题来了 这样的神兽存在吗 您可以使用Gammar
  • GLSL memoryBarrierShared() 有用吗?

    我想知道 memoryBarrierShared 的用处 事实上 当我查找屏障功能的文档时 我读到 对于计算着色器中任何给定的静态屏障实例 单个工作组内的所有调用都必须进入该实例 然后才能允许任何调用继续超出该实例 这确保了在给定的屏障静态
  • 即使我在单独的线程中运行,QT GUI 也会冻结

    我有一个小型聊天应用程序 其中使用 SQLite 数据库来存储所有对话 我注意到该应用程序随机冻结 然后我必须最小化和最大化它才能使其再次工作 我认为问题可能是 SQLite 选择 插入导致 gui 冻结 我决定尝试将所有 SQLite 方
  • QFileSystemModel setRootPath

    我正在尝试创建一个 Qt 应用程序来显示文件夹 Mac OS 中的 Users 文件夹 的内容 这是代码 QFileSystemModel dirModel new QFileSystemModel dirModel gt setRootP
  • OpenGL/GLSL - 纹理过滤的实现

    我想在 GLSL 着色器中自己实现纹理过滤 min 和 magfilter 因为我想使用 image load and store 而不是采样器 而且我想以特殊方式处理未定义的像素 并且我正在寻找一篇文章或者这样讨论过滤过程 我记得如何从我
  • 通过引用传递 [C++]、[Qt]

    我写了这样的东西 class Storage public Storage QString key const int value const void add item QString int private QMap
  • 如何连接重叠的圆圈?

    我想在视觉上连接两个重叠的圆圈 以便 becomes 我已经有部分圆的方法 但现在我需要知道每个圆的重叠角度有多大 但我不知道该怎么做 有人有主意吗 Phi ArcTan Sqrt 4 R 2 d 2 d HTH Edit 对于两个不同的半
  • 在OpenGL中,我可以在坐标(5, 5)处精确地绘制一个像素吗?

    我所说的 5 5 正是指第五行第五列 我发现使用屏幕坐标来绘制东西非常困难 OpenGL 中的所有坐标都是相对的 通常范围从 1 0 到 1 0 为什么阻止程序员使用屏幕坐标 窗口坐标如此严重 最简单的方法可能是通过以下方式设置投影以匹配渲
  • Libgdx SpriteBatch.draw() 指定 4 个顶点

    我正在使用 libGdx 创建一个 2d 游戏 并尝试使用这个特殊的方法来绘制一个简单的 2d 纹理 分别指定 4 个顶点 draw Texture texture float spriteVertices int offset int l
  • 光照不适用于 gluSphere

    这是一个简单的问题 我有点羞于寻求帮助 我正在对 gluSphere 进行简单调用来渲染球体 但是 即使我很确定我正确添加了法线和照明 它也无法正确照亮 但是 如果我添加纹理 模型会正常点亮 但它似乎总是平滑的 并且我无法将其更改为平面 这
  • 是否可以根据 QSlider 的位置来改变其手柄的颜色?

    我非常清楚如何通过样式表自定义 QSlider 但我想知道是否可以执行以下操作 我希望滑块的手柄从蓝色变为黄色 当设置在左侧时 它是蓝色的 设置在左侧时 它是蓝色的 当你将它向右移动时 它会出现从蓝色到黄色的渐变 如果可以通过样式表 如何实
  • Qt:更改 Mac OS X 上的应用程序 QMenuBar 内容

    我的应用程序对多个 页面 使用 QTabWidget 其中顶级菜单根据用户所在的页面而变化 我的问题是 尝试重新创建菜单栏的内容会导致严重的显示问题 它在除 Mac OS X 之外的所有平台上按预期使用第一种和第三种样式 尚未测试第二种 但
  • QFileDialog::getOpenFileName 调试时崩溃,显然是由项目名称引起的?

    我遇到了一个让我非常困惑的问题 我在 Windows 7 上使用 Qt Creator 3 1 2 和 Qt 5 3 使用 MSVC 10 0 编译器和 Windows 8 1 调试工具中的 CDB 不确定我是否应该寻找特定于 Window
  • 并排显示图像的一半 - OpenGL

    我为两个图像创建了两个纹理 现在我想在opengl中按图像2的左侧部分 完整的图像1 图像2的右侧部分的顺序显示该纹理 我已经做了如下 Image1 显示在 opengl 屏幕的中央 但屏幕的左右部分不正确 应分别显示 image2 的左侧
  • CMake AUTOMOC,文件位于不同文件夹中

    我有一个简单的 CMake 项目 proj project folder a h a cpp CMakeLists txt CMakeLists txt cmake minimum required VERSION 3 2 set CMAK
  • 使用 QWT 构建时出错

    我收到一个错误 undefined reference to QwtPlot QwtPlot QWidget 当我尝试构建我的项目时 即使设置中一切看起来都很好 在我的 CmakeLists txt 中我有 include director
  • QT:模块“QtWebView”未安装

    我的操作系统是win10 QT版本是Qt5 7 mingw53 32 目标操作系统是win10 当我使用qmlscene执行qml文件时 发生了一些错误 qrc qml 3 模块 QtWebView 未安装 我的 qml 文件如下 impo

随机推荐

  • lua文件读写

    文件读写 文件读写对制作游戏很有帮助 可以调用别的文件中的代码 保存最高分 游戏存档 玩家状态等信写到文件中 首先 让我们看一个简单的命令 dofile 这个命令会读入另一个文件的代码并立即执行 代码 dofile test lua 很简单
  • 记录一个vue项目报错UnhandledPromiseRejectionWarning: Unhandled promise rejection.

    使用vue cli创建vue项目 加入一些之前的代码 然后打包运行报错 node 4892 UnhandledPromiseRejectionWarning Unhandled promise rejection This error or
  • 一种复杂业务场景的解决方案(代码结构)

    背景 我个人负责交易线的一些服务优化工作 如购物车 预购单等 这些服务是前台服务 需要基于很多中台服务能力来实现业务功能 中台服务如商品中心 协议中心 用户中心 营销活动等 前台服务通过RPC调用中台服务获取数据 在2020年度的优化工作汇
  • 如何做好nodejs服务在服务器上的安全防护?

    Web服务器安全问题仍然是IT部门最关心的问题之一 因为频发的网络攻击已被证明 由于存在托管敏感数据 Web服务器是一个组织中最容易被黑客针对攻击的地方 因此 本篇文章结合nodejs服务对如何提高Web服务器安全性给出了下面几条提示 一
  • 2023蓝桥杯C++A组题解(第十四届)

    今年广东省三中游 按New Oj估分 前5题估分17 第1题 3 4 5题暴力 第2题 B dfs写错了 第7题 G 并查集 多了个以前没见过的要求 找不到思路 面向爆零选手 水平有限 将就着看 有空再补充后5题 目录 吐槽 A 2067
  • Vue全家桶(四)之ES6模块化与webpack打包

    Vue全家桶 Vue全家桶 地址 Vue全家桶 一 之基础指令 https blog csdn net m0 55990909 article details 123917809 Vue全家桶 一 之常用特性 https blog csdn
  • Air32

    Air32 合宙Air001单片机内部FLASH读写示例 代码已经通过测试 开发环境KEIL MDK 5 36 测试代码 void FLASH RdWrTest void uint32 t Address uint32 t PageRead
  • vue + ant design vue 搭配 less 动态自定义主题颜色

    今天搞了一下午 终于搞成功了 分享给大家看看 思路解析 less 提供一个 modifyVars 可以修改浏览器中 less 文件里的变量 所以我们需要在浏览器端引入 less js 需要引入一个 less 文件 其中包含要修改的变量 但是
  • yum install net-tools安装报错could not resolve host: mirrorlist.centos.org

    Could not retrieve mirrorlist http mirrorlist centos org release 7 arch x86 64 repo os infra stock error was 14 curl 6 C
  • 移远EC600S-CN (3) - HTTP(S)应用GET请求POST请求,HTTP接入OneNET物联网云平台

    移远EC600S CN 使用AT指令HTTP连接GET请求POST请求 并接入OneNET物联网云平台 实现HTTP对物联网设备的接入 同样也适用于 EC200S EC200S不支持QuecPython 体积比EC600S略大 但便宜很多
  • Ubuntu 命令行安装android studio

    安装 sudo apt add repository ppa paolorotolo android studio sudo apt get update sudo apt get install android studio 创建桌面快捷
  • Unity 最新UnityWebRequest下载,同时显示下载进度,和 显示网速,今天贴出来和大家分享

    Unity 最新UnityWebRequest下载网络资源 支持断点续传 多文件同时下载 同时显示下载进度 和 显示网速 今天贴出来和大家分享 显示网速图片 附上案例链接 可下载 https download csdn net downlo
  • 【代码重构 & JDT】遍历AST,获取每个节点的所有直接子节点

    public class DataNode public ASTNode node 所代表的的AST节点 public int label 编号 public List
  • ORB特征提取与匹配

    ORB特征是目前最优秀的特征提取与匹配算法之一 下面具体讲解一下 特征点的检测 图像的特征点可以简单的理解为图像中比较显著显著的点 如轮廓点 较暗区域中的亮点 较亮区域中的暗点等 ORB采用FAST features from accele
  • 【编码】使用JavaScript做中文编码转换

    背景 用git bash跑curl命令的时候 会碰到中文无法输入or无法正常工作的情况 这里介绍先把中文转码 就可以正常使用了 这里介绍JavaScript的方法 1 在url地址上的GET参数是中文时 使用 console log enc
  • Android 13 - Media框架(9)- NuPlayer::Decoder

    这一节我们将了解 NuPlayer Decoder 学习如何将 MediaCodec wrap 成一个强大的 Decoder 这一节会提前讲到 MediaCodec 相关的内容 如果看不大懂可以先跳过此篇 原先觉得 Decoder 部分简单
  • Selenium JSON通信协议

    JSON wire protocol JSONWP 是WebDriver开发者编写的一种通信机制 这个通信协议是一个预定义的特殊设置 通过RESTful API暴露标准端口 WebDriver和JSONWP目的是通过Firefox driv
  • 7-3 成绩等级

    7 3 成绩等级 给出一个成绩 要求输出成绩等级 A B C D E 90分以上为 A 80到89分为 B 70到79分为 C 60到69分为 D 60分以下为 E 输入格式 在一行输入一个整数n n lt 100 输出格式 在一行中输出成
  • 视频汇聚/视频云存储/视频监控管理平台EasyCVR添加萤石云设备详细操作来啦!

    安防视频监控 视频集中存储 云存储 磁盘阵列EasyCVR平台可拓展性强 视频能力灵活 部署轻快 可支持的主流标准协议有国标GB28181 RTSP Onvif RTMP等 以及支持厂家私有协议与SDK接入 包括海康Ehome 海大宇等设备
  • QT With OpenGL(延时着色法)(Deferred Shading)

    文章目录 1 创建G Buffer帧缓存 2 修改各类型物体的着色器 3 测试G Buffer 4 使用G Buffer生成场景 5 添加高光项 1 如果为光源物体 则不进行光照结果计算 2 对高光项进行高斯模糊 3 泛光合成 更多 光体积