Skip to content

Commit

Permalink
Merge pull request #98 from DeltaDesigns/main
Browse files Browse the repository at this point in the history
Basic string exporting, source 2 shader updates
  • Loading branch information
MontagueM authored Dec 12, 2022
2 parents d1df927 + 80589fb commit 2e81da2
Show file tree
Hide file tree
Showing 6 changed files with 114 additions and 36 deletions.
26 changes: 24 additions & 2 deletions Charm/TagListView.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
using Field;
using Microsoft.Toolkit.Mvvm.Input;
using Serilog;
using System.Text;

namespace Charm;

Expand Down Expand Up @@ -1313,6 +1314,7 @@ private void LoadStringContainer(TagHash tagHash)
// Would be nice to do something with colour formatting.
private void LoadStrings(TagHash tagHash)
{
var viewer = GetViewer();
_allTagItems = new ConcurrentBag<TagItem>();
StringContainer stringContainer = PackageHandler.GetTag(typeof(StringContainer), tagHash);
Parallel.ForEach(stringContainer.Header.StringHashTable, hash =>
Expand All @@ -1325,12 +1327,32 @@ private void LoadStrings(TagHash tagHash)
});
});
RefreshItemList();
SetExportFunction(ExportString, (int)EExportTypeFlag.Full);
viewer.ExportControl.SetExportInfo(tagHash);
}

private void ExportString(ExportInfo info)
{

StringContainer stringContainer = PackageHandler.GetTag(typeof(StringContainer), new TagHash(info.Hash));
StringBuilder text = new StringBuilder();

Parallel.ForEach(stringContainer.Header.StringHashTable, hash =>
{
text.Append($"{hash} : {stringContainer.GetStringFromHash(ELanguage.English, hash)} \n");
});

string saveDirectory = ConfigHandler.GetExportSavePath() + $"/Strings/{info.Hash}_{info.Name}/";
Directory.CreateDirectory(saveDirectory);

File.WriteAllText(saveDirectory + "strings.txt", text.ToString());

}

#endregion

#region Sound

private async Task LoadSoundsPackagesList()
{
// If there are packages, we don't want to reload the view as very poor for performance.
Expand Down
36 changes: 27 additions & 9 deletions Field/General/InfoConfigHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using Field.Models;
using Field.Statics;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

namespace Field.General;

Expand Down Expand Up @@ -128,15 +129,6 @@ public void AddCustomTexture(string material, int index, TextureHeader texture)

public void WriteToFile(string path)
{
List<string> s2 = new List<string>();
foreach (var material in _config["Materials"])
{
s2.Add($"ps_{material.Key}.vfx");
}
if(!Directory.Exists($"{path}/Shaders/Source2/"))
Directory.CreateDirectory($"{path}/Shaders/Source2/");

File.WriteAllLines($"{path}/Shaders/Source2/_S2BuildList.txt", s2);

// If theres only 1 part, we need to rename it + the instance to the name of the mesh (unreal imports to fbx name if only 1 mesh inside)
if (_config["Parts"].Count == 1)
Expand All @@ -152,6 +144,32 @@ public void WriteToFile(string path)
_config["Parts"] = new ConcurrentDictionary<string, string>();
_config["Parts"][_config["MeshName"]] = part;
}


//im not smart enough to have done this, so i made an ai do it lol
//this just sorts the "instances" part of the cfg so its ordered by scale
//makes it easier for instancing models in Hammer/S&Box

var sortedDict = new ConcurrentDictionary<string, ConcurrentBag<JsonInstance>>();

// Use LINQ's OrderBy method to sort the values in each array
// based on the "Scale" key. The lambda expression specifies that
// the "Scale" property should be used as the key for the order.
foreach (var keyValuePair in (ConcurrentDictionary<string, ConcurrentBag<JsonInstance>>)_config["Instances"])
{
var array = keyValuePair.Value;
var sortedArray = array.OrderBy(x => x.Scale);

// Convert the sorted array to a ConcurrentBag
var sortedBag = new ConcurrentBag<JsonInstance>(sortedArray);

// Add the sorted bag to the dictionary
sortedDict.TryAdd(keyValuePair.Key, sortedBag);
}

// Finally, update the _config["Instances"] object with the sorted values
_config["Instances"] = sortedDict;


string s = JsonConvert.SerializeObject(_config, Formatting.Indented);
if (_config.ContainsKey("MeshName"))
Expand Down
27 changes: 22 additions & 5 deletions Field/Textures/Material.cs
Original file line number Diff line number Diff line change
Expand Up @@ -153,9 +153,9 @@ public void SavePixelShader(string saveDirectory, bool isTerrain = false)
{
File.WriteAllText($"{saveDirectory}/PS_{Hash}.usf", usf);
}
if (!File.Exists($"{saveDirectory}/Source2/PS_{Hash}.vfx"))
if (!File.Exists($"{saveDirectory}/Source2/PS_{Hash}.shader"))
{
File.WriteAllText($"{saveDirectory}/Source2/PS_{Hash}.vfx", vfx);
File.WriteAllText($"{saveDirectory}/Source2/PS_{Hash}.shader", vfx);
}

Console.WriteLine($"Saved pixel shader {Hash}");
Expand All @@ -166,17 +166,34 @@ public void SavePixelShader(string saveDirectory, bool isTerrain = false)
}

