How to achieve flat shading without texture? [SOLVED]

If you are a new Irrlicht Engine user, and have a newbie-question, this is the forum for you. You may also post general programming questions here.
Post Reply
Wodzu
Posts: 27
Joined: Wed May 07, 2014 5:41 pm

How to achieve flat shading without texture? [SOLVED]

Post by Wodzu »

Hi guys,

Today I wanted to ask is it possible to have a flat shading without texture on mesh? Currently I do not want to be disctracted by the textures, I would like to see only flat shading of my mesh on solid color.

For example, take a look at this:

I had to add random texture for this two meshes because otherwise I do not have shading and evertything looks "flat".

Image

By flat shading I mean this:

Image


So, I would like to get rid of texture from my mesh and leave only solid color with this shading.

Currently I do:

Code: Select all

 
driver->setTextureCreationFlag(video::ETCF_ALWAYS_32_BIT, true);
//....
 
IAnimatedMesh* mesh = smgr->getMesh(device->getFileSystem()->getWorkingDirectory() + "//Debug//test.ywf");
IAnimatedMeshSceneNode* node = smgr->addAnimatedMeshSceneNode(mesh);
node->setMaterialFlag(EMF_LIGHTING, false);
 
node->setMaterialTexture(0,
    driver->getTexture("E:\\CODING\\Developement\\C++\\Libs\\irrlicht-1.8.1\\media\\stones.jpg"));
node->setMaterialType(video::EMT_SOLID);
 

How to change this code to achieve the desired effect?

Thanks.
Last edited by Wodzu on Wed Feb 11, 2015 5:53 pm, edited 1 time in total.
mongoose7
Posts: 1227
Joined: Wed Apr 06, 2011 12:13 pm

Re: How to achieve flat shading without texture?

Post by mongoose7 »

I just looked through the material types and there is none for vertex colour, they all require at least one texture.

But you could use a paint program and create a texture which has a solid colour throughout.
Wodzu
Posts: 27
Joined: Wed May 07, 2014 5:41 pm

Re: How to achieve flat shading without texture?

Post by Wodzu »

mongoose7 wrote:I just looked through the material types and there is none for vertex colour, they all require at least one texture.
Thank you for that :)
mongoose7 wrote: But you could use a paint program and create a texture which has a solid colour throughout.
I was thinking about that but even if I do this I will end up having a smooth shading and I would like to have this flat shading as on the image with blue sphere.
thanhle
Posts: 325
Joined: Wed Jun 12, 2013 8:09 am

Re: How to achieve flat shading without texture?

Post by thanhle »

I think for flat shading you would do:

sceneNode->setMaterialFlag(E_MATERIAL_FLAG::EMF_GOURAUD_SHADING, false);

Regards
thanh
Wodzu
Posts: 27
Joined: Wed May 07, 2014 5:41 pm

Re: How to achieve flat shading without texture?

Post by Wodzu »

thanhle wrote:I think for flat shading you would do:

sceneNode->setMaterialFlag(E_MATERIAL_FLAG::EMF_GOURAUD_SHADING, false);

Regards
thanh
Unfortunately setting this causes no effect.
mongoose7
Posts: 1227
Joined: Wed Apr 06, 2011 12:13 pm

Re: How to achieve flat shading without texture?

Post by mongoose7 »

You need to set it to "true" you know?
thanhle
Posts: 325
Joined: Wed Jun 12, 2013 8:09 am

Re: How to achieve flat shading without texture?

Post by thanhle »

Hi Mate,

Try below: I think it needs light to show correctly. I wish Irrlicht have option where you don't need to turn light on to show flat, Gouraud or Phong shade.

sceneNode->setMaterialFlag(video::EMF_LIGHTING, true);
sceneNode->setMaterialFlag(video::EMF_GOURAUD_SHADING, false);
sceneNode->setMaterialFlag(video::EMF_NORMALIZE_NORMALS, true);

If I have any normal error with the mesh.
Then I would do the following:

smgr->getMeshManipulator()->recalculateNormals(sceneNode->getMesh(), true, true);

Goodluck
thanh
hendu
Posts: 2600
Joined: Sat Dec 18, 2010 12:53 pm

Re: How to achieve flat shading without texture?

Post by hendu »

From the GL spec:
the computed color of a vertex is the result of lighting if lighting is enabled, or it is the current color at the time the vertex was specified if lighting is disabled.
It's silly to expect a lighted result without lighting ;)
Wodzu
Posts: 27
Joined: Wed May 07, 2014 5:41 pm

