I have make a 2.5D water, its works fine, and now I want to pass some effect.
Fisrt I want to make a caustic effect but I have a problem.
In my shader code wrap texture in a sampler state does’nt works. My texture is streched.
Hi,
If I invert the world matrix for the display of my background and I draw after, is it normal that it is exactly the same?
Could it be because of my camera?
I tried a lot of different things but my background always stays in the same position, in the same direction.
It’s due to my QuadRender?
public class QuadRender
{
//buffers for rendering the quad
public readonly VertexPositionNormalTexture _vertexBuffer;
private readonly short _indexBuffer;
//Declaration des Vector3 position
public Vector3 Origin;
public Vector3 UpperLeft;
public Vector3 LowerLeft;
public Vector3 UpperRight;
public Vector3 LowerRight;
public Vector3 Normal;
public Vector3 Up;
public Vector3 Left;
public Vector3 Position;
//Déclaration du type de vertex à utiliser
List<Vector2> textureCorner;
public QuadRender(Vector3 origin, Vector3 normal, Vector3 up,float width, float height)
{
textureCorner = new List<Vector2>();
Position = Vector3.Zero;
Origin = origin;
Normal = normal;
Up = up;
// Calculate the quad corners
Left = Vector3.Cross(normal, Up);
Vector3 uppercenter = (Up * height / 2) + origin;
UpperLeft = uppercenter + (Left * width / 2);
UpperRight = uppercenter - (Left * width / 2);
LowerLeft = UpperLeft - (Up * height);
LowerRight = UpperRight - (Up * height);
_vertexBuffer = new VertexPositionNormalTexture[4];
Vector2 textureUpperLeft = new Vector2(0.0f, 0.0f);
Vector2 textureUpperRight = new Vector2(1.0f, 0.0f);
Vector2 textureLowerLeft = new Vector2(0.0f, 1.0f);
Vector2 textureLowerRight = new Vector2(1.0f, 1.0f);
_vertexBuffer[0].Position = LowerLeft;
_vertexBuffer[0].TextureCoordinate = textureLowerLeft;
_vertexBuffer[1].Position = UpperLeft;
_vertexBuffer[1].TextureCoordinate = textureUpperLeft;
_vertexBuffer[2].Position = LowerRight;
_vertexBuffer[2].TextureCoordinate = textureLowerRight;
_vertexBuffer[3].Position = UpperRight;
_vertexBuffer[3].TextureCoordinate = textureUpperRight;
_indexBuffer = new short[6];
_indexBuffer[0] = 0;
_indexBuffer[1] = 1;
_indexBuffer[2] = 2;
_indexBuffer[3] = 2;
_indexBuffer[4] = 1;
_indexBuffer[5] = 3;
}
public void RenderQuad(GraphicsDevice graphicsDevice, Vector2 v1, Vector2 v2)
{
_vertexBuffer[0].Position.X = v1.X;
_vertexBuffer[0].Position.Y = -v2.Y;
_vertexBuffer[2].Position.X = v2.X;
_vertexBuffer[2].Position.Y = -v2.Y;
_vertexBuffer[1].Position.X = v1.X;
_vertexBuffer[1].Position.Y = -v1.Y;
_vertexBuffer[3].Position.X = v2.X;
_vertexBuffer[3].Position.Y = -v1.Y;
graphicsDevice.DrawUserIndexedPrimitives(PrimitiveType.TriangleList, _vertexBuffer, 0, 4, _indexBuffer, 0, 2);
}
}
Didn’t look at it other then glancing over it.
But address wrap is mostly used for pretty specific tiling cases you might want to use address mirror instead.
Also when you use wrap all it does is if the texture coordinates in the shader you pass go past 1 it uses the fractional value of the coordinates … soo…
if your passed texture sampled coordinates in your shader are 1.25 u say because you set that on a vertice. Then it will sample texture pixels at .25 instead wrapping around. The size of a texture however is 0 to 1 u and v from begining to end.
Mirror on the other hand for 1.25 u actually will subtract from 1.0 - .25 = .75 u
To draw reflections in 2d you could just render target the stuff you draw without the water then use the rendertarget to blend onto the water with the v coordinates fliped i.e. v = 1.0f - v; then drawn onto your water surface block or blended onto it.
searching for reflections should give quite a few results here is a couple.
2d
3d
for 3d the following requisite function isn’t in monogame and probably should be.
@willmotil
Thx for your reply.
Actually I attempt to understand this tuto, and yes both subject are already open in the browser
but the first topic does not concern me by being in 2.5D.
I do it a little bit differently i make the water quad partially transparent and actually use a normal texture on the water plane for waves and then apply refraction based on the normals to the water quad.
Hi,
Sorry for the late reply, I was working on Photoshop this week.
@ willmotil yeah, I will surely go in this direction after having successfully reflected on water.
So this weekend I have time to try again but the clip () function is already causing me problems.
No matter what I give it as clipPlane vector, either it’s always cut in the middle of the screen or it follows the camera but never at the right distance.
Clip in the vertex shader if i remember right will clip a entire triangle you don’t really want to clip there.
Clip is usually used to not draw a pixel typically when it has a low alpha value ect in the pixel shader.
So if ok if you have plane were your water lays at you can define that as a ray a ray has a position and normal ill denote that as Nw Pw the position lies in your world on the surface of the water the normal sticks up from it perpendicular to the surface. On the pixel shader. You can take each pixel of the triangles you draw in your scene.
Like input.Position ill just denote it as P and then subtract that by the point you passed into the shader Pw (that is a point on your waters surface), to get a direction.
so Dir= P - Pw;
normalize that so DirN = normalize(dir);
Now you have a normal from the surface of your water to the current pixel being drawn in your scene.
You also have a normal that you passed that is a surface normal for the waters plane.
Then by comparison (using a dot product of the two normals) result = dot(DirN, Nw);
You get a value that you can use to clip on one side of the water or the other.
To clip on the other side of the water just flip the sign of DirN aka result = dot(-DirN, Nw);
The resulting value’s sign depends on if the two normals point away from or are in parallel to each other aka above or below the water and so to will be the sign passed to the clip function.
So in the pixel shader you clip out pixels above or below the water plane.
clip(result); // clips pixels when the result value passed is negative.
I tried the clip function to see if it cut the triangles but without results in the vertex shader.
I use this > float clip : SV_ClipDistance0;
with 5_0 shadermodel (doesn’t work on 4_0) and its not clip triangles.
And yes, my fisrt problem was the W distance, now I see my clip but I think I misunderstand something but I don’t no what
I will try your method and I tell you again.
Edit : Do I have to do my calculations in the vertex shader?
In the pixelshader I have an error Shader model ps_4_0_level_9_1 doesn't allow reading from semantics position
No clip either with 5_0
I go back to work
Thanx
To solve my camera problem I simply made a copy of the world matrix and recreate a view matrix.
I don’t know if it’s the best method but it works.
It’s not perfect but it’s finished, some details to settle at my clip, enlarge it a little maybe.
Anyway thank you for your support @willmotil.
I wanted to make a nice video with the final effects and the beautiful textures …
But if my texture is not at position.Y = 0 my reflection is no longer good at all because its always cut at position.Y =0.
I don’t understand why.
float4 dir = input.Position3D - mul(pointW, 1);
float4 dirN = normalize(dir);
float result = dot(-dirN, mul(normalW, 1));
if(clip_)
{
uv.y = 1 - uv.y;
// I need to do this cause of my quadrender (not sure)else I see nothing
clip(-result);
}
Edit : I think its my new view, it doesn’t change my camera angle,not sure after a sleepless night reflectionCameraPosition.Y -= _heightWater * 2.0f; _heightWater = it’s not a position of my water in the world space?
_heightWater = postion.Y water + postion.Y texture its works perfectly.
If someone know why, thank you so much
Sorry I think I have to express myself badly, I really have trouble with English and shaders …
I must miss something logical but I don’t really see what it is.