U3D各向异性Shader

7 篇文章 0 订阅
4 篇文章 0 订阅


原文链接:各向异Shader

一.描述:

           这个材质提供了一种类似于在拉丝的金属或头发上的各向异高光。这种各项异性高光基于镜面地图specular map的蓝色通道来与Blinn高光进行混合,同时支持漫反射(diffuse),法线(normal),镜面反射(specular)以及 透明(alphatest)效果。对光泽度(Gloss)和镜面反射度(Specular)的调节同时也会对各向异高光进行影响。

各向异高光的上下偏移可以用shader面板上“Anisotropic Highlight Offset"进行调节。

   各向异高光的表面向量使用下列这种图来描述:

  

   各向异高光表面向量的数据的存储方式以及表现方式和切线空间下的法线图是一模一样的,但在Unity里面,它不应该使用系统转换为法线贴图.

二.使用参数说明:

  Anisotropic Direction:各向异高光的反射方向,与切线空间的法线图中描述方向的规范一样。

   Specular:镜像反射控制参数在specular texture的红通道中,控制高光的亮度

   Gloss:光泽度控制参数在specular texture的绿通道中,这个参数控制各向异高光的锐利程度(0:不锐利,1:最锐利),最好不要把这通道设定为0

   Anisotropic Mask:各向异高光与镜面反射定义在specular texture的蓝通道中,这个参数用于混合各向异高光与镜面反射(0:全镜面反射,1:全各向异高光)

   Anisotropic Offset:可以控制各向异高光与中心点的距离

三.Shader代码:

<span style="font-size:14px;">Shader "Bumped Anisotropic Specular" {
     Properties {
         _Color ("Main Color", Color) = (1,1,1,1)
         _MainTex ("Diffuse (RGB) Alpha (A)", 2D) = "white" {}
         _SpecularTex ("Specular (R) Gloss (G) Anisotropic Mask (B)", 2D) = "gray" {}
         _BumpMap ("Normal (Normal)", 2D) = "bump" {}
         _AnisoTex ("Anisotropic Direction (Normal)", 2D) = "bump" {}
         _AnisoOffset ("Anisotropic Highlight Offset", Range(-1,1)) = -0.2
         _Cutoff ("Alpha Cut-Off Threshold", Range(0,1)) = 0.5
     }

     SubShader{
         Tags { "RenderType" = "Opaque" }
     
         CGPROGRAM
         
             struct SurfaceOutputAniso {
                 fixed3 Albedo;
                 fixed3 Normal;
                 fixed4 AnisoDir;
                 fixed3 Emission;
                 half Specular;
                 fixed Gloss;
                 fixed Alpha;
             };

             float _AnisoOffset, _Cutoff;
             inline fixed4 LightingAniso (SurfaceOutputAniso s, fixed3 lightDir, fixed3 viewDir, fixed atten)
             {
				fixed3 h = normalize(normalize(lightDir) + normalize(viewDir));
				float NdotL = saturate(dot(s.Normal, lightDir));

				fixed HdotA = dot(normalize(s.Normal + s.AnisoDir.rgb), h);
				float aniso = max(0, sin(radians((HdotA + _AnisoOffset) * 180)));

				float spec = saturate(dot(s.Normal, h));
				spec = saturate(pow(lerp(spec, aniso, s.AnisoDir.a), s.Gloss * 128) * s.Specular);

				fixed4 c;
				c.rgb = ((s.Albedo * _LightColor0.rgb * NdotL) + (_LightColor0.rgb * spec)) * (atten * 2);
				c.a = 1;
				clip(s.Alpha - _Cutoff);
				return c;
             }

             #pragma surface surf Aniso
             #pragma target 3.0
             
             struct Input
             {
                 float2 uv_MainTex;
                 float2 uv_AnisoTex;
             };
             
             sampler2D _MainTex, _SpecularTex, _BumpMap, _AnisoTex;
                 
             void surf (Input IN, inout SurfaceOutputAniso o)
             {
				fixed4 albedo = tex2D(_MainTex, IN.uv_MainTex);
				 o.Albedo = albedo.rgb;
				 o.Alpha = albedo.a;
				 o.Normal = UnpackNormal(tex2D(_BumpMap, IN.uv_MainTex));
				 fixed3 spec = tex2D(_SpecularTex, IN.uv_MainTex).rgb;
				 o.Specular = spec.r;
				 o.Gloss = spec.g;
				 o.AnisoDir = fixed4(UnpackNormal(tex2D(_AnisoTex, IN.uv_AnisoTex)), spec.b);
             }
         ENDCG
     }
     FallBack "Transparent/Cutout/VertexLit"
}</span>



  


  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
