|
|
|
|
|
|
// Convert anisotropic ratio (0->no isotropic; 1->full anisotropy in tangent direction) to roughness |
|
|
|
void ConvertAnisotropyToRoughness(float roughness, float anisotropy, out float roughnessT, out float roughnessB) |
|
|
|
{ |
|
|
|
// (0 <= anisotropy <= 1), therefore (0 <= anisoAspect <= 1) |
|
|
|
// The 0.9 factor limits the aspect ratio to 10:1. |
|
|
|
roughnessT = roughness * anisoAspect; |
|
|
|
roughnessB = roughness / anisoAspect; |
|
|
|
|
|
|
|
roughnessT = roughness / anisoAspect; // Distort along tangent (rougher) |
|
|
|
roughnessB = roughness * anisoAspect; // Straighten along bitangent (smoother) |
|
|
|
// Fake anisotropic by distorting the normal as suggested by: |
|
|
|
// anisotropic ratio (0->no isotropic; 1->full anisotropy in tangent direction) |
|
|
|
float3 GetAnisotropicModifiedNormal(float3 N, float3 T, float3 V, float anisotropy) |
|
|
|
// The grain direction (e.g. hair or brush direction) is assumed to be orthogonal to the normal. |
|
|
|
// The returned normal is NOT normalized. |
|
|
|
float3 ComputeGrainNormal(float3 grainDir, float3 V) |
|
|
|
float3 anisoT = cross(-V, T); |
|
|
|
float3 anisoN = cross(anisoT, T); |
|
|
|
float3 B = cross(-V, grainDir); |
|
|
|
return cross(B, grainDir); |
|
|
|
} |
|
|
|
return normalize(lerp(N, anisoN, anisotropy)); |
|
|
|
// Fake anisotropic by distorting the normal. |
|
|
|
// The grain direction (e.g. hair or brush direction) is assumed to be orthogonal to N. |
|
|
|
// Anisotropic ratio (0->no isotropic; 1->full anisotropy in tangent direction) |
|
|
|
float3 GetAnisotropicModifiedNormal(float3 grainDir, float3 N, float3 V, float anisotropy) |
|
|
|
{ |
|
|
|
float3 grainNormal = ComputeGrainNormal(grainDir, V); |
|
|
|
// TODO: test whether normalizing 'grainNormal' is worth it. |
|
|
|
return normalize(lerp(N, grainNormal, anisotropy)); |
|
|
|
} |
|
|
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
|
|