Migrate planetary geometry consumers
This commit is contained in:
parent
492d123edb
commit
42778c183a
39 changed files with 117 additions and 52 deletions
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Aquarium.Engine.Contracts\Aquarium.Engine.Contracts.csproj" />
|
||||
<ProjectReference Include="..\..\..\CultLib\src\GameCult.Geometry\GameCult.Geometry.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ using System.Globalization;
|
|||
using System.Numerics;
|
||||
using Aquarium.Engine.Fractal;
|
||||
using CultMath;
|
||||
using GameCult.Geometry;
|
||||
|
||||
namespace Aquarium.Engine.Fractal.Grammar;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
using CultMath;
|
||||
using GameCult.Geometry;
|
||||
|
||||
namespace Aquarium.Engine.Fractal.Grammar;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
using System.Numerics;
|
||||
using CultMath;
|
||||
using GameCult.Geometry;
|
||||
using Aquarium.Engine.Fractal.Grammar;
|
||||
|
||||
namespace Aquarium.Engine.Fractal.Lod;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
using System.Numerics;
|
||||
using CultMath;
|
||||
using GameCult.Geometry;
|
||||
|
||||
namespace Aquarium.Engine.Fractal.Projection;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
using System.Numerics;
|
||||
using CultMath;
|
||||
using GameCult.Geometry;
|
||||
|
||||
namespace Aquarium.Engine.Fractal.Projection;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
using CultMath;
|
||||
using GameCult.Geometry;
|
||||
|
||||
namespace Aquarium.Engine.Fractal.Projection;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
using System.Numerics;
|
||||
using CultMath;
|
||||
using GameCult.Geometry;
|
||||
|
||||
namespace Aquarium.Engine.Fractal.Projection;
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ using System.Globalization;
|
|||
using System.Text;
|
||||
|
||||
using CultMath;
|
||||
using GameCult.Geometry;
|
||||
|
||||
namespace Aquarium.Engine.Fractal.Projection;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
using System.Numerics;
|
||||
using CultMath;
|
||||
using GameCult.Geometry;
|
||||
|
||||
namespace Aquarium.Engine.Fractal.Projection;
|
||||
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@
|
|||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\CultMath\src\CultMath\CultMath.csproj" />
|
||||
<ProjectReference Include="..\..\..\CultLib\src\GameCult.Geometry\GameCult.Geometry.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ using SharpGen.Runtime;
|
|||
using Aquarium.Engine.Render.Ui;
|
||||
using Aquarium.Engine.Ui;
|
||||
using CultMath;
|
||||
using GameCult.Geometry;
|
||||
using Vortice;
|
||||
using Vortice.D3DCompiler;
|
||||
using Vortice.Direct3D;
|
||||
|
|
|
|||
|
|
@ -65,6 +65,41 @@ internal static class D3D12ShaderCompiler
|
|||
}
|
||||
}
|
||||
}
|
||||
const string cultMathUnityPrefix = "Packages/org.gamecult.cultmath/shaders/";
|
||||
if (normalized.StartsWith(cultMathUnityPrefix, StringComparison.Ordinal))
|
||||
{
|
||||
var relative = normalized[cultMathUnityPrefix.Length..].Replace('/', Path.DirectorySeparatorChar);
|
||||
foreach (var start in new[] { directory, AppContext.BaseDirectory })
|
||||
{
|
||||
var current = Path.GetFullPath(start);
|
||||
while (!string.IsNullOrEmpty(current))
|
||||
{
|
||||
var localPackage = Path.Combine(current, "CultMath", relative);
|
||||
if (File.Exists(localPackage)) return localPackage;
|
||||
var siblingRepository = Path.Combine(current, "CultMath", "shaders", relative);
|
||||
if (File.Exists(siblingRepository)) return siblingRepository;
|
||||
var parent = Path.GetDirectoryName(current);
|
||||
if (string.IsNullOrEmpty(parent) || parent == current) break;
|
||||
current = parent;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (normalized.StartsWith("GameCult.Geometry/", StringComparison.Ordinal))
|
||||
{
|
||||
var relative = normalized["GameCult.Geometry/".Length..].Replace('/', Path.DirectorySeparatorChar);
|
||||
foreach (var start in new[] { directory, AppContext.BaseDirectory })
|
||||
{
|
||||
var current = Path.GetFullPath(start);
|
||||
while (!string.IsNullOrEmpty(current))
|
||||
{
|
||||
var candidate = Path.Combine(current, "CultLib", "src", "GameCult.Geometry", "Shaders", relative);
|
||||
if (File.Exists(candidate)) return candidate;
|
||||
var parent = Path.GetDirectoryName(current);
|
||||
if (string.IsNullOrEmpty(parent) || parent == current) break;
|
||||
current = parent;
|
||||
}
|
||||
}
|
||||
}
|
||||
return local;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#include "CultMath/CultMath.hlsl"
|
||||
#include "GameCult.Geometry/GameCult.Geometry.hlsl"
|
||||
|
||||
struct ParityInput { float4 position_base; float4 slope_fade; float4 scalar0; float4 rounding; float4 onset; float4 scalar1; float4 scalar2; float4 scalar3; };
|
||||
struct ParityOutput { float4 delta_magnitude; float4 ridge_fade; };
|
||||
|
|
@ -11,13 +11,13 @@ void D3D12AdvancedErosionParityCS(uint3 id : SV_DispatchThreadID)
|
|||
{
|
||||
if (id.x >= input_count) return;
|
||||
ParityInput input = inputs[id.x];
|
||||
CultMathAdvancedErosionParameters p;
|
||||
GameCultGeometryAdvancedErosionParameters p;
|
||||
p.scale=input.scalar0.x; p.strength=input.scalar0.y; p.gully_weight=input.scalar0.z; p.detail=input.scalar0.w;
|
||||
p.rounding=input.rounding; p.onset=input.onset; p.assumed_slope=input.scalar1.xy;
|
||||
p.cell_scale=input.scalar1.z; p.normalization=input.scalar1.w; p.octaves=(int)input.scalar2.x;
|
||||
p.lacunarity=input.scalar2.y; p.gain=input.scalar2.z;
|
||||
CultMathErosionBandSelection band; band.active_octaves=(int)input.scalar3.x; band.final_octave_weight=input.scalar3.y; band.finest_included_wavelength=input.scalar3.z; band.unresolved_height_bound=input.scalar3.w;
|
||||
CultMathAdvancedErosionResult r = cultmath_advanced_erosion_filter_banded(input.position_base.xy, float3(input.position_base.z, input.slope_fade.xy), input.slope_fade.z, p, band);
|
||||
GameCultGeometryErosionBandSelection band; band.active_octaves=(int)input.scalar3.x; band.final_octave_weight=input.scalar3.y; band.finest_included_wavelength=input.scalar3.z; band.unresolved_height_bound=input.scalar3.w;
|
||||
GameCultGeometryAdvancedErosionResult r = gamecult_geometry_advanced_erosion_filter_banded(input.position_base.xy, float3(input.position_base.z, input.slope_fade.xy), input.slope_fade.z, p, band);
|
||||
outputs[id.x].delta_magnitude=float4(r.delta, r.magnitude);
|
||||
outputs[id.x].ridge_fade=float4(r.ridge_map, r.fade_target, 0, 0);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#include "CultMath/CultMath.hlsl"
|
||||
#include "GameCult.Geometry/GameCult.Geometry.hlsl"
|
||||
|
||||
struct PageOutput { float4 height_gradient; float4 masks; };
|
||||
struct PageSummary { float4 bounds; float4 metadata; };
|
||||
|
|
@ -10,11 +10,11 @@ cbuffer PageConstants : register(b0) { uint page_sample_count; uint page_sample_
|
|||
void D3D12ZyphosTerrainPageSummaryCS(uint3 id : SV_DispatchThreadID)
|
||||
{
|
||||
if (id.x != 0 || page_sample_count == 0) return;
|
||||
float4 summary = cultmath_planetary_summary_empty();
|
||||
float4 summary = gamecult_geometry_planetary_summary_empty();
|
||||
[loop] for (uint index = 0; index < page_sample_count; index++)
|
||||
{
|
||||
PageOutput sample = summary_inputs[page_sample_offset + index];
|
||||
summary = cultmath_planetary_summary_accumulate(summary, sample.height_gradient, sample.masks.w);
|
||||
summary = gamecult_geometry_planetary_summary_accumulate(summary, sample.height_gradient, sample.masks.w);
|
||||
}
|
||||
summary_outputs[page_summary_index].bounds = summary;
|
||||
summary_outputs[page_summary_index].metadata = float4(page_sample_count, page_sample_offset, page_summary_index, 1.0);
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#include "CultMath/CultMath.hlsl"
|
||||
#include "GameCult.Geometry/GameCult.Geometry.hlsl"
|
||||
|
||||
struct PlanetaryTopologyInput
|
||||
{
|
||||
|
|
@ -26,47 +26,47 @@ void D3D12PlanetaryTopologyParityCS(uint3 id : SV_DispatchThreadID)
|
|||
if (input.coordinate_mode.z < 0.5)
|
||||
{
|
||||
int face = (int)input.direction_face.w;
|
||||
output.direction_face = float4(cultmath_planetary_face_direction(face, input.coordinate_mode.xy), (float)face);
|
||||
output.direction_face = float4(gamecult_geometry_planetary_face_direction(face, input.coordinate_mode.xy), (float)face);
|
||||
output.coordinate_valid = float4(input.coordinate_mode.xy, 0.0, 1.0);
|
||||
}
|
||||
else if (input.coordinate_mode.z < 1.5)
|
||||
{
|
||||
int face;
|
||||
float2 coordinate = cultmath_planetary_face_coordinate(input.direction_face.xyz, face);
|
||||
float2 coordinate = gamecult_geometry_planetary_face_coordinate(input.direction_face.xyz, face);
|
||||
output.direction_face = float4(normalize(input.direction_face.xyz), (float)face);
|
||||
output.coordinate_valid = float4(coordinate, 0.0, 1.0);
|
||||
}
|
||||
else if (input.coordinate_mode.z < 2.5)
|
||||
{
|
||||
output.direction_face = float4(normalize(input.direction_face.xyz), 0.0);
|
||||
output.coordinate_valid = float4(cultmath_planetary_equirectangular_forward(input.direction_face.xyz), 0.0, 1.0);
|
||||
output.coordinate_valid = float4(gamecult_geometry_planetary_equirectangular_forward(input.direction_face.xyz), 0.0, 1.0);
|
||||
}
|
||||
else if (input.coordinate_mode.z < 3.5)
|
||||
{
|
||||
output.direction_face = float4(cultmath_planetary_equirectangular_inverse(input.coordinate_mode.xy), 0.0);
|
||||
output.direction_face = float4(gamecult_geometry_planetary_equirectangular_inverse(input.coordinate_mode.xy), 0.0);
|
||||
output.coordinate_valid = float4(input.coordinate_mode.xy, 0.0, 1.0);
|
||||
}
|
||||
else if (input.coordinate_mode.z < 4.5)
|
||||
{
|
||||
output.direction_face = float4(normalize(input.direction_face.xyz), 0.0);
|
||||
output.coordinate_valid = float4(cultmath_planetary_equal_earth_forward(input.direction_face.xyz), 0.0, 1.0);
|
||||
output.coordinate_valid = float4(gamecult_geometry_planetary_equal_earth_forward(input.direction_face.xyz), 0.0, 1.0);
|
||||
}
|
||||
else if (input.coordinate_mode.z < 5.5)
|
||||
{
|
||||
output.direction_face = float4(cultmath_planetary_equal_earth_inverse(input.coordinate_mode.xy), 0.0);
|
||||
output.direction_face = float4(gamecult_geometry_planetary_equal_earth_inverse(input.coordinate_mode.xy), 0.0);
|
||||
output.coordinate_valid = float4(input.coordinate_mode.xy, 0.0, 1.0);
|
||||
}
|
||||
else if (input.coordinate_mode.z < 6.5)
|
||||
{
|
||||
float2 coordinate;
|
||||
bool valid=cultmath_planetary_projection_forward(input.direction_face.xyz,(int)input.coordinate_mode.w,input.projection_parameters.xyz,coordinate);
|
||||
bool valid=gamecult_geometry_planetary_projection_forward(input.direction_face.xyz,(int)input.coordinate_mode.w,input.projection_parameters.xyz,coordinate);
|
||||
output.direction_face=float4(normalize(input.direction_face.xyz),0);
|
||||
output.coordinate_valid=float4(coordinate,0,valid?1.0:0.0);
|
||||
}
|
||||
else
|
||||
{
|
||||
float3 direction;
|
||||
bool valid=cultmath_planetary_projection_inverse(input.coordinate_mode.xy,(int)input.coordinate_mode.w,input.projection_parameters.xyz,direction);
|
||||
bool valid=gamecult_geometry_planetary_projection_inverse(input.coordinate_mode.xy,(int)input.coordinate_mode.w,input.projection_parameters.xyz,direction);
|
||||
output.direction_face=float4(direction,0);
|
||||
output.coordinate_valid=float4(input.coordinate_mode.xy,0,valid?1.0:0.0);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@
|
|||
<ItemGroup>
|
||||
<ProjectReference Include="..\Aquarium.Engine.Contracts\Aquarium.Engine.Contracts.csproj" />
|
||||
<ProjectReference Include="..\Aquarium.Engine.Fractal\Aquarium.Engine.Fractal.csproj" />
|
||||
<ProjectReference Include="..\..\..\CultLib\src\GameCult.Geometry\GameCult.Geometry.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ static const int ZYPHOS_GEOMETRY_BRUSH_LIMIT = 4;
|
|||
|
||||
#include "D3D12SdfCommon.hlsli"
|
||||
#include "D3D12SdfMath.hlsli"
|
||||
#include "CultMath/CultMath.hlsl"
|
||||
#include "GameCult.Geometry/GameCult.Geometry.hlsl"
|
||||
#include "D3D12ZyphosTerrain.hlsli"
|
||||
|
||||
float3 zyRotateZ(float3 p, float angle)
|
||||
|
|
@ -58,7 +58,7 @@ float zyCompactBrush(float2 delta, float2 radii, float rotation, float falloff,
|
|||
float2 zyCubeFaceUv(float3 dir, out float face)
|
||||
{
|
||||
// Authored brush packets retain their legacy cube-ratio chart. Planetary
|
||||
// page addressing and patch geometry use CultMath's QSC topology.
|
||||
// Page addressing and patch geometry use GameCult.Geometry's QSC topology.
|
||||
float3 a = abs(dir);
|
||||
if (a.x >= a.y && a.x >= a.z)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef D3D12_ZYPHOS_TERRAIN_HLSLI
|
||||
#define D3D12_ZYPHOS_TERRAIN_HLSLI
|
||||
|
||||
#include "CultMath/CultMath.hlsl"
|
||||
#include "GameCult.Geometry/GameCult.Geometry.hlsl"
|
||||
|
||||
struct ZyPlanetPageOutput { float4 height_gradient; float4 masks; };
|
||||
struct ZyPlanetPageMetadata { float4 address; float4 layout; float4 bounds; float4 state; };
|
||||
|
|
@ -16,7 +16,7 @@ static const float ZY_TERRAIN_NON_EROSION_SLOPE_BOUND = 8.0;
|
|||
|
||||
bool zyTerrainPageLocal(float3 dir, ZyPlanetPageMetadata metadata, out float2 local)
|
||||
{
|
||||
return cultmath_planetary_page_local(dir,metadata.address,metadata.state.x,local);
|
||||
return gamecult_geometry_planetary_page_local(dir,metadata.address,metadata.state.x,local);
|
||||
}
|
||||
|
||||
void zySampleErosionPage(int pageIndex, float2 local, out float4 heightGradient, out float2 masks)
|
||||
|
|
@ -28,12 +28,12 @@ void zySampleErosionPage(int pageIndex, float2 local, out float4 heightGradient,
|
|||
int offset=(int)metadata.layout.x;
|
||||
ZyPlanetPageOutput a=zy_planet_page[offset+p0.y*(int)storage+p0.x], b=zy_planet_page[offset+p0.y*(int)storage+p1.x];
|
||||
ZyPlanetPageOutput c=zy_planet_page[offset+p1.y*(int)storage+p0.x], d=zy_planet_page[offset+p1.y*(int)storage+p1.x];
|
||||
CultMathPlanetaryPageSample ca,cb,cc,cd;
|
||||
GameCultGeometryPlanetaryPageSample ca,cb,cc,cd;
|
||||
ca.height_gradient=a.height_gradient; ca.masks=a.masks.xy;
|
||||
cb.height_gradient=b.height_gradient; cb.masks=b.masks.xy;
|
||||
cc.height_gradient=c.height_gradient; cc.masks=c.masks.xy;
|
||||
cd.height_gradient=d.height_gradient; cd.masks=d.masks.xy;
|
||||
CultMathPlanetaryPageSample sample=cultmath_planetary_page_lerp(ca,cb,cc,cd,fraction);
|
||||
GameCultGeometryPlanetaryPageSample sample=gamecult_geometry_planetary_page_lerp(ca,cb,cc,cd,fraction);
|
||||
heightGradient=sample.height_gradient; masks=sample.masks;
|
||||
}
|
||||
|
||||
|
|
@ -128,28 +128,28 @@ float3 zySphericalFieldGradient(float3 dir)
|
|||
float3 gradient = float3(dx,dy,dz)/(2.0*epsilon); return gradient-dir*dot(gradient,dir);
|
||||
}
|
||||
|
||||
CultMathAdvancedErosionParameters zyErosionParameters(float radius)
|
||||
GameCultGeometryAdvancedErosionParameters zyErosionParameters(float radius)
|
||||
{
|
||||
CultMathAdvancedErosionParameters p;
|
||||
GameCultGeometryAdvancedErosionParameters p;
|
||||
p.scale=radius*0.075; p.strength=0.12; p.gully_weight=0.58; p.detail=1.45;
|
||||
p.rounding=float4(0.1,0.015,0.1,2.0); p.onset=float4(1.25,1.25,2.8,1.5); p.assumed_slope=float2(0.7,0.85);
|
||||
p.cell_scale=0.7; p.normalization=0.5; p.octaves=7; p.lacunarity=2.0; p.gain=0.5; return p;
|
||||
}
|
||||
|
||||
CultMathPlanetarySurfaceSample zyAdvancedErosionSurface(float3 dir, float field, float radius, float sampleSpacing)
|
||||
GameCultGeometryPlanetarySurfaceSample zyAdvancedErosionSurface(float3 dir, float field, float radius, float sampleSpacing)
|
||||
{
|
||||
CultMathPlanetaryFieldDefinition definition;
|
||||
GameCultGeometryPlanetaryFieldDefinition definition;
|
||||
definition.radius=radius; definition.seed=0; definition.erosion=zyErosionParameters(radius);
|
||||
CultMathPlanetaryBaseFieldSample base_sample;
|
||||
GameCultGeometryPlanetaryBaseFieldSample base_sample;
|
||||
base_sample.radial_displacement=0.0; base_sample.radial_gradient=0.0;
|
||||
base_sample.field_value=field; base_sample.field_gradient=zySphericalFieldGradient(dir)/radius;
|
||||
base_sample.fade_target=saturate(field*0.5+0.5)*2.0-1.0;
|
||||
return cultmath_planetary_field_sample(definition,dir,base_sample,sampleSpacing);
|
||||
return gamecult_geometry_planetary_field_sample(definition,dir,base_sample,sampleSpacing);
|
||||
}
|
||||
|
||||
float4 zyAdvancedErosion(float3 dir, float field, float radius, float sampleSpacing)
|
||||
{
|
||||
CultMathPlanetarySurfaceSample sample=zyAdvancedErosionSurface(dir,field,radius,sampleSpacing);
|
||||
GameCultGeometryPlanetarySurfaceSample sample=zyAdvancedErosionSurface(dir,field,radius,sampleSpacing);
|
||||
return float4(sample.radial_displacement,sample.ridge,sample.gully,sample.unresolved_height_bound);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -6,15 +6,15 @@ StructuredBuffer<PageInput> page_inputs : register(t0);
|
|||
RWStructuredBuffer<PageOutput> page_outputs : register(u0);
|
||||
cbuffer PageConstants : register(b0) { uint page_sample_count; }
|
||||
|
||||
CultMathPlanetaryPageSample zyPageErosion(float3 direction, float radius, float spacing, float parent_spacing)
|
||||
GameCultGeometryPlanetaryPageSample zyPageErosion(float3 direction, float radius, float spacing, float parent_spacing)
|
||||
{
|
||||
float3 dir=normalize(direction);
|
||||
float field=zySphericalField(dir);
|
||||
CultMathPlanetarySurfaceSample child=zyAdvancedErosionSurface(dir,field,radius,spacing);
|
||||
CultMathPlanetarySurfaceSample parent=(CultMathPlanetarySurfaceSample)0;
|
||||
GameCultGeometryPlanetarySurfaceSample child=zyAdvancedErosionSurface(dir,field,radius,spacing);
|
||||
GameCultGeometryPlanetarySurfaceSample parent=(GameCultGeometryPlanetarySurfaceSample)0;
|
||||
bool has_parent=parent_spacing>0.0;
|
||||
if(has_parent)parent=zyAdvancedErosionSurface(dir,field,radius,parent_spacing);
|
||||
return cultmath_planetary_residual_sample(child,parent,has_parent);
|
||||
return gamecult_geometry_planetary_residual_sample(child,parent,has_parent);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -23,8 +23,8 @@ void D3D12ZyphosTerrainPageCS(uint3 id : SV_DispatchThreadID)
|
|||
{
|
||||
if(id.x>=page_sample_count) return;
|
||||
PageInput input=page_inputs[id.x]; float3 dir=normalize(input.direction_radius.xyz); float radius=input.direction_radius.w; float spacing=input.sampling.x; float parent_spacing=input.sampling.y;
|
||||
CultMathPlanetaryPageSample sample=zyPageErosion(dir,radius,spacing,parent_spacing);
|
||||
CultMathPlanetarySurfaceSample child=zyAdvancedErosionSurface(dir,zySphericalField(dir),radius,spacing);
|
||||
GameCultGeometryPlanetaryPageSample sample=zyPageErosion(dir,radius,spacing,parent_spacing);
|
||||
GameCultGeometryPlanetarySurfaceSample child=zyAdvancedErosionSurface(dir,zySphericalField(dir),radius,spacing);
|
||||
page_outputs[id.x].height_gradient=sample.height_gradient;
|
||||
page_outputs[id.x].masks=float4(sample.masks,0,child.unresolved_height_bound);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#include "CultMath/CultMath.hlsl"
|
||||
#include "GameCult.Geometry/GameCult.Geometry.hlsl"
|
||||
|
||||
struct PageOutput { float4 height_gradient; float4 masks; };
|
||||
struct PageSummary { float4 bounds; float4 metadata; };
|
||||
|
|
@ -10,11 +10,11 @@ cbuffer PageConstants : register(b0) { uint page_sample_count; uint page_sample_
|
|||
void D3D12ZyphosTerrainPageSummaryCS(uint3 id : SV_DispatchThreadID)
|
||||
{
|
||||
if(id.x!=0 || page_sample_count==0) return;
|
||||
float4 summary=cultmath_planetary_summary_empty();
|
||||
float4 summary=gamecult_geometry_planetary_summary_empty();
|
||||
[loop] for(uint index=0;index<page_sample_count;index++)
|
||||
{
|
||||
PageOutput sample=summary_inputs[page_sample_offset+index];
|
||||
summary=cultmath_planetary_summary_accumulate(summary,sample.height_gradient,sample.masks.w);
|
||||
summary=gamecult_geometry_planetary_summary_accumulate(summary,sample.height_gradient,sample.masks.w);
|
||||
}
|
||||
summary_outputs[page_summary_index].bounds=summary;
|
||||
summary_outputs[page_summary_index].metadata=float4(page_sample_count,page_sample_offset,page_summary_index,1);
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ struct ZyPatchSceneOut
|
|||
|
||||
float3 zyPatchDirection(uint face,float2 local)
|
||||
{
|
||||
return cultmath_planetary_face_direction((int)face,local*2.0-1.0);
|
||||
return gamecult_geometry_planetary_face_direction((int)face,local*2.0-1.0);
|
||||
}
|
||||
|
||||
ZyPatchVertexOut D3D12ZyphosTerrainPatchVS(uint vertexId:SV_VertexID,uint instanceId:SV_InstanceID)
|
||||
|
|
@ -43,7 +43,7 @@ ZyPatchSceneOut D3D12ZyphosTerrainPatchPS(ZyPatchVertexOut input)
|
|||
{
|
||||
float3 local=p-planet.centerRadius.xyz; float3 dir=zyPlanetDir(local,planet);
|
||||
float targetRadius=planet.state.x+zyTerrainOffset(dir,planet);
|
||||
p=cultmath_planetary_radial_refinement_step(p,ray,planet.centerRadius.xyz,targetRadius,0.2,0.08);
|
||||
p=gamecult_geometry_planetary_radial_refinement_step(p,ray,planet.centerRadius.xyz,targetRadius,0.2,0.08);
|
||||
}
|
||||
if(!all(isfinite(p)))p=coarsePosition;
|
||||
float travel=length(p-cameraPosition); if(!isfinite(travel)||travel<=0.0||travel>farDistance)discard;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
using System.Numerics;
|
||||
using Aquarium.Engine.Render;
|
||||
using CultMath;
|
||||
using GameCult.Geometry;
|
||||
|
||||
namespace Aquarium.Zyphos;
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
<ItemGroup>
|
||||
<ProjectReference Include="..\Aquarium.Engine.Contracts\Aquarium.Engine.Contracts.csproj" />
|
||||
<ProjectReference Include="..\Aquarium.Engine.Fractal\Aquarium.Engine.Fractal.csproj" />
|
||||
<ProjectReference Include="..\..\..\CultLib\src\GameCult.Geometry\GameCult.Geometry.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
using CultMath;
|
||||
using GameCult.Geometry;
|
||||
using System.Numerics;
|
||||
|
||||
namespace Saga;
|
||||
|
|
|
|||
|
|
@ -71,12 +71,12 @@ invariants:
|
|||
terrain should be a quadtree of brush-painted surface tiles, subdivided by
|
||||
projected footprint, curvature, brush/material detail, silhouettes, and
|
||||
temporal uncertainty before SDF probes emit detail-adaptive surface splats.
|
||||
- Deterministic planetary geometry is owned by CultMath's scale-aware
|
||||
- Deterministic planetary geometry is owned by GameCult.Geometry's scale-aware
|
||||
planetary field runtime. It owns field identity, point/batch and
|
||||
double-position CPU queries, tangent/QSC cube-sphere topology, bordered
|
||||
pages and child residual composition, projected-error LOD, residual
|
||||
lifecycle, ray/path/region queries, coarse patch topology, and map
|
||||
projections/tiles. CultMath maintains matching HLSL for field evaluation,
|
||||
projections/tiles. GameCult.Geometry maintains matching HLSL for field evaluation,
|
||||
topology, page interpolation/residuals, and radial refinement. Clients own
|
||||
base fields, terrain parameters, gameplay meaning, and presentation policy.
|
||||
- The production lowering for stateless planetary erosion is specified in
|
||||
|
|
@ -86,7 +86,7 @@ invariants:
|
|||
- CPU/GPU terrain parity is measured through a standalone D3D12 compute and
|
||||
readback probe. Shader include expansion is owned by D3D12ShaderCompiler
|
||||
and shared with the renderer; parity probes must not boot a swapchain or
|
||||
duplicate CultMath equations.
|
||||
duplicate GameCult.Geometry equations.
|
||||
- Planetary erosion frequencies are selected in world-distance wavelengths
|
||||
from the current sample footprint. The last resolvable octave fades
|
||||
fractionally and reports its omitted-height bound; Zyphos lowers the planar
|
||||
|
|
@ -97,10 +97,10 @@ invariants:
|
|||
it may not change terrain at a shared boundary. Page borders evaluate the
|
||||
spherical field beyond tile bounds without reading neighbor residency.
|
||||
- D3D12 owns persistent planetary page input, output, metadata, and summary
|
||||
buffers, their bindings, dispatch, and draw submission. CultMath owns the
|
||||
buffers, their bindings, dispatch, and draw submission. GameCult.Geometry owns the
|
||||
page layout, spherical sample directions, canonical GPU input/metadata
|
||||
payload, residual semantics, interpolation, and summaries. Client adapters
|
||||
only convert CultMath vectors to their host ABI. Client compute entry points bind the client base field to
|
||||
only convert CultMath primitives to their host ABI. Client compute entry points bind the client base field to
|
||||
those functions before GPU reduction. Zyphos registers planet, Umbros, and
|
||||
star proxies in object index order and publishes all three SDF objects from
|
||||
one scene builder.
|
||||
|
|
@ -109,7 +109,7 @@ invariants:
|
|||
field; covered pixels perform four bounded radial corrections against the
|
||||
complete resident page field, then use the shared differential/material
|
||||
contract. Missing pages lower to the nearest resident ancestor (the base
|
||||
field at root). Direct CultMath evaluation and the bracketed planet SDF are
|
||||
field at root). Direct GameCult.Geometry evaluation and the bracketed planet SDF are
|
||||
verification oracles only; neither owns production visibility.
|
||||
- D3D12 binds the page atlas, metadata, summaries, and page set to both patch
|
||||
shader stages at t81-t84. Patch projection follows the renderer's established
|
||||
|
|
@ -139,13 +139,13 @@ invariants:
|
|||
filtered erosion against the summed page field at the selected spacing;
|
||||
mode 28 exposes content fingerprint, spacing ratio, and deepest level.
|
||||
The unresolved bound and measured direct error remain distinct signals.
|
||||
- The bounded radial correction step is owned by CultMath in matching C# and
|
||||
- The bounded radial correction step is owned by GameCult.Geometry in matching C# and
|
||||
HLSL bodies. Zyphos composes four steps with its terrain-offset callback;
|
||||
the renderer does not carry a private correction equation.
|
||||
- Planetary page residency is owned by CultMath and separates content from
|
||||
- Planetary page residency is owned by GameCult.Geometry and separates content from
|
||||
presentation state. ContentVersion changes only when the resident tile set
|
||||
changes; PresentationVersion carries arrival/departure weights without
|
||||
regenerating erosion. Six root pages remain resident. CultMath's
|
||||
regenerating erosion. Six root pages remain resident. GameCult.Geometry's
|
||||
projected-error selector uses unresolved-height bounds against camera
|
||||
footprint to request one ancestor chain, and its residual lifecycle keeps
|
||||
departing chains addressable until their weights reach zero.
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@
|
|||
<ProjectReference Include="..\..\src\Aquarium.Engine.Contracts\Aquarium.Engine.Contracts.csproj" />
|
||||
<ProjectReference Include="..\..\src\Aquarium.Fensalir\Aquarium.Fensalir.csproj" />
|
||||
<ProjectReference Include="..\..\src\Aquarium.Zyphos\Aquarium.Zyphos.csproj" />
|
||||
<ProjectReference Include="..\..\..\CultLib\src\GameCult.Geometry\GameCult.Geometry.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
using CultMath;
|
||||
using GameCult.Geometry;
|
||||
|
||||
namespace Aquarium.Engine.Fractal.Tests;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
using Aquarium.Engine.Fractal;
|
||||
using CultMath;
|
||||
using GameCult.Geometry;
|
||||
|
||||
namespace Aquarium.Engine.Fractal.Tests;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
using Aquarium.Engine.Fractal.Grammar;
|
||||
using Aquarium.Engine.Fractal.Lod;
|
||||
using CultMath;
|
||||
using GameCult.Geometry;
|
||||
|
||||
namespace Aquarium.Engine.Fractal.Tests;
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ using System.Numerics;
|
|||
using Aquarium.Engine.Fractal;
|
||||
using Aquarium.Engine.Fractal.Grammar;
|
||||
using CultMath;
|
||||
using GameCult.Geometry;
|
||||
|
||||
namespace Aquarium.Engine.Fractal.Tests;
|
||||
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ using Aquarium.Engine.Fractal.Brushes;
|
|||
using Aquarium.Engine.Fractal.Grammar;
|
||||
using Aquarium.Engine.Fractal.Lod;
|
||||
using CultMath;
|
||||
using GameCult.Geometry;
|
||||
|
||||
namespace Aquarium.Engine.Fractal.Tests;
|
||||
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ using Aquarium.Engine.Fractal.Brushes;
|
|||
using Aquarium.Engine.Fractal.Grammar;
|
||||
using Aquarium.Engine.Fractal.Lod;
|
||||
using CultMath;
|
||||
using GameCult.Geometry;
|
||||
|
||||
namespace Aquarium.Engine.Fractal.Tests;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
using CultMath;
|
||||
using GameCult.Geometry;
|
||||
|
||||
namespace Aquarium.Engine.Fractal.Tests;
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ using System.Numerics;
|
|||
using Aquarium.Engine.Fractal;
|
||||
using Aquarium.Engine.Fractal.Projection;
|
||||
using CultMath;
|
||||
using GameCult.Geometry;
|
||||
|
||||
namespace Aquarium.Engine.Fractal.Tests;
|
||||
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@
|
|||
<ProjectReference Include="..\..\src\Aquarium.Engine\Aquarium.Engine.csproj" />
|
||||
<ProjectReference Include="..\..\src\Aquarium.Engine.Fractal\Aquarium.Engine.Fractal.csproj" />
|
||||
<ProjectReference Include="..\..\src\Aquarium.Zyphos\Aquarium.Zyphos.csproj" />
|
||||
<ProjectReference Include="..\..\..\CultLib\src\GameCult.Geometry\GameCult.Geometry.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
|||
|
|
@ -2,13 +2,14 @@ using System.Numerics;
|
|||
using System.Runtime.InteropServices;
|
||||
using Aquarium.Engine.Render;
|
||||
using CultMath;
|
||||
using GameCult.Geometry;
|
||||
|
||||
namespace Aquarium.Engine.Tests;
|
||||
|
||||
public sealed class D3D12AdvancedErosionParityTests
|
||||
{
|
||||
[Fact]
|
||||
public void AdvancedErosionMatchesCultMathCpuAcrossDeterministicCorpus()
|
||||
public void AdvancedErosionMatchesGameCultGeometryCpuAcrossDeterministicCorpus()
|
||||
{
|
||||
if (!OperatingSystem.IsWindows()) return;
|
||||
var parameters = AdvancedErosionParameters.Default;
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ using System.Runtime.InteropServices;
|
|||
using Aquarium.Engine.Render;
|
||||
using Aquarium.Zyphos;
|
||||
using CultMath;
|
||||
using GameCult.Geometry;
|
||||
|
||||
namespace Aquarium.Engine.Tests;
|
||||
|
||||
|
|
@ -214,6 +215,7 @@ public sealed class D3D12PlanetarySurfacePageTests
|
|||
CopyShaderTree(Path.Combine(RepositoryRoot(), "src", "Aquarium.Engine", "Render", "Shaders"), temporaryRoot);
|
||||
CopyShaderTree(Path.Combine(RepositoryRoot(), "src", "Aquarium.Zyphos", "Shaders"), temporaryRoot);
|
||||
CopyShaderTree(Path.GetFullPath(Path.Combine(RepositoryRoot(), "..", "CultMath", "shaders")), Path.Combine(temporaryRoot, "CultMath"));
|
||||
CopyShaderTree(Path.GetFullPath(Path.Combine(RepositoryRoot(), "..", "CultLib", "src", "GameCult.Geometry", "Shaders")), Path.Combine(temporaryRoot, "GameCult.Geometry"));
|
||||
foreach (var shaderName in new[] { "D3D12ZyphosPlanet.hlsl", "D3D12ZyphosUmbros.hlsl", "D3D12ZyphosStar.hlsl" })
|
||||
{
|
||||
var bytecode = D3D12ShaderCompiler.Compile(Path.Combine(temporaryRoot, shaderName), "D3D12SdfProxyPS", "ps_5_0");
|
||||
|
|
|
|||
|
|
@ -1,13 +1,14 @@
|
|||
using System.Numerics;
|
||||
using Aquarium.Engine.Render;
|
||||
using CultMath;
|
||||
using GameCult.Geometry;
|
||||
|
||||
namespace Aquarium.Engine.Tests;
|
||||
|
||||
public sealed class D3D12PlanetaryTopologyParityTests
|
||||
{
|
||||
[Fact]
|
||||
public void QscFaceDirectionsAndInverseCoordinatesMatchCultMathCpu()
|
||||
public void QscFaceDirectionsAndInverseCoordinatesMatchGameCultGeometryCpu()
|
||||
{
|
||||
var cases = new List<TopologyInput>();
|
||||
foreach (var face in Enum.GetValues<PlanetaryCubeFace>())
|
||||
|
|
@ -41,7 +42,7 @@ public sealed class D3D12PlanetaryTopologyParityTests
|
|||
[Theory]
|
||||
[InlineData(PlanetaryProjectionKind.Equirectangular, 2, 3)]
|
||||
[InlineData(PlanetaryProjectionKind.EqualEarth, 4, 5)]
|
||||
public void MapProjectionForwardAndInverseMatchCultMathCpu(PlanetaryProjectionKind kind, int forwardMode, int inverseMode)
|
||||
public void MapProjectionForwardAndInverseMatchGameCultGeometryCpu(PlanetaryProjectionKind kind, int forwardMode, int inverseMode)
|
||||
{
|
||||
var projection = new PlanetaryProjectionParameters(kind);
|
||||
var inputs = new List<TopologyInput>();
|
||||
|
|
|
|||
Loading…
Reference in a new issue