openGL GLSL GLSL.Refract & Reflect & Diffraction 反射、折射、衍射Fresnel Effect

2023-11-05

一、Refract & Reflect  
Snell定律描述了光线从一个介质传播到另外一个介质时,入射角、折射角以及介质折射率的关系。通过snell定律,可以根据入射光的方向向量求取折射光的方向向量。
Fresnel定律完善了光的衍射理论,当光线到达材质交界面时,一部分光被反射,另外一部分发生折射,这个现象被称为Fresnel Effect。菲涅尔现象混合了反射与折射,使得物体更加真实,理论物理中的Fresnel公式很复杂,因而在实时计算机图形学中,只要在最终效果上满足人们的视觉感受就可以了。在Cook-Torrance光照模型中计算specular光的rough surface时用到了Fresnel系数。
   F = f + (1-f) * (1 - V · H)FresnelPower
其中f入射角为0时的菲涅尔反射系数,V视角向量,H半向量;
 color = factor * 反射光颜色 + (1 - factor) * 折射光颜色

Snell中的折射率本质上反映的是光在介质中传播速度以及折射方向;
Fresnel中折射系系数反映的是光在透明介质表面被折射的光通量的比率;
这些可以模拟水表面的折射与反射现象等等

Vertex shader:

const float Eta = 0.6;
const float FresnelPower = 5.0;
const float F = ((1.0 - Eta)*(1.0 - Eta)) / ((1.0 + Eta)*(1.0 + Eta));
varying vec3 Reflect;
varying vec3 Refract;
varying float Ratio;
void main(void) {
	
	    vec4 ecposition = gl_ModelViewMatrix * gl_Vertex;
	    vec3 ecposition3 = ecposition.xyz / ecposition.w;
	    vec3 i = normalize(ecposition3);
	    vec3 n = normalize(gl_NormalMatrix*gl_Normal);
	    Ratio = F + (1.0 - F) * pow(1.0 - dot(i, n), FresnelPower);
	
	    Refract = refract(i, n, Eta);
	    Refract = vec3(gl_TextureMatrix[0] * vec4(Refract, 1.0));
	
	    Reflect = reflect(i, n);
	    Reflect = vec3(gl_TextureMatrix[1] * vec4(Reflect, 1.0));
	
	    gl_Position = ftransform();
	
}

Frag Shader:

varying vec3 Reflect;
varying vec3 Refract;
varying float Ratio;
uniform sampler2d tex;

void main(void) {
	vec3 refractColor = vec3(texture2D(tex, Refract));
	vec3 reflectColor = vec3(texture2D(tex, Reflect));
	vec3 Color = mix(refractColor, reflectColor, Ratio);
	gl_FragColor = vec4(Color, 1.0);

}

 

如果要突出某种颜色RGB,产生色散,可以分离折射的rgb值,得到另外一种效果:

const float EtaR = 0.3;
const float EtaG = 0.67;
const float EtaB = 0.9;
varying vec3 RefractR;
varying vec3 RefractG;
varying vec3 RefractB;

RefractR = refract(i, n, EtaR);
    RefractR = vec3(gl_TextureMatrix[0] * vec4(RefractR, 1.0));

    RefractG = refract(i, n, EtaG);
    RefractG = vec3(gl_TextureMatrix[0] * vec4(RefractG, 1.0));

    RefractB = refract(i, n, EtaB);
    RefractB = vec3(gl_TextureMatrix[0] * vec4(RefractB, 1.0));
vec3 refractColor;
	refractColor.r = vec3(texture2D(tex, RefractR));
	refractColor.g = vec3(texture2D(tex, RefractG));
	refractColor.b = vec3(texture2D(tex, RefractB));

二、Diffraction
GPU Gem1里面有一章讲解
光的衍射:光在传播过程中,遇到透明或者不透明的障碍物,绕过障碍物产生偏离直线传播的现象称为光的衍射。
当表面的细节比光的波长小很多时,对于这些小尺寸的细节,例如CD,波效应就不能忽略,
shader一般步骤是:先把可见光的波长转换到0~1之间,计算半向量在切线的投影来计算u,
原理不是很懂
就这样吧。。
vertex shader

