当前位置: 首页 > wzjs >正文

建筑人才网管网什么是网站推广优化

建筑人才网管网,什么是网站推广优化,公司网站建设技术方案,校园网站管理系统目录 颜色创建一个光照场景 基础光照环境光漫反射法向量如何处理?镜面光照 GitHub主页:https://github.com/sdpyy OpenGL学习仓库:https://github.com/sdpyy1/CppLearn/tree/main/OpenGLtree/main/OpenGL):https://github.com/sdpyy1/CppLearn/tree/main…

目录

  • 颜色
    • 创建一个光照场景
  • 基础光照
    • 环境光
    • 漫反射
    • 法向量如何处理?
    • 镜面光照

GitHub主页:https://github.com/sdpyy
OpenGL学习仓库:https://github.com/sdpyy1/CppLearn/tree/main/OpenGLtree/main/OpenGL):https://github.com/sdpyy1/CppLearn/tree/main/OpenGL

颜色

颜色可以数字化的由红色(Red)、绿色(Green)和蓝色(Blue)三个分量组成,它们通常被缩写为RGB。仅仅用这三个值就可以组合出任意一种颜色。我们在现实生活中看到某一物体的颜色并不是这个物体真正拥有的颜色,而是它所反射的(Reflected)颜色。换句话说,那些不能被物体所吸收(Absorb)的颜色(被拒绝的颜色)就是我们能够感知到的物体的颜色。例如,太阳光能被看见的白光其实是由许多不同的颜色组合而成的(如下图所示)。如果我们将白光照在一个蓝色的玩具上,这个蓝色的玩具会吸收白光中除了蓝色以外的所有子颜色,不被吸收的蓝色光被反射到我们的眼中,让这个玩具看起来是蓝色的。下图显示的是一个珊瑚红的玩具,它以不同强度反射了多个颜色。
在这里插入图片描述
你可以看到,白色的阳光实际上是所有可见颜色的集合,物体吸收了其中的大部分颜色。它仅反射了代表物体颜色的部分,被反射颜色的组合就是我们所感知到的颜色(此例中为珊瑚红)。将光源设置为白色。当我们把光源的颜色与物体的颜色值相乘,所得到的就是这个物体所反射的颜色(也就是我们所感知到的颜色)

glm::vec3 lightColor(1.0f, 1.0f, 1.0f);
glm::vec3 toyColor(1.0f, 0.5f, 0.31f);
glm::vec3 result = lightColor * toyColor; // = (1.0f, 0.5f, 0.31f);

创建一个光照场景

这个就需要把入门的东西融会贯通了
首先VBO、VAO可以这样设置。把VBO绑定好之后,分别对cube和光照都绑定VAO,因为现在VBO被绑定,所以两个VAO绑定时都自动挂载了该VBO,也就是说两个物体用的同一套顶点数据,VBO实现了公用

    // 创建Object的IDGLuint VBO;GL_CALL(glGenVertexArrays(1, &cubeVAO));GL_CALL(glGenVertexArrays(1,&lightVAO));GL_CALL(glGenBuffers(1, &VBO));// VBO写入显存GL_CALL(glBindBuffer(GL_ARRAY_BUFFER, VBO));GL_CALL(glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW));// 绑定VAO到正方形GL_CALL(glBindVertexArray(cubeVAO));GL_CALL(glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void *) 0));GL_CALL(glEnableVertexAttribArray(0));// 绑定VAO到灯光GL_CALL(glBindBuffer(GL_ARRAY_BUFFER, VBO));GL_CALL(glBindVertexArray(lightVAO));glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);GL_CALL(glEnableVertexAttribArray(0));// 解绑VAO,在渲染循环中,需要哪一个再绑定哪一个glBindVertexArray(0);// VBO已经被设置到了VAO,不需要再绑定VBO了glBindBuffer(GL_ARRAY_BUFFER, 0);

下来分别需要创建两个shader用于cube和光照方块

    shader cubeShader("./shader/shader.vs", "./shader/shader.fs");shader lightingShader("./shader/shader.vs", "./shader/light_shader.fs");

在画两个方块时对两个shader设置不同的Model变换矩阵,实际上就是设置uniform变量

        // 画正方形cubeShader.use();glBindVertexArray(cubeVAO);cubeShader.setVec3("objectColor", 1.0f, 0.5f, 0.31f);cubeShader.setVec3("lightColor",  1.0f, 1.0f, 1.0f);auto modelTrans = glm::mat4(1.0f);setMVP(cubeShader,modelTrans);GL_CALL(glDrawArrays(GL_TRIANGLES, 0, 36));// 画光源lightingShader.use();glBindVertexArray(lightVAO);auto lightModelTrans = glm::mat4(1.0f);lightModelTrans = glm::translate(lightModelTrans, lightPos);lightModelTrans = glm::scale(lightModelTrans, glm::vec3(0.2f));setMVP(lightingShader,lightModelTrans);GL_CALL(glDrawArrays(GL_TRIANGLES, 0, 36));

调整摄像机的位置就可以得到下图
在这里插入图片描述

