首页 > 其他分享 >osg 使用整理 (8):基础光照和法线贴图

osg 使用整理 (8):基础光照和法线贴图

时间:2023-09-23 21:46:25浏览次数:35  
标签:贴图 法线 向量 切线 osg 纹理 vec3 光照

# osg 使用整理 (8):基础光照和法线贴图

## 1 冯氏光照模型(Phong Lighting Model)

​ 冯氏光照模型只考虑直接光照,将进入摄像机的光分为4个部分:

​ (a)自发光表示当给定一个方向时,一个表面本身会向该方向发射多少辐射量

​ (b)镜面高光表示物体表面镜面反射的辐射量,模拟有光照的亮点

​ (c)漫反射光照表示物体表面漫反射的辐射量

​ (d)环境光给物体表面一个辐射常量

 

1.1 环境光照

环境光照考虑了光在其他表面上的反射造成的间接光照,它是一种简化的全局光照模型。添加环境光照后,即使场景中没有直接光源,也能看到物体表面微弱光照。

void main()
{
  float ambientStrength = 0.1;
  vec3 ambient = ambientStrength * lightColor;

  vec3 result = ambient * objectColor;
  FragColor = vec4(result, 1.0);
}

1.3 漫反射光照

漫反射数学模型如上图所示,n表示物体表面法线向量,s表示物体表面和光照连线向量。进入物体表面的光照取决于s和n的相对关系,当s和n重合时,这个方向上的辐射度最大,反之相互垂直时最小。用数学公式可以表示为:

```
float diff = max(dot(norm, lightDir), 0.0);
vec3 diffuse = diff * lightColor;
```

​ 注意不等比缩放会改变表面法线方向,需要使用法线矩阵生成正确的法线向量。

 

1.3 镜面高光光照

 

镜面高光数学模型如上图所示,n表示物体表面法线向量,s表示物体表面和光照连线向量,r代表光线反射方向,v代表摄像机和物体表面连线向量。反射向量可以通过法向量求得,当反射向量r和观察方向n的相对角度越小,镜面高光的辐射度越大。

```
float spec = pow(max(dot(viewDir, reflectDir), 0.0), 32);
vec3 specular = specularStrength * spec * lightColor;
```

### 1.4 Blinn-Phong光照模型

​ Phong光照模型的镜面高光计算考虑了视线和反射光线向量的夹角,导致当法线和光源夹角大于90度时,镜面高光为0。如下图所示,在镜面高光区域的边缘出现了明显的断层。

 

1977年,Blinn引入了半程向量概念,即光线与视线方向夹角一般方向上的一个单位向量,当半程向量和法线向量越接近时,镜面高光辐射度越大。

vec3 lightDir   = normalize(lightPos - FragPos);
vec3 viewDir   = normalize(viewPos - FragPos);
vec3 halfwayDir = normalize(lightDir + viewDir);

float spec = pow(max(dot(normal, halfwayDir), 0.0), shininess);
vec3 specular = lightColor * spec;

2 法线贴图(Normal Mapping)

如上面所述,影响模型视觉效果的模型固有属性除了顶点位置、颜色,还有很重要的表面法线向量。可以通过改变模型表面法线达到一种虚拟的凹凸不平视角效果,极大提升模型细节而不用改变顶点位置。法线纹理存储了模型表面的法线向量。取值范围为[-1,1],主要分为模型空间的法线纹理和切线空间的法线纹理,如下图所示。可以发现模型空间下的法线纹理五颜六色的,对应到模型坐标系下不同数值的法线向量,而切线空间下的法线基本都是浅蓝色(0.5,0.5,1.0),对应到切线坐标系的数值为(0,0,1)。

 

2.1 切线空间

切线空间定义为原点在顶点上,z轴方向为顶点法线方向,x轴为顶点切线方向,y轴为切线和法线叉乘得到称为副法线。因为切线空间的法线纹理大部分与顶点法线相同,改变的部分为每个点的法线扰动方向。美术人员更喜欢切线空间的法线纹理,分析他们的优劣如下

模型空间下法线纹理优点

(a)实现简单,更加直观

(b)在纹理坐标的缝合处和尖锐的边角附近,可见的突变较少。

切线空间下的法线纹理优点

(a)自由度很高。模型空间下的法线纹理记录的是绝对法线信息,仅可用于创建它的那个模型,而不能用在其他模型上,如立方体的相同6个平面就要生成6张法线纹理。

(b)可以进行uv动画。比如可以移动一个纹理的uv坐标来实现一个凹凸移动的效果,在水和火山熔岩类型的物体上经常用到。

(c)可压缩。切线空间的法线纹理只需要存储XY方向的值。

实际使用切线空间的法线纹理时,有两种选择:

一是在切线空间下计算光照,意味着要把光照方向和视角方向变换到切线空间,基本思路是首先在顶点着色器中求得模型空间到切线空间的变换矩阵,然后将视角向量和光线向量变换到切线空间,最后在片段着色器中通过纹理采样得到切线空间下的法线并计算光照。

