unity-关于shader海平面制作

本文深入探讨了Unity Shader中实现模型表面波动效果的方法,通过详细分析代码,解释了如何使用距离、时间及正弦函数计算顶点偏移,以及如何在世界空间中应用变换矩阵。此外,还介绍了关键的CG函数如tex2D和TRANSFORM_TEX的用法。
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'

Shader "Custom/sin_shader"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 100

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
          

            #include "UnityCG.cginc"   //使用unity自带的库文件,常用的内置函数在里面

            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;//绑定第一张纹理图
            };

            struct v2f
            {
                float2 uv : TEXCOORD0;     
                float4 vertex : POSITION;
            };

            sampler2D _MainTex;//2D纹理图片
			float4 _MainTex_ST;//而_MainTex_ST的ST是SamplerTexture的意思 ,就是声明_MainTex是一张采样图,也就是会进行UV运算。  如果没有这句话,是不能进行TRANSFORM_TEX的运算的。
			//下面的两个函数是等价的o.uv =   TRANSFORM_TEX(v.texcoord,_MainTex);
			//o.uv = v.texcoord.xy * _MainTex_ST.xy + _MainTex_ST.zw;
			//_MainTex_ST中的ST是Sampler texture ,声明这个变量是为了告诉编译器_Main_TEX是一张纹理采样图,如果没有这句话,_Main_TEX是不能参与运算的。
			
            v2f vert (appdata v)
            {
				v2f o;
				float dist = distance(v.vertex.xyz, float3(0, 0, 0));
				float h = sin(dist*20 + _Time.z);
				o.vertex = mul(unity_ObjectToWorld, v.vertex);//先把模型坐标转换成世界坐标,在世界空间震荡,所以要在世界空间例修改
				o.vertex.y = h;//将顶点赋值
				o.vertex = mul(unity_WorldToObject, o.vertex);//将点的世界坐标转换成模型坐标
				o.vertex = mul(UNITY_MATRIX_MVP,o.vertex);//用于将顶点/方向矢量坐标从模型空间变换成剪裁空间,在显示器上显示 
				
				o.uv = TRANSFORM_TEX(v.uv,_MainTex);//将坐标转换成真正的uv坐标(在屏幕中的坐标)返回的是uv坐标
                return o;//保存的v2f 
            }
			//这里的i就是承接上一个函数中路下一个工位的o
            fixed4 frag (v2f i) : SV_Target
            {
                // sample the texture
				fixed4 col = tex2D(_MainTex, i.uv);//tex2D(sampler2D tex, float2 s)函数,
			//这是CG程序中用来在一张贴图中对一个点进行采样的方法,返回一个float4。这里对 _MainTex在输入点
			//上进行了采样,并将其颜色的rbg值赋予了输出的像素颜色,将a值赋予透明度。于是,
			//着色器就明白了应当怎样工作:即找到贴图上 对应的uv点,直接使用颜色信息来进行着色,over。
                return col;
            }
            ENDCG
        }
    }
}

不懂可以看后面的注释
shader中做成unity_ObjectToWorld矩阵来实现局部转世界的转换
tex2D(sampler2D tex, float2 s)函数是shader中用来在一张贴图中对一个点进行采样的方法,返回一个float4,在上面的代码中是对_MainTex在输入点上进行了采样,并将其颜色的rgb值赋予了输出的像素颜色。
distance(float3 x,float3 y),计算两个点的距离
sin()计算两点之间的正弦值

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

### 创建海平面雾气特效的方法 在 Unity 中实现海平面雾气效果可以通过多种方式完成,具体取决于所需的视觉质量和性能需求。以下是几种常见的方法及其对应的教程和脚本示例。 #### 方法一:使用 Shader 实现雾气效果 通过编写自定义着色器 (Shader),可以精确控制雾气的颜色、密度以及随高度变化的效果。这种方法适合需要高质量渲染的场景。 ```csharp // 海平面雾气着色器示例 Shader "Custom/SeaFog" { Properties { _MainTex ("Texture", 2D) = "white" {} _FogColor ("Fog Color", Color) = (0.5, 0.5, 0.5, 1) _Density ("Fog Density", Float) = 0.01 _HeightFactor ("Height Factor", Float) = 10 } SubShader { Tags { "RenderType"="Opaque" } LOD 200 Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" struct appdata_t { float4 vertex : POSITION; float2 uv : TEXCOORD0; }; struct v2f { float2 uv : TEXCOORD0; float4 vertex : SV_POSITION; float height : TEXCOORD1; // 添加高度变量 }; sampler2D _MainTex; float4 _MainTex_ST; fixed4 _FogColor; float _Density; float _HeightFactor; v2f vert (appdata_t v) { v2f o; o.vertex = UnityObjectToClipPos(v.vertex); o.uv = TRANSFORM_TEX(v.uv, _MainTex); // 计算世界空间的高度 float3 worldPos = mul(unity_ObjectToWorld, v.vertex).xyz; o.height = worldPos.y / _HeightFactor; // 归一化高度 return o; } fixed4 frag (v2f i) : SV_Target { fixed4 col = tex2D(_MainTex, i.uv); // 应用基于高度的雾效 float fogAmount = saturate(exp(-_Density * i.height)); col.rgb = lerp(col.rgb, _FogColor.rgb, fogAmount); return col; } ENDCG } } } ``` 此着色器利用指数函数计算雾浓度,并根据物体的世界坐标高度调整雾效强度[^1]。 --- #### 方法二:使用粒子系统模拟动态雾气 如果希望雾气具有更生动的表现形式(如流动感),可以借助 Unity 的 Particle System 组件来实现。 ##### 设置步骤: 1. **创建粒子系统** 在 Scene 视图中右键 -> Effects -> Particle System。 2. **配置发射参数** - 将 `Emission` Rate 调整到合适的范围。 - 使用纹理贴图赋予粒子云状外观。 3. **添加力场影响** 可以为粒子施加风力或其他外部作用力,使其看起来更加自然。 4. **限制区域** 结合 Collision 或 Trigger 模块限定雾气仅覆盖水面附近区域[^2]。 --- #### 方法三:结合 Physically Based Sky 进行环境增强 为了营造更具沉浸感的大气氛围,还可以引入真实的天空盒资源并配合 Post Processing Stack 插件调节整体色调对比度等参数。 安装 Asset Store 上提供的 “Physically Based Sky” 工具后,在其设置面板里找到有关散射光线的相关选项进行微调直至达到理想状态为止[^3]。 --- ### 注意事项 无论采用哪种技术方案都需注意平衡画质与运行效率之间的关系特别是在移动平台上更要谨慎对待复杂运算操作以免造成卡顿现象发生。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值