Write smaller EXR files using TinyEXR zip compression

This commit is contained in:
Robert Beckebans 2021-05-07 11:31:03 +02:00
parent fb7558ca1e
commit e466940b95
6 changed files with 159 additions and 22 deletions

View file

@ -646,3 +646,33 @@ They are also licensed under the MIT open source license, if you have lawyers wh
Every source file includes an explicit dual-license for you to choose from.
Research Samples by Morgan McGuire
-----------------------------------------------------------------------------
base/renderprogs/builtin/SSAO/* (AlchemyAO)
base/renderprogs/builtin/SSGI/* (Deep G-Buffer)
Morgan McGuire and Michael Mara, NVIDIA Research
Open Source under the "BSD" license: http://www.opensource.org/licenses/bsd-license.php
Copyright (c) 2011-2014, NVIDIA
Copyright (c) 2016 Robert Beckebans ( id Tech 4.x integration )
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View file

@ -22,6 +22,10 @@ _______________________________
# RBDOOM-3-BFG 1.3.0 adds PBR, Baked GI and TrenchBroom Mapping Support
The main goal of this 1.3.0 release is enabling modders the ability to make new content using up to date Material & Lighting standards. Adding PBR is a requirement to make the new content look the same in RBDOOM-3-BFG as in Blender 2.9x with Cycles or Eevee and Substance Designer. PBR became the standard material authoring since 2014. Many texture packs for Doom 3 like the Wulfen & Monoxead packs were made before and are heavily outdated. With this release modders can work with modern tools and expect that their content looks as expected.
However the PBR implementation is restricted to standard PBR using the Roughness/Metallic workflow for now.
Specialized rendering paths for skin, clothes and vegetation will be in future releases.
## Physically Based Rendering
Implementing Physically Based Rendering (PBR) in Doom 3 is a challenge and comes with a few compromises because the Doom 3 content was designed to work with the hardware constraints in 2004 and that even meant to run on a Geforce 3.
@ -34,12 +38,8 @@ PBR allows artists to create textures that are based on real world measured colo
## Baked Global Illumination using Irradiance Volumes and Image Based Lighting
The main goal is that the new content looks the same in RBDOOM-3-BFG as in Blender 2.9x with Cycles or Eevee.
```
To achieve the typical PBR look from an artistic point of view it also means to that it is necessary to add indirect lighting.
Doom 3 and even Doom 3 BFG had no indirect lighting.
```
***To achieve the typical PBR look from an artistic point of view it also means to that it is necessary to add indirect lighting.
Doom 3 and even Doom 3 BFG had no indirect lighting.***
### Irradiance Volumes aka Light Grids

View file

@ -1423,3 +1423,29 @@ CONSOLE_COMMAND( testmap, "tests a map", idCmdSystem::ArgCompletion_MapName )
sprintf( string, "devmap %s", map.c_str() );
cmdSystem->BufferCommandText( CMD_EXEC_NOW, string );
}
/*
==================
Common_TestMap_f
==================
*/
CONSOLE_COMMAND( bakemap, "loads a map and bakes environment probes", idCmdSystem::ArgCompletion_MapName )
{
idStr map, string;
map = args.Argv( 1 );
if( !map.Length() )
{
return;
}
map.StripFileExtension();
cmdSystem->BufferCommandText( CMD_EXEC_NOW, "disconnect" );
sprintf( string, "devmap %s.map", map.c_str() );
cmdSystem->BufferCommandText( CMD_EXEC_NOW, string );
sprintf( string, "bakeEnvironmentProbes" );
cmdSystem->BufferCommandText( CMD_EXEC_NOW, string );
}

View file

