Add practice range: shooting, AK47, intro cinematic, dressed warehouse scene
- PortalTestDestination practice range: Valorant-style hitscan rifle (recoil, spray/bloom, reload, controller support), debug HUD, practice-dummy targets with head/body hitboxes, hit/death/respawn animations, procedural SFX/FX - AK47 model (Quaternius, CC0) held via Animator IK, with fire/reload/equip anims - Intro cinematic (camera shots, title card, target beam-in, GO hand-off) - Scene dressing editor pass: CC0 textures, props, warehouse roof, lighting and post-processing; custom stylized skybox shader - CharacterMovement: camera recoil, shoulder offset, cinematic control lock - Unity CLI pipeline package; plus in-progress chat/Rive/player changes Asset credits: Assets/Models/Props/PROPS_CREDITS.txt (3 CC-BY 3.0 props), Assets/Textures/Range/TEXTURES_LICENSE.txt, Assets/Resources/*/..._LICENSE.txt Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
c674d76549
commit
5fc9ebf1e6
@@ -0,0 +1,163 @@
|
||||
// Stylized dusk skybox for the practice range (URP).
|
||||
// Gradient sky (zenith -> horizon band -> ground), a sun disc + glow that tracks the scene's
|
||||
// main directional light, procedural fbm clouds projected on a sky plane and drifting over
|
||||
// time (lit warmer on the sun side), and faint twinkling stars toward the zenith.
|
||||
Shader "Skybox/RangeStylizedSky"
|
||||
{
|
||||
Properties
|
||||
{
|
||||
[Header(Gradient)]
|
||||
_ZenithColor ("Zenith", Color) = (0.10, 0.11, 0.32, 1)
|
||||
_SkyColor ("Upper Sky", Color) = (0.27, 0.25, 0.55, 1)
|
||||
_HorizonColor ("Horizon", Color) = (1.00, 0.52, 0.36, 1)
|
||||
_GroundColor ("Below Horizon", Color) = (0.34, 0.26, 0.34, 1)
|
||||
_HorizonSharpness ("Horizon Sharpness", Range(1, 20)) = 6
|
||||
_HorizonGlow ("Horizon Glow", Range(0, 2)) = 0.6
|
||||
|
||||
[Header(Sun)]
|
||||
_SunColor ("Sun Color", Color) = (1.00, 0.80, 0.55, 1)
|
||||
_SunSize ("Sun Size", Range(0.001, 0.1)) = 0.025
|
||||
_SunGlow ("Sun Glow", Range(0, 4)) = 1.2
|
||||
_SunGlowFalloff ("Sun Glow Falloff", Range(1, 64)) = 10
|
||||
|
||||
[Header(Clouds)]
|
||||
_CloudColor ("Cloud Color", Color) = (0.95, 0.72, 0.70, 1)
|
||||
_CloudShadowColor ("Cloud Shadow", Color) = (0.32, 0.26, 0.45, 1)
|
||||
_CloudCoverage ("Coverage", Range(0, 1)) = 0.48
|
||||
_CloudSoftness ("Softness", Range(0.01, 0.5)) = 0.18
|
||||
_CloudScale ("Scale", Range(0.1, 5)) = 1.4
|
||||
_CloudSpeed ("Drift Speed", Range(0, 0.1)) = 0.012
|
||||
|
||||
[Header(Stars)]
|
||||
_StarDensity ("Density", Range(50, 600)) = 280
|
||||
_StarBrightness ("Brightness", Range(0, 3)) = 1.1
|
||||
}
|
||||
|
||||
SubShader
|
||||
{
|
||||
Tags { "Queue" = "Background" "RenderType" = "Background" "PreviewType" = "Skybox" "RenderPipeline" = "UniversalPipeline" }
|
||||
Cull Off
|
||||
ZWrite Off
|
||||
|
||||
Pass
|
||||
{
|
||||
HLSLPROGRAM
|
||||
#pragma vertex vert
|
||||
#pragma fragment frag
|
||||
|
||||
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
|
||||
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
|
||||
|
||||
CBUFFER_START(UnityPerMaterial)
|
||||
half4 _ZenithColor, _SkyColor, _HorizonColor, _GroundColor;
|
||||
half _HorizonSharpness, _HorizonGlow;
|
||||
half4 _SunColor;
|
||||
half _SunSize, _SunGlow, _SunGlowFalloff;
|
||||
half4 _CloudColor, _CloudShadowColor;
|
||||
half _CloudCoverage, _CloudSoftness, _CloudScale, _CloudSpeed;
|
||||
half _StarDensity, _StarBrightness;
|
||||
CBUFFER_END
|
||||
|
||||
struct Attributes { float4 positionOS : POSITION; };
|
||||
struct Varyings { float4 positionCS : SV_POSITION; float3 dir : TEXCOORD0; };
|
||||
|
||||
Varyings vert(Attributes v)
|
||||
{
|
||||
Varyings o;
|
||||
o.positionCS = TransformObjectToHClip(v.positionOS.xyz);
|
||||
o.dir = v.positionOS.xyz; // skybox mesh: object position == view direction
|
||||
return o;
|
||||
}
|
||||
|
||||
float hash21(float2 p)
|
||||
{
|
||||
p = frac(p * float2(123.34, 456.21));
|
||||
p += dot(p, p + 45.32);
|
||||
return frac(p.x * p.y);
|
||||
}
|
||||
|
||||
float valueNoise(float2 p)
|
||||
{
|
||||
float2 i = floor(p);
|
||||
float2 f = frac(p);
|
||||
float2 u = f * f * (3.0 - 2.0 * f);
|
||||
float a = hash21(i);
|
||||
float b = hash21(i + float2(1, 0));
|
||||
float c = hash21(i + float2(0, 1));
|
||||
float d = hash21(i + float2(1, 1));
|
||||
return lerp(lerp(a, b, u.x), lerp(c, d, u.x), u.y);
|
||||
}
|
||||
|
||||
float fbm(float2 p)
|
||||
{
|
||||
float sum = 0.0;
|
||||
float amp = 0.5;
|
||||
for (int i = 0; i < 5; i++)
|
||||
{
|
||||
sum += valueNoise(p) * amp;
|
||||
p = p * 2.03 + float2(17.1, 9.2);
|
||||
amp *= 0.5;
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
half4 frag(Varyings i) : SV_Target
|
||||
{
|
||||
float3 dir = normalize(i.dir);
|
||||
float y = dir.y;
|
||||
float3 sunDir = normalize(_MainLightPosition.xyz);
|
||||
float sunDot = dot(dir, sunDir);
|
||||
|
||||
// --- Gradient: ground -> horizon band -> upper sky -> zenith.
|
||||
float up = saturate(y);
|
||||
float3 sky = lerp(_SkyColor.rgb, _ZenithColor.rgb, smoothstep(0.25, 1.0, up));
|
||||
float horizonBand = pow(1.0 - up, _HorizonSharpness);
|
||||
sky = lerp(sky, _HorizonColor.rgb, horizonBand);
|
||||
// The horizon glows brighter on the sun's side.
|
||||
float sunSide = saturate(dot(normalize(float3(dir.x, 0, dir.z) + 1e-5), normalize(float3(sunDir.x, 0, sunDir.z) + 1e-5)) * 0.5 + 0.5);
|
||||
sky += _HorizonColor.rgb * horizonBand * _HorizonGlow * sunSide * sunSide;
|
||||
// Soft haze below the horizon (reads as distant fog from high camera angles, not a void).
|
||||
float below = smoothstep(0.0, -0.35, y);
|
||||
float3 col = lerp(sky, _GroundColor.rgb, below);
|
||||
|
||||
// --- Stars: sparse cells on a sphere-ish projection, fading in toward the zenith.
|
||||
float2 starUV = dir.xz / (abs(y) + 0.35) * _StarDensity * 0.1;
|
||||
float2 cell = floor(starUV);
|
||||
float starSeed = hash21(cell);
|
||||
float2 starPos = frac(starUV) - (0.25 + 0.5 * float2(hash21(cell + 3.1), hash21(cell + 7.7)));
|
||||
float star = step(0.93, starSeed) * smoothstep(0.08, 0.0, length(starPos));
|
||||
float twinkle = 0.6 + 0.4 * sin(_Time.y * (2.0 + starSeed * 5.0) + starSeed * 40.0);
|
||||
col += star * twinkle * _StarBrightness * smoothstep(0.35, 0.9, y);
|
||||
|
||||
// --- Sun: hard-ish disc plus a wide soft glow.
|
||||
float disc = smoothstep(1.0 - _SunSize, 1.0 - _SunSize * 0.6, sunDot);
|
||||
float glow = pow(saturate(sunDot), _SunGlowFalloff) * _SunGlow;
|
||||
col += _SunColor.rgb * (disc * 6.0 + glow) * (1.0 - below);
|
||||
|
||||
// --- Clouds: fbm on a plane above the camera, thinning out toward the horizon.
|
||||
if (y > 0.0)
|
||||
{
|
||||
float2 cloudUV = dir.xz / (y + 0.12) * _CloudScale;
|
||||
float2 drift = float2(_Time.y * _CloudSpeed, _Time.y * _CloudSpeed * 0.37);
|
||||
float n = fbm(cloudUV + drift);
|
||||
float n2 = fbm(cloudUV * 1.9 - drift * 1.6 + 5.0);
|
||||
float density = n * 0.75 + n2 * 0.25;
|
||||
float threshold = 1.0 - _CloudCoverage;
|
||||
float cloud = smoothstep(threshold - _CloudSoftness, threshold + _CloudSoftness, density);
|
||||
cloud *= smoothstep(0.0, 0.18, y); // fade near horizon
|
||||
|
||||
// Lighter where the cloud is thin and on the sun side; shadowed where thick.
|
||||
float thickness = saturate((density - threshold) * 3.0);
|
||||
float3 cloudCol = lerp(_CloudColor.rgb, _CloudShadowColor.rgb, thickness * 0.7);
|
||||
cloudCol += _SunColor.rgb * pow(saturate(sunDot), 6.0) * 0.8;
|
||||
col = lerp(col, cloudCol, cloud * 0.9);
|
||||
}
|
||||
|
||||
return half4(col, 1.0);
|
||||
}
|
||||
ENDHLSL
|
||||
}
|
||||
}
|
||||
|
||||
Fallback Off
|
||||
}
|
||||
Reference in New Issue
Block a user