Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/develop' into meshageddon
Browse files Browse the repository at this point in the history
  • Loading branch information
JMPZ11 committed Jun 22, 2024
2 parents 841d33a + d19e1c0 commit 013745a
Show file tree
Hide file tree
Showing 21 changed files with 247 additions and 139 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
== CHANGELOG ==

* Added new spell (Batch/Copy and Rename all Meshes) by 1OfAKindMods to copy and rename all .mesh files used by a Starfield model. Note that the spell expects a loose NIF file, if the model is from an archive, the renamed mesh files are written under the NifSkope installation directory.
* The right click menu on header strings that end with .bgsm, .bgem or .mat has a new option to browse materials. Updating the view (Alt+U) may be needed for material path changes to take effect.
* Added limited support for rendering translucent Starfield materials.
* Fixed the contrast parameter of Starfield blenders that is inverted in the material data.
* The default height scale for Starfield parallax occlusion mapping is now 0.0 in the render settings, as height textures do not actually work in the game.

#### NifSkope-2.0.dev9-20240616

* Starfield material rendering improvements, including support for layered materials with PositionContrast blend mode. CharacterCombine mode is also rendered, but it is interpreted as linear blending.
Expand Down
10 changes: 5 additions & 5 deletions build/nif.xml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
<verexpr token="#BS_GTE_SKY#" string="(#BSVER# #GTE# 83)">Skyrim and later.</verexpr>
<verexpr token="#BS_GTE_SSE#" string="(#BSVER# #GTE# 100)">SSE and later.</verexpr>
<verexpr token="#BS_GTE_F76#" string="(#BSVER# #GTE# 155)">Fallout 76 and later.</verexpr>
<verexpr token="#BS_GTE_STF#" string="(#BSVER# #GTE# 172)">Starfield and later.</verexpr>
<verexpr token="#BS_GTE_STF#" string="(#BSVER# #GTE# 170)">Starfield and later.</verexpr>
<verexpr token="#BS_SSE#" string="(#BSVER# #EQ# 100)">SSE only.</verexpr>
<verexpr token="#BS_FO4#" string="(#BSVER# #EQ# 130)">Fallout 4 strictly, excluding stream 132 and 139 in dev files.</verexpr>
<verexpr token="#BS_FO4_2#" string="((#BSVER# #GTE# 130) #AND# (#BSVER# #LTE# 139))">Fallout 4/76 including dev files.</verexpr>
Expand All @@ -29,7 +29,7 @@
<verexpr token="#BS_GTE_132#" string="(#BSVER# #GTE# 132)">Bethesda 132 and later.</verexpr>
<verexpr token="#BS_GTE_152#" string="(#BSVER# #GTE# 152)">Bethesda 152 and later.</verexpr>
<verexpr token="#BS_F76#" string="(#BSVER# #EQ# 155)">Fallout 76 stream 155 only.</verexpr>
<verexpr token="#BS_SSE_FO4_FO76#" string="((#BSVER# #GTE# 100) #AND# (#BSVER# #LT# 172))">SSE, FO4, FO76</verexpr>
<verexpr token="#BS_SSE_FO4_FO76#" string="((#BSVER# #GTE# 100) #AND# (#BSVER# #LT# 170))">SSE, FO4, FO76</verexpr>
<verexpr token="#BS_FO4_F76#" string="((#BSVER# #GTE# 130) #AND# (#BSVER# #LTE# 159))">FO4, FO76</verexpr>
<verexpr token="#BS202#" string="((#VER# #EQ# 20.2.0.7) #AND# (#BSVER# #GT# 0))">Bethesda 20.2 only.</verexpr>
<verexpr token="#DIVINITY2#" string="((#USER# #EQ# 0x20000) #OR# (#USER# #EQ# 0x30000))">Divinity 2</verexpr>
Expand Down Expand Up @@ -215,7 +215,7 @@
<version id="V20_2_0_7_FO4" num="20.2.0.7" user="12" bsver="130" ext="bto btr">{{Fallout 4}}</version>
<version id="V20_2_0_7_FO4_2" num="20.2.0.7" user="12" bsver="132 139" ext="bto btr" supported="false">Fallout 4 (LS_Mirelurk.nif, Screen.nif)</version>
<version id="V20_2_0_7_F76" num="20.2.0.7" user="12" bsver="155" ext="bto">{{Fallout 76}}</version>
<version id="V20_2_0_7_STF" num="20.2.0.7" user="12" bsver="172 173">{{Starfield}}</version>
<version id="V20_2_0_7_STF" num="20.2.0.7" user="12" bsver="170 172 173">{{Starfield}}</version>
<version id="V20_2_0_8" num="20.2.0.8" ext="nifcache">{{Empire Earth III}}, {{FFT Online}}, Atlantica Online, IRIS Online, Wizard101</version>
<version id="V20_2_4_7" num="20.2.4.7">QQSpeed</version>
<version id="V20_3_0_1" num="20.3.0.1">Emerge</version>
Expand Down Expand Up @@ -1967,8 +1967,8 @@
<field name="Unknown Int" type="uint" cond="BS Version #GT# 130" />
<field name="Process Script" type="ExportString" cond="BS Version #LT# 131" />
<field name="Export Script" type="ExportString" />
<field name="Max Filepath" type="ExportString" cond="(BS Version #GTE# 103) #AND# (BS Version #LT# 172)" />
<field name="Unknown Data" type="ExportDataSF" cond="BS Version #GTE# 172" />
<field name="Max Filepath" type="ExportString" cond="(BS Version #GTE# 103) #AND# (BS Version #LT# 170)" />
<field name="Unknown Data" type="ExportDataSF" cond="BS Version #GTE# 170" />
</struct>

