Positional light shader code in OpenGL ES2.0? - ios

Does anyone know of a good source for writing positional light code in OpenGL ES2?
All the tutorials I have seen expect your model to be at the world center (0,0,0), and the light is affecting that.
Although this might be useful in many cases, how about lights that can exist anywhere in the world? That is a lot more useful to me. :)
I am more looking for the shader code to implement this, but the current target platform is iOS with C++.

I googled "fragment shader spot light" and got the first page. It doesn't have a reflection effect but it does have positions and directions (you can use or throw out any).
Though I would suggest you to write your own shader depending on your specific needs and search web for effects you want as internet is overflowing with them.
Also you wrote that the model is in center and then applied that the light is in center. Anyway, to get the effect of light being elsewhere just use the uniform with light position and subtract that vector from the pixel position (describing the object position in light position coordinates) and use the result with the part of the shader relevant to light.

Related

Proper way to illuminate a 2D surface in 3D space?

EDIT: I've solved the issue below the tilde line -- the missing chunks -- by fixing an elementary error in my for-loop dealing with calculating face normals. I now have a new problem though: strange, unwanted shadows on the surface itself. Some areas appear darker than others... See the next picture for the current issue.
I have an omni light added to my scene's root node as well as a directional light added in the same manner. For some reason I can't seem to light the underbelly of the surface otherwise. Notice the strange shadow on the inside of the concave surface (it's more pronounced when I remove the subdivision effect as I have done here) -->
Here is the surface from above -- notice how some areas seem strangely darker.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
This is a concave surface.
I have these smooth, curved planes in 3D space. Right now, they look rather cartoonish -- I would like to utilize some form of lighting to make them look more "3D-ish."
I have tried various combinations of ambient lighting, omni lighting, and default lighting, but nothing seems to work right. I get something quite strange when I apply something like a basic omni light --
Here is another look at a better angle using omni lighting. Looks like someone took a bite out of it --
Am I overlooking a specific type of light or lighting strategy?
I'd like to avoid used baked lighting, because the scene is rather simple. Thanks.
I'll outline my steps for the bold.
1: I specify the vertices for each of the four faces of a pyramid-like shape. Like this (apologies for my lack of artistic ability) -->
2: I specify the indices for the face, i.e., [0,1,2, 0,2,3, etc.]
I create a dictionary mapping each vertex to the sum of that vertex's adjacent, normalized face normals.
I append each of these summed up normalized per-vertex normals to a vector.
I combine the vertices, indices, and vector of normals to create an SCN Geometry.
To get the rounded look, I increase the subdivision count.
Pray that it works.
I'm new to the 3D world, so I could be way out in left field and not even know it.
This should give you a reasonable result with minimal effort and the least possible need to understand 3D lighting.
Open the Fox game example/sample from Apple:
https://developer.apple.com/library/prerelease/ios/samplecode/Fox/Introduction/Intro.html
Delete everything from the level.scn Scene Graph other than Lights, Camera and the Mountain.
And then add your geometry object to a node at the bottom, where I have the sphere highlighted at the bottom of the Scene Graph....
Now the material needs a bit of work, to make it useful.
Select the Mountain by clicking on it in the View, and goto the material editor and make it look like this, just keep checking against this image until yours matches the few (weird) changes I've made. And trust me this will work out fine:
When you want to get that lovely red you have, you simply change this property: DIFFUSE : It's right at the top of the Material settings.
Now you have a material and lighting setup that gives a reasonable approximation of curvature in a 3D space.
Applying this material to your object is a little weird, and unintuitive, you go here, and click on the add button, and pick the material with the same name as the one in the above image, that’s on the mountain.
You can improve this by adding two more lights in what’s known as a “3 point lighting setup”, google this phrase to see it explained.
Further, you can add off screen (out of camera) placards, usually white, to manage key reflections to further assist in users getting a feel for what’s being presented.

HLSL How to properly outline a flat-shaded model

I have a question and hope you can help me with it. I've been busy making a game with xna and have recently started getting into shaders (hlsl). There's this shader that i like, use, and would like to improve.
The shader creates an outline by drawing the back faces of a model (in black), and translating the vertex along its normal. Now, for a smooth-shaded model, this is fine. I, however, am using flat-shaded models (I'm posting this from my phone, but if anyone is confused about what that means, I can upload a picture later). This means that the vertices are translated along the normal of its corresponding face, resulting in visible gaps between the faces.
Now, the question is: is there a way to calculate (either in the shader or in xna), how i should translate each vertex, or is the only viable option just making a copy of the 3d model, but with smooth shading?
Thanks in advance, hope you can educate me!
EDIT: Alternatively, I could load only a smooth-shaded model, and try to flat-shade it in the shader. That would, however, mean that I have to be able to find the normals of all vertices of the corresponding face, add their normals, and normalize the result. Is there a way to do this?
EDIT2: So far, I've found a few options that don't seem to work in the end: setting "shademode" in hlsl is now deprecated. Setting the fillmode to "wireframe" would be neat (while culling front faces), if only I would be able to set the line thickness.
I'm working on a new idea here. I could maybe iterate through vertices, find their position on the screen, and draw 2d lines between those points using something like the RoundLine library. I'm going to try this, and see if it works.
Ok, I've been working on this problem for a while and found something that works quite nicely.
Instead doing a lot of complex mathematics to draw 2d lines at the right depth, I simply did the following:
Set a rasterizer state that culls front faces, draws in wireframe, and has a slightly negative depth bias.
Now draw the model in all black (I modified my shader for this)
Set a rasterizer state that culls back faces, draws in fillmode.solid and has a 0 depth bias.
Now draw the model normally.
Since we can't change the thickness of wireframe lines, we're left with a very slim outline. For my purposes, this was actually not too bad.
I hope this information is useful to somebody later on.

Directional Lights

I'm working on a game idea (2D) that needs directional lights. Basically I want to add light sources that can be moved and the light rays interact with the other bodies on the scene.
What I'm doing right now is some test where using sensors (box2d) and ccDrawLine I could achieve something similar to what I want. Basically I send a bunch of sensors from certain point and with raycast detect collisions, get the end points and draw lines over the sensors.
Just want to get some opinions if this is a good way of doing this or is other better options to build something like this?
Also I would like to know how to make a light effect over this area (sensors area) to provide a better looking light effect. Any ideas?
I can think of one cool looking effect you could apply. Put some particles inside the area where light is visible, like sparks shining and falling down very slowly, something like on this picture
Any approach to this problem would need to use collision detection anyway so your is pretty nice providing you have limited number of box2d objects.
Other approach when you have a lot of box2d objects I would think of is to render your screen to texture with just solid colors (should be fast) and perform ray tracing on that generated texture to find pixels that are going to be affected by light. That way you are limited to resolution not the number of box2d objects.
There is a good source code here about dynamic and static lights in a 2D space.
It's Ruby code but easy to understand so it shouldn't be long to port it to Obj-C/Cocos2D/box2D.
I really hope it will help you as it helped me.
Hm, interesting question. Cocos2D does provide some rather flexible masking effects. You could have a gradient mask that you lay over your objects, where its position depends on the position of the "light", thereby giving the effect that your objects were being coloured by the light.

DirectX Lighting

Hi. I've got a small game using directX10 and C++. However, I started making it using the meshloaderfromOBJ10 direct X sample and I have just been building on it. However, my objects are all looking just plain black althought they have colour.
I know this is because of the light, but seemingly changing any of the code to do with the light does nothing from this sample.
I was wondering if anyone knows a simple(ish) method to just light everything, as in make it bright everywhere. I don't care about shadows or reflection or anything like that as for what I'm doing it is not necessary but it would be nice to see my objects instead of just silhouettes.
Cheers.
However, my objects are all looking just plain black althought they have colour.
If shader expects texture to be set and reads material information from that texture, and you set null texture to corresponding texture stage(sampler or whatever it is called in DX10), shader will read black color from that null texture. And black material without specular/emissive or reflection mapping will always look black, no matter how many lights you use.
Use white texture on materials/objects without texture (assuming your shader understands material color and multiplies it with texture color). Or switch to DX9 and use fixed-function pipeline which treats missing textures as white. Or modify the shader to support materials without texture.
method to just light everything, as in make it bright everywhere
You can use "global" ambient (which you'll have to add in your shader, because D3D10 doesn't have fixed function pipeline). However, you don't really want it, because
I don't care about shadows
you actually care about shadows just don't know it yet. global ambient value will make all materials evenly colored without any gradients. It means that if you have an untextured complicated mesh, you won't be able to figure out what you're looking at and everything that is textured will look ugly. Also, black materials will still remain black. So to "make it bright everywhere", you'll need "sun" - directional light source or a very big point light.

How do I make the lights stay fixed in the world with Direct3D

I've been using OpenGL for years, but after trying to use D3D for the first time, I wasted a significant amount of time trying figure out how to make my scene lights stay fixed in the world rather than fixed on my objects.
In OpenGL light positions get transformed just like everything else with the MODELVIEW matrix, so to get lights fixed in space, you set up your MODELVIEW the way you want for the lights, and call glLightPosition then set it up for your geometry and make geometry calls. In D3D that doesn't help.
(Comment -- I eventually figured out the answer to this one, but I couldn't find anything helpful on the web or in the MSDN. It would have saved me a few hours of head scratching if I could have found this answer then.)
The answer I discovered eventually was that while OpenGL only has its one amalgamated MODELVIEW matrix, in D3D the "world" and "view" transforms are kept separate, and placing lights seems to be the major reason for this. So the answer is you use D3DTS_VIEW to set up matrices that should apply to your lights, and D3DTS_WORLD to set up matrices that apply to the placement of your geometry in the world.
So actually the D3D system kinda makes more sense than the OpenGL way. It allows you to specify your light positions whenever and wherever the heck you feel like it once and for all, without having to constantly reposition them so that they get transformed by your current "view" transform. OpenGL has to work that way because it simply doesn't know what you think your "view" is vs your "model". It's all just a modelview to GL.
(Comment - apologies if I'm not supposed to answer my own questions here, but this was a real question that I had a few weeks ago and thought it was worth posting here to help others making the shift from OpenGL to D3D. Basic overviews of the D3D lighting and rendering pipeline seem hard to come by.)
For the fixed function pipeline, the lights position and direction are set in world space. The docs for the light structures do tell you that, but I'm not surprised that you missed it in the docs. There's not much information on the fixed function pipeline anymore as the focus has to programmable shaders.

Resources