I solved some equations to make useful tools that could convert height maps into HQ normal maps (the irrlicht method of generating normal maps is NOT great)
and i have already started solving for equations that get normal maps BACK TO heightmaps (this is attractive)
But I have very little spare time, would anyone take up the task of coding up an open-source tool (LGPL) to create and validate normal/heightmap pairs?
Anyone want to make asset-tools with me?
Re: Anyone want to make asset-tools with me?
Okay, so I derived a nice equation for bi-quartic interpolation and took partial Deriviatives of it (Fx and Fy)
then according to this http://mathworld.wolfram.com/NormalVector.html I got a normal vector (had to invert it for purpose of normal map)
you could modify this so it works with other interpolation function,
HOWEVER IT MUST BE AN EVEN-ORDER POLYNOMIAL, i.e. CANNOT USE BILINEAR,CUBIC,QUINTIC INTERPOLATION
This is because you have to have N+1 points to define ONLY ONE polynomial of N-Degree that passes through them (interpolates)
Because you want to get gradient, and therefore Normal at the same point as the middle of your sampling pattern, you need M points of either side to make the polynomial
M+1+M gives 1+2M which will always be odd, and an odd N+1 number of points requires an Even Order polynomial
THIS IS WHY IRRLICHT BUILT-IN NORMAL MAP GENERATION DOES NOT WORK PROPERLY!!!!
(Look at why the gradient of a y=|x| graph is underterminate at x=0 )
So here is the shader, I will soon translate to C++ which will take in one file and spit out a displacement map (RGBA) in .png format
Next I'll make a normal map generator which derives the gradients from the sinc()/Lanczos interpolation
then according to this http://mathworld.wolfram.com/NormalVector.html I got a normal vector (had to invert it for purpose of normal map)
you could modify this so it works with other interpolation function,
HOWEVER IT MUST BE AN EVEN-ORDER POLYNOMIAL, i.e. CANNOT USE BILINEAR,CUBIC,QUINTIC INTERPOLATION
This is because you have to have N+1 points to define ONLY ONE polynomial of N-Degree that passes through them (interpolates)
Because you want to get gradient, and therefore Normal at the same point as the middle of your sampling pattern, you need M points of either side to make the polynomial
M+1+M gives 1+2M which will always be odd, and an odd N+1 number of points requires an Even Order polynomial
THIS IS WHY IRRLICHT BUILT-IN NORMAL MAP GENERATION DOES NOT WORK PROPERLY!!!!
(Look at why the gradient of a y=|x| graph is underterminate at x=0 )
So here is the shader, I will soon translate to C++ which will take in one file and spit out a displacement map (RGBA) in .png format
Code: Select all
/**
THIS CODE IS UNDER LGPL v3
Work by Mateusz 'devsh' Kielan
**/
uniform sampler2D tex;
uniform float heightScale; // relative to where 1.0 is the size of one pixel
uniform texSz;
void main()
{
//round down to nearest texel
vec2 UV_disc = floor(gl_TexCoord[0].xy*texSz)/texSz+vec2(0.5)/texSz;
float Z[5][5];
float Dx,Dy;
for (int i=-2; i<=2; i++)
{
Z[i+2][2] = texture2D(tex,UV_disc+vec2(i,0)/texSz).r*heightScale;
}
for (int i=-2; i<=2; i++)
{
Z[2][i+2] = texture2D(tex,UV_disc+vec2(0,i)/texSz).r*heightScale;
}
/// MUL((k-x)/(k-j),k=-N toinc N,k!=j)
float PjmX[5];
PjmX[0] = Z[0][2]/12.0; // j=-2
PjmX[1] = -2.0*Z[1][2]/3.0; // j=-1
PjmX[3] = 2.0*Z[3][2]/3.0; // j=1
PjmX[4] = -Z[4][2]/12.0; // j=2
Dx = PjmX[0]+PjmX[1]+PjmX[3]+PjmX[4];
PjmX[0] = Z[2][0]/12.0; // m=-2
PjmX[1] = -2.0*Z[2][1]/3.0; // m=-1
PjmX[3] = 2.0*Z[2][3]/3.0; // m=1
PjmX[4] = -Z[2][4]/12.0; // m=2
Dy = PjmX[0]+PjmX[1]+PjmX[3]+PjmX[4];
gl_FragColor.rgba = vec4(normalize(-vec3(Dx,Dy,-1.0))*0.5+vec3(0.5),Z[2][2]);
// higher precision storage
//gl_FragColor.rgba = vec4(normalize(-vec3(Dx,Dy,-1.0))*vec3(0.5,0.5,1.0)+vec3(0.5,0.5,0.0),Z[2][2]);
}
Re: Anyone want to make asset-tools with me?
Update: Sinc/Lanczos is useless for heighmaps as it smoothes them out overly
Also the resulting normal maps have CRAPLOADS of ringing in them, to the point of being unsuable
then if you use a windowing function, you need to keep in mind the product rule which makes everything 4x more complicated and timewasting (CPU/GPU)
also by windowing you reduce the effectiveness of the interpolation so it becomes less accurate and desirable as compared to polynomial interpolation
NOW... HEIGHTMAPS from Normal Maps!
Also the resulting normal maps have CRAPLOADS of ringing in them, to the point of being unsuable
then if you use a windowing function, you need to keep in mind the product rule which makes everything 4x more complicated and timewasting (CPU/GPU)
also by windowing you reduce the effectiveness of the interpolation so it becomes less accurate and desirable as compared to polynomial interpolation
NOW... HEIGHTMAPS from Normal Maps!