基础光照

其中一个模型被称为风氏光照模型(Phong Lighting Model)。风氏光照模型的主要结构由3个分量组成:环境(Ambient)、漫反射(Diffuse)和镜面(Specular)光照。下面这张图展示了这些光照分量看起来的样子:在这里插入图片描述

环境光

光能够在其它的表面上反射,对一个物体产生间接的影响。考虑到这种情况的算法叫做全局照明(Global Illumination)算法,但是这种算法既开销高昂又极其复杂。简单做法就是给物体表面最终的效果加上一个很小的常量,这个可以写在片段着色器

#version 330 core
out vec4 FragColor;uniform vec3 objectColor;
uniform vec3 lightColor;void main()
{float ambientStrength = 0.1;vec3 ambient = ambientStrength * lightColor;vec3 result = ambient * objectColor;FragColor = vec4(result, 1.0);
}

捎带往后移动一下摄像机,太近了

Camera camera(glm::vec3(0.0f, 0.0f, 5.0f));

写到这里我其实不是很理解为什么颜色要相乘。返回去看上一章得到解释是:把光源的颜色与物体的颜色值相乘,所得到的就是这个物体所反射的颜色(也就是我们所感知到的颜色),所以ambient相当于对光照颜色的稀释(0.1),之后与物体颜色相乘得到就是物体应该反射的光,展示效果如下
在这里插入图片描述

漫反射

图左上方有一个光源,它所发出的光线落在物体的一个片段上。我们需要测量这个光线是以什么角度接触到这个片段的。如果光线垂直于物体表面,这束光对物体的影响会最大化。需要法向量来计算,在顶点数据中添加法线数据

float vertices[] = {-0.5f, -0.5f, -0.5f,  0.0f,  0.0f, -1.0f,0.5f, -0.5f, -0.5f,  0.0f,  0.0f, -1.0f, 0.5f,  0.5f, -0.5f,  0.0f,  0.0f, -1.0f, 0.5f,  0.5f, -0.5f,  0.0f,  0.0f, -1.0f, -0.5f,  0.5f, -0.5f,  0.0f,  0.0f, -1.0f, -0.5f, -0.5f, -0.5f,  0.0f,  0.0f, -1.0f, -0.5f, -0.5f,  0.5f,  0.0f,  0.0f, 1.0f,0.5f, -0.5f,  0.5f,  0.0f,  0.0f, 1.0f,0.5f,  0.5f,  0.5f,  0.0f,  0.0f, 1.0f,0.5f,  0.5f,  0.5f,  0.0f,  0.0f, 1.0f,-0.5f,  0.5f,  0.5f,  0.0f,  0.0f, 1.0f,-0.5f, -0.5f,  0.5f,  0.0f,  0.0f, 1.0f,-0.5f,  0.5f,  0.5f, -1.0f,  0.0f,  0.0f,-0.5f,  0.5f, -0.5f, -1.0f,  0.0f,  0.0f,-0.5f, -0.5f, -0.5f, -1.0f,  0.0f,  0.0f,-0.5f, -0.5f, -0.5f, -1.0f,  0.0f,  0.0f,-0.5f, -0.5f,  0.5f, -1.0f,  0.0f,  0.0f,-0.5f,  0.5f,  0.5f, -1.0f,  0.0f,  0.0f,0.5f,  0.5f,  0.5f,  1.0f,  0.0f,  0.0f,0.5f,  0.5f, -0.5f,  1.0f,  0.0f,  0.0f,0.5f, -0.5f, -0.5f,  1.0f,  0.0f,  0.0f,0.5f, -0.5f, -0.5f,  1.0f,  0.0f,  0.0f,0.5f, -0.5f,  0.5f,  1.0f,  0.0f,  0.0f,0.5f,  0.5f,  0.5f,  1.0f,  0.0f,  0.0f,-0.5f, -0.5f, -0.5f,  0.0f, -1.0f,  0.0f,0.5f, -0.5f, -0.5f,  0.0f, -1.0f,  0.0f,0.5f, -0.5f,  0.5f,  0.0f, -1.0f,  0.0f,0.5f, -0.5f,  0.5f,  0.0f, -1.0f,  0.0f,-0.5f, -0.5f,  0.5f,  0.0f, -1.0f,  0.0f,-0.5f, -0.5f, -0.5f,  0.0f, -1.0f,  0.0f,-0.5f,  0.5f, -0.5f,  0.0f,  1.0f,  0.0f,0.5f,  0.5f, -0.5f,  0.0f,  1.0f,  0.0f,0.5f,  0.5f,  0.5f,  0.0f,  1.0f,  0.0f,0.5f,  0.5f,  0.5f,  0.0f,  1.0f,  0.0f,-0.5f,  0.5f,  0.5f,  0.0f,  1.0f,  0.0f,-0.5f,  0.5f, -0.5f,  0.0f,  1.0f,  0.0f
};

相应的VAO和顶点着色器同步修改,并将顶点法线out到片段着色器

