I'm having an issue to use GLshort for representing Vertex, and Normal - iphone

As my project gets close to optimization stage, I notice that reducing Vertex Metadata could vastly improve the performance of 3D rendering.
Eventually, I've dearly searched around and have found following advices from stackoverflow.
Using GL_SHORT instead of GL_FLOAT in an OpenGL ES vertex array
How do you represent a normal or texture coordinate using GLshorts?
Advice on speeding up OpenGL ES 1.1 on the iPhone
Simple experiments show that switching from "FLOAT" to "SHORT" for vertex and normal isn't tough, but what troubles me is when you're to scale back verticies to their original size (with glScalef), normals are multiplied by the reciprocal of the scale. Natural remedy for this is to multiply the normals w/ scale before you submit to GPU. Then, my short normals almost become 0, because the scale factor is usually smaller than 0. Duh!
How do you use "short" for both vertex and normal at the same time? I've been trying this and that for about a full day, but I could only go for "float vertex w/ byte normal" or "short vertex w/ float normal" so far.
Your help would be truly appreciated.

Can't you just Normalise your normals by calling this?
glEnable( GL_NORMALIZE );
Its not ideal because normalising will likely hit the GPU a bit but it really depends on if your bottleneck is caused by the passing data to the GPU or by the GPU doing too much. As with any optimisation you need to figure out which gives the better speed up. I'd suspect you are probably slowed down by passing the vertex data so you WILL get a speed up.

Possible things to try:
try to counter the scaling by fiddling with the GL_NORMAL matrix
use a vertex shader to perform the calculations as you wish
don't scale your vertex data down, enlarge your camera matrices instead

Related

FPS drops when scale object. How fix? Unity Android

There is an empty scene with one standard cube. If you change its scale to (5;5;1), then the fps does not drop.
But if I change it to (5; 10; 1) my fps drops to ~30.
If I move the camera away from the cube with the scale (5;10;1), then the fps is again 60.
Maybe I have wrong camera settings or something else.
How to achieve high fps without moving the camera away?
p.s. The fps does not drop in the editor. Only after launching on android.
Unity version 2020.3.18f1. Tried on another version same problem.
cube with scale(5;5;1)
cube with scale(5;10;1)
cube with scale(5;10;1) and camera is distant
The problem may be due to the fact that more pixels is rendered (fragment shader is executed for every one) when the object is scaled up. The other hint is that when you move the camera far from the object the frame rate is increased as the rendered object generates fewer pixels.
As you mentioned that the program runs on Android, changing a regular shader to mobile shader may improve the performance.
From some of Unity's documentation on transforms
Performance Issues and Limitations with Non-Uniform Scaling
Non-uniform scaling is when the Scale in a Transform has different values for x, y, and z; for example (2, 4, 2). In contrast, uniform scaling has the same value for x, y, and z; for example (3, 3, 3). Non-uniform scaling can be useful in a few select cases but should be avoided whenever possible.
Non-uniform scaling has a negative impact on rendering performance. In order to transform vertex normals correctly, we transform the mesh on the CPU and create an extra copy of the data. Normally we can keep the mesh shared between instances in graphics memory, but in this case you pay both a CPU and memory cost per instance.
I'm not certain if your Z's scale matters in this case, because you're only rendering the x-y plane. I can't comment for certain on why the performance hit is reduced as you increase your camera distance. I suspect Unity has some intelligent vertex manipulation going on to simplify rendering of distant objects, saving you on CPU cost.
That being said, try to avoid non-uniform scaling. Primitives should typically only be used as placeholders.

The right way to handle procedural LOD, distant terrain chunks

I would really appreciate your thoughts on compute-generated terrain, LOD, etc. and what the 'right way' to do it is.
Here's my current plan:
I'm procedurally generating a large finite world, where at any point most or all of the map is visible.
Texturing/Colouring is done in vert/frag shader.
I'm about 50% through implementing:
Generate the closest chunks (eg a 5x5 heightmap around the player) on the CPU using a noise function.
In the middle distance, using instances of a compute shader to generate the vertices of heightmap chunks and passing buffer to vert/frag shader.
In the far distance, generating 1 huge combined chunk with much less dense vertices and passing to vert/frag.
My questions are:
Is this the (or A) right way to handle LOD/Chunks/Distant terrain?
Should I instead generate everything on the GPU and pass a mesh back to CPU for collision, instead of using CPU for near chunks?
What function should I be using to generate and draw the map? I'm currently using DrawProceduralNow in OnRenderObject().
I'm just starting experimenting with using MaterialPropertyBlocks and DrawProcedural in Update().
One idea is to have semi-autonomous chunks that change their settings depending on player location.
Or relative chunks that are based on the space around the player, so a middle distance chunk will always be a middle LOD (distance between vertices), but the heightmap is updated as the player walks towards it.
I'm trying to avoid spending too much time going down the wrong rabbit hole.
If I can establish the right concepts first, that will save me a lot of time.
Edit: I'm also considering pre-generating heightmap textures to save on procedural calculation time. But that's a moot point, my questions are around what to do after I already have the vertices.

Shader-coding: nonlinear projection models

