diff --git a/CMakeLists.txt b/CMakeLists.txt index f8710d5..b031a0e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -53,8 +53,11 @@ target_link_libraries(TexConv PRIVATE CMCore CMPlatform CMUtil Qt5::Core Qt5::Gui Qt5::Widgets DevIL ILU) -add_executable(MicroPBR MicroPBR.cpp YUV.cpp ${ILIMAGE_SOURCE}) -target_link_libraries(MicroPBR PRIVATE CMCore CMPlatform CMUtil DevIL ILU) +add_executable(MicroPBR MicroPBR.cpp YUV.cpp SpheremapNormal.cpp ${ILIMAGE_SOURCE}) +target_link_libraries(MicroPBR PRIVATE CMCore CMPlatform CMUtil DevIL ILU MathGeoLib) -add_executable(YUVTest YUVTest.cpp YUV.cpp ${ILIMAGE_SOURCE}) -target_link_libraries(YUVTest PRIVATE CMCore CMPlatform CMUtil DevIL ILU) \ No newline at end of file +add_executable(YUVTest YUVTest.cpp YUV.cpp SpheremapNormal.cpp ${ILIMAGE_SOURCE}) +target_link_libraries(YUVTest PRIVATE CMCore CMPlatform CMUtil DevIL ILU) + +add_executable(NormalTest NormalTest.cpp SpheremapNormal.cpp ${ILIMAGE_SOURCE}) +target_link_libraries(NormalTest PRIVATE CMCore CMPlatform CMUtil DevIL ILU MathGeoLib) \ No newline at end of file diff --git a/ILImage.h b/ILImage.h index 00f5066..68e392b 100644 --- a/ILImage.h +++ b/ILImage.h @@ -39,10 +39,16 @@ public: ~ILImage(); bool LoadFile(const OSString &); + bool SaveFile(const OSString &); + + bool Create(ILuint w,ILuint h,ILuint c,ILuint t,void *); void Bind(); bool Resize(uint,uint); + + void ToRGB(ILuint type=IL_UNSIGNED_BYTE); + void ToGray(ILuint type=IL_UNSIGNED_BYTE); void *GetR(ILuint type); @@ -51,4 +57,6 @@ public: // void *GetBGR(ILuint type){return GetData(IL_BGR,type);} void *GetRGBA(ILuint type){return GetData(IL_RGBA,type);} // void *GetBGRA(ILuint type){return GetData(IL_BGRA,type);} + + void *GetLum(ILuint type){return GetData(IL_LUMINANCE,type);} };//class ILImage diff --git a/ILImageSupport.cpp b/ILImageSupport.cpp index df18437..e5ef6dc 100644 --- a/ILImageSupport.cpp +++ b/ILImageSupport.cpp @@ -3,6 +3,7 @@ #include"ILImage.h" #include #include +#include using namespace hgl; @@ -56,6 +57,32 @@ ILImage::~ILImage() ilDeleteImages(1,&il_index); } +bool ILImage::Create(ILuint w,ILuint h,ILuint c,ILuint t,void *data) +{ + const ILenum format[]= + { + IL_LUMINANCE, + IL_LUMINANCE_ALPHA, + IL_RGB, + IL_RGBA, + }; + + if(c<1||c>4)return(false); + + Bind(); + + ilClearImage(); + return ilTexImage(w,h,1,c,format[c-1],t,data); +} + +bool ILImage::SaveFile(const OSString &filename) +{ + Bind(); + ilEnable(IL_FILE_OVERWRITE); + + return ilSaveImage(filename.c_str()); +} + void ILImage::Bind() { ilBindImage(il_index); @@ -87,6 +114,12 @@ bool ILImage::LoadFile(const OSString &filename) { Bind(); + if(!filesystem::FileExist(filename)) + { + LOG_INFO(OS_TEXT("Can't find filename: ")+filename); + return(false); + } + if(!ilLoadImage(filename.c_str())) return(false); @@ -139,6 +172,18 @@ bool ILImage::LoadFile(const OSString &filename) return(true); } +void ILImage::ToRGB(ILuint type) +{ + if(il_format!=IL_RGB) + Convert(IL_RGB,type); +} + +void ILImage::ToGray(ILuint type) +{ + if(il_format!=IL_LUMINANCE) + Convert(IL_LUMINANCE,type); +} + void *ILImage::GetR(ILuint type) { Bind(); diff --git a/MicroPBR.cpp b/MicroPBR.cpp index 7c3c0a8..fa26590 100644 --- a/MicroPBR.cpp +++ b/MicroPBR.cpp @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -6,36 +7,99 @@ using namespace hgl; using namespace hgl::util; -void RGB2YUV(uint8 *y,uint8 *u,uint8 *v,const uint8 *rgb,int w,int h); +#if HGL_OS == HGL_OS_Windows + #define std_cout std::wcout +#else + #define std_cout std::cout +#endif// -class PBRComponent +namespace hgl { - OSString name; + void RGB2YUV(uint8 *y,uint8 *u,uint8 *v,const uint8 *rgb,const uint w,const uint h); + void normal_compress(uint8 *x,uint8 *y,const uint8 *rgb,const uint count); - ILImage img; - -public: - - PBRComponent(const OSString &cn) + template + void MixRGB(T *rgb,const T *r,const T *g,const T *b,const uint count) { - name=cn; + for(uint i=0;i + void MixRGBA(T *rgba,const T *r,const T *g,const T *b,const T *a,const uint count) { + for(uint i=0;i>1; + const uint half_h=h>>1; + if(metallic.isHas()) + { + metallic.ToGray(); + metallic.Resize(half_w,half_h); + } + if(roughness.isHas()) + { + roughness.ToGray(); + roughness.Resize(half_w,half_h); + } + + uint8 *y,*u,*v,*nx,*ny; + + y=new uint8[w*h]; + u=new uint8[half_w*half_h]; + v=new uint8[half_w*half_h]; + nx=new uint8[w*h]; + ny=new uint8[w*h]; + + RGB2YUV(y,u,v,color.GetRGB(),w,h); + normal_compress(nx,ny,normal.GetRGB(),w*h); + + // BaseColor Y + Normal XY + { + ILImage img; + const OSString out_filename=OSString(argv[1])+OS_TEXT("_YN.png"); + + uint8 *pixels=new uint8[w*h*3]; + + MixRGB(pixels,y,nx,ny,w*h); + + img.Create(w,h,3,IL_UNSIGNED_BYTE,pixels); + + delete[] pixels; + + if(img.SaveFile(out_filename)) + std_cout<(pixels,u,v,metallic.GetLum(),roughness.GetLum(),half_w*half_h); + + img.Create(half_w,half_h,4,IL_UNSIGNED_BYTE,pixels); + + delete[] pixels; + + if(img.SaveFile(out_filename)) + std_cout<(pixels,u,v,metallic.GetLum(),half_w*half_h); + + img.Create(half_w,half_h,3,IL_UNSIGNED_BYTE,pixels); + + delete[] pixels; + + if(img.SaveFile(out_filename)) + std_cout<(pixels,u,v,roughness.GetLum(),half_w*half_h); + + img.Create(half_w,half_h,3,IL_UNSIGNED_BYTE,pixels); + + delete[] pixels; + + if(img.SaveFile(out_filename)) + std_cout< +#include +#include +#include + +using namespace hgl; +using namespace hgl::filesystem; + +namespace hgl +{ + void normal_compress(uint8 *x,uint8 *y,const uint8 *rgb,const uint count); + void normal_decompress(uint8 *rgb,const uint8 *x,const uint8 *y,const uint count); +} + +#if HGL_OS == HGL_OS_Windows +#define std_cout std::wcout + +int wmain(int argc,wchar_t **argv) +#else + +#define std_cout std::cout +int main(int argc,char **argv) +#endif// +{ + if(argc<1) + return 0; + + ilInit(); + + ILImage rgb_image; + + if(!rgb_image.LoadFile(argv[1])) + { + std::cout<<"open source file failed!"<(argv[1]); + + filename+=OS_TEXT("_XY.png"); + + if(rgb_image.SaveFile(filename)) + std_cout< +#include + +/** + * A_bit_more_deferred_-_CryEngine3 + + Normal to GBufffer: + + G=normalize(N.xy)*sqrt(N.z*0.5+0.5) + + GBuffer to Normal: + + N.z=length2(G.xy)*2-1 N.xy=normalize(G.xy)*sqrt(1-N.z*N.z) +*/ + +namespace hgl +{ + void normal_compress(uint8 *x,uint8 *y,const uint8 *rgb,const uint count) + { + Vector3f in; + Vector2f in_xy; + Vector2f out; + + for(uint i=0;i