《UnityShader入门精要》第15章的水波效果好像有问题!??

震惊 我发现书上有些地方都写错了

起初是因为完全照着敲,结果现象完全不一样,就是那种一眼就看出来错的很离谱的那种。。

遵循图形学第一定律,看上去对的就是对的

那看上去有问题,肯定有问题咯

出处是第15章的水波效果

源码如下:

// Upgrade NOTE: replaced '_Object2World' with 'unity_ObjectToWorld'
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'

Shader "Unlit/NewUnlitShader 5"
{
    Properties
	{
		_Color("水面颜色",Color) = (0,0.15,0.115,1)
		_MainTex("水面材质",2D) = "white" {}
		_WaveMap("噪声纹理",2D) = "bump" {}
		_CubeMap("环境纹理",Cube) = "_Skybox" {}
		_WaveXSpeed("波浪在水平方向上的速度",Range(-0.1,0.1)) = 0.01
		_WaveYSpeed("波浪在竖直方向上的速度",Range(-0.1,0.1)) = 0.01
		_Distortion("折射图像扭曲程度",Range(0,100)) = 10
	}
	SubShader
	{
			Tags{"Queue" = "Transparent" "RenderType" = "Opaque"}
			GrabPass {"_RefractionTex"}
			Pass
			{
				Tags{"LightMode" = "ForwardBase"}
				CGPROGRAM
				#pragma vertex vert
				#pragma fragment frag
				#pragma multi_compile_fwdbase
				#include "UnityCG.cginc"
				#include "Lighting.cginc"
				#include "AutoLight.cginc"
				
				struct a2v
				{
					float4 vertex :  POSITION;
					float2 uv : TEXCOORD0;
					float3 normal : NORMAL;
					float4 tangent : TANGENT;
				};
				struct v2f
				{
					float4 pos : SV_POSITION;
					float4 scrPos : TEXCOORD0;
					float4 uv : TEXCOORD1;
					float4 TtoW0 : TEXCOORD2;
					float4 TtoW1 : TEXCOORD3;
					float4 TtoW2 : TEXCOORD4;
				};
				fixed4 _Color;
				sampler2D _MainTex;
				float4 _MainTex_ST;
				sampler2D _WaveMap;
				float4 _WaveMap_ST;
				samplerCUBE _CubeMap;
				fixed _WaveXSpeed;
				fixed _WaveYSpeed;
				float _Distortion;
				sampler2D _RefractionTex;
				float4 _RefractionTex_TexelSize;

				v2f vert(a2v v)
				{
					v2f o;
					o.pos = UnityObjectToClipPos(v.vertex);
					o.scrPos = ComputeGrabScreenPos(o.pos);
					o.uv.xy = TRANSFORM_TEX(v.uv, _MainTex);
					o.uv.zw = TRANSFORM_TEX(v.uv, _WaveMap);
					float3 worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;
					fixed3 worldNormal = UnityObjectToWorldNormal(v.normal);
					float3 worldTangent = UnityObjectToWorldDir(v.tangent.xyz);
					float3 worldBitangent = cross(worldNormal, worldTangent) *v.tangent.w;
					o.TtoW0 = float4 (worldTangent.x, worldBitangent.x, worldNormal.x, worldPos.x);
					o.TtoW1 = float4 (worldTangent.y, worldBitangent.y, worldNormal.y, worldPos.y);
					o.TtoW2 = float4 (worldTangent.z, worldBitangent.z, worldNormal.z, worldPos.z);
					return o;
				}
				fixed4 frag(v2f i) : SV_Target
				{
					float3 worldPos = float3(i.TtoW0.z,i.TtoW1.z,i.TtoW2.z);
					fixed3 viewDir = normalize(UnityWorldSpaceViewDir(worldPos));
					fixed3 lightDir = normalize(UnityWorldSpaceLightDir(worldPos));
					float2 speed = _Time.y * float2(_WaveXSpeed, _WaveYSpeed);
					fixed3 bump1 = UnpackNormal(tex2D(_WaveMap, i.uv.zw + speed)).rgb;
					fixed3 bump2 = UnpackNormal(tex2D(_WaveMap, i.uv.zw - speed)).rgb;
					fixed3 bump = normalize(bump1 + bump2);

					float2 offset = bump.xy *_Distortion * _RefractionTex_TexelSize.xy;
					i.scrPos.xy = offset * i.scrPos.z + i.scrPos.xy;
					fixed3 refractioncolor = tex2D(_RefractionTex, i.scrPos.xy / i.scrPos.w).rgb;
					bump = normalize(half3(dot(i.TtoW0.xyz, bump), dot(i.TtoW1.xyz, bump), dot(i.TtoW2.xyz, bump)));
					fixed4 texCol = tex2D(_MainTex, i.uv.xy + speed);
					fixed3 reflDir = reflect(-viewDir, bump);
					fixed3 reflectioncolor = texCUBE(_CubeMap, reflDir).rgb * texCol * _Color.rgb;

					fixed fresnel = pow(1 - saturate(dot(viewDir, bump)), 4);
					fixed3 finalcol = reflectioncolor * fresnel + refractioncolor * (1 - fresnel);
					return fixed4(finalcol,1);
				}
				ENDCG
			}
	}
	
}

这是照搬书上的没改动之前

其中有两处疑点,一个是对于屏幕坐标的偏移,一个是反射方向的获取

i.scrPos.xy = offset * i.scrPos.z + i.scrPos.xy;

fixed3 reflDir = reflect(-viewDir, bump);

在这里插入图片描述

在这里插入图片描述

照着书上敲,现象如下

在这里插入图片描述

画面没有折射的效果,水底的物体清晰可见

而且更鬼畜的是,, 随着视角变动,水还会变成五颜六色的(捂脸)在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

经过我的无脑实验

我把 i.scrPos.xy = offset * i.scrPos.z + i.scrPos.xy; 改成了

i.scrPos.xy = offset * i.scrPos.w + i.scrPos.xy;

还有反射的计算参数,改成了光照方向

fixed3 reflDir = reflect(-lightDir, bump);

现象如下在这里插入图片描述

水的颜色突然正常了!

然后底下的图像也有了扭曲的效果,扭曲可能看不太出来,我不会截gif,所以大家自己去试试看吧,真的扭曲了

具体的原理原因,到底为什么,我也不知道 hehe

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值