As I understand it, the standard projection model places an imaginary grid in front of the camera, and for each triangle in the scene, determines which 3 pixels its 3 corners project onto. The color is determined for each of these points, and the fragment shader fills in the rest using interpolation.
My question is this: is it possible to gain control over this projection model? For example, create my own custom distorted uv-grid? Or even just supply my own algorithm:
xyPixelPos_for_Vector3( Vector3 v ) {...}
I'm working in Unity3D, so I think that limits me to cG or openGL.
I did once write a GLES2 shader, but I don't remember ever performing any kind of "ray hits quad" type test to resolve the pixel position of a particular 3D point in space.
I'm going to assume that you want to render 3d images based upon 3d primitives that are defined by vertices. This is not the only way to render images with OpenGL but it is the most common. The technique that you describe sounds much more like Ray-Tracing.
How OpenGL Typically Works:
I wouldn't say that OpenGL creates an imaginary grid. Instead, what it does is take the positions of each of your vertices, and converts them into a different space using linear algebra (Matrices).
If you want to start playing around with this, it would be best to do some reading on Matrices, to understand what the graphics card is doing.
You can easily start warping the positions of Vertices by making a vertex shader. However, there is some setup involved. See the Lighthouse tutorials (http://www.lighthouse3d.com/tutorials/glsl-tutorial/hello-world-in-glsl/) to get started with that! You will also want to read their tutorials on lighting (http://www.lighthouse3d.com/tutorials/glsl-tutorial/lighting/), to create a fully functioning vertex shader which includes a lighting model.
Thankfully, once the shader is set up, you can distort your entire scene to your hearts content. Just remember to do your distortions in the right 'space'. World coordinates are much different than eye coordinates!

iPhone 5S - Possible Depth Buffer issue

In my application, I render plane over plane. Lower plane has Z = 0, second one has Z = 0.5. If I render them (lower first), I got missing part of render, as shown on picture
On iPhone 4 and desktop (using ES emulator), there is everything correct and no problem. What could cause this bevaiour ?
Same problem occurs also for other parts of scene, like tracks, tubes (green and blue on this picture). Problem occurs, when I move camera
Ok... I have solved this. There was problem in my shader that caused depth buffer to be filled incorectly.
I have used
precision mediump float;
and that caused geometry to be not precise and Z = 0 vs Z = 0.5 has been mixed together.
Changing precision to highp solved the issue.
Bottom line. This "optimalization" was huge mistake and never use mediump in Vertex Shader (unless you are facing some performance impact and even that its not worth it. The difference in rendering is not noticable)
(This is in response to your own answer, which is only partially correct)
You've got a case of Z-fighting going on, due to the mapping of your scene's Z values, to the z-buffer. This may be a non-linear mapping (1/f(Z) is common), but I'm not sure on floating point z-buffers.
Your scene is really simple, and while chunking more z-buffer range at the problem is a partial solution, it's at the cost of performance, and not really understanding the issue. You may well run into this same problem again even with the highest possible precision z-buffer you can use on your platform!
Look at your scenes; you want to map the z-range in the 3D scene, to the maximum possible range of values the z-buffer can store, else you're wasting chunks of the range of numbers the z-buffer can store. Calculating this mapping per-frame can be useful, depending on what you want to do with the z-buffer later on.
Have a look here for some calculations. Note, that with a floating point z-buffer, you may well be worse off than with an integer one if you're chucking away a lot of small numbers - that's where the vast majority of possible storable values of a floating point number are!

Is it possible to persistently change the values of a VBO on the iPhone OpenGL ES 2.0 inside a vertex shader?

I am an Opengl ES 2.0 newbie (and GLSL newbie) so forgive me if this is an obvious question.
If I have a VBO that I initialize once on the CPU at the start of my program is it possible to then use vertex shaders to update it each frame without doing calculations on the cpu and then reuploading it to the GPU? Im not referring to sending a uniform and manipulating the data based on that. Instead I mean causing a persistent change in the VBO on the GPU itself.
So the simplest example I can think of would be adding 1 to the x,y and z component of gl_Position in the vertex shader every time the frame is rendered. This would mean that if I had only one vertex and its initial position was set on the cpu to be (0,0,0,1) then after 30 frames it would (30,30,30,1) .
If this is possible what would it look like in code?
On modern desktop hardware (GL3/DX10) you can use transform feedback to write back the output of the vertex or geometry shader into a buffer, but I really doubt that the transform_feedback extension is supported on the iPhone (or in ES in general).
If PBOs are supported (what I also doubt), you can at least do it with some GPU-GPU copies. Just copy the vertex buffer into a texture (by binding it as a PBO), then render a textured fullscreen quad and perform the update in the fragment shader. After that you copy the framebuffer (which now contains the updated vertex data) into the vertex buffer (again by binding it as PBO). But this way you have to do 2 copies (although they should both happen completely on the GPU) and if the vertex data is floating point you will need to floating point render targets and framebuffer objects to be supported, too.
I think in ES the best solution would really be to do the computation on the CPU. Just hold a CPU copy (so you at least have no unneccessary GPU-CPU readback) and update the buffer data every frame (using GL_DYNAMIC_DRAW or even GL_STREAM_DRAW as buffer usage).
Maybe you can also completely prevent the persistent update by making the changes dependent on another simpler data. In your example you could just use a uniform for the frame number and set this as coordinate in the vertex shader every frame, but I don't know how complex your update function really is.