技术美术TA之屏幕扭曲材质

本文是视频课程《Unity技术美术TA:Shader篇》,算是对自己学习的总结,也希望分享下所学知识~~
(原课程链接传送门

扭曲的作用
1.热扭曲
2.水体等特殊表现
(手机端比较耗费性能)

热扭曲如何实现?
1.扭曲材质赋予面片
2.抓取当前一帧的图片内容
3.获取屏幕坐标
4.利用屏幕坐标对抓取的图片进行采样
5.采样扰动贴图做扭曲

屏幕坐标不是屏幕分辨率坐标,是限制在 0-1 的
归一化坐标 = 当前像素 / 总像素

如何得到屏幕坐标?
1.使用 UNITY_VPOS_TYPE screenPos: VPOS

 // 在使用VPOS时,就不能在v2f中定义SV_POSITION,这样会冲突,
 //  	需要把顶点着色器的输入放在()的参数中,并且SV_POSITION添加out.
 v2f vert(
     float4 vertex : POSITION,
     out float4 pos: SV_POSITION
 )
 {
     v2f o;
     pos = UnityObjectToClipPos(vertex);
     return o;
 }
 
 //当前片断在屏幕上的位置(单位是像素,可除以_ScreenParams.xy来做归一化)
 // 大部分平台下VPOS返回的是一个四维向量,部分平台是二维向量,所以需要用UNITY_VPOS_TYPE来统一区分.
 fixed4 frag(v2f i, UNITY_VPOS_TYPE screenPos: VPOS) : SV_Target
 {
     fixed2 screenUV = screenPos.xy / _ScreenParams.xy;
     return screenUV.x or y;
 }

2.自己计算齐次坐标

v2f vert(appdata v)
{
    v2f o;
    o.pos = UnityObjectToClipPos(v.vertex);
    o.uv = TRANSFORM_TEX(v.uv, _DistortTex) + _Distort.xy * _Time.y;
    
    // 注意范围转换: [-1,1] -> [0,1]
    // 注意 openGL 和DX 坐标不一样的问题
    o.screenUV.xyz = (o.pos.xyz / o.pos.w) * 0.5 + 0.5;
    
    /也可以用内置函数: pos为裁剪空间下的坐标位置,返回的是某个投影点下的屏幕坐标位置(未除以齐次坐标)
	//    o.screenUV = ComputeGrabScreenPos(o.pos);
    return o;
}

fixed4 frag(v2f i) : SV_Target
{
     fixed2 screenUV= i.screenUV;
     // DX 左上角是0
     screenUV.y = 1 - uv.y;

	//	内置函数的用法
    // fixed2 screenUV = i.screenUV.xy / i.screenUV.w;
	//   或者采样使用用 proj tex2Dproj(_GrabTex, i.screenUV);

    return screenUV.x or y;
}

3.直接用引擎转换的 SV_POSITION

v2f vert(appdata v)
{
    v2f o;
    
	//从本地空间变换到裁剪空间(没做透视除法)
    o.pos = UnityObjectToClipPos(v.vertex);
    o.uv = TRANSFORM_TEX(v.uv, _DistortTex) + _Distort.xy * _Time.y;
    return o;
}

fixed4 frag(v2f i) : SV_Target
{
    // 顶点着色器在裁剪空间下返回的 SV_POSITION 会自动变成 屏幕像素坐标,自己定义的不会
    fixed2 screenUV = i.pos.xy / _ScreenParams.xy;
    
    return screenUV.x or y;
}

扰动贴图实现

核心代码如下:
使用原屏幕uv 和 扰动贴图采样的UV 做 lerp

fixed4 distortTex = tex2D(_DistortTex, i.uv);
fixed2 uv = lerp(screenUV, distortTex, _Distort);

效果如图:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值