Need help with simple 3D shading

This is a pick of when the CamAngle starts at 0 and is rotated to 45(ish)
http://t.co/s2ivXRxqFy

And this one is when the game starts with CamAngle at 45
http://t.co/3KBThgKRvb

Hope that helps a little.

How do you link the ‘variables’ to the color in your code?

are you using a shader, or setting the colors when you build the mesh?

what you need to do is set the colors to your base color, then use shaders to light your object.

Have you looked at the Shader demos yet? If not, I’ll try to grab something later.

@tomxp411 I think you are right. I have the colors set when the mesh builds. how would I change this?? Im using ms:color(1,CamAngle,255-CamAngle,CamAngle,255) when the mesh is being set up. Is there another way to do it where it doesn’t just run at startup?

as for shaders, I haven’t dove into them at all yet… They kind of confuse me

Use a shader. This is really what shaders are for.

In your shader, you define an attribute:

attribute vec3 normal;

Then each vertex gets a normal vector. So for a cube, each vertex would have the normal vector of the face that it is part of (remember that vertex =/= corner in this situation as each corner is repeated several times in the vertices and it will have several possible normal vectors).

You also need a uniform light vector, and a varying shade.

uniform vec3 light;
varying lowp float shade;

Then in the main for the vertex shader, you use the normals to compute the amount of light shining on that face:

lowp vec4 nor = modelViewProjection * vec4(normal,0);
vShade = (dot(nor.xyz, light) + 2.)/3.

(This ensures that even the back faces have some light.)

In the fragment shader you simply use vShade to adjust the colour:

col.rgb *= vShade;

With that, then the colour on the shape adjusts as it is moved.

@Andrew_Stacey I don’t know if it is just me, but that went straight over my head…

I’m fairly new at codea (not new at coding) and the introduction of shaders has caught me off guard… If you know any good tutorials, that would help a lot!

as for the code you posted, I have no idea how to implement it. I created a new shader and copied what it says, and it threw errors at me like there was no tomorrow.

When creating a shader, codea automatically gives 3 tabs at the top and a bunch of code, and I haven’t the slightest idea on what to do from there.

I explain shaders here
http://coolcodea.wordpress.com/category/shaders/page/2/
http://coolcodea.wordpress.com/category/shaders/

Is there a way that I can just move that part of the code somewhere where it can be run continually? That way I wouldn’t have to use shaders

@Ignatz I started to get the hang of shaders. Thanks!

I was also wondering if cartoon shaders would be possible. By that, I mean shaders like borderlands. I guess the proper term is cell shaders.

here is an example

http://www.minecraftforum.net/topic/1720766-glsl-shaderpack-naelegos-cel-shaders/

I want those too. I have a great camera app called ToonCamera and I’ve been trying to replicate its effects. You can get a basic toon effect by greatly reducing the colour palette, eg by rounding every colour value to a multiple of 50, and one of the built in shaders does that (posterize) but that’s not very good.

I’ve looked at pages like this
http://www.lighthouse3d.com/tutorials/glsl-tutorial/toon-shading/
But it’s pretty hard stuff…

Even just the outline effect would be cool!

After I understand shaders more, I might try it out a little.

Honestly, shaders really are simple. A shader is just a little function that colors one pixel at a time. Seriously: check out the shader examples in Codea. If you’ve already got the math to calculate normals, you have the mental horsepower you need.

Actually, I’m surprised there’s not a 3D lighting shader already in the library…

@tomxp411 - feel free to write one! :smiley:

@Ignatz toon shader link is a good start, but that is the color flattening effect, ie coloring it with fewer colors and becoming a little blocky. This is relatively straight forward although it does rely on first having a lighting model. (also note the example is full openGL and not OpenGL ES)

But, it doesn’t sort out the black highlighting of borders which is a key part of the cartoon look. As far as I know I believe this can only be done by a 2 pass shading approach, where the first pass sorts out the colors and the second does the borders. One problem in codea is if you do a first pass to an offscreen buffer then you don’t have a depth part to the buffer, so you can’t do borders. However you can hack around it, I did a 2 pass shader for shadows and I encoded the depth in the off screen buffer into the alpha channel and it was workable.

But 2 pass shaders are another level of complexity so not necessarily a first project thing to do.

@spacemonkey - I would love to have a really simple diffuse example, because I’m trying to build a 3D lunar landing game. I have created 3D terrain but it needs shadows to emphasize the hills.

So far, my efforts at creating a diffuse light shader, based on something I think you did, just produce a very blocky black and white result. I’ve even calculated normals by averaging them for across all the surrounding vertices for greater accuracy, but it still looks awful.

