- Home /
Order dependent transparency, shaders (planet atmosphere rendering)
Hello.
I'm attempting to achieve an atmosphere effect on a planet (simple sphere primative) by a billboard / quad with an RGBA blended texture displayed in front of the sphere.
To get the best sizing for the quad, its positioned at the sphere center, and rendered with a custom shader which has Z-test always. A script orients the quad to look at the camera.
However, my atmospheres for planets are all drawn on top even if another planet/sphere should obscure an atmosphere (as expected).
I need to draw the most distant planet from the camera first, then its atmosphere, then the next nearest and so on. I've looked at render queues but this only allows changes to the order for all at once (eg: drawing all atmospheres last).
How do I achieve this render order? Do I need to manually calculate planet/camera distance (not too bad), but how do I set the render order? can I do that with render queues? This doesn't seem to be the right way.
Regards Matt
Answer by Pangamini · Dec 19, 2016 at 09:34 AM
You may try and create a quad mesh with pivot offset (the quad not passing through [0;0;0] point, but being moved backwards a bit, resulting in the actual pivot distance of the atmosphere mesh being closer to the camera than the planet's pivot. Then keep planets and atmospheres in the same renderQueue (transparent one, ofc) and let the sorting by depth do the rest
That was my initial approach. And it works with respect to transparency ordering.
However having the quad closer to the camera causes sizing and parallax issues when the camera gets closer. I've tried to resolve these by dynamically sizing the quad depending on the camera distance, however its very fiddly and requires so much tweaking that I gave up on that approach.
If its the only way, I'll look again.
Ah no you misunderstood - you need to create a new quad mesh that will have the offset baked in. Then you can just put the visible quad exactly where it's supposed to be, but with the pivot sticking out so it's rendered later
Answer by gibber10 · Dec 27, 2016 at 05:03 AM
In the end I wrote a surface shader for a sphere that surrounds the planet. It uses the dot product of viewDir and the normal then manipulates that number to calculate the transparency.
The shader is shown below in case anyone finds this thread. There will certainly be much better ways to get the effect to appear on the rim of the sphere other than uses sin / cos like this, but the principle is sound I think. You have to tweak the values in the inspector quite a bit to get the desired effect.
Shader "Atmosphere2" {
Properties{
_RimColor("_Color", Color) = (0.26,0.19,0.16,0.0)
_RimPower("_RimPower", Range(-8.0,8.0)) = 3.0
_SinFactor("_SinFactor", Range(-10.0,10.0)) = 7.0
_CosFactor("_CosFactor", Range(-10.0,10.0)) = 7.0
_SinOffset("_SinOffset", Range(-10.0,10.0)) = -4.0
_CosOffset("_CosOffset", Range(-10.0,10.0)) = -4.0
_SinFrequency("_SinFrequency", Range(-10.0,10.0)) = 1.0
_CosFrequency("_CosFrequency", Range(-10.0,10.0)) = 1.0
}
SubShader{
Tags{ "Queue" = "Transparent" "RenderType" = "Transparent" }
LOD 200
ZWrite Off
//Blend SrcAlpha OneMinusSrcAlpha
CGPROGRAM
#pragma surface surf Lambert alpha
struct Input {
float3 viewDir;
};
float4 _RimColor;
float _RimPower;
float _SinFactor;
float _CosFactor;
float _SinOffset;
float _CosOffset;
float _SinFrequency;
float _CosFrequency;
void surf(Input IN, inout SurfaceOutput o) {
float vdot = dot(normalize(IN.viewDir), o.Normal);
float cosdot = _SinOffset + cos(vdot * _SinFrequency) * _SinFactor;
float sindot = _CosOffset + sin(vdot * _CosFrequency) * _CosFactor;
half rim = cosdot * sindot;
o.Albedo = _RimColor.rgb;
o.Alpha = pow(rim, _RimPower) * rim * _RimColor.a;
//o.Emission = _RimColor.rgb * rim;
}
ENDCG
}
Fallback "Diffuse"
}
Your answer
Follow this Question
Related Questions
Why does the 3D Text shader show specular at certain angles? 2 Answers
Two transparent objects passing through each other problem 1 Answer
Can I make any parts of an object inside a partially transparent object fully invisible? 1 Answer
Unity System Fog Access 0 Answers
Add Color Property to Unlit Alpha? 1 Answer