vmat.AppendLine("Layer0 \n{");
vmat.AppendLine($" shader \"ps_{Hash}.vfx\"");
vmat.AppendLine(" F_ALPHA_TEST 1");

//If the shader doesnt exist, just use the default complex.shader
if (!File.Exists($"{saveDirectory}/Source2/PS_{Hash}.shader"))
{
vmat.AppendLine($" shader \"complex.shader\"");

//Use just the first texture for the diffuse
if (Header.PSTextures.Count > 0)
{
vmat.AppendLine($" TextureColor \"materials/Textures/{Header.PSTextures[0].Texture.Hash}.png\"");
}
}
else
{
vmat.AppendLine($" shader \"ps_{Hash}.shader\"");
vmat.AppendLine(" F_ALPHA_TEST 1");
}

foreach (var e in Header.PSTextures)
{
if (e.Texture == null)
{
continue;
}
//Console.WriteLine("Saving texture " + e.Texture.Hash + " " + e.TextureIndex + " " + e.Texture.IsSrgb().ToString());

vmat.AppendLine($" TextureT{e.TextureIndex} \"materials/Textures/{e.Texture.Hash}.png\"");
}

// if(isTerrain)
// {
// vmat.AppendLine($" TextureT14 \"materials/Textures/{partEntry.Dyemap.Hash}.png\"");
Expand Down
43 changes: 26 additions & 17 deletions Field/Textures/VfxConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,31 +32,41 @@ public class VfxConverter
Description = ""Charm Auto-Generated Source 2 Shader"";
}
MODES
{
VrForward();
Depth( ""vr_depth_only.vfx"" );
ToolsVis( S_MODE_TOOLS_VIS );
ToolsWireframe( ""vr_tools_wireframe.vfx"" );
ToolsShadingComplexity( ""vr_tools_shading_complexity.vfx"" );
Reflection( ""high_quality_reflections.vfx"" );
}
FEATURES
{
#include ""common/features.hlsl""
//Feature( F_ALPHA_TEST, 0..1, ""Rendering"" );
//Feature( F_PREPASS_ALPHA_TEST, 0..1, ""Rendering"" );
}
MODES
{
VrForward();
Depth( ""vr_depth_only.vfx"" );
ToolsVis( S_MODE_TOOLS_VIS );
ToolsWireframe( ""vr_tools_wireframe.vfx"" );
ToolsShadingComplexity( ""vr_tools_shading_complexity.vfx"" );
Feature( F_HIGH_QUALITY_REFLECTIONS, 0..1, ""Rendering"" );
}
COMMON
{
#include ""common/shared.hlsl""
#define USES_HIGH_QUALITY_REFLECTIONS
//#define S_GGX_SHADING 1
//#define S_SPECULAR_CUBE_MAP 1
#define D_NO_MODEL_TINT 1
//translucent
}
struct VertexInput
{
float4 vColorBlendValues : TEXCOORD4 < Semantic( color ); >;
float4 vColorBlendValues : Color0 < Semantic( Color ); >;
#include ""common/vertexinput.hlsl""
};
Expand All @@ -69,6 +79,9 @@ struct PixelInput
VS
{
#include ""common/vertex.hlsl""
BoolAttribute( UsesHighQualityReflections, ( F_HIGH_QUALITY_REFLECTIONS > 0 ) );
PixelInput MainVs( INSTANCED_SHADER_PARAMS( VS_INPUT i ) )
{
PixelInput o = ProcessVertex( i );
Expand Down Expand Up @@ -380,12 +393,12 @@ private void WriteFunctionDefinition(Material material, bool bIsVertexShader)
vfx.AppendLine(" float alpha = 1;");
vfx.AppendLine(" float4 tx = float4(i.vTextureCoords, 1, 1);");

vfx.AppendLine(" float4 v0 = {1,1,1,1};"); //Seems to only be used for normals.
vfx.AppendLine(" float4 v0 = {1,1,1,1};"); //Seems to only be used for normals. No idea what it is.
vfx.AppendLine(" float4 v1 = {i.vNormalWs, 1};"); //Pretty sure this is mesh normals
vfx.AppendLine(" float4 v2 = {i.vTangentUWs, 1};"); //Tangent? Seems to only be used for normals.
vfx.AppendLine(" float4 v3 = {i.vTextureCoords, 1,1};"); //seems only used as texture coords
vfx.AppendLine(" float4 v4 = i.vBlendValues;"); //Not sure if this is VC or not
vfx.AppendLine(" float4 v5 = i.vBlendValues;"); //seems like this is always the same as v4/only used if shader uses VC alpha
vfx.AppendLine(" float4 v3 = {i.vTextureCoords, 1,1};"); //99.9% sure this is always UVs
vfx.AppendLine(" float4 v4 = i.vBlendValues;"); //Mostly seen on materials with parallax. Some kind of view vector or matrix?
vfx.AppendLine(" float4 v5 = i.vBlendValues;"); //seems to always be vertex color/vertex color alpha
//vfx.AppendLine(" uint v6 = 1;"); //no idea

foreach (var i in inputs)
Expand All @@ -395,10 +408,6 @@ private void WriteFunctionDefinition(Material material, bool bIsVertexShader)
vfx.AppendLine($" {i.Variable}.x = {i.Variable}.x * tx.x;");
}
}
// vfx.Replace("v0.xyzw = v0.xyzw * tx.xyzw;", "v0.xyzw = v0.xyzw;");
// vfx.Replace("v1.xyzw = v1.xyzw * tx.xyzw;", "v1.xyzw = v1.xyzw;");
// vfx.Replace("v2.xyzw = v2.xyzw * tx.xyzw;", "v2.xyzw = v2.xyzw;");
// vfx.Replace("v5.xyzw = v5.xyzw * tx.xyzw;", "v5.xyzw = v5.xyzw;");
}
}

