What's new
  • Most issues reported these days stem from users not enabling their emulators to use the required amount of RAM.
    We also tend not to use the search feature but post our issues within the texture pack release page.
    Failure to load a texture pack should not be posted in the release thread unless you have already patched the emulator.

    If you don't have the resources to use Large/HD texture packs please do not attempt to do so.
    Users should have a minimum amount of System RAM not less then 4GB's.
    If you have less then 4GB's of RAM do not post about how your emulator crashes,
    RAM is dirt cheap so invest some money into your PC.

    I would like to say thanks to squall_leonhart
    for posting this Solution.

I wish ... someone to implement ... Cel-shading

Elite Knight

Nintedo Fan Mad
Thats what i was sorta thinking and the colour is to dark from the other green all it needs is a shade of darkness not a huge ammout i have no idear on how to make cell shader textures but i know what cell shader looks like if he toned it down. Also it could be the 3d model most N64 models dont have textures like in Super Mario 64 it has 6 textures on mario the rest is polyes mabey thats the reason.
 
Last edited:

Risio

Vectrex Fanboy
Someone needs to get in touch with Mudlord. I'd be interested to see what he could do with Orkins plugin, provided that the source is availible.
 

Mollymutt

Member
I talked about cell shading with Mudlord over at homebrewheaven. He doesn't seem interested in it at all. I wouldn't count on him helping out on this issue.
 

Gonetz

Plugin Developer (GlideN64)
After careful examination of the article, I found, that implementing this technique for N64 graphics plugin is VERY simple, unless I miss something important. All lighting calculations are already done as described in the article, so the only thing we should do is to use a value from the Sharp Lighting Map instead of light’s color.

Cite from Cel-Shading Textures section:
1. Load the Sharp Lighting map from file and store in an array (remember to convert values to a range of 0-1).
2. Calculate the lighting as normal, but multiply the dot product by the width of the texture - 1 (remember 0-15), and cast it to an integer.
3. When drawing, lookup the color to use in the Sharp Lighting map array, using the lighting value as the index.
4. Use this value for the red, green and blue values of the vertex color.
5. Render the object like you would normally, but remember to update the color for each vertex. Don't forget to disable lighting, etc.

Here is my code:

//Load the Sharp Lighting map from file and store in an array
BYTE shade_light_map[16] = {90, 90, 90, 180, 180, 180, 180, 180, 255, 255, 255, 255, 255, 255, 255, 255};

void calc_celshade_light (VERTEX *v)
{
float light_intensity = 0.0f;
//Calculate the lighting as normal
for (DWORD l=0; l<rdp.num_lights; l++)
{
float dp = DotProduct (rdp.light_vector[l], v->vec);
/*if we have another light lighting that vertex, you compare the existing lighting value with the newly created one. If the new light value is higher, then replace the existing one with that. If it's darker, then ignore it. That's just another stupidly simple trick that will make your scene look nicer*/
if (dp > light_intensity)
light_intensity = dp;
}
if (light_intensity > 1.0f)
light_intensity = 1.0f;

// multiply the dot product by the width of the texture - 1 (remember 0-15), and cast it to an integer.
int index = (int)(light_intensity * 15.0f);
// When drawing, lookup the color to use in the Sharp Lighting map array, using the lighting value as the index.
// Use this value for the red, green and blue values of the vertex color.
v->r = v->g = v->b = shade_light_map[index];
//Now Render the object like you would normally
}

Just call it instead of standard calc_light, and you will get your cel-shading.
This can be implemented with any plugin, 5 min of work.

Currently it looks terrible. Sometimes it looks like good cel-shading, but most of time it looks like khaki – all in dark and light spots.

It’s just a test. You may adjust brightness by changing values in the light map array. You may make it less sharp. Also, this cel-shading probably will look better with outlines, which I did not implement.

And of course, I might just miss something.
 
Last edited:

Djipi

Zelda CelShade Producer
simply great !!!!!!! Hope Rice plug , (mudlord then ) and your will have this code with Good adjust

i'm just excited to see my celda project and mario's one this this . It would be great too to implement black line for a best cell shading render.

Hope to see that soon.
 
Last edited:

mudlord

