[外文翻译] 基于位置的梯度着色器
本帖最后由 492899250 于 2017-11-3 19:32 编辑

基于位置的梯度着色器
这是本博客的第一篇文章,一个很容易理解的着色器。



为了PegJam2017,我决定做一个游戏,灵感来自于纪念碑谷。我想在我的jam游戏中,营造一些类似于下图关卡的气氛。这个jam游戏叫“Isolation”,可以从这里下载。



想要实现这种几何体消失在雾/背景中的效果,最简单的方法就是我要在文中分享的着色器。这个着色器所做的就是,根据几何体顶点和y轴0点之间的距离,将顶点逐渐变为一个新的颜色。

步骤1:声明2个颜色变量。

[mw_shl_code=csharp,true]fixed4 _Color;
fixed4 _FogColor;[/mw_shl_code]

_Color是几何体的颜色,_FogColor是最终需要渐变成的背景颜色。

步骤2:声明2个新变量,用于对每个对象定义,渐变开始和渐变结束的y坐标。这样可以控制场景中每个物体的最终效果。

[mw_shl_code=csharp,true]half _FogStart;
half _FogEnd;[/mw_shl_code]

步骤3:把顶点的输出坐标转换为游戏的世界坐标,以便计算特效的开始坐标和结束的y坐标。

[mw_shl_code=csharp,true]float4 pos = mul(unity_ObjectToWorld, v.vertex).xyzw;[/mw_shl_code]

步骤4:需要计算一下这个效果的而影响范围,它基于顶点的y坐标,然后用saturate函数将结果限制在0到1之间。

[mw_shl_code=csharp,true]data.fog = saturate((_FogStart - pos.y) / (_FogStart - _FogEnd));[/mw_shl_code]

步骤5:计算最终颜色,利用步骤4中计算的data.fog的强度,在_Color和_FogColor之间进行差值。color.rgb是由unity标准着色器计算的输出颜色,把它和_Color相乘。如果不这样做,会遗漏场景中的阴影和光照信息。

[mw_shl_code=csharp,true]color.rgb = lerp(color.rgb * _Color , _FogColor, IN.fog);[/mw_shl_code]

最后,将它嵌入到unity中。需要创建一个新的材质,使用这个着色器,然后将它应用到所有的3d资源。使背景色和雾的颜色相同,同时还需要将相机的Background属性设置为雾的颜色。



这样就完成了一个简单的着色器,它的效果和纪念碑谷的很相似,而且不需要为任何模型创建自定义纹理。这个着色器可用于任何颜色、光照和阴影,据我实践,对模型上的纹理也有效。因为这个效果是用着色器创建的,当物体从地面向上移动时,会有一个很酷的渐显效果。



通过调整开始和结束位置,可以改变效果的影响范围,甚至可以让它渐隐到天空中而不是地面。



感谢阅读!
[mw_shl_code=csharp,true]Shader "Custom/Fog"

{

Properties

{

_Color("Color", Color) = (1,1,1,1)

_MainTex("Texture", 2D) = "white" {}

_FogColor("Fog Color", Color) = (0.3, 0.4, 0.7, 1.0)

_FogStart("Fog Start", float) = 0

_FogEnd("Fog End", float) = 0

}



SubShader

{

Tags{ "RenderType" = "Opaque" }



CGPROGRAM



#pragma surface surf Lambert finalcolor:mycolor vertex:myvert



struct Input

{

float2 uv_MainTex;

half fog;

};



fixed4 _Color;

fixed4 _FogColor;

half _FogStart;

half _FogEnd;

sampler2D _MainTex;



void myvert(inout appdata_full v, out Input data)

{

UNITY_INITIALIZE_OUTPUT(Input,data);

float4 pos = mul(unity_ObjectToWorld, v.vertex).xyzw;

data.fog = saturate((_FogStart - pos.y) / (_FogStart - _FogEnd));

}



void mycolor(Input IN, SurfaceOutput o, inout fixed4 color)

{

fixed3 fogColor = _FogColor.rgb;

fixed3 tintColor = _Color.rgb;

#ifdef UNITY_PASS_FORWARDADD

fogColor = 0;

#endif

color.rgb = lerp(color.rgb * tintColor, fogColor, IN.fog);

}



void surf(Input IN, inout SurfaceOutput o)

{

o.Albedo = tex2D(_MainTex, IN.uv_MainTex).rgb;

}



ENDCG

}



Fallback "Diffuse"

}[/mw_shl_code]

原文标题:Position Based Gradient Shader
原文链接:https://spennerino.wordpress.com/2017/06/20/gradient-shader/

  • 沙发 hc026
  • 2017-11-4 07:12:33 来自Mobile---
感谢分享
好厉害的样子
[外文翻译] 基于位置的梯度着色器
6666666666666666666666666666
感谢分享,很不错,简单实用
感谢分享
  • 8# JUcoco
  • 2017-11-7 16:38:19
6666666666666666666
谢谢分享
感谢分享
  • 11# ylaier
  • 2017-11-8 10:12:10
不错,支持楼主!
  • 12# Azr
  • 2017-11-8 10:22:51
感谢分享
好厉害的样子  留着自学用
[外文翻译] 基于位置的梯度着色器
1234.. 7下一页