Coverage Report

Created: 2025-11-24 06:46

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/ogre/Components/RTShaderSystem/src/OgreShaderExPerPixelLighting.cpp
Line
Count
Source
1
/*
2
-----------------------------------------------------------------------------
3
This source file is part of OGRE
4
(Object-oriented Graphics Rendering Engine)
5
For the latest info, see http://www.ogre3d.org
6
7
Copyright (c) 2000-2014 Torus Knot Software Ltd
8
Permission is hereby granted, free of charge, to any person obtaining a copy
9
of this software and associated documentation files (the "Software"), to deal
10
in the Software without restriction, including without limitation the rights
11
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12
copies of the Software, and to permit persons to whom the Software is
13
furnished to do so, subject to the following conditions:
14
15
The above copyright notice and this permission notice shall be included in
16
all copies or substantial portions of the Software.
17
18
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24
THE SOFTWARE.
25
-----------------------------------------------------------------------------
26
*/
27
#include "OgreShaderPrecompiledHeaders.h"
28
#ifdef RTSHADER_SYSTEM_BUILD_EXT_SHADERS
29
30
namespace Ogre {
31
namespace RTShader {
32
33
/************************************************************************/
34
/*                                                                      */
35
/************************************************************************/
36
const String SRS_PER_PIXEL_LIGHTING = "SGX_PerPixelLighting";
37
38
//-----------------------------------------------------------------------
39
const String& PerPixelLighting::getType() const
40
0
{
41
0
    return SRS_PER_PIXEL_LIGHTING;
42
0
}
43
44
bool PerPixelLighting::setParameter(const String& name, const String& value)
45
0
{
46
0
  if(name == "two_sided")
47
0
  {
48
0
    return StringConverter::parse(value, mTwoSidedLighting);
49
0
  }
50
51
0
  return FFPLighting::setParameter(name, value);
52
0
}
53
54
//-----------------------------------------------------------------------
55
bool PerPixelLighting::resolveParameters(ProgramSet* programSet)
56
0
{
57
0
    if (false == resolveGlobalParameters(programSet))
58
0
        return false;
59
    
60
0
    if (false == resolvePerLightParameters(programSet))
61
0
        return false;
62
    
63
0
    return true;
64
0
}
65
66
//-----------------------------------------------------------------------
67
bool PerPixelLighting::resolveGlobalParameters(ProgramSet* programSet)
68
0
{
69
0
    Program* vsProgram = programSet->getCpuProgram(GPT_VERTEX_PROGRAM);
70
0
    Program* psProgram = programSet->getCpuProgram(GPT_FRAGMENT_PROGRAM);
71
0
    Function* vsMain = vsProgram->getEntryPointFunction();
72
0
    Function* psMain = psProgram->getEntryPointFunction();
73
74
    // Resolve world view IT matrix.
75
0
    mWorldViewITMatrix = vsProgram->resolveParameter(GpuProgramParameters::ACT_NORMAL_MATRIX);
76
77
    // Get surface ambient colour if need to.
78
0
    if ((mTrackVertexColourType & TVC_AMBIENT) == 0)
79
0
    {       
80
0
        mDerivedAmbientLightColour = psProgram->resolveParameter(GpuProgramParameters::ACT_DERIVED_AMBIENT_LIGHT_COLOUR);
81
0
    }
82
0
    else
83
0
    {
84
0
        mLightAmbientColour = psProgram->resolveParameter(GpuProgramParameters::ACT_AMBIENT_LIGHT_COLOUR);
85
0
    }
86
87
    // Get surface emissive colour if need to.
88
0
    if ((mTrackVertexColourType & TVC_EMISSIVE) == 0)
89
0
    {
90
0
        mSurfaceEmissiveColour = psProgram->resolveParameter(GpuProgramParameters::ACT_SURFACE_EMISSIVE_COLOUR);
91
0
    }
92
93
    // Get derived scene colour.
94
0
    mDerivedSceneColour = psProgram->resolveParameter(GpuProgramParameters::ACT_DERIVED_SCENE_COLOUR);
95
96
0
    mViewNormal = psMain->getLocalParameter(Parameter::SPC_NORMAL_VIEW_SPACE);
97
98
0
    if(!mViewNormal)
99
0
    {
100
        // Resolve input vertex shader normal.
101
0
        mVSInNormal = vsMain->resolveInputParameter(Parameter::SPC_NORMAL_OBJECT_SPACE);
102
103
        // Resolve output vertex shader normal.
104
0
        mVSOutNormal = vsMain->resolveOutputParameter(Parameter::SPC_NORMAL_VIEW_SPACE);
105
106
        // Resolve input pixel shader normal.
107
0
        mViewNormal = psMain->resolveInputParameter(mVSOutNormal);
108
0
    }
109
110
0
    mInDiffuse = psMain->getInputParameter(Parameter::SPC_COLOR_DIFFUSE);
111
0
    if (mInDiffuse.get() == NULL)
112
0
    {
113
0
        mInDiffuse = psMain->getLocalParameter(Parameter::SPC_COLOR_DIFFUSE);
114
0
    }
115
116
0
    OgreAssert(mInDiffuse, "mInDiffuse is NULL");
117
118
0
    mOutDiffuse = psMain->resolveOutputParameter(Parameter::SPC_COLOR_DIFFUSE);
119
120
0
    if (mSpecularEnable)
121
0
    {
122
        // Get surface shininess.
123
0
        mSurfaceShininess = psProgram->resolveParameter(GpuProgramParameters::ACT_SURFACE_SHININESS);
124
125
0
        mOutSpecular = psMain->resolveLocalParameter(Parameter::SPC_COLOR_SPECULAR);
126
127
0
        mVSInPosition = vsMain->getLocalParameter(Parameter::SPC_POSITION_OBJECT_SPACE);
128
0
        if(!mVSInPosition)
129
0
            mVSInPosition = vsMain->resolveInputParameter(Parameter::SPC_POSITION_OBJECT_SPACE);
130
131
0
        mVSOutViewPos = vsMain->resolveOutputParameter(Parameter::SPC_POSITION_VIEW_SPACE);
132
133
0
        mViewPos = psMain->resolveInputParameter(mVSOutViewPos);
134
135
0
        mWorldViewMatrix = vsProgram->resolveParameter(GpuProgramParameters::ACT_WORLDVIEW_MATRIX);
136
0
    }
137
138
0
    if(mLtcLUT1SamplerIndex > -1)
139
0
    {
140
0
        mLTCLUT1 = psProgram->resolveParameter(GCT_SAMPLER2D, "ltcLUT1Sampler", mLtcLUT1SamplerIndex);
141
0
        mLTCLUT2 = psProgram->resolveParameter(GCT_SAMPLER2D, "ltcLUT2Sampler", mLtcLUT1SamplerIndex + 1);
142
0
    }
143
144
0
    return true;
145
0
}
146
147
//-----------------------------------------------------------------------
148
bool PerPixelLighting::resolvePerLightParameters(ProgramSet* programSet)
149
0
{
150
0
    Program* vsProgram = programSet->getCpuProgram(GPT_VERTEX_PROGRAM);
151
0
    Program* psProgram = programSet->getCpuProgram(GPT_FRAGMENT_PROGRAM);
152
0
    Function* vsMain = vsProgram->getEntryPointFunction();
153
0
    Function* psMain = psProgram->getEntryPointFunction();
154
155
    // Resolve per light parameters.
156
0
    mPositions = psProgram->resolveParameter(GpuProgramParameters::ACT_LIGHT_POSITION_VIEW_SPACE_ARRAY, mLightCount);
157
0
    mDirections = psProgram->resolveParameter(GpuProgramParameters::ACT_LIGHT_DIRECTION_VIEW_SPACE_ARRAY, mLightCount);
158
0
    mAttenuatParams = psProgram->resolveParameter(GpuProgramParameters::ACT_LIGHT_ATTENUATION_ARRAY, mLightCount);
159
0
    mSpotParams = psProgram->resolveParameter(GpuProgramParameters::ACT_SPOTLIGHT_PARAMS_ARRAY, mLightCount);
160
161
    // Resolve diffuse colour.
162
0
    if ((mTrackVertexColourType & TVC_DIFFUSE) == 0)
163
0
    {
164
0
        mDiffuseColours = psProgram->resolveParameter(GpuProgramParameters::ACT_DERIVED_LIGHT_DIFFUSE_COLOUR_ARRAY, mLightCount);
165
0
    }
166
0
    else
167
0
    {
168
0
        mDiffuseColours = psProgram->resolveParameter(GpuProgramParameters::ACT_LIGHT_DIFFUSE_COLOUR_POWER_SCALED_ARRAY, mLightCount);
169
0
    }
170
171
0
    if (mSpecularEnable)
172
0
    {
173
        // Resolve specular colour.
174
0
        if ((mTrackVertexColourType & TVC_SPECULAR) == 0)
175
0
        {
176
0
            mSpecularColours = psProgram->resolveParameter(GpuProgramParameters::ACT_DERIVED_LIGHT_SPECULAR_COLOUR_ARRAY, mLightCount);
177
0
        }
178
0
        else
179
0
        {
180
0
            mSpecularColours = psProgram->resolveParameter(GpuProgramParameters::ACT_LIGHT_SPECULAR_COLOUR_POWER_SCALED_ARRAY, mLightCount);
181
0
        }   
182
0
    }
183
184
    //if (needViewPos)
185
0
    {
186
0
        mWorldViewMatrix = vsProgram->resolveParameter(GpuProgramParameters::ACT_WORLDVIEW_MATRIX);
187
0
        if(!mVSInPosition)
188
0
            mVSInPosition = vsMain->resolveInputParameter(Parameter::SPC_POSITION_OBJECT_SPACE);
189
0
        mVSOutViewPos = vsMain->resolveOutputParameter(Parameter::SPC_POSITION_VIEW_SPACE);
190
191
0
        mViewPos = psMain->resolveInputParameter(mVSOutViewPos);
192
0
    }
193
194
0
    if(mTwoSidedLighting)
195
0
    {
196
0
        mFrontFacing = psMain->resolveInputParameter(Parameter::SPC_FRONT_FACING);
197
0
        mTargetFlipped = psProgram->resolveParameter(GpuProgramParameters::ACT_RENDER_TARGET_FLIPPING);
198
0
    }
199
200
0
    return true;
201
0
}
202
203
//-----------------------------------------------------------------------
204
bool PerPixelLighting::resolveDependencies(ProgramSet* programSet)
205
0
{
206
0
    Program* vsProgram = programSet->getCpuProgram(GPT_VERTEX_PROGRAM);
207
0
    Program* psProgram = programSet->getCpuProgram(GPT_FRAGMENT_PROGRAM);
208
209
0
    vsProgram->addDependency(FFP_LIB_TRANSFORM);
210
0
    vsProgram->addDependency(SGX_LIB_PERPIXELLIGHTING);
211
212
0
    psProgram->addDependency(SGX_LIB_PERPIXELLIGHTING);
213
214
0
    addDefines(psProgram);
215
216
0
    if(mLtcLUT1SamplerIndex > -1)
217
0
        psProgram->addPreprocessorDefines("HAVE_AREA_LIGHTS");
218
219
0
    return true;
220
0
}
221
222
//-----------------------------------------------------------------------
223
bool PerPixelLighting::addFunctionInvocations(ProgramSet* programSet)
224
0
{
225
0
    Program* vsProgram = programSet->getCpuProgram(GPT_VERTEX_PROGRAM); 
226
0
    Function* vsMain = vsProgram->getEntryPointFunction();  
227
0
    Program* psProgram = programSet->getCpuProgram(GPT_FRAGMENT_PROGRAM);
228
0
    Function* psMain = psProgram->getEntryPointFunction();  
229
230
    // Add the global illumination functions.
231
0
    addVSInvocation(vsMain->getStage(FFP_VS_LIGHTING));
232
233
0
    auto stage = psMain->getStage(FFP_PS_COLOUR_BEGIN + 1);
234
    // Add the global illumination functions.
235
0
    addPSGlobalIlluminationInvocation(stage);
236
237
0
    if(mFrontFacing)
238
0
        stage.callFunction("SGX_Flip_Backface_Normal", mFrontFacing, mTargetFlipped, mViewNormal);
239
240
0
    mShadowFactor = psMain->getLocalParameter("lShadowFactor");
241
242
    // Add per light functions.
243
0
    for (int i = 0; i < mLightCount; i++)
244
0
    {
245
0
        addIlluminationInvocation(i, stage);
246
0
    }
247
248
    // Assign back temporary variables
249
0
    stage.assign(mOutDiffuse, mInDiffuse);
250
251
0
    return true;
252
0
}
253
254
//-----------------------------------------------------------------------
255
void PerPixelLighting::addVSInvocation(const FunctionStageRef& stage)
256
0
{
257
    // Transform normal in view space.
258
0
    if(mLightCount && mVSInNormal)
259
0
        stage.callBuiltin("mul", mWorldViewITMatrix, mVSInNormal, mVSOutNormal);
260
261
    // Transform view space position if need to.
262
0
    if (mVSOutViewPos)
263
0
    {
264
0
        stage.callFunction(FFP_FUNC_TRANSFORM, mWorldViewMatrix, mVSInPosition, mVSOutViewPos);
265
0
    }
266
0
}
267
268
269
//-----------------------------------------------------------------------
270
void PerPixelLighting::addPSGlobalIlluminationInvocation(const FunctionStageRef& stage)
271
0
{
272
0
    if ((mTrackVertexColourType & TVC_AMBIENT) == 0 && 
273
0
        (mTrackVertexColourType & TVC_EMISSIVE) == 0)
274
0
    {
275
0
        stage.assign(mDerivedSceneColour, mOutDiffuse);
276
0
    }
277
0
    else
278
0
    {
279
0
        if (mTrackVertexColourType & TVC_AMBIENT)
280
0
        {
281
0
            stage.mul(mLightAmbientColour, mInDiffuse, mOutDiffuse);
282
0
        }
283
0
        else
284
0
        {
285
0
            stage.assign(mDerivedAmbientLightColour, mOutDiffuse);
286
0
        }
287
288
0
        if (mTrackVertexColourType & TVC_EMISSIVE)
289
0
        {
290
0
            stage.add(In(mInDiffuse).xyz(), In(mOutDiffuse).xyz(), Out(mOutDiffuse).xyz());
291
0
        }
292
0
        else
293
0
        {
294
0
            stage.add(mSurfaceEmissiveColour, mOutDiffuse, mOutDiffuse);
295
0
        }       
296
0
    }
297
0
}
298
299
//-----------------------------------------------------------------------
300
const String& PerPixelLightingFactory::getType() const
301
0
{
302
0
    return SRS_PER_PIXEL_LIGHTING;
303
0
}
304
305
//-----------------------------------------------------------------------
306
SubRenderState* PerPixelLightingFactory::createInstance(const ScriptProperty& prop, Pass* pass, SGScriptTranslator* translator)
307
0
{
308
0
    if (prop.name != "lighting_stage" || prop.values.empty())
309
0
        return NULL;
310
311
0
    if(prop.values[0] != "per_pixel")
312
0
        return NULL;
313
314
0
    auto ret = createOrRetrieveInstance(translator);
315
316
    // process the flags
317
0
    for(auto it = prop.values.begin() + 1; it != prop.values.end(); it++)
318
0
    {
319
0
        if (!ret->setParameter(*it, "true"))
320
0
            translator->emitError(*it);
321
0
    }
322
323
0
    return ret;
324
0
}
325
326
//-----------------------------------------------------------------------
327
void PerPixelLightingFactory::writeInstance(MaterialSerializer* ser, SubRenderState* subRenderState, 
328
                                            Pass* srcPass, Pass* dstPass)
329
0
{
330
0
    ser->writeAttribute(4, "lighting_stage");
331
0
    ser->writeValue("per_pixel");
332
0
}
333
334
//-----------------------------------------------------------------------
335
SubRenderState* PerPixelLightingFactory::createInstanceImpl()
336
0
{
337
    return OGRE_NEW PerPixelLighting;
338
0
}
339
340
}
341
}
342
343
#endif