简单模拟水效果shader练习——UnityShader学习笔记


自言自语

学习shader已经有几个月了。痛并快乐着。今天是学习简单水效果制作。 根据书中讲解。又自己调整和变化了下。出现如下效果。写起来挺简单,不过思路确实如果书上不说,我可想不到。面板就不贴了,支持颜色和方向光颜色强度,存档在这 后边继续。 想把投影也加进去。结果太晚了。肝不动了 空了再说吧。

一、效果

在这里插入图片描述

二、shader部分

Shader "TNShaderPractise/ShaderPractise_WaterMate_041"
{
    Properties
    {
		[HDR]_Color("水体颜色",color)=(1.0,1.0,1.0,1.0)
		[HDR]_Color2("水体反射颜色",color)=(1.0,1.0,1.0,1.0)
        _MainTex ("表面水花", 2D) = "white" {}
		_WaterBump("水体噪声法线贴图",2D)="bump"{}
		_CubeMap("镜面反射环境贴图",Cube)="Skybox"{}
		_Distortion("水折射强度",Range(0,1000.0))=1000
		_Xspeed("横向水流速度", Range(-0.1,0.1))=0
		_Yspeed("横向水流速度",Range(-0.1,0.1))=0
		_AlphaValue("水体透明度",Range(0,1.0))=1.0

    }
    SubShader
    {
        Tags { "RenderType"="Opaque" "Queue"="Transparent" }

		GrabPass{"_RefrctionTex"}

        Pass
        {
			Tags{"LightMode"="ForwardBase"}
			
			Cull Off

			Blend SrcAlpha OneMinusSrcAlpha

            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"
			#include "Lighting.cginc"
			#include "AutoLight.cginc"
			#pragma multi_compile_fwdbase

		    sampler2D _MainTex;
            float4 _MainTex_ST;
			sampler2D _WaterBump;
			float4 _WaterBump_ST;
			samplerCUBE _CubeMap;
			sampler2D _RefrctionTex;
			float4 _RefrctionTex_TexelSize;
			fixed4 _Color;
			float _Xspeed;
			float _Yspeed;
			float _Distortion;
			float4 _Color2;
			float _AlphaValue;


            struct a2v
            {
                float4 vertex : POSITION;
                float2 texcoord : TEXCOORD0;
				float3 normal : NORMAL;
				float4 tangent : TANGENT;
            };

            struct v2f
            {
                float4 uv : TEXCOORD1;
                float4 pos : SV_POSITION;
				float4 posWS : TEXCOORD2;
				float3 TtoW1 : TEXCOORD3;
				float3 TtoW2 : TEXCOORD4;
				float3 TtoW3 : TEXCOORD5;
				float4 scrPos : TEXCOORD7;
				SHADOW_COORDS(6)
            };

            v2f vert (a2v v)
            {
                v2f o;
                o.pos = UnityObjectToClipPos(v.vertex);
                o.uv.xy = TRANSFORM_TEX(v.texcoord, _MainTex);
                o.uv.zw = TRANSFORM_TEX(v.texcoord, _WaterBump);

				o.posWS = mul(unity_ObjectToWorld,v.vertex);
				//获取当前像素所在的屏幕空间坐标
				o.scrPos = ComputeGrabScreenPos(o.pos);
				//常规TBN
				float3 normalWS = UnityObjectToWorldNormal(v.normal);
				float3 tangentWS =UnityObjectToWorldDir(v.tangent.xyz);
				float3 binormalWS = cross(tangentWS,normalWS)*v.tangent.w;

			    o.TtoW1 = float3 (tangentWS.x,binormalWS.x,normalWS.x);
				o.TtoW2 = float3 (tangentWS.y,binormalWS.y,normalWS.y);
				o.TtoW3 = float3 (tangentWS.z,binormalWS.z,normalWS.z);

               TRANSFER_SHADOW(o)

                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
				//声明一个XY轴的速度变量
				float2 speed = _Time.y * float2 (_Xspeed,_Yspeed);
				float3 vDir = normalize(UnityWorldSpaceViewDir(i.posWS.xyz));

				fixed4 col = tex2D (_MainTex,i.uv.xy+speed);
				//通过动态坐标采样并叠加两层 做出水的两层不同流向的感觉
				fixed3 bump1 = UnpackNormal(tex2D(_WaterBump,i.uv.zw+speed));
				fixed3 bump2 = UnpackNormal(tex2D(_WaterBump,i.uv.zw-speed));
				fixed3 bump = normalize(bump1+bump2);

				//做折射表现  因为我乘了一个透明度,所以折射会被削弱那么这里再除回来 进行加强
				float2 offset = bump.xy*_Distortion*_RefrctionTex_TexelSize.xy/_AlphaValue;
				//这个是随着深度加强折射变强 也可以不要乘以i.scrPos.z
				i.scrPos.xy = offset*i.scrPos.z+i.scrPos.xy;
				//折射吗 齐次除法后进行采样
				fixed4 refR = tex2D(_RefrctionTex,i.scrPos.xy/i.scrPos.w);

				half3 nDir = normalize(half3(dot(i.TtoW1.xyz,bump),dot(i.TtoW2.xyz,bump),dot(i.TtoW3.xyz,bump)));

				//反射方向来了哦 
				float3 reflDir = normalize(reflect(-vDir,nDir));

				float3 ambCol = UNITY_LIGHTMODEL_AMBIENT.xyz*col ;

				UNITY_LIGHT_ATTENUATION(atten,i,i.posWS);
				//这里加上灯光强度和颜色对海水的影响 感觉还不错
				fixed4 refL = (texCUBE(_CubeMap,reflDir)*_Color2+_Color*col)*atten*_LightColor0+_LightColor0*0.3+float4(ambCol,1);

				//加上frsnel进行动态插值 这样更符合睡眠反射原理
				float fresnel =1- pow(saturate(dot(vDir,nDir)),4);

				float4 finalCol = lerp(refR,refL,fresnel);

				return fixed4 (finalCol.rgb,_AlphaValue);

            }
            ENDCG

			//应该再有pass写投影.但是太晚了 有空再加吧
        }
    }
	FallBack "Diffuse"
}

总结

反正挺有意思的 继续努力

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值