Skip to main content
GameDev.net gamedev.net
🔒 Locked

Gerstner wave function [HLSL]

Started by JJtheGerman Sep 29, 2013 at 8:13 PM 3 replies 11.7k views
Original Post
JJtheGerman
JJtheGerman

Hi, I am new to these forums here, just joined, so hi to everyone reading this.

I have started with HLSL around 6months ago, and use AMD's RenderMonkey to create shaders.

I already made alot of progress with learning HLSL and the occasional success keeps me coming back for more :D

Now one topic I tried to stear clear from are wave simulations because I dont understand how to move specific vertices.

For example. I tried moving the vertices in WorldSpace on the y axis, by moving them in an if statement by checking what the position of the vertex is in world space and then moving them accordingly.

But I cant believe that this is how you are supposed to do it.

I have yet to find something about this on google. Which is why I decided to sign up here, and also I believe this will be a great site for helping me with my journey into 3D :D.

So the question is, what would be some more or less arbitary code to move selected vertices up and down.

Some short pseudo code example would really help.

Thanks in advance and I appreciate any help I can get.

PS: If you know of some better software of creating shaders then RenderMonkey then please let me know. A software where its easier to assemble 3d scenes using custom shaders to light the scene would be nice :D

Waaayoff
Waaayoff

Here's some code I wrote a while back. It's only a test code for a single wave. You will want to create a number of waves at different frequencies to obtain a more realistic look.


cbuffer World
{
	float3 SunDirection;
}

cbuffer Instance
{
	float4x4 WorldViewProj;
}

cbuffer PerFrame
{
	float DeltaT;
}

Texture2D DiffuseTexture;
SamplerState Sampler;

struct VS_IN
{
	float4 position : POSITION;
	float2 uv 		: TEXCOORD0;
};

struct VS_OUT
{
	float4 position	: SV_POSITION;
	float2 uv		: TEXCOORD0;
};

VS_OUT VShader(VS_IN input)
{
	VS_OUT output = (VS_OUT)0;
	
	// Gerstner Wave
	
	float A = 5;	// amplitude
	float L = 50;	// wavelength
	float w = 2*3.1416/L;
	float Q = 0.5;
	
	float3 P0 = input.position.xyz;
	float2 D = float2(0, 1);
	float dotD = dot(P0.xz, D);
	float C = cos(w*dotD + DeltaT/100);
	float S = sin(w*dotD + DeltaT/100);
	
	float3 P = float3(P0.x + Q*A*C*D.x, A * S, P0.z + Q*A*C*D.y);
	
	output.position = mul(WorldViewProj, float4(P,1));
	output.uv = input.uv;

	return output;
}

float4 PShader(VS_OUT input) : SV_Target
{
	return float4(DiffuseTexture.Sample(Sampler, input.uv).rgb, 1);
}

And some literature:

http://http.developer.nvidia.com/GPUGems/gpugems_ch01.html

http://hyperphysics.phy-astr.gsu.edu/hbase/waves/watwav2.html

http://www.gamedev.net/blog/715/entry-2249487-ocean-rendering/

http://graphics.ucsd.edu/courses/rendering/2005/jdewall/tessendorf.pdf

"Spending your life waiting for the messiah to come save the world is like waiting around for the straight piece to come in Tetris...even if it comes, by that time you've accumulated a mountain of shit so high that you're fucked no matter what you do. "
JJtheGerman
JJtheGerman

Thanks for the help!

The code helped a lot, although it doesnt work with a plane for some reason. Still I get the idea and can now write the rest myself.

I appreciate the help! biggrin.png

Waaayoff
Waaayoff

Thanks for the help!

The code helped a lot, although it doesnt work with a plane for some reason. Still I get the idea and can now write the rest myself.

I appreciate the help! biggrin.png

The code works by transforming vertices. A plane only has 4. You need to use a grid.

Anytime.

"Spending your life waiting for the messiah to come save the world is like waiting around for the straight piece to come in Tetris...even if it comes, by that time you've accumulated a mountain of shit so high that you're fucked no matter what you do. "
JJtheGerman
JJtheGerman

The problem was actually not your code, sorry for the confusion. It just turned out the default grid (isn't any model that is a rectangel and only has one side a grid?),
has its local z vector pointing up instead of y, so the code just needed a little bit of adjustment. As follows:

float2 D = float2(0,1);

to

float3 D = float3(0,0,1);

and

float dotD = dot(PO.xz, D);

to

float dotD = dot(PO.xy, D.z);

Currently working on the normals, but there are enough topics about calculating them already and your references are going to help.

Thanks, man! laugh.png

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.