#The water in my game is basically a

1 messages ยท Page 1 of 1 (latest)

next coral
#

let's continue here

tawdry swan
#

coool

#

first time using the threads feature

#

i understand the usecase now

#

anyhow

#

So my understanding of the ShaderGraph is that..
Each vertex, looks at the same Gradient Noise, offsets its Y position using some Multiply and Add Nodes

#

Now I need to somehow recreate this in C#

#

Though there is a lot of ambiguity in my mind

#

what exactly us UV0, How does Tiling and Offset work, What is Normal Vector, What is Position

#

Time was pretty straightforward to convert, it was just Time.time

#

also in case it does help, I was using this video as reference to set up my water shader

#

Let's make some simple cartoon water!

82% OFF for Web Hosting and FREE Domain included!: https://www.hostinger.com/brackeys
Coupon Code is "BRACKEYS" for an additional 15% discount.

The shader is based on this amazing video: https://youtu.be/jBmBb-je4Lg

GduX: https://www.gdux.me/
Game Dev Unchained: https://www.gamedevunchained.com/
ยทยทยทยทยทยทยทยทยท...

โ–ถ Play video
next coral
tawdry swan
#

okay, with you so far

next coral
tawdry swan
#

ah okay

next coral
#

@tawdry swan actually, could you share the shader graph you have right now with me (as an actual shader graph file) so I could experiment with it. I'd change the shader a bit to make this little bit easier

next coral
#

seems to work

tawdry swan
#

cool!

next coral
# tawdry swan cool!

ok so this is what I changed this to to more easily make this is c# (the uv coordinate depends on the mesh you're using so if you decide to change the plane later, you'd need to change the code). now if you multiply the wave speed (in inspector, not in the shader code itself) by 10 and divide the turbulance value (in inspector too) by 10, you should get exactly same look (assuming your plane isn't scaled, if it is, you can play around with the values to get the results you want)

tawdry swan
#

ok let me try to understand this

#

okay.. this does look a bit more intuitive

#

I'm still a bit confused with the beginning and ending Position nodes though

#

what exactly do they give us?

next coral
# tawdry swan what exactly do they give us?

they both give us the position of the vertex we are currently deforming. the only difference is that the one on the left is in world space (global coordinates. relative to the actual world coordinates) and the one on the right is in object space (relative to the objects transform)

#

I think the object space position is bit more tricky to understand am I right?

#

so if you imagine the vertex being child of the water plane, the object space value would be the one you see in inspector. even if you rotate or scale the plane, the object space value will remain the same

tawdry swan
#

so basically the object's transform will be the origin

#

0,0,0

#

and in relation to that

next coral
#

yes

tawdry swan
#

My confusion is again, when recreating this in C# what do I plug in place of those two

next coral
#

and x axis would be the objects right direction, y would be up direction etc.

tawdry swan
#

Everything else seems understandable to me

next coral
#

so now in the shader code the Position node gives the position of the vertex we are currently deforming (in world/object space). because we want to sample the water height at position named Position (the function parameter) we have to put in those places the Vector2 Position in world space and (the water planes) objects space

tawdry swan
#

ok, so the first time around we provide the Vector2 Position in world space. Then towards the end we provide the same but in Object space instead (of water plane)

#

and we convert world space to Object Space using
waterPlaneTransform.InverseTransformPoint(Position)

next coral
#

you're figuring this out faster than I can type ๐Ÿ™‚, exactly

next coral
#

but pretty close

#

the thing you forgot is that InverseTransformPoint takes a world space position (vector3) and Position is vector2 where x is x axis and y is z axis

tawdry swan
next coral
#

so you can make new vector3 (Position.x, 0f, Position.y) and plot that to InverseTransformPoint

tawdry swan
#

cool, I feel like im getting a handle on things..

#

Dude, Thanks so much for having the patience to sit through this with me

#

and explaining all of this

next coral
#

np mate

tawdry swan
#

I think I can get cracking on this

next coral
next coral
# tawdry swan yupp that's what I had in mind

