Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

Fastest shader not using any lights ???

Discussion in 'Shaders' started by EducaSoft, Apr 24, 2009.

  1. EducaSoft

    EducaSoft

    Joined:
    Sep 9, 2007
    Posts:
    650
    In the unité videos I heard Aras (or his companion) talk about how to render your meshes with the highest speed.

    For an upcoming project we expect a lot of users to have very low end hardware like those intel gma cards.

    In the unité video there is talk about a shader to render textures which uses NO LIGHTS at all. So I think it just uses the rgb colors of the texture or so.

    Is this shader available somewhere?

    I found this on the forum

    Code (csharp):
    1.  
    2. Shader "Texture Simple" {
    3.    Properties {
    4.       _MainTex ("Base (RGB)", 2D) = "white"
    5.    }
    6.    SubShader {
    7.       Pass {
    8.          SetTexture [_MainTex]
    9.       }
    10.    }
    11. }
    Is this the shader talked about ?
    Is this absolutely the fastest rendering texture of all possible shaders? (with less quality of course)


    Would this be a lot faster then "diffuse fast" on gma cards?



    Regards,

    Bart
     
  2. Aras

    Aras

    Unity Technologies

    Joined:
    Nov 7, 2005
    Posts:
    4,770
    Diffuse Fast is a per-pixel lit shader. So it's much slower than VertexLit.

    If you really don't need any realtime lighting, then the shader you wrote is pretty much as fast as it can get. Unless you don't need textures either, in which case it's possible to make it faster :)
     
  3. EducaSoft

    EducaSoft

    Joined:
    Sep 9, 2007
    Posts:
    650
    So can we say that in terms of render speed (and certainly on lower end 3d solutions) if we order the shaders by speed (and not by quality) we get

    TEXTURE SIMPLE > VERTEXLIT > DIFFUSE FAST > DIFFUSE

    Where ">" means "faster then"?



    And for vertexlit, what does that actually do ? Just take vertex colors inside the mesh and do some gouraud shading with the texture?



    I tried my demo today with texture simple, diffuse fast and diffuse and almost got no difference in fps count. all 3 tests went at around 130fps while displaying 6800tris on a gma950 card.
     
  4. EducaSoft

    EducaSoft

    Joined:
    Sep 9, 2007
    Posts:
    650
    Would it be benificial to include something like "Lighting Off" or "Cull Back" in the shader above? And where should I put these lines?

    I'm trying to really write te fastest possible shader at all. Lighting is not important since I want to display the textures at full color with not lights at all. All faces to be drawn will also be front facing.
     
  5. Aras

    Aras

    Unity Technologies

    Joined:
    Nov 7, 2005
    Posts:
    4,770
    Yes. Some more in the docs.

    At each vertex, it computes the lighting based on the lights that affect the mesh. Then interpolates the lighting color over the triangles and modulates with texture. It is called "vertex lighting" because it computes lighting at vertex level (not at pixel level).

    Of course with VertexLit the performance depends on how many lights you have. Less lights = more performance. Simpler lights = more performance (directional lights are the simplest, and spot lights are the most complex).

    If you need vertex lighting, but don't need specular, it's possible to modify VertexLit shader to turn specular computations off. This should be faster as well.

    Then apparently you haven't reached the bottleneck yet. There can be lots of different bottlenecks; you can be limited by CPU (doing game logic, physics, issuing draw calls or transforming vertices in GMA950 case), can be limited by GPU (various parts of it), by memory bandwitdh and so on. 6800 triangles is not much, I wouldn't expect that to bottleneck CPU or GMA950.

    Lighting is off by default. Culling is on by default. So if you'd add those commands to the shader, they would not change anything.
     
  6. imaginaryhuman

    imaginaryhuman

    Joined:
    Mar 21, 2010
    Posts:
    5,834
    Hey, nice to see something minimal is possible, but I'm actually looking into how to do something even simpler. Sorry to resurrect this old thread (1 year old) but it seems to be pretty much on topic.

    Initially all I want to do is the equivalent of gouraud shading using vertex colors. In OpenGL the code would be glShadeModel(GL_SMOOTH) to switch on vertex color interpolation, and I'd be passing it a vertex array and a color array only. No normals, no texturing, no lighting whatsoever. The vertex colors would be RGBA and I'd need to be able to switch alphablending on and off.

    Would I be better of doing this with a fixed function setup and would fixed function actually be faster at this than using a shader?

    Also I need to do a slight hybrid whereby I need an 8-bit alpha texture (GL_ALPHA8) whose alpha value is used to alphablend the resulting output. So there would be RGBA vertex colors, gouraud/smooth color interpolation, vertex alpha can alphablend, plus a source alpha channel texture provides per-pixel alpha blending. Can that be done without fragment/vertex shaders, and if not, what might such a shader look like?

    Also this is really for flat 2D so is it possible to turn off things like the depth buffer/depth testing to gain some performance when I know there won't be any depth to the scene?

    Thanks in advance.
     
  7. Daniel_Brauer

    Daniel_Brauer

    Unity Technologies

    Joined:
    Aug 11, 2006
    Posts:
    3,355
    Here's vertex colours only:
    Code (csharp):
    1. Shader "Vertex Colors/Solid" {
    2.     SubShader {
    3.         ZWrite Off
    4.         ZTest Always
    5.         Pass {
    6.             BindChannels {
    7.                 Bind "Color", color
    8.                 Bind "Vertex", vertex
    9.             }
    10.         }
    11.     }
    12. }
    And with alpha blending:
    Code (csharp):
    1. Shader "Vertex Colors/Alpha" {
    2.     SubShader {
    3.         ZWrite Off
    4.         ZTest Always
    5.         Blend SrcAlpha OneMinusSrcAlpha
    6.         AlphaTest Greater 0.0
    7.         Pass {
    8.             BindChannels {
    9.                 Bind "Color", color
    10.                 Bind "Vertex", vertex
    11.             }
    12.         }
    13.     }
    14. }
    ...and with an alpha texture:
    Code (csharp):
    1. Shader "Vertex Colors/Alpha Texture" {
    2.     Properties {
    3.         _Alpha ("Opacity (A)", 2D) = "white" {}
    4.     }
    5.     SubShader {
    6.         ZWrite Off
    7.         ZTest Always
    8.         Blend SrcAlpha OneMinusSrcAlpha
    9.         AlphaTest Greater 0.0
    10.         Pass {
    11.             BindChannels {
    12.                 Bind "Color", color
    13.                 Bind "Vertex", vertex
    14.                 Bind "TexCoord", texcoord
    15.             }
    16.             SetTexture[_Alpha] {
    17.                 combine primary, primary*texture
    18.             }
    19.         }
    20.     }
    21. }
    If you're programming for iPhone, remove the AlphaTest lines, as they will slow things down rather than speed them up.
     
  8. imaginaryhuman

    imaginaryhuman

    Joined:
    Mar 21, 2010
    Posts:
    5,834
    Wow, this is great, thank you so much. It looks fairly simple once you've written it out but I'm new to writing shaders so you took a lot of time off my hands. I'll give these a try and see how it goes.

    Just one question... if I want the vertex colors to have smooth shading still and also alpha values, but also want the alpha texture to apply an alphablend, do I just need to add a second texture combiner pass? ie e.g. say my vertices for a triangle have three sets of different RGBA colors, and the alpha in the vertex causes an interpolated alpha fade across the triangle, I also want this effect but at the same time as a per-pixel texture based blend. So do I just need to multiply the alpha texture by the vertex alpha somehow?

    Thanks again.
     
  9. Daniel_Brauer

    Daniel_Brauer

    Unity Technologies

    Joined:
    Aug 11, 2006
    Posts:
    3,355
    If I understand the effect you're trying to get, the third shader already does that. The SetTexture operation uses texture*primary (primary being vertex alpha) to determine the alpha value of a fragment. The vertex alpha is interpolated like the vertex colour, and the texture is interpolated using its import settings.
     
  10. imaginaryhuman

    imaginaryhuman

    Joined:
    Mar 21, 2010
    Posts:
    5,834
    I guess so. I haven't been able to try it yet. I think there needs to be two alpha blends. ... the first is the interpolated alpha based on vertex alpha values, and then after this there needs to be a second transparency operation based on the per-pixel texture alpha. If that's what you're code is doing already then great.

    An example..

    Lets say a vertex is red with full alpha, ie $FF0000FF, and the opposite vertex is blue with half alpha, ie $0000FF80. About halway between the two points will be the interpolated value $800080B0, ie halway between red and blue, and halfway between full alpha and half alpha. If we were to draw this triangle on the screen at this point, with alphablending, the source color $800080 would be scaled to about 3/4 of its value and added to 1/4 of the destination pixel's value, producing a final alphablended pixel.

    But lets say we now introduce an alpha texture which gets applied prior to writing out the final result. After the above process, and prior to actually doing the alphablend, I need to scale the interpolated alpha value based on an alpha texture. So let's say that halway between the vertices is an alpha pixel value of $80, about half intensity. This needs to scale the interpolated alpha value by half, from $B0 to about $68 or so. Then finally there is one alphablend operation between the interpolated pixel color $800080 and the background, using the scaled alpha of $68.

    Did I spell that our clearly enough? Is that what your shader above is doing, ie does it take both vertex alpha and texture alpha into account, or just the texture alpha?

    [Edit] actually after writing this out and re-reading what you just said, it looks like that's what your third code is doing, since it multiplies the texture alpha by the `primary` color ie the vertex alpha, but only for the alpha values, and keeps the RGB without multiplying. It looks like it does what I needed, right?
     
  11. Daniel_Brauer

    Daniel_Brauer

    Unity Technologies

    Joined:
    Aug 11, 2006
    Posts:
    3,355
    That's right. "primary" gets interpolated from the vertices, and then gets its alpha multiplied by "texture". Blending is only done once, at the end, with SrcAlpha being the product of the vertex and texture alphas.
     
  12. imaginaryhuman

    imaginaryhuman

    Joined:
    Mar 21, 2010
    Posts:
    5,834
    Ok good, I'm looking forward to giving this a whirl very soon. It's basically to provide a flat-shaded shape mostly composed of geometry to form the shape but with some highly variegated parts, and only in 2D.
     
  13. imaginaryhuman

    imaginaryhuman

    Joined:
    Mar 21, 2010
    Posts:
    5,834
    I got this shader working last night, with the alpha from the vertex and the alpha from the texture. It works great. Thanks again.

    I did have to tweak it very slightly to make it work, as Unity was giving some errors. I think the main thing was some case sensitivity in the `bind` commands.
     
  14. Daniel_Brauer

    Daniel_Brauer

    Unity Technologies

    Joined:
    Aug 11, 2006
    Posts:
    3,355
    That's strange. All three shaders worked fine as-is on my Mac.
     
  15. imaginaryhuman

    imaginaryhuman

    Joined:
    Mar 21, 2010
    Posts:
    5,834
    Oh well. It's good enough, and working now. Must've been something I messed up or changed without understanding.

    The performance seems pretty good so far, am drawing about 3500 alpha-texture surfaces in the 100-200 fps range.
     
  16. Daniel_Brauer

    Daniel_Brauer

    Unity Technologies

    Joined:
    Aug 11, 2006
    Posts:
    3,355
    Are you batching using sprite manager or something similar?
     
  17. imaginaryhuman

    imaginaryhuman

    Joined:
    Mar 21, 2010
    Posts:
    5,834
    No, I had a bunch of procedurally generated meshes, each with one instance of the material and then used the combine children script.
     
  18. Sep200

    Sep200

    Joined:
    Jul 29, 2013
    Posts:
    13
    I have a problem, this is a little bit transparent for me :/