random float
Some checks failed
CI / React UI Build (push) Successful in 11s
CI / Native Windows Build And Tests (push) Successful in 1m45s
CI / Windows Release Package (push) Has been cancelled

This commit is contained in:
2026-05-08 13:35:15 +10:00
parent c9fed70a60
commit 5eff189bbf
8 changed files with 27 additions and 8 deletions

View File

@@ -245,4 +245,3 @@ If `SLANG_ROOT` is not set, the workflow falls back to the repo-local default un
- allow shaders to read other shaders data store based on name? or putput over OSC
- Mipmappong needed?
- unwrap a fish eyelens and mirror it and map it to equirectangulr for environmnet map purposes
- add a random flaot between 0-1 that changes each time the application loads for shaders to use

View File

@@ -76,7 +76,7 @@ Important rules:
- Keep parameter IDs, texture IDs, font IDs, and function entry points as valid shader identifiers: letters, numbers, and underscores only, starting with a letter or underscore.
- Add only controls that are actually used by the shader.
- Prefer a small number of clear controls with conservative defaults.
- Keep shaders deterministic unless randomness is an explicit feature. For stable pseudo-randomness, hash from `uv`, pixel coordinates, `frameCount`, or trigger values rather than using unavailable global state.
- Keep shaders deterministic unless randomness is an explicit feature. For stable process-level variation, use `context.startupRandom`; for per-pixel pseudo-randomness, hash from `uv`, pixel coordinates, `frameCount`, or trigger values.
- If adapting third-party code, include attribution and source URL in the manifest description when the license allows adaptation.
- If the source license is unclear or incompatible, do not add the shader package.
@@ -149,6 +149,7 @@ struct ShaderContext
float time;
float utcTimeSeconds;
float utcOffsetSeconds;
float startupRandom;
float frameCount;
float mixAmount;
float bypass;
@@ -166,6 +167,7 @@ Fields:
- `time`: elapsed runtime time in seconds.
- `utcTimeSeconds`: current UTC time of day from the host PC clock, expressed as seconds since UTC midnight.
- `utcOffsetSeconds`: host PC local UTC offset in seconds. Add this to `utcTimeSeconds` and wrap to `0..86400` to get local time of day.
- `startupRandom`: random `0..1` value generated once when the host process starts. It stays constant for the lifetime of the app and changes on the next launch.
- `frameCount`: incrementing frame counter.
- `mixAmount`: runtime mix amount.
- `bypass`: `1.0` when the layer is bypassed, otherwise `0.0`.

View File

@@ -20,6 +20,7 @@ bool GlobalParamsBuffer::Update(const RuntimeRenderState& state, unsigned availa
AppendStd140Vec2(buffer, static_cast<float>(state.outputWidth), static_cast<float>(state.outputHeight));
AppendStd140Float(buffer, static_cast<float>(state.utcTimeSeconds));
AppendStd140Float(buffer, static_cast<float>(state.utcOffsetSeconds));
AppendStd140Float(buffer, static_cast<float>(state.startupRandom));
AppendStd140Float(buffer, static_cast<float>(state.frameCount));
AppendStd140Float(buffer, static_cast<float>(state.mixAmount));
AppendStd140Float(buffer, static_cast<float>(state.bypass));

View File

@@ -9,6 +9,7 @@
#include <algorithm>
#include <cmath>
#include <fstream>
#include <random>
#include <set>
#include <sstream>
@@ -55,6 +56,13 @@ bool MatchesControlKey(const std::string& candidate, const std::string& key)
return candidate == key || SimplifyControlKey(candidate) == SimplifyControlKey(key);
}
double GenerateStartupRandom()
{
std::random_device randomDevice;
std::uniform_real_distribution<double> distribution(0.0, 1.0);
return distribution(randomDevice);
}
bool TryParseLayerIdNumber(const std::string& layerId, uint64_t& number)
{
const std::string prefix = "layer-";
@@ -691,6 +699,7 @@ RuntimeHost::RuntimeHost()
mCompletionIntervalMilliseconds(0.0),
mSmoothedCompletionIntervalMilliseconds(0.0),
mMaxCompletionIntervalMilliseconds(0.0),
mStartupRandom(GenerateStartupRandom()),
mLateFrameCount(0),
mDroppedFrameCount(0),
mFlushedFrameCount(0),
@@ -1351,6 +1360,7 @@ void RuntimeHost::RefreshDynamicRenderStateFields(std::vector<RuntimeRenderState
state.timeSeconds = timeSeconds;
state.utcTimeSeconds = clock.utcTimeSeconds;
state.utcOffsetSeconds = clock.utcOffsetSeconds;
state.startupRandom = mStartupRandom;
state.frameCount = frameCount;
}
}