@ -15905,7 +15905,7 @@ static size_t SaveEXRNPartImageToMemory( const EXRImage* exr_images,
return 0;
}
#else
for( int c = 0; c < exr_header->num_channels; ++c )
for( int c = 0; c < exr_headers[i]->num_channels; ++c )
{
if( exr_headers[i]->requested_pixel_types[c] != TINYEXR_PIXELTYPE_FLOAT )
{

View file

@ -992,19 +992,20 @@ static void LoadEXR( const char* filename, unsigned char** pic, int* width, int*
R_WriteEXR
================
*/
// miniexr.cpp - v0.2 - public domain - 2013 Aras Pranckevicius / Unity Technologies
//
// Writes OpenEXR RGB files out of half-precision RGBA or RGB data.
//
// Only tested on Windows (VS2008) and Mac (clang 3.3), little endian.
// Testing status: "works for me".
//
// History:
// 0.2 Source data can be RGB or RGBA now.
// 0.1 Initial release.
void R_WriteEXR( const char* filename, const void* rgba16f, int channelsPerPixel, int width, int height, const char* basePath )
{
#if 0
// miniexr.cpp - v0.2 - public domain - 2013 Aras Pranckevicius / Unity Technologies
//
// Writes OpenEXR RGB files out of half-precision RGBA or RGB data.
//
// Only tested on Windows (VS2008) and Mac (clang 3.3), little endian.
// Testing status: "works for me".
//
// History:
// 0.2 Source data can be RGB or RGBA now.
// 0.1 Initial release.
const unsigned ww = width - 1;
const unsigned hh = height - 1;
const unsigned char kHeader[] =
@ -1140,6 +1141,86 @@ void R_WriteEXR( const char* filename, const void* rgba16f, int channelsPerPixel
fileSystem->WriteFile( filename, buf, bufSize, basePath );
Mem_Free( buf );
#else
// TinyEXR version with compression to save disc size
if( channelsPerPixel != 3 )
{
common->Error( "R_WriteEXR( %s ): channelsPerPixel = %i not supported", filename, channelsPerPixel );
}
EXRHeader header;
InitEXRHeader( &header );
EXRImage image;
InitEXRImage( &image );
image.num_channels = 3;
std::vector<halfFloat_t> images[3];
images[0].resize( width * height );
images[1].resize( width * height );
images[2].resize( width * height );
halfFloat_t* rgb = ( halfFloat_t* ) rgba16f;
for( int i = 0; i < width * height; i++ )
{
images[0][i] = ( rgb[3 * i + 0] );
images[1][i] = ( rgb[3 * i + 1] );
images[2][i] = ( rgb[3 * i + 2] );
}
halfFloat_t* image_ptr[3];
image_ptr[0] = &( images[2].at( 0 ) ); // B
image_ptr[1] = &( images[1].at( 0 ) ); // G
image_ptr[2] = &( images[0].at( 0 ) ); // R
image.images = ( unsigned char** )image_ptr;
image.width = width;
image.height = height;
header.num_channels = 3;
header.channels = ( EXRChannelInfo* )malloc( sizeof( EXRChannelInfo ) * header.num_channels );
// Must be BGR(A) order, since most of EXR viewers expect this channel order.
strncpy( header.channels[0].name, "B", 255 );
header.channels[0].name[strlen( "B" )] = '\0';
strncpy( header.channels[1].name, "G", 255 );
header.channels[1].name[strlen( "G" )] = '\0';
strncpy( header.channels[2].name, "R", 255 );
header.channels[2].name[strlen( "R" )] = '\0';
header.pixel_types = ( int* )malloc( sizeof( int ) * header.num_channels );
header.requested_pixel_types = ( int* )malloc( sizeof( int ) * header.num_channels );
for( int i = 0; i < header.num_channels; i++ )
{
header.pixel_types[i] = TINYEXR_PIXELTYPE_FLOAT; // pixel type of input image
header.requested_pixel_types[i] = TINYEXR_PIXELTYPE_HALF; // pixel type of output image to be stored in .EXR
}
header.compression_type = TINYEXR_COMPRESSIONTYPE_ZIP;
byte* buffer = NULL;
const char* err;
size_t size = SaveEXRImageToMemory( &image, &header, &buffer, &err );
if( size == 0 )
{
common->Error( "R_WriteEXR( %s ): Save EXR err: %s\n", filename, err );
goto cleanup;
}
fileSystem->WriteFile( filename, buffer, size, basePath );
cleanup:
free( header.channels );
free( header.pixel_types );
free( header.requested_pixel_types );
#endif
}
// RB end

View file

@ -497,7 +497,7 @@ void idVulkanBlock::Print()
idLib::Printf( "Usage: %s\n", memoryUsageStrings[ usage ] );
idLib::Printf( "Count: %d\n", count );
// SRS - Changed %lu to %PRIu64 pre-defined macro to handle platform differences
// SRS - Changed %lu to %PRIu64 pre-defined macro to handle platform differences
idLib::Printf( "Size: %" PRIu64"\n", size );
idLib::Printf( "Allocated: %" PRIu64"\n", allocated );
idLib::Printf( "Next Block: %u\n", nextBlockId );
@ -508,7 +508,7 @@ void idVulkanBlock::Print()
idLib::Printf( "{\n" );
idLib::Printf( "\tId: %u\n", current->id );
// SRS - Changed %lu to %PRIu64 pre-defined macro to handle platform differences
// SRS - Changed %lu to %PRIu64 pre-defined macro to handle platform differences
idLib::Printf( "\tSize: %" PRIu64"\n", current->size );
idLib::Printf( "\tOffset: %" PRIu64"\n", current->offset );
idLib::Printf( "\tType: %s\n", allocationTypeStrings[ current->type ] );
@ -683,7 +683,7 @@ void idVulkanAllocator::Print()
{
idLib::Printf( "Device Local MB: %d\n", int( deviceLocalMemoryBytes / 1024 * 1024 ) );
idLib::Printf( "Host Visible MB: %d\n", int( hostVisibleMemoryBytes / 1024 * 1024 ) );
// SRS - Changed %lu to %PRIu64 pre-defined macro to handle platform differences
// SRS - Changed %lu to %PRIu64 pre-defined macro to handle platform differences
idLib::Printf( "Buffer Granularity: %" PRIu64"\n", bufferImageGranularity );
idLib::Printf( "\n" );
@ -708,7 +708,7 @@ CONSOLE_COMMAND( Vulkan_PrintHeapInfo, "Print out the heap information for this
{
VkMemoryHeap heap = props.memoryHeaps[ i ];
// SRS - Changed %lu to %PRIu64 pre-defined macro to handle platform differences
// SRS - Changed %lu to %PRIu64 pre-defined macro to handle platform differences
idLib::Printf( "id=%d, size=%" PRIu64", flags=", i, heap.size );
if( heap.flags & VK_MEMORY_HEAP_DEVICE_LOCAL_BIT )
{