<!-- Don't use vercond in Header, it breaks niflib -->
Expand Down
2 changes: 1 addition & 1 deletion lib/libfo76utils
25 changes: 22 additions & 3 deletions res/shaders/stf_default.frag
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,9 @@ float getBlenderMask(int n)

vec2 parallaxMapping( int n, vec3 V, vec2 offset )
{
if ( parallaxOcclusionSettings.z < 0.0005 )
return offset; // disabled

// determine optimal height of each layer
float layerHeight = 1.0 / mix( parallaxOcclusionSettings.y, parallaxOcclusionSettings.x, abs(V.z) );

Expand Down Expand Up @@ -446,6 +449,7 @@ void main()
vec3 pbrMap = vec3(0.75, 0.0, 1.0); // roughness, metalness, AO
float alpha = 1.0;
vec3 emissive = vec3(0.0);
vec3 transmissive = vec3(0.0);

for (int i = 0; i < 4; i++) {
if ( !lm.layersEnabled[i] )
Expand Down Expand Up @@ -498,7 +502,7 @@ void main()
if ( lm.blenders[i - 1].blendMode == 2 ) {
float blendPosition = lm.blenders[i - 1].floatParams[2];
float blendContrast = lm.blenders[i - 1].floatParams[3];
blendContrast = max( (1.0 - blendContrast) * min(blendPosition, 1.0 - blendPosition), 0.001 );
blendContrast = max( blendContrast * min(blendPosition, 1.0 - blendPosition), 0.001 );
blendPosition = ( blendPosition - 0.5 ) * 3.17;
blendPosition = ( blendPosition * blendPosition + 1.0 ) * blendPosition + 0.5;
float maskMin = blendPosition - blendContrast;
Expand Down Expand Up @@ -581,6 +585,12 @@ void main()
continue;
emissive += getLayerTexture( i, 7, offset ).rgb * tmp.rgb * tmp.a;
}

if ( lm.layers[i].material.textureSet.textures[8] != 0 ) {
// _transmissive.dds
if ( lm.translucencySettings.isEnabled && i == lm.translucencySettings.transmittanceSourceLayer )
transmissive = vec3( getLayerTexture( i, 8, offset ).r * lm.translucencySettings.transmissiveScale );
}
}

normal = normalize( btnMatrix_norm * normal );
Expand Down Expand Up @@ -667,8 +677,6 @@ void main()
float ao = pbrMap.b;
refl *= f * envLUT.g * ao;

// TODO: translucency

// Diffuse
color.rgb = diffuse * albedo * D.rgb;
// Ambient
Expand All @@ -680,6 +688,17 @@ void main()
// Emissive
color.rgb += emissive;

// Transmissive
if ( lm.translucencySettings.isEnabled && lm.translucencySettings.isThin ) {
transmissive *= albedo * ( vec3(1.0) - f );
// TODO: implement flipBackFaceNormalsInViewSpace
color.rgb += transmissive * D.rgb * max( -NdotL, 0.0 );
if ( hasCubeMap )
color.rgb += textureLod( CubeMap2, -normalWS, 0.0 ).rgb * transmissive * A.rgb * ao;
else
color.rgb += transmissive * A.rgb * ( ao * 0.08 );
}

color.rgb = tonemap(color.rgb * D.a, A.a);
color.a = baseMap.a * alpha;

Expand Down
2 changes: 1 addition & 1 deletion res/shaders/stf_default.prog
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

checkgroup begin and
# Starfield
check HEADER/BS Header/BS Version >= 172
check HEADER/BS Header/BS Version >= 170
check BSGeometry
check BSLightingShaderProperty
checkgroup end
Expand Down
2 changes: 1 addition & 1 deletion res/shaders/stf_effectshader.prog
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

checkgroup begin and
# Starfield
check HEADER/BS Header/BS Version == 172
check HEADER/BS Header/BS Version >= 170
check BSGeometry
check BSEffectShaderProperty
checkgroup end
Expand Down
1 change: 1 addition & 0 deletions src/gamemanager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -430,6 +430,7 @@ GameMode GameManager::get_game( const NifModel * nif )
return FALLOUT_4;
case BSSTREAM_155:
return FALLOUT_76;
case BSSTREAM_170:
case BSSTREAM_172:
case BSSTREAM_173:
return STARFIELD;
Expand Down
1 change: 1 addition & 0 deletions src/gamemanager.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ enum BSVersion
BSSTREAM_100 = 100,
BSSTREAM_130 = 130,
BSSTREAM_155 = 155,
BSSTREAM_170 = 170,
BSSTREAM_172 = 172,
BSSTREAM_173 = 173
};
Expand Down
10 changes: 5 additions & 5 deletions src/gl/glproperty.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -851,7 +851,7 @@ void BSShaderLightingProperty::updateImpl( const NifModel * nif, const QModelInd

if ( index == iBlock ) {
bsVersion = (unsigned short) nif->getBSVersion();
if ( bsVersion >= 160 ) {
if ( bsVersion >= 170 ) {
setSFMaterial( name );
} else {
if ( bsVersion < 83 )
Expand Down Expand Up @@ -1072,7 +1072,7 @@ enum
QString BSShaderLightingProperty::fileName( int id ) const
{
// Starfield (not implemented here)
if ( bsVersion >= 160 )
if ( bsVersion >= 170 )
return QString();

// Fallout 4 or 76 BGSM file
Expand Down Expand Up @@ -1241,7 +1241,7 @@ void BSLightingShaderProperty::updateImpl( const NifModel * nif, const QModelInd
BSShaderLightingProperty::updateImpl( nif, index );

if ( index == iBlock ) {
if ( name.endsWith(".bgsm", Qt::CaseInsensitive) && bsVersion < 160 ) {
if ( name.endsWith(".bgsm", Qt::CaseInsensitive) && bsVersion < 170 ) {
setMaterial( new ShaderMaterial( name, nif ) );
if ( bsVersion >= 151 )
const_cast< NifModel * >(nif)->loadFO76Material( index, material );
Expand Down Expand Up @@ -1307,7 +1307,7 @@ void BSLightingShaderProperty::updateParams( const NifModel * nif )
{
resetParams();

if ( bsVersion >= 172 ) {
if ( bsVersion >= 170 ) {
setSFMaterial( nif->get<QString>( iBlock, "Name" ) );
return;
}
Expand Down Expand Up @@ -1482,7 +1482,7 @@ void BSEffectShaderProperty::updateImpl( const NifModel * nif, const QModelIndex
BSShaderLightingProperty::updateImpl( nif, index );

if ( index == iBlock ) {
if ( name.endsWith(".bgem", Qt::CaseInsensitive) && bsVersion < 160 ) {
if ( name.endsWith(".bgem", Qt::CaseInsensitive) && bsVersion < 170 ) {
setMaterial( new EffectMaterial( name, nif ) );
if ( bsVersion >= 151 )
const_cast< NifModel * >(nif)->loadFO76Material( index, material );
Expand Down
2 changes: 1 addition & 1 deletion src/gl/glshape.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ void Shape::updateShader()
else if ( alphaProperty && alphaProperty->hasAlphaBlend() )
drawInSecondPass = true;
else if ( bssp ) {
if ( bssp->bsVersion >= 160 ) {
if ( bssp->bsVersion >= 170 ) {
const CE2Material * sfMat = nullptr;
bssp->getSFMaterial( sfMat, scene->nifModel );
if ( sfMat && ( sfMat->shaderRoute != 0 || (sfMat->flags & CE2Material::Flag_IsDecal) ) )
Expand Down
20 changes: 19 additions & 1 deletion src/gl/renderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -442,7 +442,7 @@ void Renderer::updateSettings()

cfg.useShaders = settings.value( "Settings/Render/General/Use Shaders", true ).toBool();
cfg.sfParallaxMaxSteps = short( settings.value( "Settings/Render/General/Sf Parallax Steps", 200 ).toInt() );
cfg.sfParallaxScale = settings.value( "Settings/Render/General/Sf Parallax Scale", 0.033f).toFloat();
cfg.sfParallaxScale = settings.value( "Settings/Render/General/Sf Parallax Scale", 0.0f).toFloat();
cfg.sfParallaxOffset = settings.value( "Settings/Render/General/Sf Parallax Offset", 0.5f).toFloat();
cfg.cubeMapPathFO76 = settings.value( "Settings/Render/General/Cube Map Path FO 76", "textures/shared/cubemaps/mipblur_defaultoutside1.dds" ).toString();
cfg.cubeMapPathSTF = settings.value( "Settings/Render/General/Cube Map Path STF", "textures/cubemaps/cell_cityplazacube.dds" ).toString();
Expand Down Expand Up @@ -957,6 +957,24 @@ bool Renderer::setupProgramSF( Program * prog, Shape * mesh )
prog->uni1b_l( prog->uniLocation("lm.emissiveSettings.isEnabled"), false );
}

// translucency settings
if ( mat->flags & CE2Material::Flag_Translucency ) {
const CE2Material::TranslucencySettings * sp = mat->translucencySettings;
prog->uni1b_l( prog->uniLocation("lm.translucencySettings.isEnabled"), sp->isEnabled );
prog->uni1b_l( prog->uniLocation("lm.translucencySettings.isThin"), sp->isThin );
prog->uni1b_l( prog->uniLocation("lm.translucencySettings.flipBackFaceNormalsInViewSpace"), sp->flipBackFaceNormalsInVS );
prog->uni1b_l( prog->uniLocation("lm.translucencySettings.useSSS"), sp->useSSS );
prog->uni1f_l( prog->uniLocation("lm.translucencySettings.sssWidth"), sp->sssWidth );
prog->uni1f_l( prog->uniLocation("lm.translucencySettings.sssStrength"), sp->sssStrength );
prog->uni1f_l( prog->uniLocation("lm.translucencySettings.transmissiveScale"), sp->transmissiveScale );
prog->uni1f_l( prog->uniLocation("lm.translucencySettings.transmittanceWidth"), sp->transmittanceWidth );
prog->uni1f_l( prog->uniLocation("lm.translucencySettings.specLobe0RoughnessScale"), sp->specLobe0RoughnessScale );
prog->uni1f_l( prog->uniLocation("lm.translucencySettings.specLobe1RoughnessScale"), sp->specLobe1RoughnessScale );
prog->uni1i_l( prog->uniLocation("lm.translucencySettings.transmittanceSourceLayer"), sp->sourceLayer );
} else {
prog->uni1b_l( prog->uniLocation("lm.translucencySettings.isEnabled"), false );
}

// decal settings
if ( mat->flags & CE2Material::Flag_IsDecal ) {
const CE2Material::DecalSettings * sp = mat->decalSettings;
Expand Down
2 changes: 1 addition & 1 deletion src/gl/renderer.h
Original file line number Diff line number Diff line change
Expand Up @@ -411,7 +411,7 @@ public slots:
{
bool useShaders = true;
short sfParallaxMaxSteps = 200;
float sfParallaxScale = 0.033f;
float sfParallaxScale = 0.0f;
float sfParallaxOffset = 0.5f;
QString cubeMapPathFO76;
QString cubeMapPathSTF;
Expand Down
28 changes: 15 additions & 13 deletions src/io/MeshFile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ quint32 MeshFile::readMesh()

quint32 magic;
in >> magic;
if ( magic != 1 && magic != 2 )
if ( magic > 2U )
return 0;

quint32 indicesSize;
Expand Down Expand Up @@ -173,18 +173,20 @@ quint32 MeshFile::readMesh()
weights[i] = BoneWeightsUNorm(weightsUNORM, i);
}

quint32 numLODs;
in >> numLODs;
lods.resize(numLODs);
for ( quint32 i = 0; i < numLODs; i++ ) {
quint32 indicesSize2;
in >> indicesSize2;
lods[i].resize(indicesSize2 / 3);

for ( quint32 j = 0; j < indicesSize2 / 3; j++ ) {
Triangle tri;
in >> tri;
lods[i][j] = tri;
if ( magic ) {
quint32 numLODs;
in >> numLODs;
lods.resize(numLODs);
for ( quint32 i = 0; i < numLODs; i++ ) {
quint32 indicesSize2;
in >> indicesSize2;
lods[i].resize(indicesSize2 / 3);

for ( quint32 j = 0; j < indicesSize2 / 3; j++ ) {
Triangle tri;
in >> tri;
lods[i][j] = tri;
}
}
}

Expand Down
8 changes: 4 additions & 4 deletions src/lib/importex/importex.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,9 @@ struct ImportExportOption


QVector<ImportExportOption> impexOptions{
ImportExportOption{ ".OBJ", importObj, exportObj, 0, 171 },
ImportExportOption{ ".OBJ as Collision", importObjAsCollision, nullptr, 0, 171 },
ImportExportOption{ ".glTF", nullptr, exportGltf, 172 },
ImportExportOption{ ".OBJ", importObj, exportObj, 0, 169 },
ImportExportOption{ ".OBJ as Collision", importObjAsCollision, nullptr, 0, 169 },
ImportExportOption{ ".glTF", nullptr, exportGltf, 170 },
};


Expand Down Expand Up @@ -126,4 +126,4 @@ void NifSkope::sltExport( QAction* a )
if ( impex.exportFn ) {
impex.exportFn(nif, ogl->scene, index);
}
}
}
2 changes: 1 addition & 1 deletion src/model/nifextfiles.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ void NifModel::loadSFBlender( NifItem * parent, const void * o )
setValue<float>( parent, "Height Blend Threshold", floatParams[0] );
setValue<float>( parent, "Height Blend Factor", floatParams[1] );
setValue<float>( parent, "Position", floatParams[2] );
setValue<float>( parent, "Contrast", floatParams[3] );
setValue<float>( parent, "Contrast", 1.0f - floatParams[3] );
setValue<float>( parent, "Mask Intensity", floatParams[4] );
setValue<bool>( parent, "Blend Color", boolParams[0] );
setValue<bool>( parent, "Blend Metalness", boolParams[1] );
Expand Down
2 changes: 1 addition & 1 deletion src/spells/filerename.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class spResourceRename final : public Spell
{
public:
QString name() const override final { return Spell::tr( "Search/Replace Resource Paths" ); }
QString page() const override final { return Spell::tr( "" ); }
QString page() const override final { return Spell::tr( "Batch" ); }
QIcon icon() const override final
{
return QIcon();
Expand Down
Loading

0 comments on commit 013745a

Please sign in to comment.