Long shadow with fragment shader - webgl

What's the best/simplest way to generate a long shadow similar to this with a fragment shader?
Thanks!

Related

Does Metal support anything like glDepthRange()?

I'm writing some metal code that draws a skybox. I'd like for the depth output by the vertex shader to always be 1, but of course, I'd also like the vertices to be drawn in their correct positions.
In OpenGL, you could use glDepthRange(1,1) to have the depth always be written out as 1.0 in this scenario. I don't see anything similar in Metal. Does such a thing exist? If not, is there another way to always output 1.0 as the depth from the vertex shader?
What I'm trying to accomplish is drawing the scenery first and then drawing the skybox to avoid overdraw. If I just set the z component of the outgoing vertex to 1.0, then the geometry doesn't draw correctly, obviously. What are my options here?
Looks like you can specify the fragment shader output (return value) format roughly so:
struct MyFragmentOutput {
// color attachment 0
float4 color_att [[color(0)]];
// depth attachment
float depth_att [[depth(depth_argument)]]
}
as seen in the section "Fragment Function Output Attributes" on page 88 of the Metal Shading Language Specification (https://developer.apple.com/metal/Metal-Shading-Language-Specification.pdf). Looks like any is a working value for depth_argument (see here for more: In metal how to clear the depth buffer or the stencil buffer?)
Then you would set you fragment shader to use that format
fragment MyFragmentOutput interestingShaderFragment
// instead of: fragment float4 interestingShaderFragment
and finally just write to the depth buffer in your fragment shader:
MyFragmentOutput out;
out.color_att = float(rgb_color_here, 1.0);
out.depth_att = 1.0;
return out;
Tested and it worked.

how to set back face color of a 3D square in Metalkit?

while using metalkit for an iOS application to draw a 3D square. I'd like the square to have different color on front face and back face. How do I do with this? any code examples?
Well, the color of anything is not "set", it's whatever is produced by your fragment shader. So, you would make your fragment shader produce a different color if the primitive is drawn back-facing. To determine that, use the [[front_facing]] attribute on a bool input parameter to your fragment shader and check that parameter's value in your shader logic.

Optimize Fragment Shader

I want to optimize the fragment shader performance. Currently my fragment shader is
fragment half4 fragmen_shader_texture(VertexOutTexture vIn [[stage_in]],
texture2d<half> texture [[texture(0)]]){
constexpr sampler defaultSampler;
half4 color = half4(texture.sample(defaultSampler, vIn.textureCoordinates));
return color;
}
The task of this is to return the texture color. Anyway to optimize more than this.
No options for optimizing the fragment shader AFAICT, it's doing virtually nothing other than sampling the texture. However, depending on your situation, there still might be scope for optimization by:
Reducing bandwidth usage by using a more compact texture format (565 or 4444 instead of 8888, or better still 4-bit or 2-bit PVRTC).
Making sure that alpha blending is disabled if alpha blending is not required.
If the texture has lots of 'empty space' (e.g. think particle texture with a central circular blob and blank corners) then you could make sure the geometry fits it more tightly by rendering it as an Octagon rather than as a quad for instance.
Enable mipmapping if there's any possibility the image can be minimized. Disable more expensive mipmapping options like trilinear/anisotropic filtering.

Reading variable from vertex shader for rendering in webgl

I want to implement a collision detector between a moving and a static object. The way I am thinking of doing so is by checking in vertex shader every time if any vertex of the moving object intersects with the position of the static object.
By doing the above, I would get the point of collision in the vertex shader, but I want to use the variable for rendering purposes in the js file.
Is there a way to do it.
In WebGL 1 you can not directly read any data from a vertex shader. The best you can do is use the vertex shader to affect the pixels rendered in the fragment shader. So you could for example set gl_Position so nothing is rendered if it fails your test and a single pixel is rendered if the test passes. Or you can set some varying that sets certain colors based on your test results. Then you can either read the pixel with gl.readPixels or you can just pass the texture you wrote to to another shader in a different draw calls.
In WebGL2 you can use transform feedback to allow a vertex shader to write its varyings to a buffer. You can then use that buffer in other draw calls or read it's contents with gl.getSubBuffer
In WebGL2 you can also do occlusion queries which means you can try to draw something and test if it was actually drawn or if the depth buffer prevented it from being drawn.

WebGL texture2DLod alternative?

I'm writing texture atlas on the fragment shader and I really need to use texture2DLod in order to render the textures correctly in different mip levels. I just found out that WebGL only supports texture2DLod on the vertex shader. Is there some way for me to access texture2DLod on the fragment shader? Perhaps I could use a custom function that does the same?
Simply use texture2D with the third parameter set to the lod you want to use:
gl_FragColor = texture2D(map, uv, lod)

Resources