Edit in GitHubLog an issue

lib-normal.glsl


Public Functions: normalBlend normalBlendOriented normalFade normalUnpack normalFromBaseNormal normalFromNormal normalFromHeight getTSNormal computeWSBaseNormal computeWSNormal

Import from library

Copied to your clipboard
import lib-defines.glsl
import lib-sparse.glsl

All engine parameters useful for normal-centric operations.

Copied to your clipboard
//: param auto channel_height
uniform SamplerSparse height_texture;
//: param auto channel_normal
uniform SamplerSparse normal_texture;
//: param auto texture_normal
uniform SamplerSparse base_normal_texture;
//: param auto normal_blending_mode
uniform int normal_blending_mode;
//: param auto height_2_normal_method
uniform int height_2_normal_method;

Used to invert the Y axis of the normal map

Copied to your clipboard
//: param auto normal_y_coeff
uniform float base_normal_y_coeff;

Empirically determined by our artists...

Copied to your clipboard
const float HEIGHT_FACTOR = 400.0;

Perform the blending between 2 normal maps

This is based on Whiteout blending http://blog.selfshadow.com/publications/blending\-in\-detail/

Copied to your clipboard
vec3 normalBlend(vec3 baseNormal, vec3 overNormal)
{
return normalize(vec3(
baseNormal.xy + overNormal.xy,
baseNormal.z * overNormal.z));
}

Perform a detail oriented blending between 2 normal maps

This is based on Detail Oriented blending http://blog.selfshadow.com/publications/blending\-in\-detail/

Copied to your clipboard
vec3 normalBlendOriented(vec3 baseNormal, vec3 overNormal)
{
baseNormal.z += 1.0;
overNormal.xy = -overNormal.xy;
return normalize(baseNormal * dot(baseNormal,overNormal) -
overNormal*baseNormal.z);
}

Returns a normal flattened by an attenuation factor

Copied to your clipboard
vec3 normalFade(vec3 normal,float attenuation)
{
if (attenuation<1.0 && normal.z<1.0)
{
float phi = attenuation * acos(normal.z);
normal.xy *= 1.0/sqrt(1.0-normal.z*normal.z) * sin(phi);
normal.z = cos(phi);
}
return normal;
}

Unpack a normal w/ alpha channel

Copied to your clipboard
vec3 normalUnpack(vec4 normal_alpha, float y_coeff)
{
if (normal_alpha.a == 0.0 || normal_alpha.xyz == vec3(0.0)) {
return vec3(0.0, 0.0, 1.0);
}
// Attenuation in function of alpha
vec3 normal = normal_alpha.xyz/normal_alpha.a * 2.0 - vec3(1.0);
normal.y *= y_coeff;
normal.z = max(1e-3, normal.z);
normal = normalize(normal);
normal = normalFade(normal, normal_alpha.a);
return normal;
}

Unpack a normal w/ alpha channel, no Y invertion

Copied to your clipboard
vec3 normalUnpack(vec4 normal_alpha)
{
return normalUnpack(normal_alpha, 1.0);
}

Compute the tangent space normal from document's height channel