Re: How to achieve flat shading without texture?

Post by Wodzu »

thanhle wrote:Hi Mate,

Try below:
Hi mate, thank you. Unfortunately that did not help. I've prepared a full example here, if you would be so kind to take a look at it:

Code: Select all

 
#include <irrlicht.h>
#include "SMesh.h"
#include "SMeshBuffer.h"
#include "ISceneNodeAnimator.h"
#include "CSceneNodeAnimatorCameraRTS.h"
#include <ILightSceneNode.h>
 
using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;
 
int main()
{
    IrrlichtDevice *device = createDevice(video::EDT_OPENGL, dimension2d<u32>(640, 480), 16, false, false, false, 0);
 
    if (!device)
        return 1;
    IVideoDriver* driver = device->getVideoDriver();
    ISceneManager* smgr = device->getSceneManager();
    IGUIEnvironment* guienv = device->getGUIEnvironment();
 
    array<vector3df> vertices;
    
    vertices.push_back(vector3df(-10.0f, -10.0f, -10.0f));
    vertices.push_back(vector3df(-10.0f, -10.0f, 10.0f));
    vertices.push_back(vector3df(-10.0f, 10.0f, 10.0f));
    vertices.push_back(vector3df(10.0f, 10.0f, -10.0f));
    vertices.push_back(vector3df(-10.0f, -10.0f, -10.0f));
    vertices.push_back(vector3df(-10.0f, 10.0f, -10.0f));
    vertices.push_back(vector3df(10.0f, -10.0f, 10.0f));
    vertices.push_back(vector3df(-10.0f, -10.0f, -10.0f));
    vertices.push_back(vector3df(10.0f, -10.0f, -10.0f));
    vertices.push_back(vector3df(10.0f, 10.0f, -10.0f));
    vertices.push_back(vector3df(10.0f, -10.0f, -10.0f));
    vertices.push_back(vector3df(-10.0f, -10.0f, -10.0f));
    vertices.push_back(vector3df(-10.0f, -10.0f, -10.0f));
    vertices.push_back(vector3df(-10.0f, 10.0f, 10.0f));
    vertices.push_back(vector3df(-10.0f, 10.0f, -10.0f));
    vertices.push_back(vector3df(10.0f, -10.0f, 10.0f));
    vertices.push_back(vector3df(-10.0f, -10.0f, 10.0f));
    vertices.push_back(vector3df(-10.0f, -10.0f, -10.0f));
    vertices.push_back(vector3df(-10.0f, 10.0f, 10.0f));
    vertices.push_back(vector3df(-10.0f, -10.0f, 10.0f));
    vertices.push_back(vector3df(10.0f, -10.0f, 10.0f));
    vertices.push_back(vector3df(10.0f, 10.0f, 10.0f));
    vertices.push_back(vector3df(10.0f, -10.0f, -10.0f));
    vertices.push_back(vector3df(10.0f, 10.0f, -10.0f));
    vertices.push_back(vector3df(10.0f, -10.0f, -10.0f));
    vertices.push_back(vector3df(10.0f, 10.0f, 10.0f));
    vertices.push_back(vector3df(10.0f, -10.0f, 10.0f));
    vertices.push_back(vector3df(10.0f, 10.0f, 10.0f));
    vertices.push_back(vector3df(10.0f, 10.0f, -10.0f));
    vertices.push_back(vector3df(-10.0f, 10.0f, -10.0f));
    vertices.push_back(vector3df(10.0f, 10.0f, 10.0f));
    vertices.push_back(vector3df(-10.0f, 10.0f, -10.0f));
    vertices.push_back(vector3df(-10.0f, 10.0f, 10.0f));
    vertices.push_back(vector3df(10.0f, 10.0f, 10.0f));
    vertices.push_back(vector3df(-10.0f, 10.0f, 10.0f));
    vertices.push_back(vector3df(10.0f, -10.0f, 10.0f));
 
    SMesh* mesh = new SMesh();
    SMeshBuffer* meshBuffer = new SMeshBuffer();
    mesh->addMeshBuffer(meshBuffer);
    for (u32 i = 0; i != vertices.size(); i=i+3)
    {
        vector3df normal = core::plane3df(vertices[i], vertices[i + 1], vertices[i + 2]).Normal;
        video::SColor color(255, 255, 0, 0);
        meshBuffer->Vertices.push_back(video::S3DVertex(vertices[i], normal, color, vector2df()));
        meshBuffer->Vertices.push_back(video::S3DVertex(vertices[i + 1], normal, color, vector2df()));
        meshBuffer->Vertices.push_back(video::S3DVertex(vertices[i + 2], normal, color, vector2df()));
 
        meshBuffer->Indices.push_back(i);
        meshBuffer->Indices.push_back(i + 1);
        meshBuffer->Indices.push_back(i + 2);
    }
 
    SAnimatedMesh* animMesh = 0;
    if (0 != mesh->getMeshBufferCount())
    {
        mesh->recalculateBoundingBox();
        animMesh = new SAnimatedMesh();
        animMesh->Type = EAMT_OBJ;
        animMesh->addMesh(mesh);
        animMesh->recalculateBoundingBox();
    }
    mesh->drop();
 
    IAnimatedMeshSceneNode* node = smgr->addAnimatedMeshSceneNode(animMesh);
    
    node->setMaterialFlag(EMF_LIGHTING, true);
    node->setMaterialFlag(EMF_GOURAUD_SHADING, true);
    node->setMaterialFlag(EMF_NORMALIZE_NORMALS, true);
    smgr->getMeshManipulator()->recalculateNormals(node->getMesh(), true, true);
    smgr->setAmbientLight(SColorf(0, 1, 0, 1));
    ICameraSceneNode* camera = smgr->addCameraSceneNodeFPS(0, 50, 0.02);
    camera->setPosition(vector3df(-50, -50, -50));
    camera->setTarget(vector3df(0, 0, 0));
    while (device->run())
    {
        driver->beginScene(true, true, SColor(255, 100, 101, 140));
        smgr->drawAll();
        guienv->drawAll();
 
        driver->endScene();
    }
 
    device->drop();
 
    return 0;
}
 