View File

@@ -167,6 +167,7 @@ private:
double mCompletionIntervalMilliseconds;
double mSmoothedCompletionIntervalMilliseconds;
double mMaxCompletionIntervalMilliseconds;
double mStartupRandom;
uint64_t mLateFrameCount;
uint64_t mDroppedFrameCount;
uint64_t mFlushedFrameCount;

View File

@@ -115,6 +115,7 @@ struct RuntimeRenderState
double timeSeconds = 0.0;
double utcTimeSeconds = 0.0;
double utcOffsetSeconds = 0.0;
double startupRandom = 0.0;
double frameCount = 0.0;
double mixAmount = 1.0;
double bypass = 0.0;

View File

@@ -13,6 +13,7 @@ struct ShaderContext
float time;
float utcTimeSeconds;
float utcOffsetSeconds;
float startupRandom;
float frameCount;
float mixAmount;
float bypass;
@@ -27,6 +28,7 @@ cbuffer GlobalParams
float2 gOutputResolution;
float gUtcTimeSeconds;
float gUtcOffsetSeconds;
float gStartupRandom;
float gFrameCount;
float gMixAmount;
float gBypass;
@@ -86,6 +88,7 @@ float4 fragmentMain(FragmentInput input) : SV_Target
context.time = gTime;
context.utcTimeSeconds = gUtcTimeSeconds;
context.utcOffsetSeconds = gUtcOffsetSeconds;
context.startupRandom = gStartupRandom;
context.frameCount = gFrameCount;
context.mixAmount = gMixAmount;
context.bypass = gBypass;

View File

@@ -64,6 +64,7 @@ void TestGlobalParamStylePacking()
AppendStd140Vec2(buffer, 1280.0f, 720.0f); // output resolution
AppendStd140Float(buffer, 45296.0f); // UTC time of day
AppendStd140Float(buffer, 36000.0f); // UTC offset
AppendStd140Float(buffer, 0.75f); // startup random
AppendStd140Float(buffer, 42.0f); // frame count
AppendStd140Float(buffer, 0.5f); // mix
AppendStd140Float(buffer, 1.0f); // bypass
@@ -76,17 +77,18 @@ void TestGlobalParamStylePacking()
AppendStd140Int(buffer, 2); // enum parameter
buffer.resize(AlignStd140(buffer.size(), 16), 0);
Expect(buffer.size() == 96, "global parameter style block is padded to a 16-byte boundary");
Expect(buffer.size() == 112, "global parameter style block is padded to a 16-byte boundary");
Expect(ReadFloat(buffer, 0) == 10.0f, "time is at the start of the block");
Expect(ReadFloat(buffer, 8) == 1920.0f, "first vec2 aligns after scalar padding");
Expect(ReadFloat(buffer, 16) == 1280.0f, "second vec2 follows first vec2");
Expect(ReadFloat(buffer, 24) == 45296.0f, "UTC time follows output resolution");
Expect(ReadFloat(buffer, 28) == 36000.0f, "UTC offset follows UTC time");
Expect(ReadInt(buffer, 44) == 3, "history length scalar remains tightly packed");
Expect(ReadFloat(buffer, 56) == 4.0f, "vec2 shader parameter aligns to 8 bytes");
Expect(ReadFloat(buffer, 64) == 0.1f, "color parameter aligns to 16 bytes");
Expect(ReadInt(buffer, 80) == 1, "boolean parameter follows vec4");
Expect(ReadInt(buffer, 84) == 2, "enum parameter follows boolean");
Expect(ReadFloat(buffer, 32) == 0.75f, "startup random follows UTC offset");
Expect(ReadInt(buffer, 48) == 3, "history length scalar remains tightly packed");
Expect(ReadFloat(buffer, 64) == 4.0f, "vec2 shader parameter aligns to 8 bytes");
Expect(ReadFloat(buffer, 80) == 0.1f, "color parameter aligns to 16 bytes");
Expect(ReadInt(buffer, 96) == 1, "boolean parameter follows vec4");
Expect(ReadInt(buffer, 100) == 2, "enum parameter follows boolean");
}
}