Unity着色器教程 | 积雪效果(改进版 原版本有问题)

    最近想在游戏项目中实现一套天气系统,看到这个文章自己做了一下实现发现不对不知道是不是因为我升级u3d至5.5的原因总是报错主要两个错误:

1、摄像机反转,摄像机的显示和shader执行后的是上下翻转的出现这个情况我的解决方法是将Rendering Path从Deferred设置为Legacy Deferred就ok了。

2、return lerp(col, snowColor, snowAmount);这句话会有一个错误Shader error in 'Jamesloo/ScreenSpaceSnow': cannot implicitly convert from 'const half3' to 'half4' at line 86 (on d3d11) 修改办法是将half3 col = tex2D(_MainTex, i.uv); 改为half4 col = tex2D(_MainTex, i.uv);即可。

奉上源码:

using UnityEngine;
using System.Collections;

[ExecuteInEditMode]
public class ScreenSpaceSnow : MonoBehaviour
{
    public Camera m_Cam;
	public Texture2D SnowTexture;

	public Color SnowColor = Color.white;

	public float SnowTextureScale = 0.1f;

	[Range(-1, 1)]
	public float BottomThreshold = 0f;
	[Range(-1, 1)]
	public float TopThreshold = 1f;

	private Material _material;

	void OnEnable()
	{
		// dynamically create a material that will use our shader
		_material = new Material(Shader.Find("Jamesloo/ScreenSpaceSnow"));

		// tell the camera to render depth and normals
		GetComponent<Camera>().depthTextureMode |= DepthTextureMode.DepthNormals;
	}

	void OnRenderImage(RenderTexture src, RenderTexture dest) 
	{
        // set shader properties
        //_material.SetMatrix("_CamToWorld", GetComponent<Camera>().cameraToWorldMatrix);
        //m_Cam.ResetWorldToCameraMatrix
        _material.SetMatrix("_CamToWorld", m_Cam.worldToCameraMatrix);
        _material.SetColor("_SnowColor", SnowColor);
		_material.SetFloat("_BottomThreshold", BottomThreshold);
		_material.SetFloat("_TopThreshold", TopThreshold);
		_material.SetTexture("_SnowTex", SnowTexture);
		_material.SetFloat("_SnowTexScale", SnowTextureScale);

		// execute the shader on input texture (src) and write to output (dest)
		Graphics.Blit(src, dest, _material);
    }
}

创建脚本绑定至你的场景主摄像机。

Shader "Jamesloo/ScreenSpaceSnow"
{
	Properties
	{
		_MainTex ("Texture", 2D) = "white" {}
	}
	SubShader
	{
		// No culling or depth
		Cull Off ZWrite Off ZTest Always

		Pass
		{
			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag
			
			#include "UnityCG.cginc"

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

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

			v2f vert (appdata v)
			{
				v2f o;
				o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
				o.uv = v.uv;
				return o;
			}
			
			sampler2D _MainTex;
			sampler2D _CameraDepthNormalsTexture;
			float4x4 _CamToWorld;

			sampler2D _SnowTex;
			float _SnowTexScale;

			half4 _SnowColor;

			fixed _BottomThreshold;
			fixed _TopThreshold;
			
			half4 frag (v2f i) : SV_Target
			{
				half3 normal;
				float depth;

				DecodeDepthNormal(tex2D(_CameraDepthNormalsTexture, i.uv), depth, normal);
				normal = mul((float3x3)_CamToWorld, normal);

				// find out snow amount
				half snowAmount = normal.g;
				half scale = (_BottomThreshold + 1 - _TopThreshold) / 1 + 1;
				snowAmount = saturate((snowAmount - _BottomThreshold) * scale);

				 //find out snow color
				float2 p11_22 = float2(unity_CameraProjection._11, unity_CameraProjection._22);
		        float3 vpos = float3((i.uv * 2 - 1) / p11_22, -1) * depth;
		        float4 wpos = mul(_CamToWorld, float4(vpos, 1));
		        wpos += float4(_WorldSpaceCameraPos, 0) / _ProjectionParams.z;

		        half4 snowColor = tex2D(_SnowTex, wpos.xz * _SnowTexScale * _ProjectionParams.z) * _SnowColor;

		        // get color and lerp to snow texture
		        half4 col = tex2D(_MainTex, i.uv);
				//return col;
				return lerp(col, snowColor, snowAmount);
			}
			ENDCG
		}
	}
}

如果不明白实现的原理可以参考原文http://blog.theknightsofunity.com/make-it-snow-fast-screen-space-snow-shader/

最终效果图

Bottom Threshold = -1


Bottom Threshold = 0

评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值