Render 3d surface with correctly illumination

Anything and everything that's related to OGRE or the wider graphics field that doesn't fit into the other forums.
Post Reply
dcavallini
Gnoblar
Posts: 17
Joined: Fri Jul 16, 2021 10:04 am
x 2

Render 3d surface with correctly illumination

Post by dcavallini »

I am newbie for ogre3d
I need to render 3d surface in space with correct illumination.
The problem is very similar at this: viewtopic.php?t=81559

The solution I understand is modify calculus's normal in fragment shader with this:
In OpenGL:
Normal = gl_FrontFacing ? Normal0 : -Normal0; where Normal0 is normal calculated in vertex shader
in DirectX I presume need to use SV_IsFrontFace

In the ogre3d newer version exist a simplest method?
How can I modify the existent shader for this?
Last edited by dcavallini on Fri Sep 03, 2021 3:06 pm, edited 2 times in total.
paroj
OGRE Team Member
OGRE Team Member
Posts: 1994
Joined: Sun Mar 30, 2014 2:51 pm
x 1074
Contact:

Re: Render 3d surface with correctly illumination

Post by paroj »

the shader code is here:
https://github.com/OGRECave/ogre/blob/4 ... g.glsl#L48

it should be sufficient to abs() nDotL for what you want. Take a look on how the NORMALISED define is handled in the RTSS, if you only want to enable this for some materials.
dcavallini
Gnoblar
Posts: 17
Joined: Fri Jul 16, 2021 10:04 am
x 2

Re: Render 3d surface with correctly illumination

Post by dcavallini »

the shader code is here:
https://github.com/OGRECave/ogre/blob/4 ... g.glsl#L48

it should be sufficient to abs() nDotL for what you want. Take a look on how the NORMALISED define is handled in the RTSS, if you only want to enable this for some materials.
Thank you for the reply.
For directional light I tried this :

Code: Select all

void SGX_Light_Directional_Diffuse(...)
				  
{
	vec3 vNormalView = normalize(vNormal);
	float nDotL = abs(dot(vNormalView, -vLightDirView));
	
	vOut += vDiffuseColour * clamp(nDotL, 0.0, 1.0);
	vOut = clamp(vOut, 0.0, 1.0);
}

//-----------------------------------------------------------------------------
void SGX_Light_Directional_DiffuseSpecular(...)
					
{
	vec3 vNormalView = normalize(vNormal);		
	float nDotL		   = abs(dot(vNormalView, -vLightDirView));
	vec3 vView       = normalize(vViewDir);
	vec3 vHalfWay    = normalize(vView + -vLightDirView);
	float nDotH        = dot(vNormalView, vHalfWay);
	
	
	}
}
but I obtain strange result (see the image)
Image

I tried to use:

Code: Select all

vec3 Normal0 = gl_FrontFacing ? vNormal : -vNormal;
but obtain the error:
Use of undeclared identifier 'gl_FrontFacing'
Any suggest?
dcavallini
Gnoblar
Posts: 17
Joined: Fri Jul 16, 2021 10:04 am
x 2

Re: Render 3d surface with correctly illumination

Post by dcavallini »

I try to simplify my question: is it possible to use Built-in Variable (GLSL) as

in vec4 gl_FragCoord;
in bool gl_FrontFacing;
in vec2 gl_PointCoord;

in Ogre3d shader like "SGXLib_PerPixelLighting.glsl"
paroj
OGRE Team Member
OGRE Team Member
Posts: 1994
Joined: Sun Mar 30, 2014 2:51 pm
x 1074
Contact:

Re: Render 3d surface with correctly illumination

Post by paroj »

you might need to guard the code with
#ifdef OGRE_OGRE_SHADER

as that file can be included in the vertex shader.
dcavallini
Gnoblar
Posts: 17
Joined: Fri Jul 16, 2021 10:04 am
x 2

Re: Render 3d surface with correctly illumination

Post by dcavallini »

