using UnityEngine;
using System.Collections;
[ExecuteInEditMode]
[RequireComponent (typeof (Camera))]
public class PostEffectsBase : MonoBehaviour {
protected void Start () {
CheckResources();
}
protected void CheckResources () {
bool isSupported = CheckSupport();
if (isSupported == false ) {
NotSupported();
}
}
protected bool CheckSupport () {
if (SystemInfo.supportsImageEffects == false || SystemInfo.supportsRenderTextures == false ) {
Debug.LogWarning("This platform does not support image effects or render textures." );
return false ;
}
return true ;
}
protected void NotSupported () {
enabled = false ;
}
protected Material CheckShaderAndCreateMaterial (Shader shader, Material material) {
if (shader == null ) {
return null ;
}
if (shader.isSupported && material && material.shader == shader)
return material;
if (!shader.isSupported) {
return null ;
}
else {
material = new Material(shader);
material.hideFlags = HideFlags.DontSave;
if (material)
return material;
else
return null ;
}
}
}
using UnityEngine;
using System.Collections;
public class FogWithNoise : PostEffectsBase {
public Shader fogShader;
private Material fogMaterial = null ;
public Material material {
get {
fogMaterial = CheckShaderAndCreateMaterial(fogShader, fogMaterial);
return fogMaterial;
}
}
private Camera myCamera;
public Camera camera {
get {
if (myCamera == null ) {
myCamera = GetComponent<Camera>();
}
return myCamera;
}
}
private Transform myCameraTransform;
public Transform cameraTransform {
get {
if (myCameraTransform == null ) {
myCameraTransform = camera.transform;
}
return myCameraTransform;
}
}
[Range(0.1 f, 3.0 f)]
public float fogDensity = 1.0 f;
public Color fogColor = Color.white;
public float fogStart = 0.0 f;
public float fogEnd = 2.0 f;
public Texture noiseTexture;
[Range(-0.5 f, 0.5 f)]
public float fogXSpeed = 0.1 f;
[Range(-0.5 f, 0.5 f)]
public float fogYSpeed = 0.1 f;
[Range(0.0 f, 3.0 f)]
public float noiseAmount = 1.0 f;
void OnEnable() {
GetComponent<Camera>().depthTextureMode |= DepthTextureMode.Depth;
}
void OnRenderImage (RenderTexture src, RenderTexture dest) {
if (material != null ) {
Matrix4x4 frustumCorners = Matrix4x4.identity;
float fov = camera.fieldOfView;
float near = camera.nearClipPlane;
float aspect = camera.aspect;
float halfHeight = near * Mathf.Tan(fov * 0.5 f * Mathf.Deg2Rad);
Vector3 toRight = cameraTransform.right * halfHeight * aspect;
Vector3 toTop = cameraTransform.up * halfHeight;
Vector3 topLeft = cameraTransform.forward * near + toTop - toRight;
float scale = topLeft.magnitude / near;
topLeft.Normalize();
topLeft *= scale;
Vector3 topRight = cameraTransform.forward * near + toRight + toTop;
topRight.Normalize();
topRight *= scale;
Vector3 bottomLeft = cameraTransform.forward * near - toTop - toRight;
bottomLeft.Normalize();
bottomLeft *= scale;
Vector3 bottomRight = cameraTransform.forward * near + toRight - toTop;
bottomRight.Normalize();
bottomRight *= scale;
frustumCorners.SetRow(0 , bottomLeft);
frustumCorners.SetRow(1 , bottomRight);
frustumCorners.SetRow(2 , topRight);
frustumCorners.SetRow(3 , topLeft);
material.SetMatrix("_FrustumCornersRay" , frustumCorners);
material.SetFloat("_FogDensity" , fogDensity);
material.SetColor("_FogColor" , fogColor);
material.SetFloat("_FogStart" , fogStart);
material.SetFloat("_FogEnd" , fogEnd);
material.SetTexture("_NoiseTex" , noiseTexture);
material.SetFloat("_FogXSpeed" , fogXSpeed);
material.SetFloat("_FogYSpeed" , fogYSpeed);
material.SetFloat("_NoiseAmount" , noiseAmount);
Graphics.Blit (src, dest, material);
} else {
Graphics.Blit(src, dest);
}
}
}
Shader "Fog With Noise" {
Properties {
_MainTex ("Base (RGB)" , 2 D) = "white" {}
_FogDensity ("Fog Density" , Float) = 1.0
_FogColor ("Fog Color" , Color) = (1 , 1 , 1 , 1 )
_FogStart ("Fog Start" , Float) = 0.0
_FogEnd ("Fog End" , Float) = 1.0
_NoiseTex ("Noise Texture" , 2 D) = "white" {}
_FogXSpeed ("Fog Horizontal Speed" , Float) = 0.1
_FogYSpeed ("Fog Vertical Speed" , Float) = 0.1
_NoiseAmount ("Noise Amount" , Float) = 1
}
SubShader {
CGINCLUDE
#include "UnityCG.cginc"
float4x4 _FrustumCornersRay
sampler2D _MainTex
half4 _MainTex_TexelSize
sampler2D _CameraDepthTexture
half _FogDensity
fixed4 _FogColor
float _FogStart
float _FogEnd
sampler2D _NoiseTex
half _FogXSpeed
half _FogYSpeed
half _NoiseAmount
struct v2f {
float4 pos : SV_POSITION
float2 uv : TEXCOORD0
float2 uv_depth : TEXCOORD1
float4 interpolatedRay : TEXCOORD2
}
v2f vert(appdata_img v) {
v2f o
o.pos = mul (UNITY_MATRIX_MVP, v.vertex )
o.uv = v.texcoord
o.uv _depth = v.texcoord
// unity左下角0 ,0 右上角1 ,1
//判断是否是directx平台,如果开启了抗锯齿,如果此时使用了渲染到纹理技术
//那么此时纹理不会翻转,在顶点着色器中加入这样的处理
#if UNITY_UV_STARTS_AT_TOP
if (_MainTex_TexelSize.y < 0 )
o.uv _depth.y = 1 - o.uv _depth.y
#endif
// 4 3
// 1 2
int index = 0
if (v.texcoord .x < 0.5 && v.texcoord .y < 0.5 ) {
index = 0
} else if (v.texcoord .x > 0.5 && v.texcoord .y < 0.5 ) {
index = 1
} else if (v.texcoord .x > 0.5 && v.texcoord .y > 0.5 ) {
index = 2
} else {
index = 3
}
#if UNITY_UV_STARTS_AT_TOP
if (_MainTex_TexelSize.y < 0 )
index = 3 - index
#endif
o.interpolatedRay = _FrustumCornersRay[index]
return o
}
fixed4 frag(v2f i) : SV_Target {
// LinearEyeDepth:视角空间下的线性深度值,
// SAMPLE_DEPTH_TEXTURE:深度纹理采样
float linearDepth = LinearEyeDepth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, i.uv _depth))
// 1. 摄像机在世界空间中的位置
// 2. 空间世界下该像素相对于摄像机的偏移量,把他们相加,得到的就是该像素的世界坐标
float3 worldPos = _WorldSpaceCameraPos + linearDepth * i.interpolatedRay .xyz
float2 speed = _Time.y * float2(_FogXSpeed, _FogYSpeed)
float noise = (tex2D(_NoiseTex, i.uv + speed).r - 0.5 ) * _NoiseAmount
float fogDensity = (_FogEnd - worldPos.y ) / (_FogEnd - _FogStart)
fogDensity = saturate(fogDensity * _FogDensity * (1 + noise))
fixed4 finalColor = tex2D(_MainTex, i.uv )
finalColor.rgb = lerp(finalColor.rgb , _FogColor.rgb , fogDensity)
return finalColor
}
ENDCG
Pass {
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
ENDCG
}
}
FallBack Off
}