Live data from Hacker News

A Shader Trick

the-witness.net

11–20 of 56 posts

Re: A Shader Trick

#11

Could you use a non-float integer instead? Do GPUs have cheap int % float -> float operations?

I'm confused why you need a global total game-time anyways, or if you have one why it has to be precise. Could you use your precise time in float, and then increment a larger but less-precise total gametime value every 10 minutes?

Re: A Shader Trick

#12
The blog suggests that you need to use integers to describe time because floats have problems. Granted.

Why limit one’s self to absolutely having to describe it in a single integer value? Why not some wrapper around a handful of integer values that can handle a much bigger max?

Would this have a meaningful performance cost?

Re: A Shader Trick

#13
post #10

I think that instead of this, my solution would be to have each function that depends on dt to accumulate the dt themselves, and reset it at their individual periods. A Rust trait with an associated const would help with this: trait TimeDependentFn { const PERIOD: f32; type Output; fn call(&self, dt: f32) -> Self::Output; }

But then you would need a local dt for each time-dependent function, and shaders don't really have packaged-up member variables in structs like you think they would if you come from Rust. That means you would have to maintain a massive list of dt's for each time-dependent function your shader calls, and then change this list everytime you introduce or remove a time-dependent function to the shader code. It's a solution that only works in a language that can hide the complexity from the programmer like Rust.

Re: A Shader Trick

#14
i have been doing this for a while playing around with shadertoy. i don't think i learned it from anywhere, i just wanted some things to match up and repeat over hours and it was obvious that sin/cos are periodic, and cycling the time value would improve the imprecision at the seam.

seeing it delivered as a clever trick in a blog post makes me wonder if i'm more competent than i thought, or if everyone else is generally less competent than i thought.

Re: A Shader Trick

#15

The blog suggests that you need to use integers to describe time because floats have problems. Granted. Why limit one’s self to absolutely having to describe it in a single integer value? Why not some wrapper around a handful of integer values that can handle a much bigger max? Would this have a meaningful performance cost?

you'd still end up either losing precision or using a truncated (cycling) part when you wanted to use it in a float calculation. it's effectively the same.

Re: A Shader Trick

#16
post #11

Could you use a non-float integer instead? Do GPUs have cheap int % float -> float operations?

I'm confused why you need a global total game-time anyways, or if you have one why it has to be precise. Could you use your precise time in float, and then increment a larger but less-precise total gametime value every 10 minutes?

It doesn't have to be game time, as the article says it could be time since level or some other trigger. It's basically about any time based counter you need for a time based effect, such as a predefined cyclical wind effect on trees or waves in water. The article also explains why it has to be precise, looping effects will behave oddly if the loop is not occurring precisely. Splitting the number into a large part and a precise part doesn't actually solve for anything, it just moves the problem into "how do I make arbitrary effects precisely loop based on the 2 parts of the time" instead of "how do I make arbitrary effects precisely loop based on the time".

Re: A Shader Trick

#17
post #11

Earlier quoted context omitted.

I'm confused why you need a global total game-time anyways, or if you have one why it has to be precise. Could you use your precise time in float, and then increment a larger but less-precise total gametime value every 10 minutes?

It doesn't have to be game time, as the article says it could be time since level or some other trigger. It's basically about any time based counter you need for a time based effect, such as a predefined cyclical wind effect on trees or waves in water. The article also explains why it has to be precise, looping effects will behave oddly if the loop is not occurring precisely. Splitting the number into a large part an…

If it moves the problem far enough forward in practice it won't matter though. If somebody runs The Witness for 100 days that's on them

Re: A Shader Trick

#18
post #14

i have been doing this for a while playing around with shadertoy. i don't think i learned it from anywhere, i just wanted some things to match up and repeat over hours and it was obvious that sin/cos are periodic, and cycling the time value would improve the imprecision at the seam. seeing it delivered as a clever trick in a blog post makes me wonder if i'm more competent than i thought, or if everyone else is genera…

You can use a similar approach for adding time features to a ML model. In this context, I think it is a quite common technique.

Re: A Shader Trick

#19
post #2

I think I've read that minecraft behaves differently depending on how far away you are standing from the origin for similar reasons: [1] https://minecraft.fandom.com/wiki/Bedrock_Edition_distance_e... [2] https://minecraft.fandom.com/wiki/Java_Edition_distance_effe...

I first encountered this in Active Worlds around 2000 or so, as a teenager. I managed to get the head developer to check it out, and he seemed surprised by it.

Re: A Shader Trick

#20
post #10

I think that instead of this, my solution would be to have each function that depends on dt to accumulate the dt themselves, and reset it at their individual periods. A Rust trait with an associated const would help with this: trait TimeDependentFn { const PERIOD: f32; type Output; fn call(&self, dt: f32) -> Self::Output; }

this is about shaders, which have no persistent memory even pixel-to-pixel on the same frame. there is no way to accumulate over time. and calculating outside of the shader would miss the point.

so you're stuck doing it from scratch every pixel. that's fine, shaders are fast.

at most it might make sense to calculate a truncated time globally per frame and provide that as a uniform.

Post reply on HN