Add precompiled CultMath Unity package
This commit is contained in:
parent
69856d4f3a
commit
9a5597d233
19 changed files with 542 additions and 33 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -6,3 +6,4 @@ target/
|
|||
**/target/
|
||||
/native/cultmath-core/target.meta
|
||||
.tools/
|
||||
/artifacts/
|
||||
|
|
|
|||
21
README.md
21
README.md
|
|
@ -73,21 +73,24 @@ dotnet build CultMath.slnx
|
|||
dotnet test CultMath.slnx
|
||||
cargo test --manifest-path native/cultmath-core/Cargo.toml
|
||||
cargo build --release --manifest-path native/cultmath-core/Cargo.toml
|
||||
.\scripts\build-unity-package.ps1
|
||||
```
|
||||
|
||||
## Unity compiler
|
||||
## Unity package
|
||||
|
||||
CultMath uses C# 10 record structs and file-scoped namespaces. Unity projects
|
||||
must select the compiler's latest language mode with an `Assets/csc.rsp` file:
|
||||
CultMath's Unity 2021.3 surface is the tracked precompiled package at
|
||||
`unity/org.gamecult.cultmath`. Unity consumes `CultMath.dll` and the numeric
|
||||
`CultMath.hlsl`; it does not compile the repository's current-language C# source
|
||||
tree and does not require a consumer `csc.rsp` workaround.
|
||||
|
||||
```text
|
||||
-langversion:latest
|
||||
```json
|
||||
"org.gamecult.cultmath": "https://github.com/GameCult/CultMath.git?path=/unity/org.gamecult.cultmath"
|
||||
```
|
||||
|
||||
The package's Unity smoke project verifies this contract against Unity 6. The
|
||||
setting is already present in current GameCult Unity clients; it belongs to the
|
||||
consumer project because Unity only reads compiler response files from its
|
||||
`Assets` root.
|
||||
The repository root is not a Unity package. Build the tracked package with
|
||||
`scripts/build-unity-package.ps1`; the script fresh-builds the netstandard2.1
|
||||
assembly and rejects stale binaries, missing metadata, unexpected assemblies,
|
||||
or leaked C# source.
|
||||
|
||||
## Shader Tooling
|
||||
|
||||
|
|
|
|||
107
scripts/build-unity-package.ps1
Normal file
107
scripts/build-unity-package.ps1
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
param(
|
||||
[string] $Configuration = "Release",
|
||||
[string] $OutputDirectory = "artifacts\unity\org.gamecult.cultmath"
|
||||
)
|
||||
|
||||
$ErrorActionPreference = "Stop"
|
||||
|
||||
$repoRoot = Split-Path -Parent $PSScriptRoot
|
||||
$projectPath = Join-Path $repoRoot "src\CultMath\CultMath.csproj"
|
||||
$templateRoot = Join-Path $repoRoot "unity\org.gamecult.cultmath"
|
||||
$buildRoot = Join-Path $repoRoot "artifacts\cultmath-unity-build"
|
||||
$outputRoot = if ([System.IO.Path]::IsPathRooted($OutputDirectory)) {
|
||||
$OutputDirectory
|
||||
} else {
|
||||
Join-Path $repoRoot $OutputDirectory
|
||||
}
|
||||
$freshAssembly = Join-Path $buildRoot "CultMath.dll"
|
||||
$freshSymbols = Join-Path $buildRoot "CultMath.pdb"
|
||||
$trackedPluginRoot = Join-Path $templateRoot "Runtime\Plugins"
|
||||
$trackedAssembly = Join-Path $trackedPluginRoot "CultMath.dll"
|
||||
$trackedSymbols = Join-Path $trackedPluginRoot "CultMath.pdb"
|
||||
|
||||
if (Test-Path -LiteralPath $buildRoot) {
|
||||
Remove-Item -LiteralPath $buildRoot -Recurse -Force
|
||||
}
|
||||
if (Test-Path -LiteralPath $outputRoot) {
|
||||
Remove-Item -LiteralPath $outputRoot -Recurse -Force
|
||||
}
|
||||
|
||||
dotnet build $projectPath -c $Configuration -f netstandard2.1 -o $buildRoot `
|
||||
--disable-build-servers -p:UseSharedCompilation=false -p:ContinuousIntegrationBuild=true -m:1
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
throw "CultMath Unity assembly build failed with exit code $LASTEXITCODE"
|
||||
}
|
||||
|
||||
foreach ($path in @($freshAssembly, $freshSymbols)) {
|
||||
if (-not (Test-Path -LiteralPath $path -PathType Leaf)) {
|
||||
throw "CultMath Unity build is missing $path"
|
||||
}
|
||||
}
|
||||
|
||||
$requiredTemplateFiles = @(
|
||||
"LICENSE.md",
|
||||
"README.md",
|
||||
"THIRD-PARTY-NOTICES.md",
|
||||
"package.json",
|
||||
"Runtime\CultMath.asmdef",
|
||||
"Runtime\CultMath.asmdef.meta",
|
||||
"Runtime\Plugins\CultMath.dll",
|
||||
"Runtime\Plugins\CultMath.dll.meta",
|
||||
"Runtime\Plugins\CultMath.pdb",
|
||||
"Runtime\Plugins\CultMath.pdb.meta",
|
||||
"Shaders\CultMath.hlsl",
|
||||
"Shaders\CultMath.hlsl.meta"
|
||||
)
|
||||
foreach ($relativePath in $requiredTemplateFiles) {
|
||||
if (-not (Test-Path -LiteralPath (Join-Path $templateRoot $relativePath) -PathType Leaf)) {
|
||||
throw "Tracked CultMath Unity package is incomplete: missing $relativePath"
|
||||
}
|
||||
}
|
||||
|
||||
$unityAssetFiles = @(Get-ChildItem -LiteralPath $templateRoot -Recurse -File | Where-Object {
|
||||
$_.Extension -in @(".asmdef", ".dll", ".pdb", ".hlsl")
|
||||
})
|
||||
$missingAssetMetas = @($unityAssetFiles | Where-Object { -not (Test-Path -LiteralPath ($_.FullName + ".meta")) })
|
||||
$missingDirectoryMetas = @(Get-ChildItem -LiteralPath $templateRoot -Recurse -Directory | Where-Object {
|
||||
-not (Test-Path -LiteralPath ($_.FullName + ".meta"))
|
||||
})
|
||||
if ($missingAssetMetas.Count -ne 0 -or $missingDirectoryMetas.Count -ne 0) {
|
||||
$missing = @($missingAssetMetas.FullName) + @($missingDirectoryMetas.FullName)
|
||||
throw "Tracked CultMath Unity package has assets without stable .meta files: $($missing -join ', ')"
|
||||
}
|
||||
|
||||
$manifest = Get-Content -LiteralPath (Join-Path $templateRoot "package.json") -Raw | ConvertFrom-Json
|
||||
$expectedFileVersion = "$($manifest.version).0"
|
||||
$trackedFileVersion = [Diagnostics.FileVersionInfo]::GetVersionInfo($trackedAssembly).FileVersion
|
||||
$freshFileVersion = [Diagnostics.FileVersionInfo]::GetVersionInfo($freshAssembly).FileVersion
|
||||
if ($trackedFileVersion -ne $expectedFileVersion -or $freshFileVersion -ne $expectedFileVersion) {
|
||||
throw "CultMath Unity assemblies must match package version $expectedFileVersion; tracked=$trackedFileVersion fresh=$freshFileVersion"
|
||||
}
|
||||
|
||||
foreach ($pair in @(@($freshAssembly, $trackedAssembly), @($freshSymbols, $trackedSymbols))) {
|
||||
$freshHash = (Get-FileHash -LiteralPath $pair[0] -Algorithm SHA256).Hash
|
||||
$trackedHash = (Get-FileHash -LiteralPath $pair[1] -Algorithm SHA256).Hash
|
||||
if ($freshHash -ne $trackedHash) {
|
||||
throw "Tracked Unity artifact is stale: $($pair[1]) differs from a fresh deterministic build"
|
||||
}
|
||||
}
|
||||
|
||||
$trackedSourceFiles = @(Get-ChildItem -LiteralPath $templateRoot -Recurse -File -Filter "*.cs")
|
||||
if ($trackedSourceFiles.Count -ne 0) {
|
||||
throw "CultMath Unity package must not compile repository C# sources: $($trackedSourceFiles.FullName -join ', ')"
|
||||
}
|
||||
|
||||
New-Item -ItemType Directory -Force -Path $outputRoot | Out-Null
|
||||
Copy-Item -Path (Join-Path $templateRoot "*") -Destination $outputRoot -Recurse -Force
|
||||
|
||||
$stagedAssemblies = @(Get-ChildItem -LiteralPath (Join-Path $outputRoot "Runtime\Plugins") -Filter "*.dll")
|
||||
$stagedSources = @(Get-ChildItem -LiteralPath $outputRoot -Recurse -File -Filter "*.cs")
|
||||
if ($stagedAssemblies.Count -ne 1 -or $stagedAssemblies[0].Name -ne "CultMath.dll" -or $stagedSources.Count -ne 0) {
|
||||
throw "CultMath package must contain one owned DLL and no C# source files"
|
||||
}
|
||||
|
||||
Write-Host "CultMath Unity package: $outputRoot"
|
||||
Write-Host "Package: $($manifest.name)@$($manifest.version)"
|
||||
Write-Host "Managed assemblies: $($stagedAssemblies.Count)"
|
||||
Write-Host "C# source files: $($stagedSources.Count)"
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
{
|
||||
"name": "CultMath.Unity",
|
||||
"rootNamespace": "CultMath.Unity",
|
||||
"references": [
|
||||
"CultMath"
|
||||
],
|
||||
"includePlatforms": [],
|
||||
"excludePlatforms": [],
|
||||
"allowUnsafeCode": false,
|
||||
"overrideReferences": false,
|
||||
"precompiledReferences": [],
|
||||
"autoReferenced": true,
|
||||
"defineConstraints": [],
|
||||
"versionDefines": [],
|
||||
"noEngineReferences": false
|
||||
}
|
||||
10
unity/org.gamecult.cultmath/LICENSE.md
Normal file
10
unity/org.gamecult.cultmath/LICENSE.md
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
# CultMath License
|
||||
|
||||
CultMath is licensed under the Mozilla Public License 2.0 (`MPL-2.0`).
|
||||
|
||||
The complete license text is available from the Mozilla Foundation at
|
||||
<https://www.mozilla.org/MPL/2.0/>. Source and modification history for the
|
||||
precompiled assembly in this package are available in the GameCult/CultMath
|
||||
repository at the corresponding package tag.
|
||||
|
||||
Third-party code retains its original license. See `THIRD-PARTY-NOTICES.md`.
|
||||
28
unity/org.gamecult.cultmath/README.md
Normal file
28
unity/org.gamecult.cultmath/README.md
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
# CultMath for Unity
|
||||
|
||||
This is CultMath's Unity 2021.3-compatible Git-UPM surface. It contains the
|
||||
precompiled `CultMath.dll`, portable symbols, and the numeric
|
||||
`Shaders/CultMath.hlsl` mirror.
|
||||
|
||||
Unity does not compile CultMath's repository source tree. That source uses the
|
||||
current C# language and remains owned by the normal .NET project. The package
|
||||
facade references only the tracked precompiled assembly, so consumers do not
|
||||
need `csc.rsp` language overrides.
|
||||
|
||||
Build and inspect the package from the repository root:
|
||||
|
||||
```powershell
|
||||
.\scripts\build-unity-package.ps1
|
||||
```
|
||||
|
||||
The builder fresh-builds CultMath for `netstandard2.1`, verifies the tracked
|
||||
DLL/PDB and stable Unity metadata, and stages an inspectable package under
|
||||
`artifacts/unity/org.gamecult.cultmath`.
|
||||
|
||||
Consume the repository package with:
|
||||
|
||||
```json
|
||||
"org.gamecult.cultmath": "https://github.com/GameCult/CultMath.git?path=/unity/org.gamecult.cultmath"
|
||||
```
|
||||
|
||||
Production consumers should pin that URL to a commit or release tag.
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 8226365c03c5e1a438408b7e42b98740
|
||||
guid: a31bf2bb35e54dd1ad1c765337682769
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
16
unity/org.gamecult.cultmath/Runtime/CultMath.asmdef
Normal file
16
unity/org.gamecult.cultmath/Runtime/CultMath.asmdef
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"name": "CultMath",
|
||||
"rootNamespace": "CultMath",
|
||||
"references": [],
|
||||
"includePlatforms": [],
|
||||
"excludePlatforms": [],
|
||||
"allowUnsafeCode": true,
|
||||
"overrideReferences": true,
|
||||
"precompiledReferences": [
|
||||
"CultMath.dll"
|
||||
],
|
||||
"autoReferenced": true,
|
||||
"defineConstraints": [],
|
||||
"versionDefines": [],
|
||||
"noEngineReferences": true
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
fileFormatVersion: 2
|
||||
guid: d1906c397c420ae4eb222a3f09f36843
|
||||
guid: 4b5c49d478124399a5310d7a9d8ed166
|
||||
AssemblyDefinitionImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
8
unity/org.gamecult.cultmath/Runtime/Plugins.meta
Normal file
8
unity/org.gamecult.cultmath/Runtime/Plugins.meta
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: f84156013e814c14b73f668b6610b9e0
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
BIN
unity/org.gamecult.cultmath/Runtime/Plugins/CultMath.dll
Normal file
BIN
unity/org.gamecult.cultmath/Runtime/Plugins/CultMath.dll
Normal file
Binary file not shown.
|
|
@ -0,0 +1,21 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 063b8a850f0f474aa7e89c4167f97a19
|
||||
PluginImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
iconMap: {}
|
||||
executionOrder: {}
|
||||
defineConstraints: []
|
||||
isPreloaded: 0
|
||||
isOverridable: 0
|
||||
isExplicitlyReferenced: 1
|
||||
validateReferences: 1
|
||||
platformData:
|
||||
- first:
|
||||
Any:
|
||||
second:
|
||||
enabled: 1
|
||||
settings: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
BIN
unity/org.gamecult.cultmath/Runtime/Plugins/CultMath.pdb
Normal file
BIN
unity/org.gamecult.cultmath/Runtime/Plugins/CultMath.pdb
Normal file
Binary file not shown.
|
|
@ -1,6 +1,6 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 1abf066549a826c4ba7a30d6676735c0
|
||||
PackageManifestImporter:
|
||||
guid: a8cc555f643a4d7eb4dd340025b208f6
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
8
unity/org.gamecult.cultmath/Shaders.meta
Normal file
8
unity/org.gamecult.cultmath/Shaders.meta
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: ca5d773061ed49b3a173526048d40cb3
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
302
unity/org.gamecult.cultmath/Shaders/CultMath.hlsl
Normal file
302
unity/org.gamecult.cultmath/Shaders/CultMath.hlsl
Normal file
|
|
@ -0,0 +1,302 @@
|
|||
#ifndef CULTMATH_HLSL
|
||||
#define CULTMATH_HLSL
|
||||
|
||||
// CultMath HLSL mirror.
|
||||
//
|
||||
// HLSL already owns the float2/float3/float4 type names and most primitive
|
||||
// intrinsics. This include names the CultMath semantic surface explicitly so
|
||||
// shader code, C# wrappers, and Rust/native parity fixtures can share the same
|
||||
// small vocabulary without local helper drift.
|
||||
|
||||
static const float CULTMATH_PI = 3.14159265358979323846;
|
||||
static const float CULTMATH_TAU = 6.28318530717958647692;
|
||||
static const float CULTMATH_HALF_PI = 1.57079632679489661923;
|
||||
static const float CULTMATH_NORMALIZE_EPSILON = 1.0e-20;
|
||||
|
||||
float cultmath_radians(float degrees_value) { return degrees_value * (CULTMATH_PI / 180.0); }
|
||||
float cultmath_degrees(float radians_value) { return radians_value * (180.0 / CULTMATH_PI); }
|
||||
|
||||
float cultmath_frac(float value) { return value - floor(value); }
|
||||
float2 cultmath_frac(float2 value) { return value - floor(value); }
|
||||
float3 cultmath_frac(float3 value) { return value - floor(value); }
|
||||
float4 cultmath_frac(float4 value) { return value - floor(value); }
|
||||
|
||||
float cultmath_clamp(float value, float minimum, float maximum) { return min(max(value, minimum), maximum); }
|
||||
float2 cultmath_clamp(float2 value, float2 minimum, float2 maximum) { return min(max(value, minimum), maximum); }
|
||||
float3 cultmath_clamp(float3 value, float3 minimum, float3 maximum) { return min(max(value, minimum), maximum); }
|
||||
float4 cultmath_clamp(float4 value, float4 minimum, float4 maximum) { return min(max(value, minimum), maximum); }
|
||||
|
||||
float cultmath_saturate(float value) { return cultmath_clamp(value, 0.0, 1.0); }
|
||||
float2 cultmath_saturate(float2 value) { return cultmath_clamp(value, float2(0.0, 0.0), float2(1.0, 1.0)); }
|
||||
float3 cultmath_saturate(float3 value) { return cultmath_clamp(value, float3(0.0, 0.0, 0.0), float3(1.0, 1.0, 1.0)); }
|
||||
float4 cultmath_saturate(float4 value) { return cultmath_clamp(value, float4(0.0, 0.0, 0.0, 0.0), float4(1.0, 1.0, 1.0, 1.0)); }
|
||||
|
||||
float cultmath_lerp(float start, float end, float amount) { return start + (end - start) * amount; }
|
||||
float2 cultmath_lerp(float2 start, float2 end, float2 amount) { return start + (end - start) * amount; }
|
||||
float3 cultmath_lerp(float3 start, float3 end, float3 amount) { return start + (end - start) * amount; }
|
||||
float4 cultmath_lerp(float4 start, float4 end, float4 amount) { return start + (end - start) * amount; }
|
||||
|
||||
float cultmath_step(float edge, float value) { return value < edge ? 0.0 : 1.0; }
|
||||
float2 cultmath_step(float2 edge, float2 value) { return float2(cultmath_step(edge.x, value.x), cultmath_step(edge.y, value.y)); }
|
||||
float3 cultmath_step(float3 edge, float3 value) { return float3(cultmath_step(edge.x, value.x), cultmath_step(edge.y, value.y), cultmath_step(edge.z, value.z)); }
|
||||
float4 cultmath_step(float4 edge, float4 value) { return float4(cultmath_step(edge.x, value.x), cultmath_step(edge.y, value.y), cultmath_step(edge.z, value.z), cultmath_step(edge.w, value.w)); }
|
||||
|
||||
float cultmath_smoothstep(float minimum, float maximum, float value)
|
||||
{
|
||||
float t = cultmath_saturate((value - minimum) / (maximum - minimum));
|
||||
return t * t * (3.0 - 2.0 * t);
|
||||
}
|
||||
|
||||
float2 cultmath_smoothstep(float2 minimum, float2 maximum, float2 value)
|
||||
{
|
||||
float2 t = cultmath_saturate((value - minimum) / (maximum - minimum));
|
||||
return t * t * (float2(3.0, 3.0) - float2(2.0, 2.0) * t);
|
||||
}
|
||||
|
||||
float3 cultmath_smoothstep(float3 minimum, float3 maximum, float3 value)
|
||||
{
|
||||
float3 t = cultmath_saturate((value - minimum) / (maximum - minimum));
|
||||
return t * t * (float3(3.0, 3.0, 3.0) - float3(2.0, 2.0, 2.0) * t);
|
||||
}
|
||||
|
||||
float4 cultmath_smoothstep(float4 minimum, float4 maximum, float4 value)
|
||||
{
|
||||
float4 t = cultmath_saturate((value - minimum) / (maximum - minimum));
|
||||
return t * t * (float4(3.0, 3.0, 3.0, 3.0) - float4(2.0, 2.0, 2.0, 2.0) * t);
|
||||
}
|
||||
|
||||
float cultmath_smoothstep01(float value) { return cultmath_smoothstep(0.0, 1.0, value); }
|
||||
|
||||
float cultmath_smootherstep(float value)
|
||||
{
|
||||
value = cultmath_saturate(value);
|
||||
return value * value * value * (value * (value * 6.0 - 15.0) + 10.0);
|
||||
}
|
||||
|
||||
float2 cultmath_simplex_mod289(float2 value) { return value - floor(value * (1.0 / 289.0)) * 289.0; }
|
||||
float3 cultmath_simplex_mod289(float3 value) { return value - floor(value * (1.0 / 289.0)) * 289.0; }
|
||||
float3 cultmath_simplex_permute(float3 value) { return cultmath_simplex_mod289(((value * 34.0) + 1.0) * value); }
|
||||
|
||||
float cultmath_simplex_noise(float2 value)
|
||||
{
|
||||
const float4 c = float4(
|
||||
0.211324865405187,
|
||||
0.366025403784439,
|
||||
-0.577350269189626,
|
||||
0.024390243902439);
|
||||
float2 i = floor(value + dot(value, c.yy));
|
||||
float2 x0 = value - i + dot(i, c.xx);
|
||||
float2 i1 = x0.x > x0.y ? float2(1.0, 0.0) : float2(0.0, 1.0);
|
||||
float4 x12 = float4(x0.x + c.x - i1.x, x0.y + c.x - i1.y, x0.x + c.z, x0.y + c.z);
|
||||
|
||||
i = cultmath_simplex_mod289(i);
|
||||
float3 p = cultmath_simplex_permute(
|
||||
cultmath_simplex_permute(i.y + float3(0.0, i1.y, 1.0)) + i.x + float3(0.0, i1.x, 1.0));
|
||||
float3 m = max(0.5 - float3(dot(x0, x0), dot(x12.xy, x12.xy), dot(x12.zw, x12.zw)), 0.0);
|
||||
m *= m;
|
||||
m *= m;
|
||||
|
||||
float3 x = 2.0 * frac(p * c.w) - 1.0;
|
||||
float3 h = abs(x) - 0.5;
|
||||
float3 ox = floor(x + 0.5);
|
||||
float3 a0 = x - ox;
|
||||
m *= 1.79284291400159 - 0.85373472095314 * (a0 * a0 + h * h);
|
||||
|
||||
float3 g = float3(
|
||||
a0.x * x0.x + h.x * x0.y,
|
||||
a0.y * x12.x + h.y * x12.y,
|
||||
a0.z * x12.z + h.z * x12.w);
|
||||
return 130.0 * dot(m, g);
|
||||
}
|
||||
|
||||
float cultmath_lengthsq(float2 value) { return dot(value, value); }
|
||||
float cultmath_lengthsq(float3 value) { return dot(value, value); }
|
||||
float cultmath_lengthsq(float4 value) { return dot(value, value); }
|
||||
|
||||
float cultmath_distance(float2 left, float2 right) { return length(left - right); }
|
||||
float cultmath_distance(float3 left, float3 right) { return length(left - right); }
|
||||
float cultmath_distance(float4 left, float4 right) { return length(left - right); }
|
||||
|
||||
float2 cultmath_normalize(float2 value) { return value / max(length(value), CULTMATH_NORMALIZE_EPSILON); }
|
||||
float3 cultmath_normalize(float3 value) { return value / max(length(value), CULTMATH_NORMALIZE_EPSILON); }
|
||||
float4 cultmath_normalize(float4 value) { return value / max(length(value), CULTMATH_NORMALIZE_EPSILON); }
|
||||
|
||||
float2 cultmath_reflect(float2 incident, float2 normal_value)
|
||||
{
|
||||
return incident - 2.0 * dot(normal_value, incident) * normal_value;
|
||||
}
|
||||
|
||||
float3 cultmath_reflect(float3 incident, float3 normal_value)
|
||||
{
|
||||
return incident - 2.0 * dot(normal_value, incident) * normal_value;
|
||||
}
|
||||
|
||||
float2 cultmath_rotate(float2 value, float radians_value)
|
||||
{
|
||||
float s = sin(radians_value);
|
||||
float c = cos(radians_value);
|
||||
return float2(value.x * c - value.y * s, value.x * s + value.y * c);
|
||||
}
|
||||
|
||||
float2 cultmath_rotate_degrees(float2 value, float degrees_value)
|
||||
{
|
||||
return cultmath_rotate(value, cultmath_radians(degrees_value));
|
||||
}
|
||||
|
||||
float cultmath_csum(float2 value) { return value.x + value.y; }
|
||||
float cultmath_csum(float3 value) { return value.x + value.y + value.z; }
|
||||
float cultmath_csum(float4 value) { return value.x + value.y + value.z + value.w; }
|
||||
|
||||
float cultmath_decay(float source, float lambda_value, float dt) { return source * exp(-lambda_value * dt); }
|
||||
float2 cultmath_decay(float2 source, float lambda_value, float dt) { return source * exp(-lambda_value * dt); }
|
||||
float3 cultmath_decay(float3 source, float lambda_value, float dt) { return source * exp(-lambda_value * dt); }
|
||||
float4 cultmath_decay(float4 source, float lambda_value, float dt) { return source * exp(-lambda_value * dt); }
|
||||
|
||||
float cultmath_damp(float start, float end, float lambda_value, float dt)
|
||||
{
|
||||
return cultmath_lerp(start, end, 1.0 - exp(-lambda_value * dt));
|
||||
}
|
||||
|
||||
float2 cultmath_damp(float2 start, float2 end, float lambda_value, float dt)
|
||||
{
|
||||
return cultmath_lerp(start, end, 1.0 - exp(-lambda_value * dt));
|
||||
}
|
||||
|
||||
float3 cultmath_damp(float3 start, float3 end, float lambda_value, float dt)
|
||||
{
|
||||
return cultmath_lerp(start, end, 1.0 - exp(-lambda_value * dt));
|
||||
}
|
||||
|
||||
float4 cultmath_damp(float4 start, float4 end, float lambda_value, float dt)
|
||||
{
|
||||
return cultmath_lerp(start, end, 1.0 - exp(-lambda_value * dt));
|
||||
}
|
||||
|
||||
float cultmath_catmullrom(float p0, float p1, float p2, float p3, float t)
|
||||
{
|
||||
float t2 = t * t;
|
||||
float t3 = t2 * t;
|
||||
return 0.5 * ((2.0 * p1) + (p2 - p0) * t + (2.0 * p0 - 5.0 * p1 + 4.0 * p2 - p3) * t2 + (-p0 + 3.0 * p1 - 3.0 * p2 + p3) * t3);
|
||||
}
|
||||
|
||||
float2 cultmath_catmullrom(float2 p0, float2 p1, float2 p2, float2 p3, float t)
|
||||
{
|
||||
float t2 = t * t;
|
||||
float t3 = t2 * t;
|
||||
return 0.5 * ((2.0 * p1) + (p2 - p0) * t + (2.0 * p0 - 5.0 * p1 + 4.0 * p2 - p3) * t2 + (-p0 + 3.0 * p1 - 3.0 * p2 + p3) * t3);
|
||||
}
|
||||
|
||||
float3 cultmath_catmullrom(float3 p0, float3 p1, float3 p2, float3 p3, float t)
|
||||
{
|
||||
float t2 = t * t;
|
||||
float t3 = t2 * t;
|
||||
return 0.5 * ((2.0 * p1) + (p2 - p0) * t + (2.0 * p0 - 5.0 * p1 + 4.0 * p2 - p3) * t2 + (-p0 + 3.0 * p1 - 3.0 * p2 + p3) * t3);
|
||||
}
|
||||
|
||||
float4 cultmath_catmullrom(float4 p0, float4 p1, float4 p2, float4 p3, float t)
|
||||
{
|
||||
float t2 = t * t;
|
||||
float t3 = t2 * t;
|
||||
return 0.5 * ((2.0 * p1) + (p2 - p0) * t + (2.0 * p0 - 5.0 * p1 + 4.0 * p2 - p3) * t2 + (-p0 + 3.0 * p1 - 3.0 * p2 + p3) * t3);
|
||||
}
|
||||
|
||||
float cultmath_quadratic_bezier(float p0, float p1, float p2, float t)
|
||||
{
|
||||
t = cultmath_saturate(t);
|
||||
float inv = 1.0 - t;
|
||||
return inv * inv * p0 + 2.0 * inv * t * p1 + t * t * p2;
|
||||
}
|
||||
|
||||
float3 cultmath_quadratic_bezier(float3 p0, float3 p1, float3 p2, float t)
|
||||
{
|
||||
t = cultmath_saturate(t);
|
||||
float inv = 1.0 - t;
|
||||
return inv * inv * p0 + 2.0 * inv * t * p1 + t * t * p2;
|
||||
}
|
||||
|
||||
float cultmath_cubic_bezier(float p0, float p1, float p2, float p3, float t)
|
||||
{
|
||||
t = cultmath_saturate(t);
|
||||
float inv = 1.0 - t;
|
||||
return inv * inv * inv * p0 + 3.0 * inv * inv * t * p1 + 3.0 * inv * t * t * p2 + t * t * t * p3;
|
||||
}
|
||||
|
||||
float3 cultmath_cubic_bezier(float3 p0, float3 p1, float3 p2, float3 p3, float t)
|
||||
{
|
||||
t = cultmath_saturate(t);
|
||||
float inv = 1.0 - t;
|
||||
return inv * inv * inv * p0 + 3.0 * inv * inv * t * p1 + 3.0 * inv * t * t * p2 + t * t * t * p3;
|
||||
}
|
||||
|
||||
float cultmath_hash(float value) { return cultmath_frac(sin(value) * 43758.5453); }
|
||||
float cultmath_hash(float2 value) { return cultmath_hash(dot(value, float2(127.1, 311.7))); }
|
||||
float cultmath_hash(float3 value) { return cultmath_hash(dot(value, float3(127.1, 311.7, 74.7))); }
|
||||
|
||||
float cultmath_value_noise(float2 position)
|
||||
{
|
||||
float2 cell = floor(position);
|
||||
float2 local = cultmath_frac(position);
|
||||
float2 u = local * local * (float2(3.0, 3.0) - float2(2.0, 2.0) * local);
|
||||
|
||||
float a = cultmath_hash(cell);
|
||||
float b = cultmath_hash(cell + float2(1.0, 0.0));
|
||||
float c = cultmath_hash(cell + float2(0.0, 1.0));
|
||||
float d = cultmath_hash(cell + float2(1.0, 1.0));
|
||||
|
||||
return cultmath_lerp(cultmath_lerp(a, b, u.x), cultmath_lerp(c, d, u.x), u.y);
|
||||
}
|
||||
|
||||
float cultmath_value_noise_bicubic(float2 position)
|
||||
{
|
||||
float2 cell = floor(position);
|
||||
float2 local = cultmath_frac(position);
|
||||
|
||||
float y0 = cultmath_catmullrom(cultmath_hash(cell + float2(-1.0, -1.0)), cultmath_hash(cell + float2(0.0, -1.0)), cultmath_hash(cell + float2(1.0, -1.0)), cultmath_hash(cell + float2(2.0, -1.0)), local.x);
|
||||
float y1 = cultmath_catmullrom(cultmath_hash(cell + float2(-1.0, 0.0)), cultmath_hash(cell + float2(0.0, 0.0)), cultmath_hash(cell + float2(1.0, 0.0)), cultmath_hash(cell + float2(2.0, 0.0)), local.x);
|
||||
float y2 = cultmath_catmullrom(cultmath_hash(cell + float2(-1.0, 1.0)), cultmath_hash(cell + float2(0.0, 1.0)), cultmath_hash(cell + float2(1.0, 1.0)), cultmath_hash(cell + float2(2.0, 1.0)), local.x);
|
||||
float y3 = cultmath_catmullrom(cultmath_hash(cell + float2(-1.0, 2.0)), cultmath_hash(cell + float2(0.0, 2.0)), cultmath_hash(cell + float2(1.0, 2.0)), cultmath_hash(cell + float2(2.0, 2.0)), local.x);
|
||||
|
||||
return cultmath_catmullrom(y0, y1, y2, y3, local.y);
|
||||
}
|
||||
|
||||
float cultmath_value_noise_texture(Texture2D<float> noise_texture, SamplerState noise_sampler, float2 uv, float scale)
|
||||
{
|
||||
return noise_texture.SampleLevel(noise_sampler, uv * scale, 0.0).r;
|
||||
}
|
||||
|
||||
float cultmath_value_noise_texture_bicubic(Texture2D<float> noise_texture, SamplerState noise_sampler, float2 uv, float scale, float2 texel_size)
|
||||
{
|
||||
float2 position = uv * scale;
|
||||
float2 cell = floor(position);
|
||||
float2 local = cultmath_frac(position);
|
||||
float2 base_uv = cell / scale;
|
||||
|
||||
float row0 = cultmath_catmullrom(
|
||||
noise_texture.SampleLevel(noise_sampler, base_uv + texel_size * float2(-1.0, -1.0), 0.0).r,
|
||||
noise_texture.SampleLevel(noise_sampler, base_uv + texel_size * float2(0.0, -1.0), 0.0).r,
|
||||
noise_texture.SampleLevel(noise_sampler, base_uv + texel_size * float2(1.0, -1.0), 0.0).r,
|
||||
noise_texture.SampleLevel(noise_sampler, base_uv + texel_size * float2(2.0, -1.0), 0.0).r,
|
||||
local.x);
|
||||
float row1 = cultmath_catmullrom(
|
||||
noise_texture.SampleLevel(noise_sampler, base_uv + texel_size * float2(-1.0, 0.0), 0.0).r,
|
||||
noise_texture.SampleLevel(noise_sampler, base_uv + texel_size * float2(0.0, 0.0), 0.0).r,
|
||||
noise_texture.SampleLevel(noise_sampler, base_uv + texel_size * float2(1.0, 0.0), 0.0).r,
|
||||
noise_texture.SampleLevel(noise_sampler, base_uv + texel_size * float2(2.0, 0.0), 0.0).r,
|
||||
local.x);
|
||||
float row2 = cultmath_catmullrom(
|
||||
noise_texture.SampleLevel(noise_sampler, base_uv + texel_size * float2(-1.0, 1.0), 0.0).r,
|
||||
noise_texture.SampleLevel(noise_sampler, base_uv + texel_size * float2(0.0, 1.0), 0.0).r,
|
||||
noise_texture.SampleLevel(noise_sampler, base_uv + texel_size * float2(1.0, 1.0), 0.0).r,
|
||||
noise_texture.SampleLevel(noise_sampler, base_uv + texel_size * float2(2.0, 1.0), 0.0).r,
|
||||
local.x);
|
||||
float row3 = cultmath_catmullrom(
|
||||
noise_texture.SampleLevel(noise_sampler, base_uv + texel_size * float2(-1.0, 2.0), 0.0).r,
|
||||
noise_texture.SampleLevel(noise_sampler, base_uv + texel_size * float2(0.0, 2.0), 0.0).r,
|
||||
noise_texture.SampleLevel(noise_sampler, base_uv + texel_size * float2(1.0, 2.0), 0.0).r,
|
||||
noise_texture.SampleLevel(noise_sampler, base_uv + texel_size * float2(2.0, 2.0), 0.0).r,
|
||||
local.x);
|
||||
|
||||
return cultmath_catmullrom(row0, row1, row2, row3, local.y);
|
||||
}
|
||||
|
||||
#endif
|
||||
7
unity/org.gamecult.cultmath/Shaders/CultMath.hlsl.meta
Normal file
7
unity/org.gamecult.cultmath/Shaders/CultMath.hlsl.meta
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
fileFormatVersion: 2
|
||||
guid: a46136cb4acb4ff2bc47b6a4f786e4b3
|
||||
ShaderIncludeImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
11
unity/org.gamecult.cultmath/THIRD-PARTY-NOTICES.md
Normal file
11
unity/org.gamecult.cultmath/THIRD-PARTY-NOTICES.md
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
# Third-Party Notices
|
||||
|
||||
## 2D Simplex Noise
|
||||
|
||||
`math.simplex_noise` and `cultmath_simplex_noise` port the textureless 2D
|
||||
simplex-noise function by Ian McEwan and Ashima Arts, as distributed by Stefan
|
||||
Gustavson's `webgl-noise` project and Unity Mathematics.
|
||||
|
||||
- Copyright 2011 Ashima Arts.
|
||||
- Upstream: <https://github.com/ashima/webgl-noise>
|
||||
- License: MIT.
|
||||
|
|
@ -3,12 +3,15 @@
|
|||
"displayName": "CultMath",
|
||||
"version": "0.1.0",
|
||||
"unity": "2021.3",
|
||||
"description": "Clean-room C# math primitives shaped for HLSL-style renderer and simulation code.",
|
||||
"description": "Precompiled CultMath numeric primitives and matching HLSL semantics for GameCult Unity runtimes.",
|
||||
"license": "MPL-2.0",
|
||||
"author": {
|
||||
"name": "GameCult"
|
||||
},
|
||||
"keywords": [
|
||||
"GameCult",
|
||||
"Math",
|
||||
"HLSL",
|
||||
"Simulation"
|
||||
],
|
||||
"license": "MPL-2.0",
|
||||
"category": "Scripting"
|
||||
]
|
||||
}
|
||||
Loading…
Reference in a new issue