because we are overwriting the y position to be always 0f (we should put the "vertices" y position in world space in there but in this case it doesn't matter), we are getting wrong y coordinate on the object space position. because the mesh is a plane (every vertex has y coordinate of 0 in object space) we can just set the y of the result of InverseTransformPoint to be 0f

tawdry swan
#

okay so whatever float value I get from the final add function,
needs to be plugged back into a Vector3 and transformed using planeTransform.TransformPoint

The vec3 would look something like (0f, Height, 0f). This would convert it back into world space to be used by the cube

#

Since while inputting the Y is irrelevant, and while Outputting X and Z are irrelevant

next coral
tawdry swan
#

oh wait. yeah

next coral
#

at this point it would be good idea for me to try to do this myself to see if it works ๐Ÿ˜‚. I'm not that confident I haven't made any mistakes

tawdry swan
#

makes sense, im a dummy

#

ah don't bother going through the trouble >.<
I've got another hour or so before I head to sleep.. I'll try implementing this and update here if it works out or not

next coral
tawdry swan
#

ohp well :P

tawdry swan
#

i converted the hlsl functions to c#

#

now connecting all inputs and outputs

#

ok im done implementing it, time to test whew

next coral
#

im in testing part too ๐Ÿ™

tawdry swan
#

well

#

it seems to be moving up and down somewhat with the phase of the wave

#

but its like, a few feet under the water

#

for some reason

#

nvm its glitching and teleporting

#
Transform myTransform = GetComponent<Transform>();
float waterLevel = GetHeight(new Vector2(myTransform.position.x, myTransform.position.z));
myTransform.position = new Vector3(myTransform.position.x, waterLevel, myTransform.position.z);

Does this seem like the right way to be changing position?

next coral
tawdry swan
#

god damn that looks beautiful

#

well in that case there must be something wrong in my implementation

tawdry swan
#

can I put my code here and you can have a look and tell me where i'm messing up?

#

or better if you share yours and i'll compare

next coral
tawdry swan
#

Maybe the time variable?

#

or float precision loss??

#

dunno..

#

also hey, I'm gonna have to start packing up and heading off now, its like 5am here..
I'll have to continue on this in the morning

#

could you share your code for reference?

#

I'll have a look at it in the morning

next coral
#

yup

tawdry swan
#

welp, nights still young for you

#

๐ŸŒ™

next coral
#

it seems so weird because first it doesnt work, then it works perfectly for a moment and snaps off the road something like 10 seconds later. it still keeps going up and down but at wrong timing

next coral
#

ok, i'll continue debugging this tomorrow. because it still works for a moment, we are surely close to the correct solution

tawdry swan
#

Aye!

#

Welp, im up now, ready to continue working when yoh are

next coral
#

for some reason it seems to be off sync for exactly 1 second at the very start

#

after that it seems to be going gradually more and more off sync

tawdry swan
#

hmm

#

im going to try to implement your code in my project and try to experiment too

#

damn you're so much better at writing cleaner and efficient code >.<

#

I had all these unnecessary functions all over the place for simple calculations

#

I have a doubt in your code

#

Vector3 objectSpacePosition = plane.InverseTransformPoint(new Vector3(posXZ.x, 0f, posXZ.y)); Over here

#

You use plane.InverseTrasnform...

#

but

#

while plane is declared, its value is never initilizaed to anything

#

public Transform plane, sphere;

#

unless wait, you exposed that variable and set the value from there

#

im stupid

next coral
tawdry swan
#

aye

#

for the off sync think

#

could it be maybe that we need to multiply something with Time.deltaTime somewhere?

#

im not sure though

next coral
tawdry swan
#

hmmm

next coral
#

but I think the problem with off sync over time is related to Time.timeSinceLevelLoad somehow

#

wait a minute, that seems to be the case...

tawdry swan
#

Would simply using Time.time be better?

next coral
#

I can try

#

but I don't think that's it

#

the time node seems to be doing something really odd

#

nope. Time.time wasn't any better, i'm currently experimenting with the time thingy

tawdry swan
#

hmm man its so strange

next coral
#

it is. I have been told that _Time.y (which Time node uses) is exactly same as Time.timeSinceLevelLoad but actually they seems to get off sync after some time (it seems like _Time.y grows slightly faster than Time.timeSinceLevelLoad)

tawdry swan
#

huh

#

well is there some sort of fixed rate at which it grows

#

which maybe we can just hardcode?

#

oh or maybe

#

instead of in
void Update(){}

we run it in
void FixedUpdate(){}

#

would that make a difference?

#

also umm

#

unsure what i'm doing wrong

#

but its not working on my end..

#

for some reason

next coral
tawdry swan
next coral
# tawdry swan

btw you have to use exactly same waveSpeed and turbulence values as you do in the shader code

tawdry swan
#

I am, infact i'm pulling the values from the shader itself

#
    Vector3 GetPosition(Vector2 posXZ)
    {
        float waveSpeed = rend.material.GetFloat("_Wave_Speed");
        float turbulence = rend.material.GetFloat("_Turbulence");

        float time = Time.timeSinceLevelLoad/*Shader.GetGlobalVector("_Time").y*/ * waveSpeed;
        Vector2 addNode = posXZ + Vector2.one * time;
        float gradientNode = Unity_GradientNoise_float(addNode, turbulence);
        Vector3 multiplyNode = new Vector3(0f, gradientNode, 0f);
        Vector3 objectSpacePosition = plane.InverseTransformPoint(new Vector3(posXZ.x, 0f, posXZ.y));
        objectSpacePosition.y = 0f;
        Vector3 finalAddNode = multiplyNode + objectSpacePosition;
        return plane.TransformPoint(finalAddNode);
    }
next coral
#

I'm currently trying to build the game to see how the Time.timeSinceLevelLoad and _Time.y works there. in the editor it seems those are definitely not the same (_Time.y doesn't even seem to reset when I load the scene again)

