Search Unity

rendering emmisive objects (stars) as minimum one pixel no matter how far away it is

Discussion in 'Shaders' started by gaiastellar, Aug 21, 2017.

  1. gaiastellar

    gaiastellar

    Joined:
    Nov 8, 2013
    Posts:
    57
    dear all,
    im creating a 3d star map, using self illuminated spheres as stars. so far so good, but at a certain distance (500 plus) they disapear, or appear as pixels flickering on and off as the camera moves around.

    does anyone know if there is a way (with a shader perhaps?) to render them as 1 pixel no matter how far away they are?

    this would add to the background light from the mass of distant stars instead of having them disapear...

    any suggestions please?

    many thanks

    paul uk
     
  2. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,348
    Actual sphere geometry? That will be kind of expensive if you've got a lot of stars, and wasteful if they're getting to be smaller than a single pixel. However you could use this to your advantage by expanding the sphere in a shader by the normal direction when it gets far away.

    http://www.humus.name/index.php?page=3D&ID=89

    It might be easier to LOD out the spheres that are far away and replace them with camera facing billboards / particles. Unity's particles have a built in min-size feature, though it's not defined in pixels. What I've done before is used instanced quads that face the camera in the shader, and keep themselves at ~3 pixels wide by knowing their size, distance from the camera, and the fov (from the projection matrix passed to the shader) and calculating a min size. I do 3 pixels rather than 1 because I use a blurred spot texture, like the default particle texture, and it ensure no visible aliasing occurs. Confining it perfectly to a single pixel is possible, but looks less smooth.
     
  3. gaiastellar

    gaiastellar

    Joined:
    Nov 8, 2013
    Posts:
    57
    hi bgolus,
    thanks. great answer.
    im currently getting around 20,000 spheres rendering as self illuminating, many too far away to see(or just single pixels that show up when the camera moves. i tried to use LOD with a lower poly 'sphere' for further distance because i thought it would save some cpu/gpu, and it might enable me to push up the amount of stars, but it seemed to make it worse. im not sure why, perhaps because its holding the info for 2 meshes instead of one on memory even though its only rendering 1. im not sure - i thought if i LOD'ed it , it would help?

    i would love to try LODing with camera facing bilboards/particles, but ive no idea to start with that, or with messing around with shaders - im afraid that's way above my level of comprehension right now. im defo up for learning, but not really sure where to start with that. the reason i want to keep the stars visible at max distances, is because, in some galaxy sims ive seen done with unity, the stars all add to the 'glowing galaxy' effect, even when the the camera is far enough away to see the whole thing. im not sure how they do that?

    perhaps it would be less expensive if i used something different for the stars completely, but tried with point lights with a small halo to make them visible, but performance got better when i used the spheres. also the reason im going down this route is that i wanted to give an idea of different star types/ colour/sizes, and textured spheres seemed to be the way to go with that, but im all open to ideas, but i really want them to glow/ emit, to give a more realistic appearence.

    any ideas where i can go with this?

    thanks for your help,

    paul uk
     
  4. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,348
    The main thing is don't try to LOD 20,000 game objects using Unity's built in LODGroup stuff. You'll want to handle this more manually on your own. Likely purely based on distance, and maybe size. Unity's LODGroup is calculating the approximate screen coverage of the gameobjects' bounds, which for a bunch of spheres is overkill.

    For shader stuff I would start with this:
    http://www.alanzucconi.com/2015/06/10/a-gentle-introduction-to-shaders-in-unity3d/

    That'll get you started with understanding how shaders work. There are plenty of examples of billboard shaders out there you could start with as well. To keep the minimum size you'll need to dig in to that first post, or search online some more. It'll be a bit of a long road to get to where you want to go though.
     
  5. gaiastellar

    gaiastellar

    Joined:
    Nov 8, 2013
    Posts:
    57
    hi bgolus,
    thats great thanks!
    ive got some way to where i need to get to- ive got a working billboard shader, and also a working surface shader for transparency and emmision. they are both short and sweet and work great, but i need to combine them together into one shader. ive tried several times but with no success. btw im going to use star billboards/quads for the whole lot, because thats all i need for the effect im after - and then i'll focus on the minimum size later i think - hopefully using quads will lower gpu and cpu and allow more stars...
    if you can help in any way with combining these 2 simple shaders, that would be awesome. i think they may be different kinds of shaders - one is a vert/frag, and one is a surface shader - can these be combined? im on a steep learning curve and ill learning a lot by seeing it done... im going to make a seperate post about combining these shaders, but any help you can give me would be awesome!
    the two shaders ill post below...

    paul uk
    billboard shader:
    Shader "Cg shader for billboards" {
    Properties {
    _MainTex ("Texture Image", 2D) = "white" {}
    _ScaleX ("Scale X", Float) = 1.0
    _ScaleY ("Scale Y", Float) = 1.0
    }
    SubShader {
    Pass {
    CGPROGRAM
    #pragma vertex vert
    #pragma fragment frag

    // User-specified uniforms
    uniform sampler2D _MainTex;
    uniform float _ScaleX;
    uniform float _ScaleY;

    struct vertexInput {
    float4 vertex : POSITION;
    float4 tex : TEXCOORD0;
    };
    struct vertexOutput {
    float4 pos : SV_POSITION;
    float4 tex : TEXCOORD0;
    };
    vertexOutput vert(vertexInput input)
    {
    vertexOutput output;

    output.pos = mul(UNITY_MATRIX_P,
    mul(UNITY_MATRIX_MV, float4(0.0, 0.0, 0.0, 1.0))
    + float4(input.vertex.x, input.vertex.y, 0.0, 0.0)
    * float4(_ScaleX, _ScaleY, 1.0, 1.0));
    output.tex = input.tex;

    return output;
    }
    float4 frag(vertexOutput input) : COLOR
    {
    return tex2D(_MainTex, float2(input.tex.xy));
    }
    ENDCG
    }
    }
    }

    transparent/ emmisive shader:

    Shader "Transparent/AlphaSelfIllum3" {
    Properties {
    _Color ("Main Color", Color) = (1,1,1,1)
    _MainTex ("Base (RGB) Trans (A)", 2D) = "white" {}
    _EmissionLM ("Emission (Lightmapper)", Float) = 0
    }

    SubShader {
    Tags {"Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent"}
    LOD 200

    CGPROGRAM
    #pragma surface surf Lambert alpha

    sampler2D _MainTex;
    sampler2D _Illum;
    fixed4 _Color;

    struct Input {
    float2 uv_MainTex;
    float2 uv_Illum;
    };

    void surf (Input IN, inout SurfaceOutput o) {
    fixed4 c = tex2D(_MainTex, IN.uv_MainTex) * _Color;
    o.Albedo = c.rgb;
    o.Emission = c.rgb * tex2D(_Illum, IN.uv_Illum).a;
    o.Alpha = c.a;
    }
    ENDCG
    }

    Fallback "Transparent/VertexLit"
    }
     
  6. gaiastellar

    gaiastellar

    Joined:
    Nov 8, 2013
    Posts:
    57
    hi bgolus,
    ive just seen your reply to my other post about combining with the standard shader ! i see someone has written a snippen of a billboard function for a surface shader, so i just need to combine the billboard surface shader with the transparency /emmisive shader. mmm - i'll look into that one!

    thanks paul uk
     
  7. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,348
    If you just need emissive and transparency, don't use a surface shader. The only reason to use a surface shader is if you need it to be lit by other lights.

    Also, you should use code tags when posting code in the forums. Click on the "Insert..." button (the one that looks like a newspaper article icon).
     
  8. gaiastellar

    gaiastellar

    Joined:
    Nov 8, 2013
    Posts:
    57
    Ok thanks.
    I think the only reason I was using a surface shader was because the simple transparency/emmisive shader I found code for was surface, but if I can find a very/frag shader that would make combing the 2 simpler I guess.

    Paul uk