Firstly my cube was black (with light turned on), I've added ambient green light and now it is green. But there is no shading on it:

Image

Perhaps I need another source of light...

hendu wrote: It's silly to expect a lighted result without lighting ;)
Instead of beeing such a smartass, you could help me a little ;-)
mongoose7
Posts: 1227
Joined: Wed Apr 06, 2011 12:13 pm

Re: How to achieve flat shading without texture?

Post by mongoose7 »

Maybe you should lighten up! ;-)

I can't see any lights in your code. Where do you create them?
Having all your normals the same means you will always get a flat look.
Note that ambient light always gives a flat look, regardless of normals.
Wodzu
Posts: 27
Joined: Wed May 07, 2014 5:41 pm

Re: How to achieve flat shading without texture?

Post by Wodzu »

mongoose7 wrote:Maybe you should lighten up! ;-)
Oh I am very bright person, trust me ;-)
mongoose7 wrote:I can't see any lights in your code. Where do you create them?
The thing is I do not know how to properly create a light. I will try to use this post as a reference: http://irrlicht.sourceforge.net/forum/v ... ht#p291396
mongoose7 wrote:Having all your normals the same means you will always get a flat look.
By "the same" you mean the same per polygon? And to have them different I should calculate each vertex normal by taking into account all neighbouring vertices?
Will Irrlicht calculate normals for me when I use:

Code: Select all

smgr->getMeshManipulator()->recalculateNormals(sceneNode->getMesh(), true, true);
mongoose7 wrote:Note that ambient light always gives a flat look, regardless of normals.
Thanks :)
thanhle
Posts: 325
Joined: Wed Jun 12, 2013 8:09 am

Re: How to achieve flat shading without texture?

Post by thanhle »

Yes, doing that will calculate the normal for you.

//Basic light
smgr->addLightSceneNode( 0, irr::core::vector3df(0, 10, 10), irr::video::SColorf(1.0f, 1.0f, 1.0f), 3.0f, 1 );


//Flat shade
sceneNode->setMaterialFlag(video::EMF_GOURAUD_SHADING, false);

regards
thanh
mongoose7
Posts: 1227
Joined: Wed Apr 06, 2011 12:13 pm

Re: How to achieve flat shading without texture?

Post by mongoose7 »

@Wodzu Excuse me, I made a mistake, your normals are correct and you should not call recalculateNormals. Note that, if you do call recalculateNormals, you should call it with recalculateNormals(mesh, false, false) because you don't want the mesh smoothed.
Wodzu
Posts: 27
Joined: Wed May 07, 2014 5:41 pm

Re: How to achieve flat shading without texture?

Post by Wodzu »

Thank you guys :)

It works as expected:

Image
Post Reply