Add dual paraboloid transform.

pull/216/head
castano 13 years ago
parent 9302ee2cb0
commit 92d7ebded3

@ -1593,6 +1593,31 @@ void TexImage::transformNormals(NormalTransform xform)
n.y = n.y * t;
n.z = 0.0f;
}
else if (xform == NormalTransform_DualParaboloid) {
// Use Newton's method to solve equation:
// f(t) = 1 - zt - (x^2+y^2)t^2 + x^2y^2t^4 = 0
// f'(t) = - z - 2(x^2+y^2)t + 4x^2y^2t^3
// Initial approximation:
float a = (n.x * n.x) + (n.y * n.y);
float b = n.z;
float c = -1.0f;
float discriminant = b * b - 4.0f * a * c;
float t = (-b + sqrtf(discriminant)) / (2.0f * a);
float d = fabs(n.z * t - (1 - n.x*n.x*t*t) * (1 - n.y*n.y*t*t));
while (d > 0.0001) {
float ft = 1 - n.z * t - (n.x*n.x + n.y*n.y)*t*t + n.x*n.x*n.y*n.y*t*t*t*t;
float fit = - n.z - 2*(n.x*n.x + n.y*n.y)*t + 4*n.x*n.x*n.y*n.y*t*t*t;
t -= ft / fit;
d = fabs(n.z * t - (1 - n.x*n.x*t*t) * (1 - n.y*n.y*t*t));
};
n.x = n.x * t;
n.y = n.y * t;
n.z = 0.0f;
}
x = n.x;
y = n.y;
@ -1632,6 +1657,12 @@ void TexImage::reconstructNormals(NormalTransform xform)
n.z = 1.0f - nv::clamp(n.x * n.x + n.y * n.y, 0.0f, 1.0f);
n = normalizeSafe(n, Vector3(0.0f), 0.0f);
}
else if (xform == NormalTransform_DualParaboloid) {
n.x = n.x;
n.y = n.y;
n.z = nv::clamp((1 - n.x * n.x) * (1 - n.y * n.y), 0.0f, 1.0f);
n = normalizeSafe(n, Vector3(0.0f), 0.0f);
}
x = n.x;
y = n.y;

@ -391,6 +391,7 @@ namespace nvtt
NormalTransform_Orthographic,
NormalTransform_Stereographic,
NormalTransform_Paraboloid,
NormalTransform_DualParaboloid,
};
/// A texture mipmap.

@ -185,6 +185,7 @@ enum Mode {
Mode_BC5_Normal,
Mode_BC5_Normal_Stereographic,
Mode_BC5_Normal_Paraboloid,
Mode_BC5_Normal_DualParaboloid,
Mode_Count
};
static const char * s_modeNames[] = {
@ -201,6 +202,7 @@ static const char * s_modeNames[] = {
"BC5-Normal", // Mode_BC5_Normal,
"BC5-Normal-Stereographic", // Mode_BC5_Normal_Stereographic,
"BC5-Normal-Paraboloid", // Mode_BC5_Normal_Paraboloid,
"BC5-Normal-DualParaboloid", // Mode_BC5_Normal_DualParaboloid,
};
nvStaticCheck(NV_ARRAY_SIZE(s_modeNames) == Mode_Count);
@ -213,7 +215,7 @@ static Test s_imageTests[] = {
{"Color", 3, {Mode_BC1, Mode_BC3_YCoCg, Mode_BC3_RGBM, Mode_BC3_LUVW}},
{"Alpha", 3, {Mode_BC1_Alpha, Mode_BC2_Alpha, Mode_BC3_Alpha}},
//{"Normal", 3, {Mode_BC1_Normal, Mode_BC3_Normal, Mode_BC5_Normal}},
{"Normal", 3, {Mode_BC5_Normal, Mode_BC5_Normal_Stereographic, Mode_BC5_Normal_Paraboloid}},
{"Normal", 4, {Mode_BC5_Normal_DualParaboloid, Mode_BC5_Normal, Mode_BC5_Normal_Stereographic, Mode_BC5_Normal_Paraboloid}},
{"Lightmap", 4, {Mode_BC1, Mode_BC3_YCoCg, Mode_BC3_RGBM, Mode_BC3_RGBS}},
};
const int s_imageTestCount = ARRAY_SIZE(s_imageTests);
@ -404,7 +406,7 @@ int main(int argc, char *argv[])
printf(" -dec x \tDecompressor.\n");
printf(" 0: \tReference (D3D10).\n");
printf(" 1: \tReference (D3D9).\n");
printf(" 1: \tNVIDIA.\n");
printf(" 2: \tNVIDIA.\n");
printf("Compression options:\n");
printf(" -fast \tFast compression.\n");
@ -551,7 +553,7 @@ int main(int argc, char *argv[])
else if (mode == Mode_BC3_Normal) {
format = nvtt::Format_BC3n;
}
else if (mode == Mode_BC5_Normal) {
else if (mode == Mode_BC5_Normal || mode == Mode_BC5_Normal_Stereographic || mode == Mode_BC5_Normal_Paraboloid || mode == Mode_BC5_Normal_DualParaboloid) {
format = nvtt::Format_BC5;
}
@ -661,6 +663,9 @@ int main(int argc, char *argv[])
else if (mode == Mode_BC5_Normal_Paraboloid) {
tmp.transformNormals(nvtt::NormalTransform_Paraboloid);
}
else if (mode == Mode_BC5_Normal_DualParaboloid) {
tmp.transformNormals(nvtt::NormalTransform_DualParaboloid);
}
printf("Compressing: \t'%s'\n", set.fileNames[i]);
@ -735,6 +740,9 @@ int main(int argc, char *argv[])
else if (mode == Mode_BC5_Normal_Paraboloid) {
img_out.reconstructNormals(nvtt::NormalTransform_Paraboloid);
}
else if (mode == Mode_BC5_Normal_DualParaboloid) {
img_out.reconstructNormals(nvtt::NormalTransform_DualParaboloid);
}
nvtt::TexImage diff = nvtt::diff(img, img_out, 1.0f);

Loading…
Cancel
Save