tawdry swan
#

okai

#

wait that's weird. I kept the code same, but changed the turbulence and wavespeed to match it to what you've set it

#

and now it works

#

why is it only working for specific values?

#

The same exact code.
It works like you are showing at

Wavespeed = 2```

But if I change it back to 

Turbulence = 2
WaveSpeed = 0.05

It stops working
next coral
tawdry swan
#

Try adjusting the Turbulence and Wavespeed on ur end to
2 and 0.05 respectively

#

it doesn't work properly at those valules

next coral
tawdry swan
next coral
#

so it doesn't work at all...

#

I'm really confused about _Time.y now... according to docs it should be

Time since level load (t/20, t, t*2, t*3), use to animate things inside the shaders.

tawdry swan
#

hmm

#

hey..

next coral
#

but it seems it's for sure not time since level load

tawdry swan
#

just a thought.. Maybe the time itself is actually fine.

#

but the gradient function

#

does some weird math with integer and float subtractions

#

could that be going wrong in C# somehow?

#

Maybe this

next coral
#

have to try that too

#

wait... why does print(Shader.GetGlobalVector("_Time").y); give these values? that's surely not same as Time.timeSinceLevelLoad. maybe I should ask about this in #archived-shaders. maybe unity have changed this behaviour

tawdry swan
#

how much is the difference between the two??

next coral
#

about 6000 seconds ๐Ÿ˜‚

#

actually, I think I know what's happening. print(Shader.GetGlobalVector("_Time").y); seems to give different value when I'm looking at game view and scene view

tawdry swan
#

huh

#

ok wait

#

what is game view vs scene view

#

ik its probably a noob question

#

i've implemented a differnet frac function, testing with it rn

#
    Vector2 frac(Vector2 p)
    {
        string sx = p.x.ToString().Substring(p.x.ToString().LastIndexOf('.'));
        string sy = p.y.ToString().Substring(p.y.ToString().LastIndexOf('.'));

        return new Vector2(float.Parse(sx), float.Parse(sy));
        //return new Vector2(p.x % 1f, p.y % 1f);
    }
next coral
tawdry swan
#

ah ok

next coral
tawdry swan
#

instead of doing x%1f to get the decimals off a float

#

its doing string manipulation

#

i know it looks horrendous

#

but its just a test >.<

next coral
#

that is horrendous, doing float calculations using strings, yuck

tawdry swan
#

aand it has no effect whatsoever

#

it just gives the same result

#

going back to %1f ...

next coral
tawdry swan
#

oki

tawdry swan
#

im trying to implement what Cyan suggested for now

#

just testing if it does solve the issue

#

okay...

#

thats strange

#

even with a custom variable which Updates in C# itself being used as time

#

it goes off sync

#
    public Transform plane, sphere;
    float WaveTimer = 0f;

    //Get Rendeder to get Material to get floats from
    Renderer rend;

    void Start()
    {
        //Get Water Plane Renderer
        rend = plane.GetComponent<Renderer>();
    }

    void Update()
    {
        WaveTimer += 0.005f;
        rend.material.SetFloat("_Wave_Timer", WaveTimer);
        
        sphere.position = GetPosition(new Vector2(sphere.position.x, sphere.position.z));
    }

    Vector3 GetPosition(Vector2 posXZ)
    {
        float waveSpeed = rend.material.GetFloat("_Wave_Speed");
        float turbulence = rend.material.GetFloat("_Turbulence");

        float time = WaveTimer * waveSpeed; /*Time.timeSinceLevelLoad //Shader.GetGlobalVector("_Time").y*/
        Vector2 addNode = posXZ + Vector2.one * time;
        float gradientNode = Unity_GradientNoise_float(addNode, turbulence);
        Vector3 multiplyNode = new Vector3(0f, gradientNode, 0f);
        Vector3 objectSpacePosition = plane.InverseTransformPoint(new Vector3(posXZ.x, 0f, posXZ.y));
        objectSpacePosition.y = 0f;
        Vector3 finalAddNode = multiplyNode + objectSpacePosition;
        return plane.TransformPoint(finalAddNode);
    }
#

This is just strange...

tawdry swan
#

does this mean that the Time.time being out of sync is not the issue?

next coral
#

I think it does, which means we have error somewhere in our calculations

next coral
#

I think I'm about to get this (once again)

tawdry swan
#

hmm

#

I'm fiddling around with the GradientNoise C# Calculations

#

That is the function which has the most weird calculations

tawdry swan
#

.<

#

I get this feeling that if it doesnt work out

tawdry swan
#

The next step could be to generate the Noise in C# using Mathf.PerlinNoise

next coral
#

I'm currently trying to use the GradientNoise function inside compute shader to see if there's difference between c# and hlsl version (i'm generating texture using both)

tawdry swan
#

and then Pass that into the ShaderNode

next coral
tawdry swan
#

okay.. how is it different from the normal ShaderGraph?

#

doesnt it do the same thing?

next coral
tawdry swan
#

oh ok

next coral
# tawdry swan oh ok

yep, the problem is somewhere within the generate noise function. see, with noise scale of 0.1, both looks pretty much the same (left is generated by c# script and right is generated by compute shader running the exact hlsl code copied from the docs page) but not quite

#

scale of 2.433

#

and scale of -0.1, lol ๐Ÿ˜‚ (I mean you're not supposed to use negative scale ig but still, doesn't look the same as they should)

tawdry swan
#

Ah god damn

#

well there we go..

#

in HLSL

#
float2 Unity_GradientNoise_Dir_float(float2 p)
{
    // Permutation and hashing used in webgl-nosie goo.gl/pX7HtC
    p = p % 289;
    // need full precision, otherwise half overflows when p > 1
    float x = float(34 * p.x + 1) * p.x % 289 + p.y;
    x = (34 * x + 1) * x % 289;
    x = frac(x / 41) * 2 - 1;
    return normalize(float2(x - floor(x + 0.5), abs(x) - 0.5));
}
#

this function has these two comments

#

I have no idea what they actually mean, but they sound very important

#

would it maybe be better to work in Double instead of float?

next coral
tawdry swan
#

yeah..

next coral
#

most of the issues seems to happen with negative uv values (off sync seems to happen when further away from origin too) which makes me believe it has something to do with frac/floor/abs functions

tawdry swan
#

I think I got it..?

#

so frac() is supposed to return the decimal part to us

#

so for example frac(1.23) should return 0.23

#

but should frac(-1.23) return -0.23 or 0.23

#

because using -1.23%1f is going to return -0.23 not 0.23

#

does the return value have to be absolute?

#

Yeah.. % operator seems to be the wrong way of going about things

#

frac(-1.2) should return 0.8
but in our case it would return -0.2

next coral
tawdry swan
#

Yo

#

i think...

#

I made a change to the frac function

#

It is no longer doing that 1s delay before it snaps into position on start

#

though it is still going off sync

next coral
#

that's different problem then ๐Ÿ˜…, here we go again

tawdry swan
#

the new frac function btw

#
    Vector2 frac(Vector2 p)
    {
        return new Vector2(p.x-Mathf.Floor(p.x), p.y-Mathf.Floor(p.y));
        //return new Vector2(p.x % 1f, p.y % 1f);
    }
tawdry swan
#

also dude, you're going above and beyond in helping me, I hope im not taking away time from your chores and work and stuff

next coral
tawdry swan
#

:P

#

Thanks a bunch

next coral
tawdry swan
#

can you send an ss of how it looks?

next coral
tawdry swan
#

yes please, i was researching how to write my own and it was unfortunately going all over my head

next coral
tawdry swan
#

ohk

#

how do i use it??

next coral
tawdry swan
#

npp at all

#

ok wait i have one more doubt >.<

#

where do I attach this script

#

to run it

next coral
tawdry swan
#

cool

#

think i've set it up wrong

#

the plans are just blank

next coral
tawdry swan
#

hmm

#

ah ok

#

i changed it to 30.23 and it does display

#

yeah i can see the differences

#

hmm

next coral
tawdry swan
#

yup

#

got it

#

I can see like minute differences near the boundaries of the planes

#

which then add up and change a lot as the offset changes

next coral
#

yeah

tawdry swan
#

hmm

#

seems to me like there is some weird different math working behind the scenes

#

how can this even be fixed >.<

next coral
tawdry swan
#

well..

#

if only it were that easy T_T

#

I mean, HLSL and C# are interpreting the same math

#

in different ways

#

how do we get them to see eye to eye

#

hmm

next coral
#

maybe I should try to create the c# noise function again very carefully

tawdry swan
#

how much more careful, it looks pretty correct to me >.<

#

i don't see what could be changed further

next coral
#

wait a minute (once again)

#

no need to wait anymore, it wasn't that one

tawdry swan
#

lmao

#

I have one more solution..

#

Can we use this

#

and then simply pass in the Same function we use in C# into this node

#

then we can plug in the Custom Node instead of gradient noise node

next coral
#

hold on

tawdry swan
#

oki

next coral
# tawdry swan oki

well, it wasn't that. I spotted this error here but it didn't fix anything I think

tawdry swan
#

oh hmm

#

is there a difference between order of operations in HLSL and C#?

next coral
tawdry swan
#

all good man, enjoy your meal!

tawdry swan
#

welp, i'm back

#

gonna continue experimenting

tawdry swan
#

people facing same issue as here

tawdry swan
#

Also..

#

is it possible to just use the Compute shader to make those calculations

#

since it works in HLSL

#

the output "Should" be same?

#

And then pass the value back to C# using a buffer or something

next coral
tawdry swan
#

yeah.. That's true as well..

#

but wait

next coral
#

except if you calculate a lot of values at once

tawdry swan
#

I understand that GPU's are great at working calcs in parallel

next coral
#

yes, they are incredible fast

tawdry swan
#

but is there any downside to actually just giving it a single calc

#

Like does it hog resources from other tasks, or is it generally slower at single calculations than a CPU?

next coral
# tawdry swan Like does it hog resources from other tasks, or is it generally slower at single...

i'm pretty sure it is slower than cpu, yes. the thing is, gpu can calculate a lot of things parallel but it can't calculate single calculation at once. gpu calculates things using so called "wavefronts" which nowadays consists 64 threads meaning all of the 64 threads (gpus can also lauch couple of wavefronts at once, many gpus have thousands of threads on them) will calculate the same thing even if you use the result of only one of them. I'm also not sure what is the general cost of preparing the threads for calculations/moving data between cpu and gpu etc.

tawdry swan
#

Hmm okay..

#

so then.. what options are we left with ๐Ÿ˜ญ

next coral
# tawdry swan so then.. what options are we left with ๐Ÿ˜ญ

I can't really say using compute shader is bad solution tho. not so long ago I made conways game of life using compute shaders and I managed to use 8192x8192 grid simulated every frame at realtime (I didn't read the data back to cpu tho, afaik that's the slowest part. I just rendered the map using the buffer calculated in the compute shader). if I can calculate 67 million values per frame, I don't think 1 (well technically 64 ig) will cause that many problems, I think only way to know is try and see

tawdry swan
#

Yeah.. I'm looking at a video on introduction to compute shaders

#

Trying to understand how it works

#

I'm gonna have a shower first, will continue in a bit

next coral
#

the compute shader approach would allow you to calculate a lot of positions at once if you need many floating objects for example (maybe millions? no problem ๐Ÿ™‚)

tawdry swan
#

but yeah..

#

i'm gonna try my hand at this now

next coral
#

I just got this working using compute shader

#

seems to stay on sync forever

#

I'm not actually sure if this is usable in actual game application. for me it seems to take several milliseconds per call (maybe 5 ms). i'm using dell latitude 3300 laptop atm so that's obviously not the most optimal gaming pc but still that sounds quite lot. if it's possible to do some other way, i'd probably choose not to use compute shaders in this case (I think reading the data back from gpu to cpu is the heaviest part here even though it's only 32 bits). you can obviously try that yourself and see how it performs

tawdry swan
#

woah

#

i'm still learning how to implement this in a compute shader >.<

#

first time working

#

with them

#

5ms huh..

#

dang

tawdry swan
next coral
tawdry swan
#

Well they're going to be used

next coral
#

ah ok

tawdry swan
#

To calculate buyoyancy for objects

#

otherwise i'd have just made them into a shader as well :P >.<

next coral
tawdry swan
#

can you show me how you got the calculations into a compute shader

#

i'm struggling to understand this..

next coral
tawdry swan
#

the precalculated texture would have to be about as big as the water in my game then

#

and it would only work for fixed Turbulence and Wavespeed

#

i'd have to generate a new one every time right..?

#

and even then, how would I make the waves actually happen unless this texture is infinitely big

next coral
next coral
tawdry swan
tawdry swan
#

how would I go about making a seamless texture like this

next coral
tawdry swan
#

hmm yeah.. bigger the texture means less noticeable the patterning

#

makes sense

next coral
#

just make sure:

The final image will tile seamlessly if the width and height of the image are whole multiples of the cell spacing. For best results, use numbers that are powers of 2 for the image width, height and cell spacing

tawdry swan
#

I'm gonna try this compute shader stuff first, observe the performance issues. If they seem like a huge problem to me at this stage or even later.
I'll overhaul this, into this new method that you're suggesting.. it does sound much more resource friendly and consistent..
In that case i'd have to learn a bunch of things.

1) Generating a seamless noise texture
2) Passing a pre calculated texture in place of Gradient Noise
3) Reading values from a texture in C#
#

but it does sound doable

#

and hey howsoever this ends up, i've ended up learning a lot of shaders, hlsl, c#, etc..

#

so thats good

tawdry swan
#

also

#

could you share that compute shader code with me?

#

that you're working with

#

I'm having trouble understanding how to Get values after dispatching a shader

next coral
tawdry swan
#

both >.<

#

i assume a c# script is dispatching a compute shader from within it

#

then getting the values calculated by the compute shader somehow

#

i wanted to see both, i'm looking at references online, but I'm having some doubts

next coral
#

this is how I dispatch the shader and read the data back. arrayData is just float[] arrayData = new float[1] which unity then fills with the results from the buffer when buffer.Getdata is called. ```cs
computeShader.SetVector("_Uv", addNode);
computeShader.SetFloat("_Scale", turbulence);
computeShader.Dispatch(computeShader.FindKernel("CSMain"), 1, 1, 1);
buffer.GetData(arrayData);
float gradientNode = arrayData[0];

