GLSL实现HDR Rendering 【转】
http://blog.csdn.net/a3070173/archive/2008/11/29/3408573.aspx
- HDR - 全称High dynamic rang,是目前流行的3D特效技术.其基本原理是:虽然在计算机图形中可以使用完全的浮点型来表
- 示颜色,但之前由于一直受到硬件的限制,从外部载入的纹理格式大多只能以每种颜色成分用一个字节来表示,也就是0-255,
- 当这个低范围的颜色值转换为浮点型之后就会导致一定量的颜色间隔,而HDR技术通过采用浮点型的外部纹理格式弥补了原来
- 整型纹理格式所导致的颜色间隔,从而增强了计算机图形的颜色表现能力.当然这只是笼统的说法,而且每个人对同一个概念
- 的理解也不尽相同,所以我在本文的最后列出了一些个人认为比较有用的参考资料,这里只简单描述一下我的HDR - OpenGL实
- 现,其实HDR的理念理解了之后就会比较简单,但真要编码实现的话还是有很多东西需要琢磨.
- 下面列出的是主要渲染流程:
- 备注(FBO代表Frame Buffer Object)
- 1.渲染整个场景到FBO1
- 2.下采样FBO1到尺寸为原来1/4的FBO2中
- 3.下采样FBO2到尺寸为原来1/8的FBO3中
- DownSample片元着色器:
- uniform sampler2D g_SceneTexture;
- void main()
- {
- gl_FragColor = texture2D(g_SceneTexture, gl_TexCoord[0].st);
- }
- 4.对经过两次下采样并保存在FBO3中的内容进行高斯过滤,并将处理过后的图像
- 保存在FBO4中(备注:高斯过滤分为横向过滤和纵向过滤两个通道,所以需要一个FBO5进行过渡)
- 高斯过滤片元着色器:
- const int g_iWeightNumber = 17;
- uniform sampler2D g_DecalTexture;
- uniform bool g_bFilterModel;
- uniform float g_aryWeight[g_iWeightNumber]; // Blur权重数组
- uniform vec2 g_aryVerticalOffset[g_iWeightNumber]; // 横向Blur偏移数组
- uniform vec2 g_aryHorizontalOffset[g_iWeightNumber]; // 纵向Blur偏移数组
- void main()
- {
- vec4 vec4Sum = vec4(0.0);
- if (g_bFilterModel)
- {
- // 横向过滤
- for(int i = 0; i < g_iWeightNumber; ++i)
- {
- vec4Sum += texture2D(g_DecalTexture, gl_TexCoord[0].st + g_aryVerticalOffset[i])*g_aryWeight[i];
- }
- }
- else
- {
- // 纵向过滤
- for(int i = 0; i < g_iWeightNumber; ++i)
- {
- vec4Sum += texture2D(g_DecalTexture, gl_TexCoord[0].st + g_aryHorizontalOffset[i])*g_aryWeight[i];
- }
- }
- gl_FragColor = vec4Sum;
- }
- 5.FBO4中的内容与FBO1中的内容进行特效处理和ToneMapping以将高动态范围的颜色值映射对低动态范围以便于显示.
- ToneMapping片元着色器:
- const float g_fGamma = 1.0/2.0;
- uniform float g_fBlurAmount; // 模糊量
- uniform float g_fRadialEffectAmount; // 放射式效果量
- uniform float g_fExposure; // 暴光量
- uniform sampler2D g_SceneTexture;
- uniform sampler2D g_BlurTexture;
- // 计算放射式效果
- vec4 CaculateRadial(vec2 p_vec2TexCoord,int p_iSampleNumber,
- float p_fStartScale = 1.0, float p_fScaleMul = 0.9)
- {
- // 临时变量
- vec4 vec4TempColor = vec4(0.0);
- float fCurrentScale = p_fStartScale;
- vec2 vec2TempTexCoord = vec2(0.0);
- // 遍历采样
- for(int i = 0; i < p_iSampleNumber; ++i)
- {
- vec2TempTexCoord = (p_vec2TexCoord - 0.5)*fCurrentScale + 0.5; // 采样方式
- vec4TempColor += texture2D(g_BlurTexture, vec2TempTexCoord);
- fCurrentScale *= p_fScaleMul;
- }
- vec4TempColor /= float(p_iSampleNumber);
- return vec4TempColor;
- }
- // 计算小插图效果
- float CaculateVignette(vec2 p_vec2Position, float p_fInner, float p_fOuter)
- {
- float L = length(p_vec2Position);
- return ( 1.0 - smoothstep(p_fInner, p_fOuter, L) );
- }
- void main()
- {
- vec4 vec4SceneColor = texture2D(g_SceneTexture, gl_TexCoord[0].st); // 计算原始场景颜色
- vec4 vec4BlurColor = texture2D(g_BlurTexture, gl_TexCoord[0].st); // 计算经Blur后的场景颜色
- vec4 vec4RadialEffectColor = CaculateRadial(gl_TexCoord[0].st, 30, 1.0, 0.95); // 计算放射效果的颜色
- // 混合场景与Blur
- vec4 vec4Temp = lerp(vec4SceneColor, vec4BlurColor, g_fBlurAmount);
- // 添加放射性效果
- vec4Temp += vec4RadialEffectColor*g_fRadialEffectAmount;
- // 进行暴光
- vec4Temp *= g_fExposure;
- // 添加圆形扩散小插图效果使得中间部分较亮而四个边角逐渐变暗
- vec4Temp *= CaculateVignette(gl_TexCoord[0].st*2.0 - 1.0, 0.7, 1.5);
- // 使用Gamma校正规范会低范围光照
- vec4Temp.rgb = pow(vec4Temp.rgb, vec3(g_fGamma));
- // 最终颜色
- gl_FragColor = vec4Temp;
- }
- Demo效果截图:
- exe文件:http://www.fileupyours.com/view/219112/GLSL/HDR%20Rendering.rar
- VC9运行库:http://www.fileupyours.com/view/219112/GLSL/VC9RunningLib.rar
- 参考资料:1.DirectX SDK Sample - HDRLighting(备注:这个可以从DirectX SDK中获得)
- 2.Nvidia SDK 10.5 - HDR(备注:Nvidia SDK可以在Nvidia的网站上免费下载)
GLSL实现HDR Rendering 【转】的更多相关文章
- paper 72 :高动态范围(HDR)图像 HDR (High Dynamic Range)
In standard rendering, the red, green and blue values for a pixel are each represented by a fraction ...
- Unity3d HDR和Bloom效果(高动态范围图像和泛光)
文章开始先放两组效果,文章结尾再放两组效果本文测试场景资源来自浅墨大神,shader效果为本文效果 HDR 人们有限的视觉系统,只支持16.7百万的颜色,超出这个范围的颜色就不能显示了bmp或jprg ...
- Deferred shading rendering path翻译
Overview 概述 When using deferred shading, there is no limit on the number of lights that can affect a ...
- 由浅入深学习PBR的原理和实现
目录 一. 前言 1.1 本文动机 1.2 PBR知识体系 1.3 本文内容及特点 二. 初阶:PBR基本认知和应用 2.1 PBR的基本介绍 2.1.1 PBR概念 2.1.2 与物理渲染的差别 2 ...
- iOS 10.0 更新点(开发者视角)
html, body {overflow-x: initial !important;}html { font-size: 14px; } body { margin: 0px; padding: 0 ...
- NV SDK 9.5, 10 and 11
NVIDIA SDK 10 Overview This all-new collection of DirectX 10 and OpenGL code samples teaches devel ...
- (转)Unity3d中的属性(Attributes)整理
Attributes属性属于U3D的RunTimeClass,所以加上以下的命名空间是必须的了.其它倒没什么需要注意的.本文将所有运行属性过一遍罢了. using UnityEngine; using ...
- Unity3d该物业(Attributes)整理
http://blog.sina.com.cn/s/blog_5b6cb9500101857b.html Attributes属性属于U3D的RunTimeClass,所以加上下面的命名空间是必须的了 ...
- Unity3d中的属性(Attributes)整理
Attributes属性属于U3D的RunTimeClass,所以加上以下的命名空间是必须的了.其它倒没什么需要注意的.本文将所有运行属性过一遍罢了. using UnityEngine; using ...
随机推荐
- bjfu1253 最大上升子序列和
n^2的算法就行,很简单的动态规划.直接上代码 /* * Author : ben */ #include <cstdio> #include <cstdlib> #inclu ...
- XML Schema 简介
XML Schema 是基于 XML 的 DTD 替代者. XML Schema 可描述 XML 文档的结构. XML Schema 语言也可作为 XSD(XML Schema Definition) ...
- js 判断字符是否以汉字开头
javascript代码如下: var re = new RegExp("^[\u4e00-\u9fa5]"); if (re.test("aaa好")) { ...
- XHTML学习进度备忘
书签:XHTML 高级教程没有看:另外跳过的内容有待跟进 __________________ 学习资源:W3School. _________________ 跳过的内容: 1.“XHTML 简介” ...
- atoi()函数的实现
atoi()函数的功能:将字符串转换成整型数:atoi()会扫描参数nptr字符串,跳过前面的空格字符,直到遇上数字或正负号才开始做转换,而再遇到非数字或字符串时('\0')才结束转化,并将结果返回( ...
- 流式计算之Storm简介
Storm是一个分布式的.容错的实时计算系统,遵循Eclipse Public License 1.0,Storm可以方便地在一个计算机集群中编写与扩展复杂的实时计算,Storm之于实时处理,就好比H ...
- linux进程控制命令
& 加在一个命令的最后,可以把这个命令放到后台执行 ,如gftp &. ctrl + z 可以将一个正在前台执行的命令放到后台,并且处于暂停状态,不可执行. jobs 查看当前有多少在 ...
- 无线网WEP的安全测试及防范
650) this.width=650;" border="0" alt="" src="http://img1.51cto.com/att ...
- php基础知识(3)(文件加载include)
文件加载 综述: 有4个文件加载的语法形式(注意,不是函数): include, include_once, require, require_once; 他们的本质是一样的,都是用于加载/引入/ ...
- 转】用Maven构建Mahout项目
原博文出自于: http://blog.fens.me/hadoop-mahout-maven-eclipse/ 感谢! 用Maven构建Mahout项目 Hadoop家族系列文章,主要介绍Hadoo ...