写在前面
Unity从学习到工作至今已经有三个年头了,开发中每次遇到难点第一件事就是百度搜索,从来没有自己的想法,甚是惭愧。想着不能再这样浑浑噩噩下去了,也决定开个博客,记录一下开发中自己觉得有用的东西,希望日后某一天回顾起来不会觉得日子白过,如果还能帮助到有需要有同学那就再好不过了。
关于Shader
candycat这个博主。工作后陆续遇到了shader方面的问题,基本都是无法个人解决的,带我的人就向我推荐了这个博主。当时连个CSDN账号都懒得登录,就这样一篇一篇的看着她的文章学习起了shader,期间还买了她出过的shader书籍,不过现在都还没看完,十分惭愧。学习到现在,虽然说无法吃透shader,但起码阅读起shader的代码,写一些简单的shader效果是没多大问题的。说起来candycat还是女生,年纪比我还小,无意识间敬佩又增加了一分。
正文
这里看看。因为我是学Unity的,所以还是偏向于Shadertoy转Unity的Shaderlab之后的运用。首先要说的是candycat的那个shadertoy转shaderlab的模板。下面是这位博主的原代码。
//Design By candycat(https://blog.csdn.net/candycat1992) Shader "Shadertoy/Template" { Properties{ iMouse ("Mouse Pos", Vector) = (100, 100, 0, 0) iChannel0("iChannel0", 2D) = "white" {} iChannelResolution0 ("iChannelResolution0", Vector) = (100, 100, 0, 0) } CGINCLUDE #include "UnityCG.cginc" #pragma target 3.0 #define vec2 float2 #define vec3 float3 #define vec4 float4 #define mat2 float2x2 #define mat3 float3x3 #define mat4 float4x4 #define iGlobalTime _Time.y #define mod fmod #define mix lerp #define fract frac #define texture2D tex2D #define iResolution _ScreenParams #define gl_FragCoord ((_iParam.scrPos.xy/_iParam.scrPos.w) * _ScreenParams.xy) #define PI2 6.28318530718 #define pi 3.14159265358979 #define halfpi (pi * 0.5) #define oneoverpi (1.0 / pi) fixed4 iMouse; sampler2D iChannel0; fixed4 iChannelResolution0; struct v2f { float4 pos : SV_POSITION; float4 scrPos : TEXCOORD0; }; v2f vert(appdata_base v) { v2f o; o.pos = mul (UNITY_MATRIX_MVP, v.vertex); o.scrPos = ComputeScreenPos(o.pos); return o; } vec4 main(vec2 fragCoord); fixed4 frag(v2f _iParam) : COLOR0 { vec2 fragCoord = gl_FragCoord; return main(gl_FragCoord); } vec4 main(vec2 fragCoord) { return vec4(1, 1, 1, 1); } ENDCG SubShader { Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag #pragma fragmentoption ARB_precision_hint_fastest ENDCG } } FallBack Off }
CGINCLUDE
Shader "Shadertoy/Template" { Properties{ iMouse ("Mouse Pos", Vector) = (100, 100, 0, 0) iChannel0("iChannel0", 2D) = "white" {} iChannelResolution0 ("iChannelResolution0", Vector) = (100, 100, 0, 0) } SubShader { Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag //使用低精度来提升片段着色器的运行速度 一般指fp16 半精度 #pragma fragmentoption ARB_precision_hint_fastest #include "UnityCG.cginc" #pragma target 3.0 //定义各种常用宏 #define vec2 float2 #define vec3 float3 #define vec4 float4 #define mat2 float2x2 #define mat3 float3x3 #define mat4 float4x4 #define iGlobalTime _Time.y #define mod fmod #define mix lerp #define fract frac #define texture2D tex2D //_ScreenParams为屏幕的分辨率 #define iResolution _ScreenParams #define PI2 6.28318530718 #define pi 3.14159265358979 #define halfpi (pi * 0.5) #define oneoverpi (1.0 / pi) fixed4 iMouse; sampler2D iChannel0; fixed4 iChannelResolution0; struct v2f { float4 pos : SV_POSITION; float4 scrPos : TEXCOORD0; }; v2f vert(appdata_base v) { v2f o; o.pos = mul (UNITY_MATRIX_MVP, v.vertex); //将顶点转成屏幕坐标 o.scrPos = ComputeScreenPos(o.pos); return o; } /*代码是从上到下读取的,要想在方法前面调用还没定义好的main函数,需要先声main方法 或者将main方法写在调用之前,这里将main方法写在后面是为了代码的可观性 因这之后逻辑大都在main方法上编写 */ vec4 main(vec2 fragCoord); fixed4 frag(v2f _iParam) : COLOR0 { /* 1.在四维中有xyzw四个分量 其中xyz三个点与w相除得到归一化的点 2.(_iParam.srcPos.xy/_iParam.srcPos.w)将得到在屏幕中归一化后的屏幕位置 3.最后与屏幕的分辨率相乘获得具体的位置 */ vec2 fragCoord = ((_iParam.scrPos.xy/_iParam.scrPos.w) * _ScreenParams.xy); return main(fragCoord); } vec4 main(vec2 fragCoord) { return vec4(1, 1, 1, 1); } ENDCG } } FallBack Off }
文章来源: Shader与ShaderToy开篇