• Advertisement
  • Popular Tags

  • Popular Now

  • Advertisement
  • Similar Content

    • By Fadey Duh
      Good evening everyone!

      I was wondering if there is something equivalent of  GL_NV_blend_equation_advanced for AMD?
      Basically I'm trying to find more compatible version of it.

      Thank you!
    • By Jens Eckervogt
      Hello guys, 
      Please tell me! 
      How do I know? Why does wavefront not show for me?
      I already checked I have non errors yet.
      using OpenTK; using System.Collections.Generic; using System.IO; using System.Text; namespace Tutorial_08.net.sourceskyboxer { public class WaveFrontLoader { private static List<Vector3> inPositions; private static List<Vector2> inTexcoords; private static List<Vector3> inNormals; private static List<float> positions; private static List<float> texcoords; private static List<int> indices; public static RawModel LoadObjModel(string filename, Loader loader) { inPositions = new List<Vector3>(); inTexcoords = new List<Vector2>(); inNormals = new List<Vector3>(); positions = new List<float>(); texcoords = new List<float>(); indices = new List<int>(); int nextIdx = 0; using (var reader = new StreamReader(File.Open("Contents/" + filename + ".obj", FileMode.Open), Encoding.UTF8)) { string line = reader.ReadLine(); int i = reader.Read(); while (true) { string[] currentLine = line.Split(); if (currentLine[0] == "v") { Vector3 pos = new Vector3(float.Parse(currentLine[1]), float.Parse(currentLine[2]), float.Parse(currentLine[3])); inPositions.Add(pos); if (currentLine[1] == "t") { Vector2 tex = new Vector2(float.Parse(currentLine[1]), float.Parse(currentLine[2])); inTexcoords.Add(tex); } if (currentLine[1] == "n") { Vector3 nom = new Vector3(float.Parse(currentLine[1]), float.Parse(currentLine[2]), float.Parse(currentLine[3])); inNormals.Add(nom); } } if (currentLine[0] == "f") { Vector3 pos = inPositions[0]; positions.Add(pos.X); positions.Add(pos.Y); positions.Add(pos.Z); Vector2 tc = inTexcoords[0]; texcoords.Add(tc.X); texcoords.Add(tc.Y); indices.Add(nextIdx); ++nextIdx; } reader.Close(); return loader.loadToVAO(positions.ToArray(), texcoords.ToArray(), indices.ToArray()); } } } } } And It have tried other method but it can't show for me.  I am mad now. Because any OpenTK developers won't help me.
      Please help me how do I fix.

      And my download (mega.nz) should it is original but I tried no success...
      - Add blend source and png file here I have tried tried,.....  
      PS: Why is our community not active? I wait very longer. Stop to lie me!
      Thanks !
    • By codelyoko373
      I wasn't sure if this would be the right place for a topic like this so sorry if it isn't.
      I'm currently working on a project for Uni using FreeGLUT to make a simple solar system simulation. I've got to the point where I've implemented all the planets and have used a Scene Graph to link them all together. The issue I'm having with now though is basically the planets and moons orbit correctly at their own orbit speeds.
      I'm not really experienced with using matrices for stuff like this so It's likely why I can't figure out how exactly to get it working. This is where I'm applying the transformation matrices, as well as pushing and popping them. This is within the Render function that every planet including the sun and moons will have and run.
      if (tag != "Sun") { glRotatef(orbitAngle, orbitRotation.X, orbitRotation.Y, orbitRotation.Z); } glPushMatrix(); glTranslatef(position.X, position.Y, position.Z); glRotatef(rotationAngle, rotation.X, rotation.Y, rotation.Z); glScalef(scale.X, scale.Y, scale.Z); glDrawElements(GL_TRIANGLES, mesh->indiceCount, GL_UNSIGNED_SHORT, mesh->indices); if (tag != "Sun") { glPopMatrix(); } The "If(tag != "Sun")" parts are my attempts are getting the planets to orbit correctly though it likely isn't the way I'm meant to be doing it. So I was wondering if someone would be able to help me? As I really don't have an idea on what I would do to get it working. Using the if statement is truthfully the closest I've got to it working but there are still weird effects like the planets orbiting faster then they should depending on the number of planets actually be updated/rendered.
    • By Jens Eckervogt
      Hello everyone, 
      I have problem with texture
      using System; using OpenTK; using OpenTK.Input; using OpenTK.Graphics; using OpenTK.Graphics.OpenGL4; using System.Drawing; using System.Reflection; namespace Tutorial_05 { class Game : GameWindow { private static int WIDTH = 1200; private static int HEIGHT = 720; private static KeyboardState keyState; private int vaoID; private int vboID; private int iboID; private Vector3[] vertices = { new Vector3(-0.5f, 0.5f, 0.0f), // V0 new Vector3(-0.5f, -0.5f, 0.0f), // V1 new Vector3(0.5f, -0.5f, 0.0f), // V2 new Vector3(0.5f, 0.5f, 0.0f) // V3 }; private Vector2[] texcoords = { new Vector2(0, 0), new Vector2(0, 1), new Vector2(1, 1), new Vector2(1, 0) }; private int[] indices = { 0, 1, 3, 3, 1, 2 }; private string vertsrc = @"#version 450 core in vec3 position; in vec2 textureCoords; out vec2 pass_textureCoords; void main(void) { gl_Position = vec4(position, 1.0); pass_textureCoords = textureCoords; }"; private string fragsrc = @"#version 450 core in vec2 pass_textureCoords; out vec4 out_color; uniform sampler2D textureSampler; void main(void) { out_color = texture(textureSampler, pass_textureCoords); }"; private int programID; private int vertexShaderID; private int fragmentShaderID; private int textureID; private Bitmap texsrc; public Game() : base(WIDTH, HEIGHT, GraphicsMode.Default, "Tutorial 05 - Texturing", GameWindowFlags.Default, DisplayDevice.Default, 4, 5, GraphicsContextFlags.Default) { } protected override void OnLoad(EventArgs e) { base.OnLoad(e); CursorVisible = true; GL.GenVertexArrays(1, out vaoID); GL.BindVertexArray(vaoID); GL.GenBuffers(1, out vboID); GL.BindBuffer(BufferTarget.ArrayBuffer, vboID); GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(vertices.Length * Vector3.SizeInBytes), vertices, BufferUsageHint.StaticDraw); GL.GenBuffers(1, out iboID); GL.BindBuffer(BufferTarget.ElementArrayBuffer, iboID); GL.BufferData(BufferTarget.ElementArrayBuffer, (IntPtr)(indices.Length * sizeof(int)), indices, BufferUsageHint.StaticDraw); vertexShaderID = GL.CreateShader(ShaderType.VertexShader); GL.ShaderSource(vertexShaderID, vertsrc); GL.CompileShader(vertexShaderID); fragmentShaderID = GL.CreateShader(ShaderType.FragmentShader); GL.ShaderSource(fragmentShaderID, fragsrc); GL.CompileShader(fragmentShaderID); programID = GL.CreateProgram(); GL.AttachShader(programID, vertexShaderID); GL.AttachShader(programID, fragmentShaderID); GL.LinkProgram(programID); // Loading texture from embedded resource texsrc = new Bitmap(Assembly.GetEntryAssembly().GetManifestResourceStream("Tutorial_05.example.png")); textureID = GL.GenTexture(); GL.BindTexture(TextureTarget.Texture2D, textureID); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)All.Linear); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)All.Linear); GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, texsrc.Width, texsrc.Height, 0, PixelFormat.Bgra, PixelType.UnsignedByte, IntPtr.Zero); System.Drawing.Imaging.BitmapData bitmap_data = texsrc.LockBits(new Rectangle(0, 0, texsrc.Width, texsrc.Height), System.Drawing.Imaging.ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppRgb); GL.TexSubImage2D(TextureTarget.Texture2D, 0, 0, 0, texsrc.Width, texsrc.Height, PixelFormat.Bgra, PixelType.UnsignedByte, bitmap_data.Scan0); texsrc.UnlockBits(bitmap_data); GL.Enable(EnableCap.Texture2D); GL.BufferData(BufferTarget.TextureBuffer, (IntPtr)(texcoords.Length * Vector2.SizeInBytes), texcoords, BufferUsageHint.StaticDraw); GL.BindAttribLocation(programID, 0, "position"); GL.BindAttribLocation(programID, 1, "textureCoords"); } protected override void OnResize(EventArgs e) { base.OnResize(e); GL.Viewport(0, 0, ClientRectangle.Width, ClientRectangle.Height); } protected override void OnUpdateFrame(FrameEventArgs e) { base.OnUpdateFrame(e); keyState = Keyboard.GetState(); if (keyState.IsKeyDown(Key.Escape)) { Exit(); } } protected override void OnRenderFrame(FrameEventArgs e) { base.OnRenderFrame(e); // Prepare for background GL.Clear(ClearBufferMask.ColorBufferBit); GL.ClearColor(Color4.Red); // Draw traingles GL.EnableVertexAttribArray(0); GL.EnableVertexAttribArray(1); GL.BindVertexArray(vaoID); GL.UseProgram(programID); GL.BindBuffer(BufferTarget.ArrayBuffer, vboID); GL.VertexAttribPointer(0, 3, VertexAttribPointerType.Float, false, 0, IntPtr.Zero); GL.ActiveTexture(TextureUnit.Texture0); GL.BindTexture(TextureTarget.Texture3D, textureID); GL.BindBuffer(BufferTarget.ElementArrayBuffer, iboID); GL.DrawElements(BeginMode.Triangles, indices.Length, DrawElementsType.UnsignedInt, 0); GL.DisableVertexAttribArray(0); GL.DisableVertexAttribArray(1); SwapBuffers(); } protected override void OnClosed(EventArgs e) { base.OnClosed(e); GL.DeleteVertexArray(vaoID); GL.DeleteBuffer(vboID); } } } I can not remember where do I add GL.Uniform2();
    • By Jens Eckervogt
      Hello everyone
      For @80bserver8 nice job - I have found Google search. How did you port from Javascript WebGL to C# OpenTK.?
      I have been searched Google but it shows f***ing Unity 3D. I really want know how do I understand I want start with OpenTK But I want know where is porting of Javascript and C#?
  • Advertisement
  • Advertisement
Sign in to follow this  

OpenGL Variable lights count

This topic is 557 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi All


I've an array of Light structures in my shaders. Typically user works with several lights only but sometimes can add tenths or more. If I set light elements count to maximum possible (limited by GL_ MAX_FRAGMENT_UNIFORM_COMPONENTS) then drawing becomes very slow. What is a standard solution here (OpenGL vers = 2.1) ?  Should I generate different shaders for different lights count ot there are other ways?


Thank you



Share this post

Link to post
Share on other sites
If you go for forward lighting, you can create several permutations with different numbers of lights. Using defines. For example: 1, 2, 4 or 8.

Where the number of lights should only be lights affecting the rendering/ draw call for that renderable. With some basic bounding sphere checks you should be generally OK with max 8. Terrain might need splitting up a bit more (or precalculated light maps or just directional light).

Share this post

Link to post
Share on other sites

Draw with multiple passes; this is the way Doom 3 did it, which used OpenGL and was targetted to a similar GL version.


First pass was a depth-only pre-pass and the screen was cleared to black.

Then enable additive blending (glBlendFunc (GL_ONE, GL_ONE);)

Then each subsequent pass draws one light and one light only, adding the contribution for each light into the framebuffer.


It's all about tradeoffs; you use a single shader irrespective of number of lights which means fewer state changes and keeping the shader instruction count down, in exchange for more draw calls and extra blend passes.  It also makes it easier to integrate shadows if you're planning on doing so in future.

Share this post

Link to post
Share on other sites

As mhagain said, doing it with multiple passes is reasonable as long as  you don't end with too many lights... If you can know what objects are impacted by each light, then you can expect some gain with rendering only impacted objects for each light.


If you can use the FBO extension, then you can try deferred shading but this is a good idea when you reach a certain amount of lights.

Edited by _Silence_

Share this post

Link to post
Share on other sites

Thanks for replies. Multi-pass (for lighting) is the code I just killed ;-) It worked but required too much support code here and there, so I'm happy to get rid of it. Now I generate shader(s) for each count of light. I understand not everything has a simple solution



Share this post

Link to post
Share on other sites

Many lights are always problematic, and while several trade-offs have already been mentioned, there is no single perfect solution.


TL;DR: I would personally try some flavour of deferred shading or a kind of cross-breed (Engel's light pre-pass), and batch something like 8 or so lights together per pass (not sure about the GL2.1 fragment shader limitations any more, this stuff is sooooo old, but 8 lights should be easily possible? I think fragment shader still had at least 65535 instructions back then?). If you can do more than 8 per pass, do that. Do not ever change whatever number of max lights per pass you choose. Or if you do, only between frames, ever. If your number of lights is not divisible by 8, do the last pass with e.g. 7 lights that are "zero" in the worst case. ALU is still way more affordable than everything else.

Changing shaders is super, super expensive (...this even used to cause, at some point, recompile/re-link on GL2 nVidia hardware! Yay! Surprise!), and dynamic branching on GL2 hardware is either non-present or extremely, painfully slow.

Thus, doing one pass with 8 lights followed by one with 3 lights is almost certainly going to kill you. Rather do two passes with 8 lights (and 5 lights in the second pass set to zero).


Doing an assumed 8 lights per pass (and also assuming "many lights" means something like 20 or 30, not 1,500) should let you get away with one, maybe two fullscreen quads (or having to render the scene three times instead of once with light pre-pass), which is not precisely constant, but "constant enough for all practical purposes", and most likely as good as you can get batch-wise, memory-wise, and bandwidth-wise.


What options do you have at all?


Multipass all lights? Works, straighforward, and consistent, predictable results. Only just, if you truly have a lot of lights, you die.

Hard limit the number of lights? Sure, that way you guarantee performance never gets worse than so-and-so-much. But once you hit the cap, lights pop in and out and it looks like shit.


Build subsets? Multipass subsets? Fast, and works great, except you have to be careful about subsets changing, or lights/subsets changing order. Wait a moment. Popping in and out, OK... but order? Light is a purely additive thing, so order does not matter, right?


There's a quote from Snepscheut that fits here: The difference between theory and practice is that in theory they are the same whereas in practice they are not. (I'll admit that a piece of wisdom coming from a man who flipped and died burning down his own house trying to kill his wife and children may seem debatable... but I think the quote is very much to the point anyway). Order shouldn't matter, but sometimes it does. With some luck you don't notice at all when two different frames come out with inconsistent lighting, but quite possibly it's visually disturbing, too.


Light indexed deferred rendering is a once-great idea which works kinda well (actually it doesn't strictly need to be deferred, does it?). Until... until you accidentially have a scene where some pixels are hit by more lights than your limit (which is set by how many indices you can squeeze into a pixel). At that point, you are in "be lucky" land again. Maybe nobody even notices, if you are lucky.

It sure isn't the method of choice for modern hardware, but either way, I really liked that idea when it was published. It kinda seemed to combine the advantages of forward and deferred, it was not too terribly expensive (I remember running it fluidly fullscreen with several dozen of lights on GF6 cards back then) and for most "sane" scenes you were unlikely to run into the limitations at any point in the scene. Not sure why it never really caught any momentum. Probably because it wasn't long after that light prepass came out.


Forward or deferred? Any kind of "forward" is usually better because of memory consumption for G-buffers, and bandwidth, and not hitting precision issues so easily in forward (8-bit color, 8-bit normals, and 16-bit depth is not that terribly great, but in the end you have to see what will fit in memory!), and of course because it "just works". And, uh, transparency, MSAA... you name it.


On the other hand, N objects with L lights (where L > some small implementation limit) on a M sized screen is something like O(NxL) draw-call wise, and something like O(M2xLxN) fragments. Which sounds nasty, and for big numbers it does get nasty, too.

Deferred separates the number of fragments that need to be shaded from the number of objects (and, in some not-totally-correct way, from the number of lights, too... if you can batch them together in 1-2 passes, which is "kinda constant"). Plus, you have consistent lighting throughout the entire scene. Yay, big win. But it is such an awful, ugly fat memory hog, and you simply can't afford to store the precision needed in your buffers, at least not on 10 year old hardware. And then of course there's that thing with transparency... but since you are targetting super-old hardware, I guess huge amounts of transparency are not much of a thing anyway. Then again, light prepass does without the ugly fat buffers at the expense of having to render some geometry twice...


In absence of compute shaders (GL 2.1) any flavour of tiled rendering (forward or deferred) is likely going to be out of the discussion simply because it's way too complicated, and way too many round trips with stalls. Otherwise, it's pretty nice either way (forward or deferred) it has no real disadvantages (well, no serious ones, in my opinion). But... I don't know... maybe still worth trying some sort into some coarse screenspace grid (maybe rendering into 8 or 16 smaller viewports with fewer lights each?), though I assume it will kill you...

Edited by samoth

Share this post

Link to post
Share on other sites
Sign in to follow this  

  • Advertisement