个人博客网址:《Unity Shader入门精要》笔记:初级篇(2) - Sugar的博客,如文章转载中出现例如传送门失效等纰漏,建议直接访问原博客网址。
目录
基础光照
Unity中实现漫反射光照模型
高光反射光照模型
补充
Shader "Unlit/Screen Position" { Properties { _MainTex ("Texture", 2D) = "white" {} } SubShader { Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag #pragma target 3.0 // 注意:此结构中没有 SV_POSITION struct v2f { float2 uv : TEXCOORD0; }; v2f vert ( float4 vertex : POSITION, // 顶点位置输入 float2 uv : TEXCOORD0, // 纹理坐标输入 out float4 outpos : SV_POSITION // 裁剪空间位置输出 ) { v2f o; o.uv = uv; outpos = UnityObjectToClipPos(vertex); return o; } sampler2D _MainTex; fixed4 frag (v2f i, UNITY_VPOS_TYPE screenPos : VPOS) : SV_Target { // screenPos.xy 将包含像素整数坐标。 // 使用它们来实现一个跳过渲染 4x4 像素块的 // 棋盘图案 // 棋盘图案中 4x4 像素块的 checker 值 // 为负 screenPos.xy = floor(screenPos.xy * 0.25) * 0.5; float checker = -frac(screenPos.r + screenPos.g); // 如果值为负,则 clip HLSL 指令停止渲染像素 clip(checker); // 对于保留的像素,读取纹理并将其输出 fixed4 c = tex2D (_MainTex, i.uv); return c; } ENDCG } } }
shader "Example/Shader01" { Properties { _Color ("Color Tint",Color) = (1.0,1.0,1.0,1.0) _MainTex("Base (RGB)", 2D) = "white" { } //定义漫反射颜色,并赋初值为白色 _Diffuse("Diffuse",Color) = (1,1,1,1) } SubShader { Pass { //定义Pass在Unity的光照流水线的角色,定义正确的LightMode才能得到内置光照变量 Tags{"LightMode" = "ForwardBase"} CGPROGRAM //使用_LightColor0要用到该头文件 #include"UnityCG.cginc" #pragma vertex vert #pragma fragment frag #include"Lighting.cginc" //定义名称和Properties中一样,然后才可以在pass中使用 fixed4 _Color; fixed4 _Diffuse; sampler2D _MainTex; struct a2v { float4 vertex : POSITION; float3 normal : NORMAL; float2 texcoord : TEXCOORD0; }; struct v2f { float4 pos : SV_POSITION; fixed3 color : COLOR; float2 texcoord : TEXCOORD0; }; v2f vert(a2v v) { v2f o; o.texcoord = v.texcoord; o.pos = UnityObjectToClipPos(v.vertex); //获取系统环境光 fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz; //转换数据到世界坐标 fixed3 worldNormal = normalize(mul(v.normal,(float3x3)unity_WorldToObject)); fixed3 worldLight = normalize(_WorldSpaceLightPos0.xyz); //计算漫反射 fixed3 diffuse = _LightColor0.rgb + _Diffuse.rgb * saturate(dot(worldNormal,worldLight)); //输出环境光+漫反射 o.color = ambient + diffuse; return o; } fixed4 frag(v2f i) : SV_Target { //获取纹理材质 fixed4 c = tex2D(_MainTex,i.texcoord);//fixed4(i.color,1.0); //注意这里是乘法 return c * fixed4(i.color,1.0); } ENDCG } } Fallback "Diffuse" }
//对于书中最后的计算输出式做了一些更改,添加了一个自定义整体亮度的控制模块 shader "Example/Shader01" { Properties { _Color ("Color Tint",Color) = (1.0,1.0,1.0,1.0) _MainTex("Base (RGB)", 2D) = "white" { } _Diffuse("Diffuse",Color) = (1,1,1,1) _Light("Light",Color) = (1.0,1.0,1.0,1.0) } SubShader { Pass { Tags{"LightMode" = "ForwardBase"} CGPROGRAM #include"UnityCG.cginc" #pragma vertex vert #pragma fragment frag #include"Lighting.cginc" fixed4 _Color; fixed4 _Diffuse; fixed4 _Light; sampler2D _MainTex; struct a2v { float4 vertex : POSITION; float3 normal : NORMAL; float2 texcoord : TEXCOORD0; }; struct v2f { float4 pos : SV_POSITION; fixed3 color : COLOR; float2 texcoord : TEXCOORD0; float3 worldNormal : TEXCOORD1; }; v2f vert(a2v v) { v2f o; o.texcoord = v.texcoord; o.pos = UnityObjectToClipPos(v.vertex); o.worldNormal = mul(v.normal,(float3x3)unity_WorldToObject); return o; } fixed4 frag(v2f i) : SV_Target { fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz; fixed3 worldNormal = normalize(i.worldNormal); fixed3 worldLightDir = normalize(_WorldSpaceLightPos0.xyz); fixed3 diffuse = _LightColor0.rgb * _Diffuse.rgb * saturate(dot(worldNormal,worldLightDir)); fixed4 c = tex2D(_MainTex,i.texcoord);//fixed4(i.color,1.0); //这里的c是材质的原本光照颜色,_Light是提高物体表面颜色(因为我的贴图有点暗),之后的才算是漫反射的光照结果。 return (c + _Light) * fixed4(ambient + diffuse,1.0) ; } ENDCG } } Fallback "Diffuse" }
在Unity对比了一下感觉确实更细腻了
正面
背面
shader "Example/Shader01" { Properties { _MainTex("Base (RGB)", 2D) = "white" { } _Diffuse("Diffuse",Color) = (1,1,1,1) _Specular("Specular",Color) = (1,1,1,1) _Gloss("Gloss",Range(8.0,256)) = 20 _Light("Light",Color) = (1.0,1.0,1.0,1.0) } SubShader { Pass { Tags{"LightMode" = "ForwardBase"} CGPROGRAM #pragma vertex vert #pragma fragment frag #include"Lighting.cginc" #include"UnityCG.cginc" fixed4 _Diffuse; fixed4 _Specular; float _Gloss; fixed4 _Light; sampler2D _MainTex; struct a2v { float4 vertex : POSITION; float3 normal : NORMAL; float2 texcoord : TEXCOORD0; }; struct v2f { float4 pos : SV_POSITION; fixed3 color : COLOR; float2 texcoord : TEXCOORD0; float3 worldNormal : TEXCOORD1; float3 worldPos : TEXCOORD2; }; v2f vert(a2v v) { v2f o; o.texcoord = v.texcoord; o.pos = UnityObjectToClipPos(v.vertex); o.worldNormal = mul(v.normal,(float3x3)unity_WorldToObject); o.worldPos = mul(unity_ObjectToWorld,v.vertex).xyz; return o; } fixed4 frag(v2f i) : SV_Target { fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz; fixed3 worldNormal = normalize(i.worldNormal); fixed3 worldLightDir = normalize(_WorldSpaceLightPos0.xyz); fixed3 diffuse = _LightColor0.rgb * _Diffuse.rgb * (dot(worldNormal,worldLightDir)*0.5+0.5); //高光计算部分 fixed3 reflectDir = normalize(reflect(-worldLightDir,worldNormal)); fixed3 viewDir = normalize(_WorldSpaceCameraPos.xyz - i.worldPos.xyz); fixed3 specular = _LightColor0.rgb * _Specular.rgb * pow(saturate(dot(reflectDir,viewDir)),_Gloss); fixed4 c = tex2D(_MainTex,i.texcoord); return (c + _Light) * fixed4(ambient + diffuse + specular,1.0) ; } ENDCG } } Fallback "Diffuse" }
不开高光
高光拉满,gloss=8
gloss=24