几个简单的各向异性光照模型

1.

dot(N,H)^specularity

    fixed HdotA = dot(normalize(Normal + AnisoDirection), halfVector);  
    float aniso = max(0, sin(radians((HdotA + _AnisoOffset) * 180f)));
  
    float spec = saturate(pow(aniso, Gloss * 128) );

2.

sin(T,H)^specularity

也就相当于(sqrt(1-dot(T,H)^2))^specularity

在ATI 2004 年的“hair rendering and shading”中提到,其中又有specular shift等特点不在此赘述

3.

ward各向异性分布函数

wiki的解释如下

The Ward anisotropic distributionuses two user-controllable parameters αx and αy to control the anisotropy. If the two parameters are equal, then an isotropic highlight results. The specular term in the distribution is:

{\displaystyle k_{\mathrm {spec} }={\frac {\rho _{s}}{\sqrt {(N\cdot L)(N\cdot V)}}}{\frac {N\cdot L}{4\pi \alpha _{x}\alpha _{y}}}\exp \left[-2{\frac {\left({\frac {H\cdot X}{\alpha _{x}}}\right)^{2}+\left({\frac {H\cdot Y}{\alpha _{y}}}\right)^{2}}{1+(H\cdot N)}}\right]}

The specular term is zero if N·L < 0 or N·V < 0. All vectors are unit vectors. The vector V is the viewing direction, L is the direction from the surface point to the light, H is the half-angle direction between V and LN is the surface normal, and X and Y are two orthogonal vectors in the normal plane which specify the anisotropic directions.


ward各向异性分布函数的优点是可以使用comb贴图,也就是各向异性方向贴图,有作为tangent方向矫正各向异性高光形状及方向的功能

http://www.poopinmymouth.com/tutorials/comb-map.html

unity wiki有相关算法

https://en.wikibooks.org/wiki/GLSL_Programming/Unity/Brushed_Metal

if (dotLN < 0.0) // light source on the wrong side?
            {
               specularReflection = vec3(0.0, 0.0, 0.0); 
                  // no specular reflection
            }
            else // light source on the right side
            {
               float dotHN = dot(halfwayVector, normalDirection);
               float dotVN = dot(viewDirection, normalDirection);
               float dotHTAlphaX = 
                  dot(halfwayVector, tangentDirection) / _AlphaX;
               float dotHBAlphaY = dot(halfwayVector, 
                  binormalDirection) / _AlphaY;

               specularReflection = attenuation * vec3(_SpecColor) 
                  * sqrt(max(0.0, dotLN / dotVN)) 
                  * exp(-2.0 * (dotHTAlphaX * dotHTAlphaX 
                  + dotHBAlphaY * dotHBAlphaY) / (1.0 + dotHN));
            }

         }
         


在Autodesk的uber shader(大杂烩shader)中也用了这个分布函数

其中的comb tex直接取代了tangent方向

comb tex相当于是一个法线贴图,所以使用的时候需要unpack

float3 WardAniso(float3 N, float3 H, float NdotL, float NdotV, float Roughness1, float Roughness2, float3 anisotropicDir, float3 specColor)
{
	float3 binormalDirection = cross(N, anisotropicDir);

	float HdotN = dot(H, N);
	float dotHDirRough1 = dot(H, anisotropicDir) / Roughness1;
	float dotHBRough2 = dot(H, binormalDirection) / Roughness2;
 
	float attenuation = 1.0;
	float3 spec = attenuation * specColor
		* sqrt(max(0.0, NdotL / NdotV)) 
		* exp(-2.0 * (dotHDirRough1 * dotHDirRough1 
		+ dotHBRough2 * dotHBRough2) / (1.0 + HdotN));

	return spec;
}
float4 anisotropicDir = float4(T, 1);	// alpha is the blinn-aniso mask
	if (UseAnisotropicDirectionMap)
	{
		float2 anisoDirUV = pickTexcoord(AnisotropicTexcoord, IN.texCoord0, IN.texCoord1, IN.texCoord2);

		if (AnisotropicDirectionType == 0)	// use tangent map for direction
		{
			anisotropicDir = AnisotropicTexture.Sample(SamplerAnisoWrap, anisoDirUV);
			anisotropicDir.xyz = anisotropicDir.xyz * 2 - 1;	// unpack
		}
	}


 
  
 
  

--wolf96  2016/10/31




你可能感兴趣的:(Shader,Unity3D,Graphic,Tips)