gta specular

This commit is contained in:
iAmAsval 2021-11-19 18:34:37 +01:00
parent dc797ade45
commit 78db897510
2 changed files with 63 additions and 55 deletions

@ -1 +1 @@
Subproject commit 878d12feb115153416d5a15028d4d5ee50479726
Subproject commit c6140adb909202ad7fe45a329b4f35153bb9007c

View File

@ -211,7 +211,7 @@ namespace FModel.ViewModels
builder.AddSphere(Vector3.Zero, 10);
var camAxis = SetupCameraAndAxis(new FBox(new FVector(-15), new FVector(15)));
var (m, isRendering) = LoadMaterial(materialInstance);
var (m, isRendering, _) = LoadMaterial(materialInstance);
_geometries.Add(new MeshGeometryModel3D
{
@ -277,17 +277,16 @@ namespace FModel.ViewModels
if (section.Material == null || !section.Material.TryLoad<UMaterialInterface>(out var unrealMaterial))
continue;
var (m, isRendering) = LoadMaterial(unrealMaterial);
var (m, isRendering, isTransparent) = LoadMaterial(unrealMaterial);
_geometries.Add(new MeshGeometryModel3D
{
Name = unrealMaterial.Name.Replace('-', '_'), Geometry = builder.ToMeshGeometry3D(),
Material = m, IsRendering = isRendering, Tag = false // flag
Material = m, IsTransparent = isTransparent, IsRendering = isRendering, Tag = false // flag
}, camAxis);
}
}
private (PBRMaterial material, bool isRendering) LoadMaterial(UMaterialInterface unrealMaterial)
private (PBRMaterial material, bool isRendering, bool isTransparent) LoadMaterial(UMaterialInterface unrealMaterial)
{
var m = new PBRMaterial { RenderShadowMap = true, EnableAutoTangent = true, RenderEnvironmentMap = true };
var parameters = new CMaterialParams();
@ -300,68 +299,77 @@ namespace FModel.ViewModels
m.AlbedoMap = new TextureModel(diffuse.Decode()?.Encode().AsStream());
if (parameters.Normal is UTexture2D normal)
m.NormalMap = new TextureModel(normal.Decode()?.Encode().AsStream());
if (_game == FGame.FortniteGame)
if (parameters.Specular is UTexture2D specular)
{
// Fortnite's Specular Texture Channels
// R Specular
// G Metallic
// B Roughness
if (parameters.Specular is UTexture2D specular)
var mip = specular.GetFirstMip();
TextureDecoder.DecodeTexture(mip, specular.Format, specular.isNormalMap,
out var data, out var colorType);
switch (_game)
{
var mip = specular.GetFirstMip();
TextureDecoder.DecodeTexture(mip, specular.Format, specular.isNormalMap,
out var data, out var colorType);
unsafe
case FGame.FortniteGame:
{
var offset = 0;
fixed (byte* d = data)
for (var i = 0; i < mip.SizeX * mip.SizeY; i++)
{
d[offset] = 0;
(d[offset+1], d[offset+2]) = (d[offset+2], d[offset+1]); // swap G and B
offset += 4;
}
}
var width = mip.SizeX;
var height = mip.SizeY;
using var bitmap = new SKBitmap(new SKImageInfo(width, height, colorType, SKAlphaType.Unpremul));
unsafe
{
fixed (byte* p = data)
// Fortnite's Specular Texture Channels
// R Specular
// G Metallic
// B Roughness
unsafe
{
bitmap.SetPixels(new IntPtr(p));
var offset = 0;
fixed (byte* d = data)
for (var i = 0; i < mip.SizeX * mip.SizeY; i++)
{
d[offset] = 0;
(d[offset+1], d[offset+2]) = (d[offset+2], d[offset+1]); // swap G and B
offset += 4;
}
}
parameters.RoughnessValue = 1;
parameters.MetallicValue = 1;
break;
}
case FGame.Gameface:
{
// GTA's Specular Texture Channels
// R Metallic
// G Roughness
// B Specular
unsafe
{
var offset = 0;
fixed (byte* d = data)
for (var i = 0; i < mip.SizeX * mip.SizeY; i++)
{
(d[offset], d[offset+2]) = (d[offset+2], d[offset]); // swap R and B
offset += 4;
}
}
break;
}
// R -> AO G -> Roughness B -> Metallic
m.RoughnessMetallicMap = new TextureModel(bitmap.Encode(SKEncodedImageFormat.Png, 100).AsStream());
m.RenderAmbientOcclusionMap = false; // red channel is not ao
m.MetallicFactor = 1;
m.RoughnessFactor = 1;
}
using var bitmap = new SKBitmap(new SKImageInfo(mip.SizeX, mip.SizeY, colorType, SKAlphaType.Unpremul));
unsafe
{
fixed (byte* p = data)
{
bitmap.SetPixels(new IntPtr(p));
}
}
// R -> AO G -> Roughness B -> Metallic
m.RoughnessMetallicMap = new TextureModel(bitmap.Encode(SKEncodedImageFormat.Png, 100).AsStream());
m.RoughnessFactor = parameters.RoughnessValue;
m.MetallicFactor = parameters.MetallicValue;
m.RenderAmbientOcclusionMap = parameters.SpecularValue > 0;
}
// if (parameters.Specular is UTexture2D specular)
// m.AmbientOcculsionMap = new TextureModel(specular.Decode()?.Encode().AsStream());
// if (parameters.Specular is UTexture2D specularPower)
// {
// m.RoughnessFactor = parameters.MobileSpecularPower;
// m.RoughnessMetallicMap = new TextureModel(specularPower.Decode()?.Encode().AsStream());
// }
// if (parameters.Emissive is UTexture2D emissive)
// {
// m.EmissiveColor = Color4.White; // FortniteGame/Content/Characters/Player/Female/Medium/Bodies/F_MED_Obsidian/Meshes/F_MED_Obsidian.uasset
// m.EmissiveMap = new TextureModel(emissive.Decode()?.Encode().AsStream());
// }
}
else
{
m = new PBRMaterial { AlbedoColor = new Color4(1, 0, 0, 1) }; //PhongMaterials.Red;
m.AlbedoColor = new Color4(1, 0, 0, 1);
}
return (m, isRendering);
return (m, isRendering, parameters.IsTransparent);
}
private CamAxisHolder SetupCameraAndAxis(FBox box)