From c39fc05c2921f5971c1de28e550102746bbea2f6 Mon Sep 17 00:00:00 2001 From: Robert Beckebans Date: Fri, 14 Jun 2024 17:35:22 +0200 Subject: [PATCH] makeMaterials command is ready for testing. #close 841 --- neo/renderer/Material.cpp | 171 +++++++++++++++++++++++++++++++++++--- 1 file changed, 161 insertions(+), 10 deletions(-) diff --git a/neo/renderer/Material.cpp b/neo/renderer/Material.cpp index 68088b89..02b4cb25 100644 --- a/neo/renderer/Material.cpp +++ b/neo/renderer/Material.cpp @@ -3933,8 +3933,8 @@ CONSOLE_COMMAND_SHIP( makeMaterials, "Make .mtr file from a models or textures f idFileList* files = fileSystem->ListFilesTree( folderName, ".png|.tga|.jpg|.exr" ); idStr mtrBuffer; - mtrBuffer += va( "// generated by %s\n\n", ENGINE_VERSION ); - mtrBuffer += "// adjust this file as needed\n"; + mtrBuffer += va( "// generated by %s\n", ENGINE_VERSION ); + mtrBuffer += "// NOTE: adjust this file as needed\n\n"; idStrList list = files->GetList(); for( int i = 0; i < files->GetNumFiles(); i++ ) @@ -3986,13 +3986,54 @@ CONSOLE_COMMAND_SHIP( makeMaterials, "Make .mtr file from a models or textures f if( testStamp != FILE_NOT_FOUND_TIMESTAMP ) { - // TODO load opacity map and store values in the alpha channel of the base color image + // load opacity map and store values in the alpha channel of the base color image - mtrBuffer += "\t{\n"; - mtrBuffer += "\t\tblend basecolormap\n"; - mtrBuffer += va( "\t\tmap %s\n", imageName.c_str() ); - mtrBuffer += "\t\talphaTest 0.5\n"; - mtrBuffer += "\t}\n"; + byte* pic = NULL; + int width, height; + R_LoadImage( imageName, &pic, &width, &height, &testStamp, true, NULL ); + + byte* pic2 = NULL; + int width2, height2; + R_LoadImage( testName, &pic2, &width2, &height2, &testStamp, true, NULL ); + + if( width == width2 || height == height2 ) + { + // merge images and save it to disk + int c = width * height * 4; + + for( int j = 0 ; j < c ; j += 4 ) + { + // just take the r channel of the alpha map + pic[j + 3] = pic2[j + 0]; + } + + // don't destroy the original image and save it as new one + idStr mergedName = baseName + "_rgba.png"; + R_WritePNG( mergedName, static_cast( pic ), 4, width, height, true, "fs_basepath" ); + + mtrBuffer += "\t{\n"; + mtrBuffer += "\t\tblend basecolormap\n"; + mtrBuffer += va( "\t\tmap %s\n", mergedName.c_str() ); + mtrBuffer += "\t\talphaTest 0.5\n"; + mtrBuffer += "\t}\n"; + } + else + { + mtrBuffer += "\t{\n"; + mtrBuffer += "\t\tblend basecolormap\n"; + mtrBuffer += va( "\t\tmap %s\n", imageName.c_str() ); + mtrBuffer += "\t\talphaTest 0.5\n"; + mtrBuffer += "\t}\n"; + } + + if( pic ) + { + R_StaticFree( pic ); + } + if( pic2 ) + { + R_StaticFree( pic2 ); + } foundAlpha = true; break; @@ -4029,6 +4070,118 @@ CONSOLE_COMMAND_SHIP( makeMaterials, "Make .mtr file from a models or textures f } } + // =============================== + // test roughness map + idStrList roughNames = { "_roughness", "_rough", "_rgh" }; + byte* roughPic = NULL; + int roughWidth = 0; + int roughHeight = 0; + + for( auto& name : roughNames ) + { + ID_TIME_T testStamp; + idStr testName = baseName + name; + + R_LoadImage( testName, &roughPic, &roughWidth, &roughHeight, &testStamp, true, NULL ); + if( testStamp != FILE_NOT_FOUND_TIMESTAMP ) + { + break; + } + } + + // =============================== + // test metallic map + idStrList metalNames = { "_metallic", "_metalness", "_metal", "_mtl" }; + byte* metalPic = NULL; + int metalWidth = 0; + int metalHeight = 0; + + for( auto& name : metalNames ) + { + ID_TIME_T testStamp; + idStr testName = baseName + name; + + R_LoadImage( testName, &metalPic, &metalWidth, &metalHeight, &testStamp, true, NULL ); + if( testStamp != FILE_NOT_FOUND_TIMESTAMP ) + { + break; + } + } + + // =============================== + // test ambient occlusion map + idStrList aoNames = { "_ao", "_ambient", "_occlusion" }; + byte* aoPic = NULL; + int aoWidth = 0; + int aoHeight = 0; + + for( auto& name : aoNames ) + { + ID_TIME_T testStamp; + idStr testName = baseName + name; + + R_LoadImage( testName, &aoPic, &aoWidth, &aoHeight, &testStamp, true, NULL ); + if( testStamp != FILE_NOT_FOUND_TIMESTAMP ) + { + break; + } + } + + // expect at least roughness and metallic values or we skip the PBR material creation here + if( roughPic && metalPic ) + { + if( roughWidth == metalWidth || roughHeight == metalHeight ) + { + // merge images and save it to disk + int c = roughWidth * roughHeight * 4; + + for( int j = 0 ; j < c ; j += 4 ) + { + // put metallic into green channel + roughPic[j + 1] = metalPic[j + 0]; + + // put middle 0.5 value into alpha channel for the case we want to add displacement later + roughPic[j + 3] = 128; + } + + if( roughWidth == aoWidth || roughHeight == aoHeight ) + { + for( int i = 0 ; i < c ; i += 4 ) + { + // put AO into blue channel + roughPic[i + 2] = aoPic[i + 0]; + } + } + else + { + // reset AO channel to white + for( int i = 0 ; i < c ; i += 4 ) + { + roughPic[i + 2] = 255; + } + } + + // don't destroy the original image and save it as new one + idStr mergedName = baseName + "_rmao.png"; + R_WritePNG( mergedName, static_cast( roughPic ), 4, roughWidth, roughHeight, true, "fs_basepath" ); + + mtrBuffer += va( "\trmaomap %s\n", mergedName.c_str() ); + } + } + + if( roughPic ) + { + R_StaticFree( roughPic ); + } + if( metalPic ) + { + R_StaticFree( metalPic ); + } + if( aoPic ) + { + R_StaticFree( aoPic ); + } + // =============================== // test emmissive map idStrList emmissiveName = { "_emission", "_emissive", "_emit" }; @@ -4050,8 +4203,6 @@ CONSOLE_COMMAND_SHIP( makeMaterials, "Make .mtr file from a models or textures f } } - //mtrBuffer += va( "\tbumpmap addnormals ( textures/%s/%s_local.%s, heightmap ( textures/%s/%s_h.%s, 4 ) )\n", args.Argv( 1 ), args.Argv( 2 ), imagepath.c_str() ); - //mtrBuffer += va( "\tspecularmap textures/%s/%s_spec.%s\n", args.Argv( 1 ), args.Argv( 2 ), imagepath.c_str() ); mtrBuffer += va( "}\n\n" ); } }