you might need to guard the code with
#ifdef OGRE_OGRE_SHADER

as that file can be included in the vertex shader.
Unfortunately I don't know how to use your suggestion.
A not exciting solution is duplicate the face.
For this need set material with

Code: Select all

setManualCullingMode( Ogre::MANUAL_CULL_BACK );
setCullingMode( Ogre::CULL_CLOCKWISE );
and invert normal and orientation (one clockwise and one anticlockwise).
This for all faces.
I hope the performance doesn't get too bad.
paroj
OGRE Team Member
OGRE Team Member
Posts: 1994
Joined: Sun Mar 30, 2014 2:51 pm
x 1074
Contact:

Re: Render 3d surface with correctly illumination

Post by paroj »

sorry I meant OGRE_FRAGMENT_SHADER. see
https://ogrecave.github.io/ogre/api/lat ... otoc_md203
dcavallini
Gnoblar
Posts: 17
Joined: Fri Jul 16, 2021 10:04 am
x 2

[SOLVED]Re: Render 3d surface with correctly illumination

Post by dcavallini »

OGRE_FRAGMENT_SHADER
It works!
paroj
OGRE Team Member
OGRE Team Member
Posts: 1994
Joined: Sun Mar 30, 2014 2:51 pm
x 1074
Contact:

Re: Render 3d surface with correctly illumination

Post by paroj »

just pushed a complete implementation (GL & D3D) of this. Here is how to enable it:
https://github.com/OGRECave/ogre/blob/m ... s.material
dcavallini
Gnoblar
Posts: 17
Joined: Fri Jul 16, 2021 10:04 am
x 2

Re: Render 3d surface with correctly illumination

Post by dcavallini »

I tried yours implementation and work fine with GL & D3D.
But in material is it possible to set programmatically rtshader_system using "lighting_stage" "per_pixel" "two_sided"?
paroj
OGRE Team Member
OGRE Team Member
Posts: 1994
Joined: Sun Mar 30, 2014 2:51 pm
x 1074
Contact:

Re: Render 3d surface with correctly illumination

Post by paroj »

you can search for SGX_PerPixelLighting similar to what is done for fog here:
https://github.com/OGRECave/ogre/blob/6 ... m.cpp#L546

and then call setParameter("two_sided", "true") on it, to globally enable two_sided lighting.
dcavallini
Gnoblar
Posts: 17
Joined: Fri Jul 16, 2021 10:04 am
x 2

Re: Render 3d surface with correctly illumination

Post by dcavallini »

This function enable programmatically the two sided shader for all materials

Code: Select all

  void Ogre3DWin::enableTwoSided( )
    {
    #ifdef RTSHADER_SYSTEM_BUILD_EXT_SHADERS

        // Grab the scheme render state.
            RenderState* schemRenderState = mShaderGenerator->getRenderState(RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME);
            const SubRenderStateList& subRenderStateList = schemRenderState->getSubRenderStates();
            SubRenderStateListConstIterator it = subRenderStateList.begin();
            SubRenderStateListConstIterator itEnd = subRenderStateList.end();
            SubRenderState* twosideSubRenderState = nullptr;

            // Search for the  two sided  sub state.
            for (; it != itEnd; ++it)
            {
                SubRenderState* curSubRenderState = *it;

                if (curSubRenderState->getType() == "SGX_PerPixelLighting")
                {
                    twosideSubRenderState = curSubRenderState;
                    break;
                }
            }

            // Create the  two sided  sub render state if need to.
            if (twosideSubRenderState == nullptr)
            {
                twosideSubRenderState = mShaderGenerator->createSubRenderState("SGX_PerPixelLighting");
                schemRenderState->addTemplateSubRenderState(twosideSubRenderState);
            }
            // enable two_sided
            twosideSubRenderState->setParameter("two_sided","true");
            // Invalidate the scheme in order to re-generate all shaders based technique related to this scheme.
            mShaderGenerator->invalidateScheme(Ogre::RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME);
    #endif
}
Post Reply