#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aNormal;
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
out vec3 Normal;
void main()
{gl_Position = projection*view*model*vec4(aPos, 1.0);Normal = aNormal;
}

另外在片段着色器中需要光照位置信息,用uniform传递即可,最后还需要每个像素对应在空间中的位置,这个直接可以用顶点着色器的顶点数据左乘模型变换,就得到了空间坐标,直接把他传递给片段着色器即可。
这些都做完的效果就是片段着色器拿到了每个像素在空间中的位置以及对应的法线。

法向量点乘光照方向得到两个方向的夹角cos(注意钝角处理和向量单位化)

void main()
{// 环境光float ambientStrength = 0.1;vec3 ambient = ambientStrength * lightColor;// 漫反射vec3 norm = normalize(Normal);vec3 lightDir = normalize(lightPos - FragPos);float diff = max(dot(norm,lightDir),0.0);vec3 diffuse = diff * lightColor;vec3 result = (ambient + diffuse)* objectColor;FragColor = vec4(result, 1.0);
}

最终效果,可以看出与光源夹角小的地方确实更亮了
在这里插入图片描述

法向量如何处理?

如果我们只是简单的进行平移,并不会影响原本的法线,但是旋转和变换会影响。如果一个平面通过Model变换进行了旋转,很显然法线确实就不一样了。另外缩放可以看下边这张图
在这里插入图片描述
这种不等比的缩放,会破会法线的。
修复这个行为的诀窍是使用一个为法向量专门定制的模型矩阵。这个矩阵称之为法线矩阵(Normal Matrix),它使用了一些线性代数的操作来移除对法向量错误缩放的影响。
法线矩阵被定义为「模型矩阵左上角3x3部分的逆矩阵的转置矩阵」

	Normal = mat3(transpose(inverse(model))) * aNormal;

在转移到片段着色器之前,这样处理法线,才能让法线正常使用。
矩阵求逆是一项对于着色器开销很大的运算,因为它必须在场景中的每一个顶点上进行,所以应该尽可能地避免在着色器中进行求逆运算。以学习为目的的话这样做还好,但是对于一个高效的应用来说,你最好先在CPU上计算出法线矩阵,再通过uniform把它传递给着色器(就像模型矩阵一样)

镜面光照

和漫反射光照一样,镜面光照也决定于光的方向向量和物体的法向量,但是它也决定于观察方向,例如玩家是从什么方向看向这个片段的。镜面光照决定于表面的反射特性。如果我们把物体表面设想为一面镜子,那么镜面光照最强的地方就是我们看到表面上反射光的地方。只有高光反射与观察方向有关
在这里插入图片描述

    // 高光反射flaot specularStrength = 0.5;vec3 viewDir = normalize(viewPos - FragPos);vec3 reflectDir = reflect(-lightDir, norm);float spec = pow(max(dot(viewDir, reflectDir), 0.0), 32);vec3 specular = specularStrength * spec * lightColor;

其中32用来定义高光的反光度(Shininess)
在这里插入图片描述

到这里我意识到Games101的作业三没有lightColor是因为它默认光源是白色的也就是(1,1,1),这里考虑到了
在这里插入图片描述
也可以在顶点着色器中对每个顶点做光照处理,这种处理就叫做Gouraud着色(Gouraud Shading),计算量更少
在这里插入图片描述

http://www.dtcms.com/wzjs/111152.html

相关文章:

  • 云南做网站哪家好雷神代刷网站推广
  • 淘宝网页设计与制作教程seo管家
  • 怎么做网站源码黄页网络的推广
  • 多边形网站西地那非片吃了多久会硬起来
  • 哪家公司建网站最好最佳的资源搜索引擎
  • 沧州高端网站建设公司今天高清视频免费播放
  • 注销网站 取消接入草根seo视频大全
  • 上蔡县住房和城乡建设局网站个人推广app的妙招
  • 南京哪里有做网站的旺道seo怎么优化网站
  • 网站推广是做什么工作百度搜图片功能
  • 做网站要多钱网络营销的定义
  • 西安微网站制作网站优化推广方法
  • 在互联网公司做网站搜索引擎营销特点是什么
  • 网站关键词优化公司哪家好网络推广的方法包括
  • 自己做培训需要网站吗如何做seo整站优化
  • 凡科网站为什么免费做网站太原百度seo
  • vultr怎么建设影视网站沈阳关键词优化报价
  • 网站直播间 是怎么做的网站怎么营销推广
  • 佛山茂名网站建设企业网络营销策划方案
  • 电子商城网站开发与设计中国站长
  • 可视化网站建设软件网上销售平台怎么做
  • 赤峰市建设委员会网站免费源码网站
  • 长春标准网站建设图片识别
  • 做电子外贸网站搜seo
  • 上海做外贸网站的公司seo推广营销靠谱
  • 免费网站建设专业的公司北京计算机培训机构前十名
  • ftp文件导入wordpress晋城seo
  • 小猪会飞网站建设厦门谷歌seo公司有哪些
  • 高端品牌网站有哪些重庆小潘seo
  • 做网站 设备小学生摘抄新闻