《真三》与我不得不说的三两事 (ಡωಡ)
《真三》系列在我心中有特殊的地位,小学五年级在姥姥家打开小舅的电脑,发现一款游戏(《真三》3),对于当时的我,从来没有玩过电脑游戏的我来说就像打开新世界的大门,在农村昏黄的白炽灯下,伴着鸡叫,我按下逐个键位尝试去操作,进入游戏后我化身关羽,在战场上任意厮杀。虽然游戏运行后非常卡(FPS极低,大概只有个位数),但对于初次接触电脑游戏的我来说,这简直太棒了! 回到家后我跟小伙伴们讲述《真三》有多么刺激,招式是怎样的,并且模仿那些武将的攻击动作。
当时家用电脑还不普及,我们胡同里七八个小伙伴只有两个人家里有电脑,其中一个就是我的隔壁。我经常去隔壁小伙伴家里看他玩游戏,甚是羡慕,回到家常常幻想我就是游戏中的人物,或是《血战上海滩》中持一把毛瑟与鬼子巷战的抗日战士,或是《魔兽争霸》中英勇无畏的牛头人,或是《侠盗猎车:罪恶都市》中黑白通吃、逍遥法外的克劳德。甚至在学校做值日时,手拿一把扫帚装作持枪模样,嘴里发出“嘚嘚哒”的子弹声......
时至今日,脑海中依旧浮现在昏黄灯下打《真三》,虽然巨卡但是很快乐的画面。
言归正传
《真三》赤壁之战中,火烧船的画面,火苗随机的摇曳:
我实现的效果,树上着火了,火苗随机的摇动:
核心思路:
在片段着色器中,给当前像素一个随机值,让这个像素根据这个随机值偏移。
如何输入随机值?
传入一个噪声图,用噪声图上某个像素的灰度表示随机值。
扫描二维码关注公众号,回复:
2440947 查看本文章
实现火苗的摇曳?
上个问题说到的噪波图,噪声图取得像素点根据时间偏移。
核心代码:
片段着色器:
float4 frag(VertexOutput i) : COLOR {
//光照函数
i.normalDir = normalize(i.normalDir);
float3 normalDirection = i.normalDir;
float3 lightDirection = normalize(_WorldSpaceLightPos0.xyz);
float3 lightColor = _LightColor0.rgb;
float attenuation = LIGHT_ATTENUATION(i);
float3 attenColor = attenuation * _LightColor0.xyz;
float NdotL = max(0.0,dot( normalDirection, lightDirection ));
float3 directDiffuse = max( 0.0, NdotL) * attenColor;
float3 indirectDiffuse = float3(0,0,0);
indirectDiffuse += UNITY_LIGHTMODEL_AMBIENT.rgb;
//x,y方向流动
float2 FlowUV = (i.uv0+float2((_SpeedX*_Time.g),(_Time.g*_SpeedY)));
float4 _NoiseMap_var = tex2D(_NoiseMap,TRANSFORM_TEX(FlowUV, _NoiseMap));
//噪波强度
float2 NoiseUV = (i.uv0+(float2(_NoiseMap_var.r,_NoiseMap_var.g)*_NoiseStrength));
float4 _MainTex_var = tex2D(_MainTex,TRANSFORM_TEX(NoiseUV, _MainTex));
float3 diffuseColor = _MainTex_var.rgb;
float3 diffuse = (directDiffuse + indirectDiffuse) * diffuseColor;
float3 finalColor = diffuse;
fixed4 finalRGBA = fixed4(finalColor,1);
UNITY_APPLY_FOG(i.fogCoord, finalRGBA);
return finalRGBA;
}
需要注意的:
1.注意噪波图不要太平均,因为火苗是块状的。
2.火焰贴图需要有alpha通道,方便开启透明度融合
源码:
Shader "Custom/NoiseFlow" {
Properties {
_MainTex ("主纹理", 2D) = "bump" {}
_NoiseMap ("噪声图", 2D) = "bump" {}
_SpeedX("x方向速度",float)=0.02
_SpeedY("y方向速度",float)=0.02
_NoiseStrength ("噪波强度",float)=0.1
}
SubShader {
Blend One One
//Blend SrcAlpha OneMinusSrcAlpha
Cull Off
Tags {
"Queue"="Transparent"
}
Pass {
Name "FORWARD"
Tags {
"LightMode"="ForwardBase"
}
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#define UNITY_PASS_FORWARDBASE
#include "UnityCG.cginc"
#include "AutoLight.cginc"
uniform float4 _LightColor0;
uniform sampler2D _MainTex; uniform float4 _MainTex_ST;
uniform sampler2D _NoiseMap; uniform float4 _NoiseMap_ST;
struct VertexInput {
float4 vertex : POSITION;
float3 normal : NORMAL;
float2 texcoord0 : TEXCOORD0;
};
struct VertexOutput {
float4 pos : SV_POSITION;
float2 uv0 : TEXCOORD0;
float4 posWorld : TEXCOORD1;
float3 normalDir : TEXCOORD2;
};
VertexOutput vert (VertexInput v) {
VertexOutput o = (VertexOutput)0;
o.uv0 = v.texcoord0;
o.normalDir = UnityObjectToWorldNormal(v.normal);
o.posWorld = mul(unity_ObjectToWorld, v.vertex);
float3 lightColor = _LightColor0.rgb;
o.pos = UnityObjectToClipPos( v.vertex );
UNITY_TRANSFER_FOG(o,o.pos);
TRANSFER_VERTEX_TO_FRAGMENT(o)
return o;
}
uniform float _SpeedX;
uniform float _SpeedY;
uniform float _NoiseStrength;
float4 frag(VertexOutput i) : COLOR {
//光照函数
i.normalDir = normalize(i.normalDir);
float3 normalDirection = i.normalDir;
float3 lightDirection = normalize(_WorldSpaceLightPos0.xyz);
float3 lightColor = _LightColor0.rgb;
float attenuation = LIGHT_ATTENUATION(i);
float3 attenColor = attenuation * _LightColor0.xyz;
float NdotL = max(0.0,dot( normalDirection, lightDirection ));
float3 directDiffuse = max( 0.0, NdotL) * attenColor;
float3 indirectDiffuse = float3(0,0,0);
indirectDiffuse += UNITY_LIGHTMODEL_AMBIENT.rgb;
//x,y方向流动
float2 FlowUV = (i.uv0+float2((_SpeedX*_Time.g),(_Time.g*_SpeedY)));
float4 _NoiseMap_var = tex2D(_NoiseMap,TRANSFORM_TEX(FlowUV, _NoiseMap));
//噪波强度
float2 NoiseUV = (i.uv0+(float2(_NoiseMap_var.r,_NoiseMap_var.g)*_NoiseStrength));
float4 _MainTex_var = tex2D(_MainTex,TRANSFORM_TEX(NoiseUV, _MainTex));
float3 diffuseColor = _MainTex_var.rgb;
float3 diffuse = (directDiffuse + indirectDiffuse) * diffuseColor;
float3 finalColor = diffuse;
fixed4 finalRGBA = fixed4(finalColor,1);
UNITY_APPLY_FOG(i.fogCoord, finalRGBA);
return finalRGBA;
}
ENDCG
}
}
FallBack "Diffuse"
}