tawdry swan
#

okay, looks like I was on the right track with the .compute at least..

#

hmm okay, I think this makes sense to me

#

and float[] arrayData = new float[1] is declared within the GetHeight funciton itself

#

any reason why we get data in form of an array instead of like just a float?

next coral
#

this is how I create the buffer (with one element that contains 4 bytes) and give it to the shader:

buffer = new ComputeBuffer(1, sizeof(float));
computeShader.SetBuffer(computeShader.FindKernel("CSMain"), "Result", buffer);
next coral
tawdry swan
#

okay, makes sense

next coral
tawdry swan
#

ah okay

#

makes sense

#

hmm

next coral
#

I don't actually know if using 1x1 RenderTexture (render texture is texture that's specifically meant to be used to read from/write to in shaders. regular textures cannot be written to in shaders) would be better in some odd way, most likely not

tawdry swan
#

yeah the video I saw was using a texture which the shader wrote to

#

but idk if it'll be faster

#

doesn't it still have to pass the data from GPU to CPU somehow

#

okay i got the ocmpute shader working..

tawdry swan
next coral
tawdry swan
#

well, thats a whole new thing to learn ๐Ÿ˜…

#

for now.. I think this works out

#

I'll continue working on the game, keep checking how performance holds up

#

Thank you so much again

