Light Properties GpuProgramParameters is not working

A place for users of OGRE to discuss ideas and experiences of utilitising OGRE in their games / demos / applications.
psysu
Halfling
Posts: 74
Joined: Tue Jun 01, 2021 7:47 am
x 6

Light Properties GpuProgramParameters is not working

Post by psysu »

hello, i have started to learn Ogre 2.1 recently. im trying to write blinn-phong material using hlsl. i have written vertex and fragment programs for it with target profiles vs_5_0 and ps_5_0 respectively. The issue im having is passing several AutoConstant GpuProgramParameters to the shader programs ( through both .program script or c++ ).

For Example, in my shader

vertex program:

Code: Select all

float4x4 world;
float4x4 worldView;
float4x4 worldViewProj;

float4 lightPos;
float4 cameraPos;

struct VertexShaderInput
{
    float4 position : POSITION;
    float3 normal : NORMAL;
};

struct VertexShaderOutput
{
    float3 worldpos : TEXCOORD0;
    float3 lightDir : TEXCOORD1;
    float3 viewDir  : TEXCOORD2;
    float4 gl_position : SV_POSITION;
};

VertexShaderOutput main( VertexShaderInput input )
{
    VertexShaderOutput vs_out;

    vs_out.gl_position = mul(worldViewProj, input.position);
    vs_out.worldpos = mul( world, input.position );
    //vs_out.normal = input.normal;
    
    vs_out.lightDir = lightPos - vs_out.worldpos;
    vs_out.viewDir = cameraPos - vs_out.worldpos;

    return vs_out;
}
fragment program:

Code: Select all

float4 ambient;
float4 diffuse;
float4 specular;
float shininess;

struct PixelShaderInput
{
    float3 worldpos   : TEXCOORD0;
    float3 lightDir : TEXCOORD1;
    float3 viewDir  : TEXCOORD2;    
};

float4 main( PixelShaderInput input ) : SV_TARGET
{
    input.lightDir  = normalize( input.lightDir );
    input.viewDir   = normalize( input.viewDir );

    float3 xTangent = float3( ddx(input.worldpos.x) , ddx(input.worldpos.y), ddx(input.worldpos.z) );
    float3 yTangent = float3( ddy(input.worldpos.x) , ddy(input.worldpos.y), ddy(input.worldpos.z) );
    float3 normal = cross(xTangent, yTangent);
    normal = normalize(normal);

    float NdotL = dot( input.lightDir, normal );
    float diffuse_factor = saturate(NdotL);
    
    float3 halfway = normalize( input.viewDir + input.lightDir );
    float HdotN = dot( halfway, normal );
    float specular_factor = pow(saturate(HdotN), shininess );
    return diffuse_factor * diffuse + specular_factor * specular + ambient;
}
and these are the .program and .material script i use for the shaders.

program script:

Code: Select all

vertex_program mesh_phong_vs hlsl
{
    source Mesh_phong_vs.hlsl
    target vs_5_0
    entry_point main
    default_params
    {
        param_named_auto world world_matrix
        param_named_auto worldView worldview_matrix
        param_named_auto worldViewProj worldviewproj_matrix
        param_named_auto lightPos light_position 0
        param_named_auto cameraPos camera_position        
    }
}

fragment_program mesh_blinn_phong_ps hlsl
{
    source Mesh_blinn_phong_ps.hlsl
    target ps_5_0
    entry_point main

    default_params
    {
        param_named_auto ambient ambient_light_colour
        param_named_auto diffuse light_diffuse_colour 0
        param_named_auto specular light_specular_colour 0
        param_named_auto shininess surface_shininess
    }
}
.material script:

Code: Select all

material Custom_Blinn_Phong
{
    technique
    {
        pass
        {
            vertex_program_ref mesh_phong_vs
            {
            }
            fragment_program_ref mesh_blinn_phong_ps
            {
            }
        }
    }
}
light properties in c++:

Code: Select all

auto* light = scene_manager->createLight();
auto* light_node = scene_manager->getRootSceneNode(Ogre::SCENE_DYNAMIC)->createChildSceneNode(Ogre::SCENE_DYNAMIC);
light_node->attachObject(light);
light->setType( Ogre::Light::LightTypes::LT_DIRECTIONAL );                                                
light->setDirection( Ogre::Vector3{ -1, -1, -1}.normalisedCopy() );
light->setPowerScale( Ogre::Math::PI );
light->setDiffuseColour( Ogre::ColourValue::Red );
light->setSpecularColour( Ogre::ColourValue::Blue );
light_node->setPosition( { 0, 4.5, 0} );
but while debugging the shaders using Visual Studio graphics debugger,
"lightPos" have {0.0, 0.0, 0.0, 1.0} value in vertex program
"diffuse", "specular" have black values {0.0, 0.0, 0.0, 1.0} and "ambient" has white value { 1.0, 1.0, 1.0, 1.0 } in fragment program.

However if i explicitly specified some values as named parameters in the .program script, the shaders is working as its intended to.

explicit values in .program script:

Code: Select all

param_named ambient float4 0 0 0 1
param_named diffuse float4 0.15 0 0 1
param_named specular float4 1 1 1 1
material using AutoConstant values:

Image

material using explicit named values:

Image
User avatar
dark_sylinc
OGRE Team Member
OGRE Team Member
Posts: 5433
Joined: Sat Jul 21, 2007 4:55 pm
Location: Buenos Aires, Argentina
x 1341

Re: Light Properties GpuProgramParameters is not working

Post by dark_sylinc »

Hi!

Enabling lights for old materials had a considerable CPU cost so it's disabled by default since it's rarely needed.

You can enable it back using SceneManager::setBuildLegacyLightList

Cheers
psysu
Halfling
Posts: 74
Joined: Tue Jun 01, 2021 7:47 am
x 6

Re: Light Properties GpuProgramParameters is not working

Post by psysu »

dark_sylinc wrote: Tue Jun 01, 2021 3:37 pm Hi!

Enabling lights for old materials had a considerable CPU cost so it's disabled by default since it's rarely needed.

You can enable it back using SceneManager::setBuildLegacyLightList

Cheers
Alright i can get Light Properties inside the shader now, thanks :D. but i still get the ambient_light_colour as white ( 1.0, 1.0, 1.0, 1.0 ) in the shader,
even though i have specified the ambient colour for the scene as

Code: Select all

_scene_manager->setAmbientLight( Ogre::ColourValue::Black, Ogre::ColourValue::Black, {0.0, 0.0, 0.0} );