uniform vec3 eyeposition;
	uniform vec3 lightposition;
	vec4  HighlightColor = (1.0, 1.0, 1.0, 1.0);
	varying vec4 Color;
	attribute vec3 Tangent;
	vec3 lambda2rgb(float lambda) {
		const float ultraviolet = 400.0;
		const float infrared = 700.0;
		//转换可见光到0~1
	    float a = (lambda - ultraviolet) / (infrared - ultraviolet);
		const float c = 10.0; //图的宽度
		vec3 b = vec3(a) - vec3(0.75, 0.5, 0.25);
		return max((1.0 - c * b*b), 0.0);

	}
	void main(void) {
		    vec3 objPosition = vec3(gl_ModelViewMatrix * gl_Vertex);
		    vec3 Normal = normalize(gl_NormalMatrix * gl_Normal);
		    vec3 LightDir = normalize(lightposition - objPosition);
		    vec3 EyeDir = normalize(eyeposition - objPosition);
		    vec3 HalfVec = normalize(LightDir + EyeDir);
		
		   vec3 T = normalize(gl_NormalMatrix * Tangent);
		 float u = abs(dot(T, HalfVec));
		
		   vec3 diffColor = vec3(0.0);
		
		   const int numspectralorders = 3;
		 for (int m = 1; m <= numspectralorders; ++m) {
		       float lambda = 660 * u / float(m);
		        diffColor += lambda2rgb(lambda);
		
		
		
		   float w = dot(Normal, HalfVec);
		 float e = 2 * u / w;
		 vec3 hilight = exp(-e * e) * HighlightColor.rgb;
		
		
		   const float diffAtten = 0.8;
		 Color = vec4(diffAtten * diffColor + hilight, 1.0);
		
		    gl_Position = ftransform();
		
			
			
	}

Frag shader

varying vec4 Color;
		 void main(void)
			{
			   gl_FragColor = Color;
			}

后面我会把c++代码补上,建一个完整的工程,供大家下载

 

参考文档:http://www.cppblog.com/init/archive/2012/03/29/169406.html

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

openGL GLSL GLSL.Refract & Reflect & Diffraction 反射、折射、衍射Fresnel Effect 的相关文章

  • GLSL 中统一浮点行为和常量浮点行为的不同

    我正在尝试在 GLSL 中实现模拟双精度 并且观察到一种奇怪的行为差异 导致 GLSL 中出现细微的浮点错误 考虑以下片段着色器 写入 4 浮点纹理以打印输出 layout location 0 out vec4 Output unifor
  • OpenGL:VAO 和 VBO 对于大型多边形渲染任务是否实用?

    如果您想渲染一次在视锥体中包含数千个多边形的大型景观 并且用户的视点不断变化 那么使用 VAO 或 VBO 是否实用 我的意思是 每次玩家的位置或摄像机旋转发生变化时 您都必须重新计算顶点数据 以便正确剔除不再可见的任何顶点或场景 以保持良
  • Opengl 视频纹理

    我正在使用 Visual Studio 10 在 Windows 上用 C 开发 opengl 应用程序 目前我在立方体上使用静态纹理 但我想集成视频纹理 你知道我可以使用哪个库来打开和解密视频吗 查看 ffmpeg libavformat
  • GL_COLOR_ATTACHMENT 有什么作用?

    我现在正在学习帧缓冲区 但我只是不明白颜色附件的作用 我了解帧缓冲区 第二个参数的意义是什么 glFramebufferTexture2D GL FRAMEBUFFER GL COLOR ATTACHMENT0 GL TEXTURE 2D
  • OpenGL什么时候完成函数中指针的处理?

    OpenGL有多项功能 http www opengl org wiki GLAPI glTexSubImage2D直接获取指针 他们中有一些从这些指针读取数据 http www opengl org wiki GLAPI glBuffer
  • 实例着色器矩阵的设置

    我想绘制实例立方体 我可以打电话GL DrawArraysInstanced PrimitiveType Triangles 0 36 2 成功地 我的问题是所有立方体都绘制在相同的位置和相同的旋转 我如何为每个立方体单独更改它 要创建不同
  • 如何在多采样纹理上渲染帧缓冲区对象?

    我目前有一个使用多个通道的渲染引擎 其中图像的各个部分在纹理上渲染 然后使用着色器进行组合 它有效 现在我想激活多重采样 我在这里读到 http www opengl org wiki Framebuffer Object Examples
  • 如何在OpenGL中像这样绘制连接的带状线

    我想用以下方式绘制一系列连接线 GL LINE STRIP 我尝试过自己编写代码 但没有得到想要的结果 所以我来到这里 帮助我找出我错在哪里 这里我只给出我的draw 函数 glBegin GL LINE STRIP glVertex2f
  • GPU-android opengl es 3.0中的亮度直方图计算

    用于亮度直方图计算 我使用了 Brad Larson 的 GPU image ios 项目中的代码 他使用混合进行直方图计算 连接顶点和片段着色器 顶点着色器 version 300 es in vec4 position out vec3
  • WGL:没有双缓冲 + 多重采样 = 失败?

    我通常使用创建像素格式wglChoosePixelFormatARB 与这些论点 除其他外 WGL DOUBLE BUFFER ARB GL TRUE WGL SAMPLE BUFFERS ARB GL TRUE WGL SAMPLES A
  • 无法在 QGLWidget 中设置所需的 OpenGL 版本

    我正在尝试在 Qt 4 8 2 中使用 QGLWidget 我注意到 QGLWidget 创建的默认上下文不显示 OpenGL 3 1 以上的任何输出 Qt wiki 有一个教程 http qt project org wiki How t
  • OpenSceneGraph 将相机设置在初始位置

    我是第一次使用 OpenSceneGraph 我有点迷失 因为文档确实不太清楚 所以 我有这段代码加载一个带有房子的 obj 文件 并且我在我想要的 人 所在的地方淹没了一个小盒子 所以现在 我不想把那个盒子放在那里 而是想把相机放在那里
  • 之前对 GL.Color3 的调用使我的纹理使用了错误的颜色

    制作 2D OpenGL 游戏 渲染帧时 我需要首先绘制一些计算的四边形几何体 然后绘制一些纹理精灵 当我的渲染方法主体仅绘制精灵时 一切正常 但是 当我尝试在精灵之前绘制几何四边形时 精灵的纹理会更改为之前使用的最后一个 GL Color
  • SDL 程序中颜色关闭

    我目前正在开发一个非常简单的游戏 使用纯 C 方法和 SDL 及其官方额外库 如 SDL image 和 OpenGL 现在 虽然我遇到了一些障碍 但我不知道为什么要这样做 绘制时颜色全部关闭 我目前在 Mac 上运行该程序 但如果我没记错
  • 开启TK onRenderFrame和onUpdateFrame的区别?

    我目前正在使用 OpenTK 框架和 OpenGL 用 C 编写 Jump n Run 游戏 Open TK 提供预设功能 例如GameWindow Run or GameWindow onUpdateFrame onRenderFrame
  • glTranslatef 不在 glBegin .. glEnd 中工作

    我正在尝试并排绘制不同颜色的两个方块 我的问题是我无法让 glTranslatef 将第二个方块向右移动 第二个方块只是绘制在第一个方块上 void display void glClear GL COLOR BUFFER BIT glMa
  • GLSL memoryBarrierShared() 有用吗?

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

    我有一个与新计算着色器相关的问题 我目前正在研究粒子系统 我将所有粒子存储在着色器存储缓冲区中 以便在计算着色器中访问它们 然后我派遣一个一维工作组 define WORK GROUP SIZE 128 shaderManager gt u
  • 如何连接重叠的圆圈?

    我想在视觉上连接两个重叠的圆圈 以便 becomes 我已经有部分圆的方法 但现在我需要知道每个圆的重叠角度有多大 但我不知道该怎么做 有人有主意吗 Phi ArcTan Sqrt 4 R 2 d 2 d HTH Edit 对于两个不同的半
  • Libgdx SpriteBatch.draw() 指定 4 个顶点

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

随机推荐

  • 前端在vue2框架中导出PDF

    1 需求 导出具有页眉页脚 页码的Pdf 并且解决Pdf分割的问题 2 实现思路 该需求主要的难点在于分页的时候容易出现分割问题 并且要将页眉页脚加进去 实现的大概思路 1 先使用jsPDF html2canvas将页面可以导出 2 第一页
  • PHP 8突破性变化

    新的PHP首要版别PHP8估计将于2020年底发布 它现在正处于十分活泼的开发中 所以在接下来的几个月里 开发速度和开发进程或许会有很大的改动 在这篇文章中 我会罗列出PHP8中会发作的一些改动 新功能 性能改善和突破性改动 由于PHP8是
  • redis 二. string 应用场景及底层分析

    String 字符串类型 一 简单命令示例 二 java 操作示例 基础 setnx 与 getset 三 使用场景举例 统计点击次数 四 底层分析 SDS 嵌入式动态字符串 再次总结 一 简单命令示例 String字符串类型 一个key对
  • Netty入门详解

    Netty是什么 Netty是 一个异步事件驱动的网络应用程序框架 用于快速开发可维护的高性能协议服务器和客户端 本质 网络应用程序框架 实现 异步 事件驱动 特性 高性能 可维护 快速开发 重要的类 方法解析 EventLoop Even
  • B站最全:给小白的Python入门教程

    如今绝大多数互联网公司 谷歌 腾讯 阿里 百度 知乎等 的很多职位要求应聘者必须具有 Python技能 学会了 Python 等于手握他们的敲门砖 0 编码基础的你 学会 Python 以后 你一个人可以做五个人的工作 最主要的是下班早 月
  • JAVA内部类

    内部类是一种类的结果扩充 一个类的内部除了属性和方法外 还可以存在其他类的结构 并且内部类也可以定义在方法或代码块中 基本概念 所谓的内部类指的就是在一个类的内部继续定义其他内部结构类 观察内部类的基本形式 package oop 观察内部
  • 服务器更换系统教程视频,更换服务器教程视频

    更换服务器教程视频 内容精选 换一换 本节操作介绍如何在移动设备上连接Linux实例 以iTerminal SSH Telnet为例介绍如何在iOS设备上连接 Linux 实例 详细操作请参考IOS设备上登录Linux云服务器 以Juice
  • vue调用视频播放插件

    安装依赖 npm install vue video player S 引入配置 import VideoPlayer from vue video player require video js dist video js css req
  • 如何直接关闭使用3306端口的进程

    要直接关闭使用3306端口的进程 你可以按照以下步骤进行操作 以关闭占领3306端口MySQL服务为例 获取占用3306端口的进程ID PID 在终端中执行以下命令 sudo lsof i 3306 查找输出中的进程ID PID 列 以及它
  • shell IF条件判断,判断条件

    http hi baidu com ryouaki item 0689dcb8a467b5a7eaba9319 前言 无论什么编程语言都离不开条件判断 SHELL也不例外 if list then do something here eli
  • k8s笔记17--ubuntu & k8s 开启 swap功能

    k8s笔记17 k8s 中途开启 swap功能 1 介绍 2 方法 2 1 ubuntu 开启swap 2 2 k8s 开启swap 3 说明 1 介绍 swap 功能是 linux是一个非常强大的功能 类似于windows的虚拟内存 当内
  • 【vue3+elementPlus】在el-table中使用popconfirm、popover、tooltip、select时,出现placement错位或者框被table的列遮挡的解决方案

    首先 第一种情况 项目设置了zoom 会导致el popconfirm el popover el tooltip el select位置不对 解决方案 temported false 给以上标签加该属性 意思是不插入body el pop
  • 一文读懂Uniswap V2的改进与创新

    Uniswap V2是链上交易所的下一个迭代产品 Uniswap是Ethereum区块链上的一个链上流动性协议 它可以实现无信任的代币交换 这意味着所有的交易都是由智能合约执行的 而不需要中介或受信任方 这种去中心化的交换代币的方法已经被证
  • Springboot2(27)集成netty实现反向代理(内网穿透)

    源码地址 springboot2教程系列 其它netty文件有博客 Springboot2 24 集成netty实现http服务 类似SpingMvc的contoller层实现 Springboot2 25 集成netty实现文件传输 Sp
  • 关于libc.so.6误删除紧急恢复的方案

    编者在一次实际生产下不小心将 libc so 6 变成了libc so 6 bak 当时没有发觉有什么不妥 但是在后面的时候 发现很多命令都无法使用 为了以后方便解决 所以将解决的方法记录 root用户下产生的libc so 6问题解决方法
  • ES6中Fetch的封装及使用,炒鸡简单~

    1 封装 http js class Ajax get url return new Promise resolve reject gt fetch url then res gt res json then data gt resolve
  • StyleCop 代码审查(VS插件)

    代码审查 StyleCop 介绍 下载 使用 自定义规则 源码 StyleCop简介 StyleCop是代码规范检查工具 Code Review 工具 它不仅仅检查代码格式 而是编码规范 包括命名和注释等 StyleCop可以帮助你更容易地
  • 【Matlab学习笔记】【数学形态学】数字图像处理(MATLAB版)冈萨雷斯第九章学习笔记

    1 形态学源于生物学 最初用于处理动植物的形状和结构 用于提取区域的形状 边界 骨骼或凸壳 形态学图像处理主要用于图像预处理和后处理 包括形态学滤波 细化和裁剪等 2 图像的形态学处理 由二值图像开始 逐步扩展到灰度图像 彩色图像 由简单到
  • 深入浅出SQL(3)-在Mac OS X上安装MySQL

    如何在Mac OS X上安装MySQL 下载安装包 打开官方下载地址 https dev mysql com downloads 选择合适版本的安装包 新建Oracle MySQL账户 email H10 登陆后下载安装包 安装 安装过程中
  • openGL GLSL GLSL.Refract & Reflect & Diffraction 反射、折射、衍射Fresnel Effect

    一 Refract Reflect Snell定律描述了光线从一个介质传播到另外一个介质时 入射角 折射角以及介质折射率的关系 通过snell定律 可以根据入射光的方向向量求取折射光的方向向量 Fresnel定律完善了光的衍射理论 当光线到