#

I can't begin to thank you enough >.<

#

Learnt a lot

#

I think we're good to archive this thread now too

next coral
#

np

next coral
# tawdry swan well, thats a whole new thing to learn ๐Ÿ˜…

Stopwatch is basically just a timer. you can create it like any other c# object by doing Stopwatch stopOrAnyOtherName:) = new Stopwatch();. when you want to start the timer, you call stop.Start(); and when you want to end it, you call stop.Stop();. after you have stop the timer, you can see how much time have elapsed between Start()/Restart() and Stop() by using stop.Elapsed.TotalMilliseconds

tawdry swan
#

oh its literally like a stopwatch operated through code

#

that sounds rad..

#

I also want to ask

#

this ComputeShader.Dispatch function

#

its Syncronous or Async?

next coral
#

yeah

next coral
tawdry swan
#

meaning it will literally hold the execution of the rest of the C# script until it finishes?

#

or no?

next coral
#

usually the c# script will not wait for the compute shader to finish but if you call buffer.GetData (or do something with the render texture I think?) in the c# script, the script will wait for the shader and after that reads the values from the buffer

tawdry swan
#

Ah cools

#

okay makes sense

#

how do we archive this thread?

next coral
tawdry swan
#

like when we look at the list of threads under #archived-code-general , you can see active threads and ones which have been "archived" or closed

