如果你只做能力范围之内的事,你就永远不会有进步!|

陈侠云

园龄:2年10个月粉丝:1关注:1

实现一个前向渲染的Phong模型(二)

前言:

实现一个前向渲染的Phong模型(一):https://www.cnblogs.com/chenxiayun/p/18130433


HDR和色调映射

HDR即指高动态光照渲染,HDR是一种提高影像亮度和对比度的处理技术,与普通图像相比,HDR可以提供更多的动态范围和图像细节,利用每个曝光时间相对应最佳细节的LDR图像来合成最终HDR图像,能够更好地反映出真实环境中的视觉效果。
举例来讲,一般电脑存储的亮度比为2^8, 但下图的亮度信息可能达到了2^16之多, 用256个数字来模拟2^16的亮度信息,这种模拟方法就是HDR的核心技术之一,学名叫Tone-Mapping(亮度映射)。
image
可以看到当亮度调高以后,很多细节都会出现过曝的情况,这是因为最终的finalColor可能远远的超出了1,这个时候就需要利用HDR技术,让细节更加完善。
image

色调映射

首先看到色调映射的拟合曲线,我们可以看到超出横坐标超出1以后,纵坐标会缓慢达到1
image
在shader中实现一下

	float3 ACESFilm(float3 x)
	{
		float a = 2.51f;
		float b = 0.03f;
		float c = 2.43f;
		float d = 0.59f;
		float e = 0.14f;
		return saturate((x*(a*x + b)) / (x*(c*x + d) + e));
	};
			
	half3 final_color = (diffuse_color + spec_color + _AmbientColor.xyz) * ao_color;
        half3 tone_color = ACESFilm(final_color);
        return fixed4(tone_color,1);

在看看实际效果对比,左边无hdr,右边有hdr
image

shader中添加环境光

                half3 ambient_color = UNITY_LIGHTMODEL_AMBIENT.rgb * base_color.xyz;
                half3 final_color = (diffuse_color + spec_color + ambient_color) * ao_color;
                half3 tone_color = ACESFilm(final_color);
                return fixed4(tone_color,1);

环境光就可以在下图所示位置进行调整
image

视差贴图

视差贴图属于位移贴图(Displacement Mapping)技术的一种,它对根据储存在纹理中的几何信息对顶点进行位移或偏移。根据纹理中的数据对平面特定区域的顶点的高度进行位移。这样的每个纹理像素包含了高度值纹理叫做高度贴图。
image
image
这里粗糙的红线代表高度贴图中的数值的立体表达,向量V¯代表观察方向。如果平面进行实际位移,观察者会在点B看到表面。然而我们的平面没有实际上进行位移,观察方向将在点A与平面接触。视差贴图的目的是,在A位置上的fragment不再使用点A的纹理坐标而是使用点B的。随后我们用点B的纹理坐标采样,观察者就像看到了点B一样。
视差贴图尝试通过对从fragment到观察者的方向向量V¯进行缩放的方式解决这个问题,缩放的大小是A处fragment的高度。所以我们将V¯的长度缩放为高度贴图在点A处H(A)采样得来的值。

                half3 normal_dir = normalize(i.normal_dir);
                half3 tangent_dir = normalize(i.tangent_dir);
                half3 binormal_dir = normalize(i.binormal_dir);
                float3x3 TBN = float3x3(tangent_dir, binormal_dir, normal_dir);
                half3 view_dir = normalize(_WorldSpaceCameraPos.xyz - i.pos_world);
                half3 view_tangentspace = normalize(mul(TBN, view_dir));
                half2 uv_parallex = i.uv;
                half height = tex2D(_ParallaxMap, uv_parallex);
                uv_parallex = uv_parallex - (1 - height) * view_tangentspace.xy * _Parallax * 0.01f;

基本原理,将观察方法转移到切线空间下,采用高度图,根据采样得到的高度,对切线空间下的观察方向做偏移,最终得到偏移后的uv坐标
左边是不做偏移,右边做了偏移
image

参考资料

  1. https://learnopengl-cn.github.io/05 Advanced Lighting/05 Parallax Mapping/

本文作者:陈侠云

本文链接:https://www.cnblogs.com/chenxiayun/p/18139727

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   陈侠云  阅读(16)  评论(0编辑  收藏  举报
//雪花飘落效果
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起