Any suggestions?

@Ignatz is your terrain a fixed terrain (ie it doesn’t move the vertices around at run time)? I haven’t touched Codea for weeks because I’ve been maxed out on other things, but I might have a play this weekend. I should be able to do something.

For normals to get a smooth effect you broadly need to: 1) Calculate the lighting in the fragment shader so it differs per pixel. 2) calculate your normals at the vertices based on the average normal for the triangles surrounding that vertex. 3) let the normal varying shader gubbins interpolate your normals for the points between vertices, but renormalise it in the fragment shader before applying the lighting as the interpolation will change it from the unit length.

Doing something simple should be fairly straight forward.

@Ignatz the last time I wrote a shader was 6 years ago, and it was in c++… but I’ll pull out that old project and take a look at it. If I can I’ll get a sample up for other people to look at.

@ignatz point (2) of @spacemonkey makes smooth shadows, it is the one i used to get that.

Okay, so I think this is the right file. I took a game programming class as an elective when I was getting my CS degree, and all I really learned from it was how to write a shader… which I promptly forgot. =)

Anyway, this is the shader from my homework project. I can translate it in to something usable in Codea tonight, but for now, here’s the raw shader code:


void vertex( 
  float4 position : POSITION,
  float4 normal   : NORMAL,
  float4 color    : COLOR,
  
  uniform float4   rootPosition,
  uniform float4x4 projection,
  uniform float4x4 modelView,
  uniform float4   lightPosition1,
  
  out     float4   outNormal            : TEXCOORD0,
  out     float4   fragPos              : TEXCOORD1,
  out     float4   outColor             : COLOR,
  out     float4   outPosition          : POSITION)
{   
  outPosition = mul(projection, position);
  outColor=color;

  normal.w=0;
  outNormal=normalize(normal);
  fragPos=rootPosition+position;
}

void fragment(
  float4 normal            : TEXCOORD0,
  float4 fragPos           : TEXCOORD1,
  float4 diffuseColor      : COLOR,           // diffuse color
  uniform float4   ambientColor,
  uniform float4   specularColor,
  uniform float    shine,
  uniform float4   dirLightDirection,
  uniform float4   dirLightColor,
  uniform float4   lightPosition1,
  uniform float4   lightColor1,
  uniform float4   lightPosition2,
  uniform float4   lightColor2,
  uniform float4   viewPos,
  out     float4   outColor)
{
  float4 lightVec=0;
  float4 reflectAngle=0;
  float4 lightValue;
  float4 viewVec; 
  float aten;
  float  specularLevel=0;
  normal.w=0;  
  fragPos.w=0;
  dirLightDirection.w=0;
  lightPosition1.w=0;

  viewVec=normalize(viewPos-fragPos);

  // directional light
  lightVec=normalize(dirLightDirection);
  float level=dot(normal,normalize(dirLightDirection));
  lightValue=level * dirLightColor * diffuseColor;
  // directional light specular highlight
  reflectAngle=(2*level*normal)-lightVec;  // specular angle
  specularLevel=max((level>0) * dot(reflectAngle,viewVec),0);
  float4 dirLight = 
   lightValue + pow(specularLevel,shine) * specularColor * dirLightColor;

  // point light 1
  lightVec=normalize(lightPosition1 - fragPos);
  level=max(dot(normal,lightVec),0);  // amplitude of the light
  aten=1/(1+length(lightPosition1-fragPos)); 
  lightValue=level * aten * diffuseColor; // get the color of the light
  
  // specular color
  reflectAngle=(2*level*normal)-lightVec;  // specular angle
  specularLevel=max((level>0) * dot(reflectAngle,viewVec),0);
  float4 light1=lightValue+pow(specularLevel,shine) * specularColor * lightColor1;

  // point light 2
  lightVec=normalize(lightPosition2 - fragPos);
  level=max(dot(normal,lightVec),0);  // amplitude of the light
  aten=1/(1+length(lightPosition2-fragPos)); 
  lightValue=level * aten * diffuseColor; // get the color of the light
  
  // specular color
  reflectAngle=(2*level*normal)-lightVec;  // specular angle
  specularLevel=max((level>0) * dot(reflectAngle,viewVec),0);
  float4 light2=lightValue+pow(specularLevel,shine) * specularColor * lightColor2;

  outColor = (ambientColor * diffuseColor) + dirLight+light1+light2;
  //outColor = light2;
}

Obviously, this is a bit more complex than the simple lighting model the OP was asking for: you can trim this down to a single light source, if you want.

Feel free to use this any way you want if it’s at all helpful.