区块链是一种块链式数据结构,以时间先后为基准,将存储数据的区块以顺序相连的形式相结合,同时以密码学方式确保数据的不可篡改和不可伪造,是一种安全性极高的分布式账本。广义来讲,区块链利用块链式数据结构来对数据进行验证与存储、利用分布式节点共识算法对数据进行更新、利用密码学方式确保数据的传输与访问安全、利用自动化脚本编写的智能合约来对数据进行编程和操作,是一种全新的分布式架构基础与计算方式。
区块链的基本特性主要体现在5个方面:
1)去中心化:以分布式网络为基础结构,对数据进行验证、记账、存储、维护和传输等操作,利用纯数学方法建立节点之间的交互信任关系,进而形成去中心化、可信任的分布式系统;
2)时序数据:块链式数据结构携带时间戳,为数据添加时间维度,使得数据能够验证与追溯;
3)集体维护:区块链系统使用特有的激励机制以保证系统中所有节点均愿意参与区块的验证,在此过程中采用共识算法选择特定节点,为区块链添加新的区块;
4)可编程:区块链技术提供灵活自由的脚本系统,可以支持用户创建多种形式的去中心化应用;
5)安全可信:以非对称密码学原理为理论基础,对数据进行单向加密,从而确保了数据的安全性;同时借助分布式系统,利用工作量证明等共识机制形成的大量算力,对可能存在的外部攻击进行抵御,保证数据不能够被篡改或伪造。
整个shader代码:
Shader"Luoyinan/ImageEffect/ScreenSpaceRain"{
Properties
{
_MainTex("Texture",2D)="white"{}
}
SubShader
{
Cull Off
ZWrite Off
ZTest Always
Fog{Mode off}
Pass
{
CGPROGRAM#pragma vertex vert
#pragma fragment frag
#include"UnityCG.cginc"
struct appdata
{
float4 vertex:POSITION;
float2 texcoord:TEXCOORD0;
};
struct v2f
{
float4 pos:SV_POSITION;
float2 uv:TEXCOORD0;
float3 ray:TEXCOORD1;
};
v2f vert(appdata v){
v2f o;
o.pos=mul(UNITY_MATRIX_MVP,v.vertex);
o.uv=v.texcoord;
//screen pos->view pos
float4 cameraRay=mul(unity_CameraInvProjection,float4(v.texcoord*2-1,1,1));//farPlane
cameraRay.z*=-1;//摄像机的正向是-Z轴,正好和Unity默认的Z轴相反.
o.ray=cameraRay.xyz/cameraRay.w;return o;
}
sampler2D _MainTex;
sampler2D _CameraDepthNormalsTexture;
float4x4 _CamToWorld;
sampler2D _RippleTex;float _RippleTexScale;fixed _RippleIntensity;fixed _RippleBlendFactor;
sampler2D _WaveTex;fixed _WaveIntensity;fixed _WaveTexScale;
half4 _WaveForce;
samplerCUBE _ReflectionTex;
fixed _RainIntensity;
half _MaxDistance;
half4 frag(v2f i):SV_Target{
fixed4 finalColor=tex2D(_MainTex,i.uv);
//normal&depth
half3 normal;float depth;
DecodeDepthNormal(tex2D(_CameraDepthNormalsTexture,i.uv),depth,normal);
normal=mul((float3x3)_CamToWorld,normal);//normal=mul((float3x3)unity_CameraToWorld,normal);
half filter=normal.y;
//view pos->world pos
float4 viewPos=float4(i.ray*depth,1);
float4 worldPos=mul(unity_CameraToWorld,viewPos);
//distance
half d=length(worldPos.xyz-_WorldSpaceCameraPos.xyz);if(d<_MaxDistance)//performance
{//wave
half3 bump=UnpackNormal(tex2D(_WaveTex,worldPos.xz_WaveTexScale+_Time.xx_WaveForce.xy));
bump+=UnpackNormal(tex2D(_WaveTex,worldPos.xz_WaveTexScale+_Time.xx_WaveForce.zw));
bump*=0.5;
//ripple
half3 ripple=UnpackNormal(tex2D(_RippleTex,worldPos.xz*_RippleTexScale));
normal.xy=lerp(normal.xy,ripple.xy_RippleIntensity+bump.xy_WaveIntensity,_RippleBlendFactor);
//reflection
half3 viewDir=normalize(_WorldSpaceCameraPos-worldPos);
half3 reflUVW=normalize(reflect(-viewDir,normal));//half fresnel=1-saturate(dot(viewDir,normal));
//fresnel=0.25+fresnel*0.75;
half4 reflection=texCUBE(_ReflectionTex,reflUVW)*_RainIntensity;
finalColor+=reflectionnormal.ystep(0.1,filter)filter2;
}
return finalColor;
}
ENDCG
}
}
}
C#脚本代码:
using UnityEngine;using System.Collections;
namespace Luoyinan{
[AddComponentMenu("Image Effects/ScreenSpaceRain")]public class ScreenSpaceRain:ImageEffect
{public float maxDistance=100.0f;public Texture2D[]rippleTextures;public Texture2D waveTexture;public Cubemap reflectionTexture;public float rippleTextureScale=0.3f;public float rippleFrequency=20.0f;
[Range(0.5f,2)]public float rippleIntensity=1.25f;
[Range(0,1)]public float rippleBlendFactor=0.9f;
public Vector4 waveForce=new Vector4(1.0f,1.0f,-1.0f,-1.0f);public float waveIntensity=0.2f;public float waveTextureScale=0.15f;
public float rainIntensity=1.0f;
private int m_CurRippleTextureIndex=0;private float m_LastTime=0;
private static ScreenSpaceRain m_Instance;public static ScreenSpaceRain Instance
{get{return m_Instance;}
}
void Awake(){if(null!=m_Instance)
{
LogSystem.ErrorLog("Awake()这个函数只能被调用一次!!!!");return;
}
m_Instance=this;
CheckSupport("Luoyinan/ImageEffect/ScreenSpaceRain",DepthTextureMode.DepthNormals);
if(rippleTextures==null)
{int count=24;
rippleTextures=new Texture2D[count];for(int i=0;i<count;++i)
{
rippleTextures<i>=Resources.Load("Texture/Rain/Ripple/ripple"+(i+1)+"_ddn")as Texture2D;
}
}
if(waveTexture==null)
{
waveTexture=Resources.Load("Texture/Rain/wave")as Texture2D;
}
if(reflectionTexture==null)
{
reflectionTexture=Resources.Load("Texture/Reflection_2")as Cubemap;
}
}
void OnEnable(){if(!isSupport)return;
ImageEffectMgr.Instance.AddDepthTextureModeCount(GetComponent<Camera>(),DepthTextureMode.DepthNormals);
}
void OnDisable(){if(!isSupport)return;
ImageEffectMgr.Instance.RemoveDepthTextureModeCount(GetComponent<Camera>(),DepthTextureMode.DepthNormals);
}
void Update(){if(!isSupport)return;
float f=rippleFrequency(rainIntensity0.5f+0.5f);if(Time.time-m_LastTime>1.0f/f)
{
m_LastTime=Time.time;
++m_CurRippleTextureIndex;if(m_CurRippleTextureIndex>=rippleTextures.Length)
m_CurRippleTextureIndex=0;
}
}
void OnRenderImage(RenderTexture src,RenderTexture dest){if(!isSupport)
{
Graphics.Blit(src,dest);return;
}
m_Material.SetMatrix("_CamToWorld",GetComponent<Camera>().cameraToWorldMatrix);
m_Material.SetFloat("_MaxDistance",maxDistance);
m_Material.SetTexture("_RippleTex",rippleTextures[m_CurRippleTextureIndex]);
m_Material.SetTexture("_WaveTex",waveTexture);
m_Material.SetTexture("_ReflectionTex",reflectionTexture);
m_Material.SetFloat("_RippleTexScale",rippleTextureScale);
m_Material.SetFloat("_RippleFrequency",rippleFrequency);
m_Material.SetFloat("_RippleIntensity",rippleIntensity);
m_Material.SetFloat("_RippleBlendFactor",rippleBlendFactor);
m_Material.SetFloat("_RainIntensity",rainIntensity);
m_Material.SetVector("_WaveForce",waveForce);
m_Material.SetFloat("_WaveIntensity",waveIntensity);
m_Material.SetFloat("_WaveTexScale",waveTextureScale);
Graphics.Blit(src,dest,m_Material);
}
void OnDestroy(){
m_Instance=null;
}
}
}