shader的个人小结

Pass

pass{
//渲染语义块
cg代码块
//1.顶点代码段 2.片元代码段
#program vertex vert
#program fragment frag

}
一个shader文件里pass是可以有一个或多个的,这个需要根据实际需求来写.

当Unity选择用于渲染的子着色器时,它为每一个被定义的通道渲染一次对象(可能会更多,这取决于光线的交互作用)。当对象的每一次渲染都是很费资源之时,我们便使用尽量少的通道来定义一个着色器。
在每个pass中也可以用UsePass "Pass1" 和 Name "Pass1"来通道复用,减少代码量

https://qianmo.blog.csdn.net/article/details/41175585
https://www.codinblack.com/shader-pass-and-multi-pass-shader/
Properties{}
properties里面写外部可以调的变量,如果这个变量在后面的函数里面要使用,要再声明一次的

 #program vertex vert 
 #program fragment frag

这两行是相当于声明函数的
顶点函数名字是vert 着色器函数名字是frag ,可以自己命名

struct a2v{
    顶点着色器的输入,使用模型空间的数据填充变量
    float4 vertex : POSITION;
    float2 uv : TEXCOORD0;
};
struct v2f{
    顶点着色器的输出,用于在顶点和片元着色器之间传递信息
     float4 pos : SV_POSITION;
     float2 uv : TEXCOORD0;

};
v2f vert (appdata v)
{
  v2f o;
  o.pos = UnityObjectToClipPos(v.vertex);
  o.uv =TRANSFORM_TEX(v.uv, _MainTex);
  return o;
}

fixed4 frag (v2f i) : SV_Target
{

}

v2f不是fixed float那种变量,是返回的结构体,很多时候要返回的变量太多,就都写进一个结构体里面了,结构体名字也可以自己改成好记的

坐标变换

坐标变换基础就是线性矩阵,UNITY把MVP矩阵进行过封装,有方法可以调用,可以在cgnic里查找到

inline float4 UnityWorldToClipPos( in float3 pos )
{
    return mul(UNITY_MATRIX_VP, float4(pos, 1.0));
}

// Tranforms position from view to homogenous space
inline float4 UnityViewToClipPos( in float3 pos )
{
    return mul(UNITY_MATRIX_P, float4(pos, 1.0));
}

// Tranforms position from object to camera space
inline float3 UnityObjectToViewPos( in float3 pos )
{
    return mul(UNITY_MATRIX_V, mul(unity_ObjectToWorld, float4(pos, 1.0))).xyz;
}
inline float3 UnityObjectToViewPos(float4 pos) // overload for float4; avoids "implicit truncation" warning for existing shaders
{
    return UnityObjectToViewPos(pos.xyz);
}

// Tranforms position from world to camera space
inline float3 UnityWorldToViewPos( in float3 pos )
{
    return mul(UNITY_MATRIX_V, float4(pos, 1.0)).xyz;
}

// Transforms direction from object to world space
inline float3 UnityObjectToWorldDir( in float3 dir )
{
    return normalize(mul((float3x3)unity_ObjectToWorld, dir));
}

https://www.codinblack.com/coordinate-spaces-and-transformations-between-them/

其他

rgba和xyzw

初学shader有个比较绕的地方一会用.r,一会用.w其实这些都差不多一个意思
vec4 vector;
vector[0] = vector.r = vector.x = vector.s;
vector[1] = vector.g = vector.y = vector.t;
vector[2] = vector.b = vector.z = vector.p;
vector[3] = vector.a = vector.w = vector.q;
vector.rgb就是vector[1,2,3]

hlsl,cg

此外,也可以用HLSL代码,URP和HDRP都支持HLSL,但不支持cg
以 HLSL 或 CG 为前缀的块之间的区别是:
以 CG 为前缀的着色器代码块较旧。默认情况下,它们包含几个 Unity 的内置着色器 include 文件,如果您需要此功能,这会很方便。内置 include 文件仅与内置渲染管线兼容。
以 HLSL 为前缀的着色器代码块较新。默认情况下,它们不包含 Unity 的内置着色器 include 文件,因此您必须手动包含要使用的任何库代码。它们适用于任何渲染管线。
HLSL和CG大部分语法相似,但写法上有区别

Shader "Examples/ExampleShader"
{
    HLSLINCLUDE
      // 在此编写要共享的 HLSL 代码
    ENDHLSL
    SubShader
    {
        Pass
        {                
              Name "ExamplePassName"
              Tags { "LightMode" = "ExampleLightModeTagValue" }

              // 在此编写设置渲染状态的 ShaderLab 命令

              HLSLPROGRAM
                // 在此编写 HLSL 着色器代码
              ENDHLSL
        }
    }
}
posted @ 2022-01-02 01:00  melt00  阅读(115)  评论(0编辑  收藏  举报