#

I assume this thread has well beyond served the purpose now :P

#

so we can close it I think

next coral
tawdry swan
#

Ahh hahaha

#

Cools

#

I'm gonna call it a night now

#

Have a good day :D

next coral
#

Gn

tawdry swan
#

wellp

#

the problem extends..

#

This is my new node setup

#

I'm using a SampleTexture2D node here to use pregenerated image noise from a .png file

#

and my C# converison is

#

now for some reason GetHeight() only returns a constant value

#

the value is not updating at all for some reason :(

#

This is the noise im using

tawdry swan
#

I checked by printing values

#

and it seems there is something that i'm doing wrong when it comes to C#

inland thistle
#

this is a long freakin thread that I only really glanced through, I guess something that kinda stood out to me is I don't see a modulus in the tiling calculation. Is the perlin noise texture set to wrap or clamp? sorry if not helpful, don't have time to follow along further. Would probably be helpful to see your printed values at various points in GetHeight

tawdry swan
#

ah no need to follow along the entire thread, most of it is unrelated to current problem

tawdry swan
#

so when I look at the Generated code for the TIling And Offset node, I get this in hlsl

inland thistle
#

can you just double check if your perlinNoise texture is set to wrap?

tawdry swan
#

okay lemme see

#
float time = Time.time * waveSpeed;
Vector2 addNode = posXZ + (Vector2.one * time);
Vector2 tilingNode = addNode * turbulence;
#

Looks like

#

it is

#

Repeat right?

inland thistle
#

yeah that's fine then

tawdry swan
#

The thing is the ShaderGraph setup itself is working,

#

its just when I'm trying to emulate the TilingNode in C#

#

The values I'm getting are

#

well they don't seem right

inland thistle
#

what about the values you printed inside GetHeight?

tawdry swan
#

Oh wow wait

#

hold on

#

I understand the problem happening..

#
Color value = perlinNoise.GetPixel(Mathf.FloorToInt(tilingNode.x), Mathf.FloorToInt(tilingNode.y));
#

Over here I use Mathf.FloorToInt

#

which well, rightly so floors the values to 0.. since tilingNode.x is a really small float like 0.00xx

#

I think this is a limitation of the fact that a png image can only really take whole numbers as coordinates

inland thistle
#

really low turbulence value causing that?

tawdry swan
#

yeah..

#

the thing is I need the turbulence values to match in the ShaderGraph and C#

#

What i'm doing here is displacing the vater using a ShaderGraph.
But I also need to calculate the "height" of water at any given X/Z coordinates in the world. So I can have objects which use that "height" and float in the water

inland thistle
#

actually wait, don't UVs in shaders cover the whole distance in texture from float 0f to 1f representing how far along the x/y axis of the texture, or am I misremembering.

tawdry swan
#

I haven't.. the faintest Idea

inland thistle
#

try multiply by texture width/height before flooring to int in getPixel

tawdry swan
#

so..

#
Color value = perlinNoise.GetPixel(Mathf.FloorToInt(tilingNode.x*texture.width), Mathf.FloorToInt(tilingNode.y*texture.height));
#

?

#

i'll try

#

oh huh

#

it seems to be working..

#

I think

inland thistle
#

correctly?

tawdry swan
#

let me plug in the transforms and check

#

yeah.. no

#

the values seem to be offset a bit than the ShaderGraph

#

I think

#

the empties are moving up and down, but out of sync with how the ShaderGraph is displacing the water

inland thistle
#

same cycle duration though? (amount of time to go up & down once?)

tawdry swan
#

I can only say visually, but it looks about right

#

oh yeah and its

#

Super laggy

#

and chunky

#

is it because the Texture2D is too low resolution?

#

its a 1024x1024 png image

inland thistle
#

yes/no, I believe shaders also interpolate between points when sampling from textures, but I can't say without research how

#

you could maybe try lerping the texture color between rounding down & rounding up based on its integer remainder

tawdry swan
#

hmm

#

hey but wait

#

there is someone

#

In this article the person is having the same exact application / use case as me

#

but they have got it to work

#

the problem is they have only provided part of their code out of context

#

and its a bit difficult for me to understand theirs

#

wait hold on

#

wrong article

inland thistle
#
float texX = tilingNode.x*texture.width;
float texY = tilingNode.y*texture.height;
Color lowValue = perlinNoise.GetPixel(Mathf.FloorToInt(texX), Mathf.FloorToInt(texY));
Color highValue = perlinNoise.GetPixel(Mathf.CeilToInt(texX), Mathf.CeilToInt(texY));
Color value = Color.Lerp(lowValue, highValue, texX - Mathf.FloorToInt(texX));

I'll take a look, sorry I just wanted to finish writing that lol

tawdry swan
#

no problemo

tawdry swan
#

While it is generally more smoother

#

it still jitters up and down for some reason, and out of sync with the water itself

inland thistle
#

well I do see that in the page you linked they are getting the linearized color, I don't actually understand why but supposedly it matches the shader more closely

#
        float textureX = Mathf.Lerp(displMapSize.x, 0, Mathf.InverseLerp(0, oceanSize.x, pointPos.x));
        float textureY = Mathf.Lerp(displMapSize.y, 0, Mathf.InverseLerp(0, oceanSize.z, pointPos.y));
``` They are also lerping the tex coords before getting the color (get rid of color lerp), so I guess try that
tawdry swan
#

hmm

tawdry swan
#

I don't exactly understand what the math behind it is doing

#

the syntax is a bit overwhelming

#

with nested lerps

#

hard to visualize

#

and what would be the variables i plug in instead of theirs

inland thistle
#

ok, I understand why they are doing it and it doesn't make sense in your case. They are applying height based on position along object, while you are doing it in world space. I do still think you need some kind of interpolation between colors to smooth it out as you move across the texture, and maybe try playing around with the linearized color. Also maybe try posting in advanced lol.

#

going to sleep now, gl ๐Ÿ‘‹

tawdry swan
#

thanks for help mate!