头发各向异性渲染Shader 这个是04年的一个ppt,主要介绍了头发的渲染,其追到源头还是要看这个原理。 各向异性的主要计算公式: 主要代码如下: 切线混合扰动部分(这部分也可以用T+k*N,来对切线进行扰动): float3x3 tangentTransform = float3x3(i.tangentDir, i.bitangentDir, i.normalDir); float3 _T_var = UnpackNormal(tex2D(_Tangent, TRANSFORM_TEX(i.uv0, _Tangent))); float3 temp = lerp(_TangentParam.xyz, _T_var, _BlenfTangent); float3 T = normalize(mul(float3(temp.xy,0), tangentTransform)); 主要是通过改变切线的xy值来造成头发高光部分的多样性。 高光部分,按公式计算即可: float StrandSpecular(float3 T, float3 V, float3 L, float exponent) { float3 H = normalize(L + V); float dotTH = dot(T, H); float sinTH = sqrt(1 - dotTH*dotTH); float dirAtten = smoothstep(-1, 0, dotTH); return dirAtten*pow(sinTH, exponent); } 注意,为了模拟的更贴近真实性,应用两层高光,第一层高光代表直射光直接反射出去,第二层代表次表面散射现象具体看代码。 最终渲染部分: float4 HairLighting(float3 T, float3 N, float3 L, float3 V, float2 uv, float3 lightColor) { float diffuse = saturate(lerp(0.25, 1.0, dot(N, L)))*lightColor; float3 indirectDiffuse = float3(0, 0, 0); indirectDiffuse += UNITY_LIGHTMODEL_AMBIENT.rgb; // Ambient Light float3 H = normalize(L + V); float LdotH = saturate(dot(L, H)); float3 specular = _Specular*StrandSpecular(T, V, L, exp2(lerp(1, 11, _Gloss))); //float specMask = tex2D(_SpecMask, TRANSFORM_TEX(uv, _SpecMask)); specular += /*specMask*/_SubColor*StrandSpecular(T, V, L, exp2(lerp(1, 11, _ScatterFactor))); float4 final; float4 base = tex2D(_MainTex, TRANSFORM_TEX(uv, _MainTex)); float3 diffuseColor = (_Color.rgb*base.rgb); //float ao = tex2D(_AO, TRANSFORM_TEX(uv, _AO)).g; final.rgb = (diffuse + indirectDiffuse)*diffuseColor + specular*lightColor* FresnelTerm(_Specular, LdotH); //final.rgb *= ao; final.a = base.a; clip(final.a - _CutOff); return final; } 这里我注释掉了AO和高光遮罩,需要的同学可以加上。 最后一点为了不让头发的边经过clip之后太硬,需要进行两个通道的belnd。 第二个pass使用以下指令: Blend SrcAlpha OneMinusSrcAlpha ZWrite Off 注意第二个通道无需再进行clip操作。 至此,头发渲染完毕。
以下是一个简单的U3D镜像模糊的shader脚本: ```c# Shader "Custom/MirrorBlur" { Properties { _MainTex ("Texture", 2D) = "white" {} _BlurSize ("Blur Size", Range(0.0, 2.0)) = 0.5 _MirrorAxis ("Mirror Axis", Range(0, 1)) = 1 } SubShader { Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" struct appdata { float4 vertex : POSITION; float2 uv : TEXCOORD0; }; struct v2f { float2 uv : TEXCOORD0; float4 vertex : SV_POSITION; }; sampler2D _MainTex; float _BlurSize; int _MirrorAxis; v2f vert (appdata v) { v2f o; o.vertex = UnityObjectToClipPos(v.vertex); o.uv = v.uv; return o; } fixed4 frag (v2f i) : SV_Target { float2 uv = i.uv; if (_MirrorAxis == 0) uv.y = 1.0 - uv.y; else uv.x = 1.0 - uv.x; fixed4 col = tex2D(_MainTex, uv); float2 blurDir = float2(0, _BlurSize); float4 blurCol = tex2D(_MainTex, uv); blurCol += tex2D(_MainTex, uv + blurDir) * 0.25; blurCol += tex2D(_MainTex, uv - blurDir) * 0.25; blurDir = float2(_BlurSize, 0); blurCol += tex2D(_MainTex, uv + blurDir) * 0.25; blurCol += tex2D(_MainTex, uv - blurDir) * 0.25; return blurCol / 2 + col / 2; } ENDCG } } FallBack "Diffuse" } ``` 这个shader使用了一个名为_MainTex的2D纹理作为输入,并接受一个名为_BlurSize的模糊尺寸参数和一个名为_MirrorAxis的镜像轴参数。 在顶点着色器中,仅仅是将顶点位置变换到剪裁空间,并将纹理坐标传递给片段着色器。 在片段着色器中,首先根据_MirrorAxis参数计算出镜像的纹理坐标,然后进行高斯模糊处理。最后,将模糊后的颜色和原始颜色混合在一起,以产生镜像模糊的效果。 请注意,这个shader仅仅是一个简单的示例,可能需要进一步的优化和调整才能达到所需的效果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值