Banned
I talked about cell shading with Mudlord over at homebrewheaven. He doesn't seem interested in it at all. I wouldn't count on him helping out on this issue.

Its not a issue, all it is, is just a additional light calc pass. The main reason I wasn't interested is because personally its a superficial change, and nothing really significant.

Looks like though all we are doing is interfering with light calculations on a ucode level. Jabo thought of this idea a while back, I'm glad its back to the spotlight.

Also, this cel-shading probably will look better with outlines, which I did not implement.

Easy to do, or you could just use a edge detection shader to do it.
 

Driscol

annoying you for over a year!
its only a little bit of code, it might increase the size, by a few bytes? and it shouldnt be to hard or take to long to get it working.
 

mudlord

Banned
its only a little bit of code, it might increase the size, by a few bytes? and it shouldnt be to hard or take to long to get it working.

Exactly, its only a few bytes.

I found the function LightVert() controls how light operates, and the dot product is already calculated, so it shouldnt take to long to do a derative implementation.

Bad to listen that Mudlord :-(

Well, I might change my mind. Though personally, I don't really like cel shading, but bleh, if people want it....
 

Djipi

Zelda CelShade Producer
Sure we want it ^^ . Mudlord , i really love your plug , sincerely , and if you can implement e cell shading with blackline option , it would be great^^
 

Elite Knight

Nintedo Fan Mad
Problem for people who dont have shadders in there card i do but just some people dont to it wont work for people without shadders.
 

Driscol

annoying you for over a year!
also if your updating your plugin, how hard is it to reset the textures with a button? as its tedious to keep on opening and closing the tab.
 

mudlord

Banned
Bingo!!!!

Thanks Gonetz for the idea! :)

I did some modifications, Rice, to how ambient lighting is handled. I found calculating the dot product by doing a square root instead of using:

Code:
CosT = norm.x*gRSPlights[l].x + norm.y*gRSPlights[l].y + norm.z*gRSPlights[l].z;

really helps with lighting quality (as in, lighting is much more realistic than to how you did it previously, plus, it looks nicer imho).

Though, heres proof of it working with Gonetz's idea..

celmicrocode.jpg
 

Djipi

Zelda CelShade Producer
WONDERFULL !!! Jsut more dark for the black and no white filter and it will be great^^^^^^
 
OP
Rice

Rice

Emulator Developer
After careful examination of the article, I found, that implementing this technique for N64 graphics plugin is VERY simple, unless I miss something important. All lighting calculations are already done as described in the article, so the only thing we should do is to use a value from the Sharp Lighting Map instead of light’s color.

Cite from Cel-Shading Textures section:
1. Load the Sharp Lighting map from file and store in an array (remember to convert values to a range of 0-1).
2. Calculate the lighting as normal, but multiply the dot product by the width of the texture - 1 (remember 0-15), and cast it to an integer.
3. When drawing, lookup the color to use in the Sharp Lighting map array, using the lighting value as the index.
4. Use this value for the red, green and blue values of the vertex color.
5. Render the object like you would normally, but remember to update the color for each vertex. Don't forget to disable lighting, etc.

Here is my code:

//Load the Sharp Lighting map from file and store in an array
BYTE shade_light_map[16] = {90, 90, 90, 180, 180, 180, 180, 180, 255, 255, 255, 255, 255, 255, 255, 255};

void calc_celshade_light (VERTEX *v)
{
float light_intensity = 0.0f;
//Calculate the lighting as normal
for (DWORD l=0; l<rdp.num_lights; l++)
{
float dp = DotProduct (rdp.light_vector[l], v->vec);
/*if we have another light lighting that vertex, you compare the existing lighting value with the newly created one. If the new light value is higher, then replace the existing one with that. If it's darker, then ignore it. That's just another stupidly simple trick that will make your scene look nicer*/
if (dp > light_intensity)
light_intensity = dp;
}
if (light_intensity > 1.0f)
light_intensity = 1.0f;

// multiply the dot product by the width of the texture - 1 (remember 0-15), and cast it to an integer.
int index = (int)(light_intensity * 15.0f);
// When drawing, lookup the color to use in the Sharp Lighting map array, using the lighting value as the index.
// Use this value for the red, green and blue values of the vertex color.
v->r = v->g = v->b = shade_light_map[index];
//Now Render the object like you would normally
}