void main()
{
  [...]
  vec3 T = normalize(vec3(model * vec4(tangent,   0.0)));
  vec3 B = normalize(vec3(model * vec4(bitangent, 0.0)));
  vec3 N = normalize(vec3(model * vec4(normal,   0.0)));
  mat3 TBN = mat3(T, B, N)
}
注:对方向矢量的坐标变换不需要考虑原点平移,因此3X3的矩阵就可以表示向量的坐标变换
void main()
{    
  [...]
  mat3 TBN = transpose(mat3(T, B, N));
  vs_out.TangentLightPos = TBN * lightPos;
  vs_out.TangentViewPos = TBN * viewPos;
  vs_out.TangentFragPos = TBN * vec3(model * vec4(position, 0.0));
}

二是在世界空间下进行光照计算,需要把采样得到的法线变换到世界空间下。

void main()
{
  [...]
  vec3 T = normalize(vec3(model * vec4(tangent,   0.0)));
  vec3 B = normalize(vec3(model * vec4(bitangent, 0.0)));
  vec3 N = normalize(vec3(model * vec4(normal,   0.0)));
  mat3 TBN = mat3(T, B, N)
}
void main()
{  
normal = texture(normalMap, fs_in.TexCoords).rgb;
normal = normalize(normal * 2.0 - 1.0);  
normal = normalize(fs_in.TBN * normal);
}

使用法线贴图可以使用更少的顶点表现出同样丰富的细节。

 

 

 

 

标签:贴图,法线,向量,切线,osg,纹理,vec3,光照
From: https://www.cnblogs.com/wangxydela/p/17725103.html

相关文章

  • vue项目中的Tinymce富文本编辑器如何从word中粘贴图片上传到七牛云
    Tinymce富文本编辑器粘贴图片时需要上传到自己的空间中才能被打开。一、首先需要安装引入七牛云npminstallqiniu-jsvarqiniu=require('qiniu-js')//orimport*asqiniufrom'qiniu-js'二、同时引入客户端生成的tokenimport{qiniuTokenCreate}from"@/assets/js/qin......
  • vue2 使用tinymce编辑器实现上传图片及粘贴word文本保留格式并粘贴图片自动上传
    下载对应的版本 npminstall@tinymce/[email protected]@5.8.2-S然后在node_modules中找到tinymce把整个文件复制下来粘到public中 在组件页面使用根据自己需求进行注释或添加功能<template><divclass="tinymce-editor"><Editor:......
  • 解决wangEditor从word复制粘贴图片,带有页眉页脚的问题
    话不多说,直接贴代码。rtf数据能提取到页眉页脚图片的原因:提取Word文档中包含的所有图像数据,包括页眉和页脚中的图像数据。这是因为RTF(RichTextFormat)是一种标记语言,可以在其中嵌入文本、图像和其他媒体类型的数据。在Word中,页眉和页脚的内容也可以通过RTF格式进行描述......
  • OSG狀態
    模式和狀態:attribute:osg::CullFace*cf=newosg::CullFace(osg::CullFace::BACK);state->setAttribute(cf);mode:state->setMode(GL_FOG,osg::StateAttribute::ON);同時設置:osg::BlendFunc*bf=newosg::BlendFunc();//关联BlendFunc并许可颜色融合模式s......
  • OSG粒子系统
    ParticleSystem:是一个drawable,有很多属性可以设置。Aparticlesystemcanonlyuseonetexture。ModularEmitter:ModularEmitter->Emitter->ParticleProcessor->node:每帧都会产生新的粒子,最好使用"conter"、"placer"、"shotter"achieveawidevariety......
  • 富文本编辑器 django-mdeditor如何复制粘贴图片
    1、找到文件\site-packages\mdeditor\templates\markdown.html文件2、找到<scripttype="text/javascript">这行3.这行及以下所有内容删除,也就是把js这块代码全删除了,把js替换<scripttype="text/javascript">$(function(){editormd("{{id}}-wmd-wrapp......
  • osg场景中的坐标和模型在3dmax的坐标有什么关联
    在OpenSceneGraph(OSG)中的坐标系统与3dsMax(3DStudioMax)中的坐标系统之间存在一些基本的关联,但也有一些重要的差异。以下是它们之间的主要区别和关联:坐标系方向:OSG使用右手坐标系,其中X轴指向右侧,Y轴指向上方,Z轴指向观察者的方向(远离观察者)。3dsMax通常使用左手坐标系,其......
  • Qt3D曲面正反面贴图例程
    主要利用GLSL中的内置变量gl_FrontFacing区分正反面。下面是正面反面效果图:头文件:classQOpenGLShaderProgram;classQOpenGLTexture;//---------------------------------------------------------------------------------------//显示图片//-----------------------......
  • Web编辑器实现WORD粘贴图片自动上传
    ​ 这种方法是servlet,编写好在web.xml里配置servlet-class和servlet-mapping即可使用后台(服务端)java服务代码:(上传至ROOT/lqxcPics文件夹下)<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%><%@     page contentType="text/html;cha......
  • osg 使用整理 (6):体渲染效果
    osg使用整理(6):体渲染效果​ ​ 体渲染技术可用于医学成像、计算流体力学、有限元、地球物理学、遥感等领域,数据通常来源于CT扫描、核磁共振MRI、卫星成像和声纳等设备,大概分为三种:直接体渲染技术(光线投射法、抛雪球法、错切变形法)、间接体绘制技术和最大密度投影技术。1光线......