Expand Down
12 changes: 12 additions & 0 deletions Field/template.vmdl
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,18 @@
[
{
_class = "RenderMeshFile"
children =
[
{
_class = "RenderMeshMarkup"
material_search_path = ""
use_expensive_tangents = true
high_high_precision_texcoords = false
calc_per_vertex_curvature = false
prefer_high_density_tris_in_uv_density_calc = false
cpu_access = false
},
]
name = "%MESHNAME%"
filename = "%FILENAME%"
import_translation = [ 0.0, 0.0, 0.0 ]
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,13 +53,13 @@ Not yet implemented:
- Generates .vfx shader files for semi-accurate game shaders (similar to UE5 shaders)
- Generates .vmat (material) and .vmdl (model) files for statics and maps

(CS:GO Source 2 support is planned once that is released and if it supports custom content similar to S&Box)
~~(CS:GO Source 2 support is planned once that is released and if it supports custom content similar to S&Box)~~ (Unlikely)

Copy files from shaders/source2 to your addons "Shaders" folder, and the .vmat, textures, and .vmdl files to "materials", "materials/textures", and "models" respectively.

**To compile shaders:**
Drag and drop all the .vfx files into your addons shaders folder while you have S&Box open, this should automatically trigger the compile process. (Not Recommended though).
The better option is to locate all your .vfx files and drag/drop them onto vfxcompile.exe in your "Steam\steamapps\common\sbox\bin\win64" folder, this should compile the shaders without having the game open, saving system resources. **THIS WILL TAKE A LONG TIME TO DO, DUE TO COMPILE SPEEDS**
Drag and drop all the .shader files into your addons shaders folder while you have S&Box open, this should automatically trigger the compile process. (Not Recommended though).
The better option is to locate all your .shader files and drag/drop them onto vfxcompile.exe in your "Steam\steamapps\common\sbox\bin\win64" folder, this should compile the shaders without having the game open, saving system resources. **THIS WILL TAKE A LONG TIME TO DO, DUE TO COMPILE SPEEDS**



Expand Down

0 comments on commit 2e81da2

Please sign in to comment.