I have a need for setting up clipping planes that aren't perpendicular to the camera. Doing that for the far plane was easy: I just added a shader that clears the background.
I just can't figure out how to do the same for the near clipping plane. I've tried to think of solutions dealing with multiple shaders and planes, a special cutting shader, having multiple cameras for this or somehow storing the view as a texture, but those ideas are mostly imperfect even if they were implementable. What I basically need is a shader that would say "don't render anything that's in front of me". Is that possible? Can I eg. make a shader to make the passed pixels "final"?
Related
I've mocked up what I am trying to accomplish in the image below - trying to pinch the pixels in towards the center of an AR marker so when I overlay AR content the AR marker is less noticeable.
I am looking for some examples or tutorials that I can reference to start to learn how to create a shader to distort the texture but I am coming up with nothing.
What's the best way to accomplish this?
This can be achieved using GrabPass.
From the manual:
GrabPass is a special pass type - it grabs the contents of the screen where the object is about to be drawn into a texture. This texture can be used in subsequent passes to do advanced image based effects.
The way distortion effects work is basically that you render the contents of the GrabPass texture on top of your mesh, except with its UVs distorted. A common way of doing this (for effects such as heat distortion or shockwaves) is to render a billboarded plane with a normal map on it, where the normal map controls how much the UVs for the background sample are distorted. This works by transforming the normal from world space to screen space, multiplying it with a strength value, and applying it to the UV. There is a good example of such a shader here. You can also technically use any mesh and use its vertex normal for the displacement in a similar way.
Apart from normal mapped planes, another way of achieving this effect would be to pass in the screen-space position of the tracker into the shader using Shader.SetGlobalVector. Then, inside your shader, you can calculate the vector between your fragment and the object and use that to offset the UV, possibly using some remap function (like squaring the distance). For instance, you can use float2 uv_displace = normalize(delta) * saturate(1 - length(delta)).
If you want to control exactly how and when this effect is applied, make it so that has ZTest and ZWrite set to Off, and then set the render queue to be after the background but before your tracker.
For AR apps, it is likely possible to avoid the preformance overhead from using GrabPass by using the camera background texture instead of a GrabPass texture. You can try looking inside your camera background script to see how it passes over the camera texture to the shader and try to replicate that.
Here are two videos demonstrating how GrabPass works:
https://www.youtube.com/watch?v=OgsdGhY-TWM
https://www.youtube.com/watch?v=aX7wIp-r48c
I'm looking for ways to clip an entire unity scene to a set of 4 planes. This is for an AR game, where I want to be able to zoom into a terrain, yet still have it only take up a given amount of space on a table (i.e: not extend over the edges of the table).
Thus far I've got clipping working as I want for the terrain and a water effect:
The above shows a much larger terrain being clipped to the size of the table. The other scene objects aren't clipped, since they use unmodifed standard shaders.
Here's a pic showing the terrain clipping in the editor.
You can see the clipping planes around the visible part of the terrain, and that other objects (trees etc) are not clipped and appear off the edge of the table.
The way I've done it involves adding parameters to each shader to define the clipping planes. This means customizing every shader I want to clip, which was fine when I was considering just terrain.
While this works, I'm not sure it's a great approach for hundreds of scene objects. I would need to modify whatever shaders I'm using, and then I'd have to be setting additional shader parameters every update for every object.
Not being an expert in Unity, I'm wondering if there are other approaches that are not "per shader" based that I might investigate?
The end goal is to render a scene within the bounds of some plane.
One easy way would be to use Box Colliders as triggers on each side of your plane. You could then turn off Renderers on objects staying in the trigger with OnTriggerEnter/OnTriggerStay and turn them on with OnTriggerExit.
You can also use Bounds.Contains.
How would i go about creating as a background for a 3d scene a plane with a texture that stretches into the horzon? I have tried a skybox but i think a skybox will also be needed "behind" the infinite plane.
It depends whether you need to have an actual geometry that will be seen from close up - if not, you can bake it into the skybox.
In some cases (i.e. when the user has stereoscopic display on their head) you will need to have actual geometry.
Its not exactly clear from your question if you want to create a 'floor' or a 'wall', but in both cases I would link it with player position somehow. A floor could follow players X an Z, while a 'wall' could be made a child to the camera, this way it would never leave the viewport.
Skybox would still be the cheapest by a significant margin, we can give more advice if you provide some additional information. i.e. what are you trying to achieve
I’ve read this article http://www.gamasutra.com/blogs/BrianKehrer/20160125/264161/VR_Distortion_Correction_using_Vertex_Displacement.php
about distortion correction with vertex displacement in VR. Moreover, there are some words about other ways of distortion correction. I use unity for my experiments(and try to modify fibrum sdk, but it does not matter in my question because I only want to understand how these methods work in general).
As I mentioned there are three ways of doing this correction:
Using Pixel-based shader.
Projecting the render target onto a warped mesh - and rendering the final output to the screen.
Vertex displacement method
I understand how the pixel-based shader works. However, I don’t understand others.
The first question is about projection render target onto a warped mesh. As I understand, I should firstly render image from game cameras to 2(for each eye) tessellated quads, then apply shader with correction to this quads and then draw quads in front of main camera. But I’m afraid, I’m wrong.
The second one is about vertex displacement. Should I simply apply shader(that translate vertex coordinates of every object from world-space into inverse-lens distorted & screenspace(lens space)) to camera?
p.s. Sorry for my terrible English, I just want to understand how it works.
For the third method (vertex displacement), yes. That's exactly what you do. However, you must be careful because this is a non-linear transformation, and it won't be properly interpolated between vertices. You need your meshes to be reasonably tessellated for this technique to work properly. Otherwiese, long edges may be displayed as distorted curves, and you can potentially have z-fighting issues too. Here you can see a good description of the technique.
For the warped distortion mesh, this is how it goes. You render the screen, without distortion, to a render texture. Usually, this texture is bigger than your real screen resolution to compensate for effects of distortion on the apparent resolution. Then you create a tessellated quad, distort its vertices, and render it to screen using the texture. Since these vertices are distorted, it will distort your image.
I'm working on an Android and iPhone app. I'm rendering lots of smallish (about 32 pixels) billboards to the screen for a particle system and want to give a glitter-like sparkle to each billboard e.g. as the particles are falling, random ones will briefly light up and sparkle as they catch the light. Is there a simple way to achieve this effect? As a limitation, I cannot use pixel/vertex shaders.
I was thinking something along the lines of a giving each billboard metal-like lighting effect (although I'm not sure how to do this part) coupled with giving each billboard a random and constantly rotating normal with flat shading so that each billboard would randomly light up. I'm having trouble making it look nice.
Disclaimer: I don't know OpenGL, and I did't actually try anything I write below.
You can have another, 'brightly lit', texture and substitute it when normal is nearly at the 'shine' position.
Take a piece of metal and rotate it. Once the normal is close to 'full shine' position, the metal shines a bit brighter, and a muted reflex travels through it, with a bright flash in the middle, then it is dull again.
If you can, apply a second bright texture of a narrow 'reflex' band and move it through surface of the billboards that are in a near-shine position, shifting them accordingly to normal angle. When the normal is at the shine position (± epsilon), apply the 'full shine' texture.
Also, unless your plates fly in vacuum, there will be a halo due to atmosphere. Add a rectangle say 50% bigger than the plate right behind it, and apply to it a semi-transparent halo texture that becomes fully transparent closer to edges. You only need it at the fill shine moment.