Copied to your clipboard
vec3 normalFromHeight(SparseCoord coord, float height_force)
{
// Normal computation using height map
// Determine gradient offset in function of derivatives
vec2 dfd = max(coord.dfdx,coord.dfdy);
dfd = max(dfd,height_texture.size.zw);
vec2 dfdx,dfdy;
textureSparseQueryGrad(dfdx, dfdy, height_texture, coord);
float h_l = textureGrad(height_texture.tex, coord.tex_coord+vec2(-dfd.x, 0 ), dfdx, dfdy).r;
float h_t = textureGrad(height_texture.tex, coord.tex_coord+vec2( 0, dfd.y), dfdx, dfdy).r;
vec2 dh_dudv;
if (height_2_normal_method==1) {
float h_c = textureGrad(height_texture.tex, coord.tex_coord, dfdx, dfdy).r;
dh_dudv = 4.0 * height_force / dfd * vec2(h_l-h_c,h_c-h_t);
}
else {
float h_r = textureGrad(height_texture.tex, coord.tex_coord+vec2( dfd.x, 0 ), dfdx, dfdy).r;
float h_b = textureGrad(height_texture.tex, coord.tex_coord+vec2( 0, -dfd.y), dfdx, dfdy).r;
float h_rt = textureGrad(height_texture.tex, coord.tex_coord+vec2( dfd.x, dfd.y), dfdx, dfdy).r;
float h_lt = textureGrad(height_texture.tex, coord.tex_coord+vec2(-dfd.x, dfd.y), dfdx, dfdy).r;
float h_rb = textureGrad(height_texture.tex, coord.tex_coord+vec2( dfd.x, -dfd.y), dfdx, dfdy).r;
float h_lb = textureGrad(height_texture.tex, coord.tex_coord+vec2(-dfd.x, -dfd.y), dfdx, dfdy).r;
dh_dudv = (0.5 * height_force) / dfd * vec2(
2.0*(h_l-h_r)+h_lt-h_rt+h_lb-h_rb,
2.0*(h_b-h_t)+h_rb-h_rt+h_lb-h_lt);
}
return normalize(vec3(dh_dudv, HEIGHT_FACTOR));
}

Helper to compute the tangent space normal from base normal and a height value, and an optional detail normal.

Copied to your clipboard
vec3 getTSNormal(SparseCoord coord, SamplerSparse texture, vec3 normalFromHeight)
{
vec3 normal = normalBlendOriented(
normalUnpack(textureSparse(texture, coord), base_normal_y_coeff),
normalFromHeight);
if (normal_texture.is_set) {
vec3 channelNormal = normalUnpack(textureSparse(normal_texture, coord));
if (normal_blending_mode == BlendingMode_Replace) {
normal = normalBlendOriented(normalFromHeight, channelNormal);
} else if (normal_blending_mode == BlendingMode_NM_Combine) {
normal = normalBlendOriented(normal, channelNormal);
}
}
return normal;
}

Overload that use base_normal_texture

Copied to your clipboard
vec3 getTSNormal(SparseCoord coord, vec3 normalFromHeight)
{
return getTSNormal(coord, base_normal_texture, normalFromHeight);
}

Helper to compute the tangent space normal from base normal and height, and an optional detail normal.

Copied to your clipboard
vec3 getTSNormal(SparseCoord coord, SamplerSparse texture)
{
float height_force = 1.0;
vec3 normalH = normalFromHeight(coord, height_force);
return getTSNormal(coord, texture, normalH);
}

Overload that use base_normal_texture

Copied to your clipboard
vec3 getTSNormal(SparseCoord coord)
{
return getTSNormal(coord, base_normal_texture);
}

Helper to compute the world space normal from tangent space base normal.

Copied to your clipboard
vec3 computeWSBaseNormal(SparseCoord coord, vec3 tangent, vec3 bitangent, vec3 normal)
{
vec3 normal_vec = normalUnpack(textureSparse(normal_texture, coord), base_normal_y_coeff);
return normalize(
normal_vec.x * tangent +
normal_vec.y * bitangent +
normal_vec.z * normal
);
}

Helper to compute the world space normal from tangent space normal given by getTSNormal helpers, and local frame of the mesh.

Copied to your clipboard
vec3 computeWSNormal(SparseCoord coord, vec3 tangent, vec3 bitangent, vec3 normal)
{
vec3 normal_vec = getTSNormal(coord);
return normalize(
normal_vec.x * tangent +
normal_vec.y * bitangent +
normal_vec.z * normal
);
}
  • Privacy
  • Terms of Use
  • Do not sell or share my personal information
  • AdChoices
Copyright © 2024 Adobe. All rights reserved.