I'm looking for an water surface effect sample like Pocket pond HD. I have found some tutorials:
iPhone OpenGL demo water waves
Waves effect
However, it's sketchy.
It is very simple.
You just have to make a 2D heightmap (2D array of water height at that particular place). With heightmap, you can calculate (approximate, interpolate) a normal at each place depending on the nearest height points.
Then you perform a "simple raytracing". You "refract each ray" depending on normal, intersect it with plane (bottom) and get a color from texture at that place.
Practically: you make a triangle mesh from height map and render those triangles. You can send normals in Vertex Buffer or compute them in Vertex Shader. Raytracing is done in Fragment Shader. Direction of each ray can be (0, 0, 1). You refract it by current normal and scale the result, so Z coordinate equals water depth. The new X and Y coordinates are texture coordinates.
To make an animation, just update the heightmap in time.
Related
Example of goal:
I see three.js has this example.
It's simply a 3D Cube with many Spheres on its surface.
How can I do something like this using SceneKit?
You could use an array of points, on planes, and place spheres at those locations.
Each plane divide by 10 in both directions (X and Y) and then make six of these planes and rotate them into the cube face positions.
I think performance is probably going to suck, though. This is a lot of polygons, for each of these spheres. Let's imagine each sphere has 200 tris. That's 100x 6x 200 = 1.2 million triangles.
Probably better to use circular textures on quads, placed facing the camera, at each of these 600 points. Then it's only 1200 triangles.
Cheats way to do this:
Create a SCNBox with the number of vertices desired in x, y & z axis.
Then use it as a particle emitter shape, and assign emittance to each vertex at a rate that makes them always appear at these locations, using a small circle texture, and the "look at camera" mode of placard presentation.
here is that cheat, done with particles:
I've been making progress in a fan-replicated game I'm coding, but I'm stuck with this problem.
Right now I'm drawing a texture pixel by pixel on the curve path, but this cuts down frames per second from 4000 to 50 on curves with long lengths.
I need to store pixel by pixel Vector2 + length data anyway, so I can produce static speed movement along it, looping through it to draw the curve as well.
Curves I need to be able to draw are Bezier, Circular and Catmull.
Any ideas of how to make it more efficient?
Maybe I have misunderstood the question but I did this once:
Create the curve and sample x points on it. (Red dots)
Create a mesh from it by calculating the cross vector of each point. (Green lines)
Build a quad between all of these. So basically 5 of them in my picture.
Set the U coordinate to be on the perpendicular plane and V coordinate follows the curve length. So 0 at the start an 1 at the end of it.
You can of course scale V if you want you texture to repeat.
Any ideas of how to make it more efficient?
Assuming the texture needs to be dynamic, draw the texture on the GPU-side using a shader. Drawing it on the CPU-side is not only slow, but bogs down both the CPU and GPU when you need to send it back to the GPU every frame. Much better to draw it GPU-side.
I need to store pixel by pixel Vector2 + length data anyway
The shader can store additional information into the texture. e.g. even though you may allocate a RGBA texture, it doesn't mean that it needs to store color information when it is your shaders that will interpret the data.
I have a mesh that is stored as an array of Vertices with an Index array used to draw it. Four of the vertices are also redrawn with a shader to highlight the points, and the indices for these are stored in another array.
The user can rotate the model using touches, which affects the modelViewMatrix:
modelViewMatrix = GLKMatrix4Multiply(modelViewMatrix, _rotMatrix);
My problem is that I need to detect which of my four highlighted points is closest to the screen when the user makes a rotation.
I think the best method would be to calculate the distance from the near clip of the view frustum to the the point, but how to I calculate those points in the first place?
You can do this easily from camera/eye space[1], where everything is relative to the camera (So, the camera will be at (0, 0, 0) and looking down the negative z axis).
Use your modelViewMatrix to transform the vertex to camera space, say vertex_cs. Then the distance of the vertex from the camera (plane) would simply be the -vertex_cs.z .
--
1. What exactly are eye space coordinates?
In order to debug my shader, I am trying to display the just the front face of the cube map.
The cube map is a 125x750 image with the 6 faces on top of each other:
First, I load the cube map with GLKit:
_cubeTexture = [GLKTextureLoader cubeMapWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"uffizi_cube_map_ios" ofType:#"png"] options:kNilOptions error:&error];
Then I load it into the shader:
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_CUBE_MAP, self.cubeTexture.name);
glUniform1i( glGetUniformLocation( self.shaderProgram, "cube"), 0);
Then in the fragment shader:
gl_FragColor = textureCube(cube, vec3(-1.0+2.0*(gl_FragCoord.x/resolution.x),-1.0+2.0*(gl_FragCoord.y/resolution.y),1.0));
This displays a distorted image which seems to be a portion of the top of the cube map:
It shouldn't be distorted, and it should show the right face, not the top face.
I can't find any documentation that describes how the coordinates map to the cube, so what am I doing wrong?
It seems that there is a problem with cubeMapWithContentsOfFile. The cubeMapWithContentsOfFiles method (the one that takes an array of 6 images) works perfectly on the simulator. (There is a different issue with both methods on device).
To visualize how texture coordinates work for cube maps, picture a cube centered at the origin, with the faces at distance 1 from the origin, and with the specified cube map image on each face.
The texture coordinates can then be seen as direction vectors. Starting at the origin, the 3 components define a vector that can point in any direction. The ray defined by the vector will then intersect one of the 6 cube faces at a given point. This is the point where the corresponding cube map image is sampled during texturing.
For example, take a vector that points in a direction that is closest to the positive z axis. The ray defined by this vector intersects the top face of the cube. Therefore, the top (POSITIVE_Z) image of the cube map is sampled, at the point where the ray intersects the face.
Equivalent rules applies to all other directions. The face corresponding to the largest absolute value of one of the vector components determines which face is sampled, and the intersection point determines the position within the image.
The exact rules and formula can be found in the spec document. For example in the latest spec (OpenGL 4.5), see Section 8.13 "Cube Map Texture Selection", with the matching table 8.19. But as long as you understand that the texture coordinates define a direction vector, you have the main aspect covered.
How you determine the texture coordinates really depends on what you want to achieve. Common cases include:
Using normal vector as the cube map texture coordinates. This can for example be used for pre-computed lighting effects, where the content of the cube map image contains pre-computed lighting results for each possible normal direction.
Using the reflection vector as the cube map texture coordinate. This supports the implementation of environment mapping. The content of the cube map is a picture of the environment.
I would like to move a 3D plane in a 3D space, and have the movement match
the screens pixels so I can snap the plane to the edges of the screen.
I have played around with the focal length, camera position and camera scale,
and I have managed to get a plane to match the screen pixels in terms of size,
however when moving the plane things are not correct anymore.
So basically my current status is that I feed the plane size with values
assuming that I am working with standard 2D graphics.
So if I set the plane size to 128x128, it more or less is viewed as a 2D sqaure with that
exact size.
I am not using and will not use Orthographic view, I am using and will be using Projection view because my application needs some perspective to it.
How can this be calculated?
Does anyone have any links to resources that I can read?
you need to grab the transformation matrices you use in the vertex shader and apply them to the point/some points that represents the plane
that will result in a set of points in -1,-1 to 1,1 (after dividing by w) which you will need to map to the viewport