Just call it instead of standard calc_light, and you will get your cel-shading.
This can be implemented with any plugin, 5 min of work.

Currently it looks terrible. Sometimes it looks like good cel-shading, but most of time it looks like khaki – all in dark and light spots.

It’s just a test. You may adjust brightness by changing values in the light map array. You may make it less sharp. Also, this cel-shading probably will look better with outlines, which I did not implement.

And of course, I might just miss something.


Gonetz, I thought to do something similar to your implementation which uses RGB color values (still 0 to 255 in your array) from the sharp lighting map as the new RGB color of the vertex. I didn't implement it because I lately figured out this is not correct.

By doing this, you will be interpolating between the RGB values of the three vertexes defining a triangle to get the RGB values for all points inside the triangle, which is gouraud shading, not cel-shading. You will have too many RGB color levels for the triangle because of the interpolation computation. We should have only very limited number of RGB levels for any triangles for cel-shading.

The correct way to do cel-shading should be through texture mapping, as suggested by the Sami "MENTAL" Hamlaoui's article.


We should

1) Create a texture for the lighting map
2) Compute the texture coordinates for every vertex using the original lighting RGB values for the vertex
3) disable lighting
4) update the color combiner setting, so that the lighting map texture will be used in places where the vertex RGB was used


Rice
 
OP
Rice

Rice

Emulator Developer
To continue my discussion about the implementation in my last post.

The way I suggested (or suggested by Sami "MENTAL" Hamlaoui's article) is actually only the principle. It works only for one color, not really work for R+G+B three colors.

We are using R+G+B colors for the games, then one 1D sharp lighting texture won't be enough.

I am not 100% sure about my following ideas yet:

1) Create a 3D RGB sharping lighting texture. Yes, a 3D color texture, not a 1D grayscale texture. The dimension of the 3D texture should be 16x16x16. (See the end of this post about how to define the RGB values for every voxels in this 3D texture)
2) Use the original lighting RGB values for a vertex to compute the texture coordinates s, t and u.
3) Disable lighting, use the new 3D RGB texture to replace the original vertex RGB in the color combiner setting.

I thought that most good video cards support 3D texture. at least for the video cards that support pixel shader functions.

Edit 1: I found that ATI cards later than Rage 128 support 3D texture mapping. Nvidia cards need to be newer than Geforce 2 MX.



The way to compose the 3D RGB sharp lighting texture:
1) The texture is to be composed according to the similar way as the 1D texture
2) Each voxel of the 3D texture will have R, G and B values
3) The 3 dimensions s, t and u represent the 1D 16x1 grayscale lighting map
4) In the s direction, the R values change according to the array suggested by Gonetz, in the t direction, the G values change, and the B values change in the u direction.



I am still trying to figure out a way to do RGB cel-shading without using a 3D texture. We really should have looked at the Orkin's source code.


Rice
 
Last edited:

KoolSmoky

Member
Hi, my first post :) I'm a newbie with N64 emulation, so I might be missing something important, but, how about multiplying a 1D sharp lighting texture to the surface? Multitexturing is need, obviously.

1) Create a 1D sharp lighting texture.
2) Compute the coordinates of the 1D texture for every vertex using the dot product between the normal and the lighting direction.
3) Disable lighting.
4) Draw the polygons using the orignal RGB color, coordinate, texture (if any), and blend the sharp lighting texture by multiplication.

I see that Gonetz's implementation does exactly as Sami "MENTAL" Hamlaoui's article in the "Cel-Shading Textures" section says. Unfortunately, that section of the article is incorrect, as the RGB values for all points inside the triangle will be interpolated between the RGB values of the three vertex defining a triangle with gouraud shading, just as Rice pointed out. I guess flat shading wouldn't work either because it would be too blocky for coarse polygoned models.

-KoolSmoky
 

mdtauk

Zelda Hi-Res Texturer
Is there any way in the programming to seperate the background environment geometry and the objects and characters? If so, the background should have static lighting, with a very subtle shading in the cel-style, where as the characters and objects should have a much stronger shading. If we are aiming for the Wind Waker form of cel-shading
 

Top