Introduce TankDefinition/TankCatalog loaded from Tanks.json, bundle the Drachengas USDZ tank models, add tank selection and preview views, and update the AR experience, editor and project views to use the catalog. Includes tests for catalog loading and model selection. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
61 lines
2.0 KiB
Metal
61 lines
2.0 KiB
Metal
//
|
||
// TankShaders.metal
|
||
// GasTankAR
|
||
//
|
||
// Created by Dennis Nemec on 26.08.26.
|
||
//
|
||
|
||
#include <metal_stdlib>
|
||
#include <RealityKit/RealityKit.h>
|
||
|
||
using namespace metal;
|
||
|
||
// Sampler für die durchgereichten Texturen des Originalmaterials.
|
||
constexpr sampler textureSampler(address::clamp_to_edge, filter::bicubic);
|
||
|
||
/// Surface-Shader für den unterirdischen Tank: reicht Basisfarbe/Roughness/Metallic
|
||
/// des Originalmaterials durch und verblasst die Opacity anhand der Welt-Höhe.
|
||
///
|
||
/// custom_parameter():
|
||
/// x = Boden-Höhe (Welt-Y)
|
||
/// y = Fade-Band (Meter, über die die Transparenz einsetzt)
|
||
/// z = minimale Opacity des vergrabenen Teils
|
||
[[visible]]
|
||
void tankDepthFadeSurface(realitykit::surface_parameters params)
|
||
{
|
||
auto tex = params.textures();
|
||
auto constants = params.material_constants();
|
||
|
||
float2 uv = params.geometry().uv0();
|
||
uv.y = 1.0 - uv.y;
|
||
|
||
// Originale USDZ-Farbe und Textur beibehalten.
|
||
half3 tint = (half3)constants.base_color_tint();
|
||
half3 color = (half3)tex.base_color().sample(textureSampler, uv).rgb;
|
||
params.surface().set_base_color(color * tint);
|
||
|
||
half roughness = tex.roughness().sample(textureSampler, uv).r * constants.roughness_scale();
|
||
params.surface().set_roughness(roughness);
|
||
|
||
half metallic = tex.metallic().sample(textureSampler, uv).r * constants.metallic_scale();
|
||
params.surface().set_metallic(metallic);
|
||
|
||
// Höhenbasierter Alpha-Fade.
|
||
float3 worldPosition = params.geometry().world_position();
|
||
float4 custom = params.uniforms().custom_parameter();
|
||
float groundY = custom.x;
|
||
float band = max(custom.y, 1e-3);
|
||
float belowAlpha = custom.z;
|
||
|
||
// Bei maximaler Transparenz wird alles unterhalb der Bodenhöhe
|
||
// vollständig ausgeblendet – nicht nur abgeschwächt.
|
||
if (belowAlpha <= 0.001 && worldPosition.y < groundY) {
|
||
params.surface().set_opacity(half(0.0));
|
||
return;
|
||
}
|
||
|
||
float t = clamp((groundY - worldPosition.y) / band, 0.0, 1.0);
|
||
float alpha = mix(1.0, belowAlpha, t);
|
||
params.surface().set_opacity(half(alpha));
|
||
}
|