mirror of
https://github.com/jmarshall23/DoomRTX.git
synced 2026-08-12 08:11:10 +02:00
Fixes for BC7
This commit is contained in:
@@ -1164,6 +1164,21 @@ static float R_NormalProjection( const byte *rgba, const idVec3 &axis ) {
|
||||
( rgba[2] * ( 2.0f / 255.0f ) - 1.0f ) * axis.z;
|
||||
}
|
||||
|
||||
static byte R_NormalFloatToByte( float v ) {
|
||||
return (byte)idMath::ClampInt( 0, 255, (int)( ( v * 0.5f + 0.5f ) * 255.0f + 0.5f ) );
|
||||
}
|
||||
|
||||
static float R_NormalToSlopeHeight( const idVec3 &normal ) {
|
||||
const float slope = idMath::ClampFloat( 0.0f, 1.0f, idMath::Sqrt( normal.x * normal.x + normal.y * normal.y ) );
|
||||
return idMath::ClampFloat( 0.0f, 1.0f, 0.5f + idMath::Pow( slope, 0.65f ) * 0.5f );
|
||||
}
|
||||
|
||||
static byte R_NormalToBakedHeightByte( const idVec3 &normal, float blockAverageHeight ) {
|
||||
const float localHeight = 0.5f + ( R_NormalToSlopeHeight( normal ) - blockAverageHeight ) * 0.55f;
|
||||
const float height = idMath::ClampFloat( 0.35f, 0.65f, localHeight );
|
||||
return (byte)idMath::ClampInt( 1, 254, (int)( height * 255.0f + 0.5f ) );
|
||||
}
|
||||
|
||||
static void R_EncodeBC7Mode6Block( const byte *rgba, int width, int height, int x, int y, bool normalMap, byte *block ) {
|
||||
memset( block, 0, 16 );
|
||||
|
||||
@@ -1176,8 +1191,11 @@ static void R_EncodeBC7Mode6Block( const byte *rgba, int width, int height, int
|
||||
idVec3 averageNormal( 0.0f, 0.0f, 0.0f );
|
||||
idVec3 variance( 0.0f, 0.0f, 0.0f );
|
||||
idVec3 axis( 1.0f, 0.0f, 0.0f );
|
||||
float averageProjection = 0.0f;
|
||||
float averageSlopeHeight = 0.5f;
|
||||
|
||||
if ( normalMap ) {
|
||||
averageSlopeHeight = 0.0f;
|
||||
for ( int by = 0; by < 4; by++ ) {
|
||||
const int sy = ( y + by < height ) ? y + by : height - 1;
|
||||
for ( int bx = 0; bx < 4; bx++ ) {
|
||||
@@ -1186,9 +1204,18 @@ static void R_EncodeBC7Mode6Block( const byte *rgba, int width, int height, int
|
||||
averageNormal.x += p[0] * ( 2.0f / 255.0f ) - 1.0f;
|
||||
averageNormal.y += p[1] * ( 2.0f / 255.0f ) - 1.0f;
|
||||
averageNormal.z += p[2] * ( 2.0f / 255.0f ) - 1.0f;
|
||||
idVec3 sampleNormal(
|
||||
p[0] * ( 2.0f / 255.0f ) - 1.0f,
|
||||
p[1] * ( 2.0f / 255.0f ) - 1.0f,
|
||||
p[2] * ( 2.0f / 255.0f ) - 1.0f );
|
||||
if ( !sampleNormal.Normalize() ) {
|
||||
sampleNormal.Set( 0.0f, 0.0f, 1.0f );
|
||||
}
|
||||
averageSlopeHeight += R_NormalToSlopeHeight( sampleNormal );
|
||||
}
|
||||
}
|
||||
averageNormal *= 1.0f / 16.0f;
|
||||
averageSlopeHeight *= 1.0f / 16.0f;
|
||||
for ( int by = 0; by < 4; by++ ) {
|
||||
const int sy = ( y + by < height ) ? y + by : height - 1;
|
||||
for ( int bx = 0; bx < 4; bx++ ) {
|
||||
@@ -1207,6 +1234,7 @@ static void R_EncodeBC7Mode6Block( const byte *rgba, int width, int height, int
|
||||
} else if ( variance.z > variance.x && variance.z > variance.y ) {
|
||||
axis.Set( 0.0f, 0.0f, 1.0f );
|
||||
}
|
||||
averageProjection = averageNormal * axis;
|
||||
}
|
||||
|
||||
for ( int by = 0; by < 4; by++ ) {
|
||||
@@ -1218,11 +1246,9 @@ static void R_EncodeBC7Mode6Block( const byte *rgba, int width, int height, int
|
||||
const float projection = R_NormalProjection( p, axis );
|
||||
if ( projection < minProjection ) {
|
||||
minProjection = projection;
|
||||
memcpy( minColor, p, 4 );
|
||||
}
|
||||
if ( projection > maxProjection ) {
|
||||
maxProjection = projection;
|
||||
memcpy( maxColor, p, 4 );
|
||||
}
|
||||
continue;
|
||||
}
|
||||
@@ -1238,6 +1264,30 @@ static void R_EncodeBC7Mode6Block( const byte *rgba, int width, int height, int
|
||||
}
|
||||
}
|
||||
|
||||
if ( normalMap ) {
|
||||
idVec3 minNormal = averageNormal + axis * ( minProjection - averageProjection );
|
||||
idVec3 maxNormal = averageNormal + axis * ( maxProjection - averageProjection );
|
||||
if ( variance.x + variance.y + variance.z < 0.0002f || ( maxProjection - minProjection ) < 0.01f ) {
|
||||
minNormal = averageNormal;
|
||||
maxNormal = averageNormal;
|
||||
minProjection = maxProjection = averageProjection;
|
||||
}
|
||||
if ( !minNormal.Normalize() ) {
|
||||
minNormal.Set( 0.0f, 0.0f, 1.0f );
|
||||
}
|
||||
if ( !maxNormal.Normalize() ) {
|
||||
maxNormal.Set( 0.0f, 0.0f, 1.0f );
|
||||
}
|
||||
minColor[0] = R_NormalFloatToByte( minNormal.x );
|
||||
minColor[1] = R_NormalFloatToByte( minNormal.y );
|
||||
minColor[2] = R_NormalFloatToByte( minNormal.z );
|
||||
minColor[3] = R_NormalToBakedHeightByte( minNormal, averageSlopeHeight );
|
||||
maxColor[0] = R_NormalFloatToByte( maxNormal.x );
|
||||
maxColor[1] = R_NormalFloatToByte( maxNormal.y );
|
||||
maxColor[2] = R_NormalFloatToByte( maxNormal.z );
|
||||
maxColor[3] = R_NormalToBakedHeightByte( maxNormal, averageSlopeHeight );
|
||||
}
|
||||
|
||||
int bit = 0;
|
||||
R_WriteBitsLSB( block, bit, 0x40, 7 ); // BC7 mode 6: six zero mode bits followed by one.
|
||||
|
||||
@@ -1294,7 +1344,7 @@ static void R_AppendBytes( idList<byte> &dst, const void *src, int bytes ) {
|
||||
}
|
||||
|
||||
static unsigned long R_GeneratedBC7CookVersion() {
|
||||
return DDS_MAKEFOURCC( 'B', '7', 'C', '3' );
|
||||
return DDS_MAKEFOURCC( 'B', '7', 'C', '8' );
|
||||
}
|
||||
|
||||
static bool R_GetDDSAverageColor( const byte *data, int len, float averageColor[4] ) {
|
||||
@@ -1456,7 +1506,7 @@ bool idImage::CookGeneratedBC7Image( const byte *pic, int width, int height, ID_
|
||||
header.dwFlags = DDSF_CAPS | DDSF_PIXELFORMAT | DDSF_WIDTH | DDSF_HEIGHT | DDSF_LINEARSIZE;
|
||||
header.dwHeight = scaled_height;
|
||||
header.dwWidth = scaled_width;
|
||||
header.dwPitchOrLinearSize = ( ( scaled_width + 3 ) / 4 ) * 16;
|
||||
header.dwPitchOrLinearSize = ( ( scaled_width + 3 ) / 4 ) * ( ( scaled_height + 3 ) / 4 ) * 16;
|
||||
header.dwMipMapCount = numLevels;
|
||||
header.dwFlags |= DDSF_MIPMAPCOUNT;
|
||||
header.dwCaps1 = DDSF_TEXTURE | DDSF_MIPMAP | DDSF_COMPLEX;
|
||||
|
||||
Reference in New Issue
Block a user