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
9 Permission is hereby granted, free of charge, to any person obtaining a copy
10 of this software and associated documentation files (the "Software"), to deal
11 in the Software without restriction, including without limitation the rights
12 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 copies of the Software, and to permit persons to whom the Software is
14 furnished to do so, subject to the following conditions:
15
16 The above copyright notice and this permission notice shall be included in
17 all copies or substantial portions of the Software.
18
19 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25 THE SOFTWARE.
26 -----------------------------------------------------------------------------
27 */
28 #include "OgreShaderPrecompiledHeaders.h"
29 #ifdef RTSHADER_SYSTEM_BUILD_EXT_SHADERS
30
31 namespace Ogre {
32 namespace RTShader {
33
34 /************************************************************************/
35 /* */
36 /************************************************************************/
37 String IntegratedPSSM3::Type = "SGX_IntegratedPSSM3";
38
39 //-----------------------------------------------------------------------
IntegratedPSSM3()40 IntegratedPSSM3::IntegratedPSSM3()
41 {
42
43 }
44
45 //-----------------------------------------------------------------------
getType() const46 const String& IntegratedPSSM3::getType() const
47 {
48 return Type;
49 }
50
51
52 //-----------------------------------------------------------------------
getExecutionOrder() const53 int IntegratedPSSM3::getExecutionOrder() const
54 {
55 return FFP_TEXTURING + 1;
56 }
57
58 //-----------------------------------------------------------------------
updateGpuProgramsParams(Renderable * rend,Pass * pass,const AutoParamDataSource * source,const LightList * pLightList)59 void IntegratedPSSM3::updateGpuProgramsParams(Renderable* rend, Pass* pass,
60 const AutoParamDataSource* source,
61 const LightList* pLightList)
62 {
63 ShadowTextureParamsIterator it = mShadowTextureParamsList.begin();
64 size_t shadowIndex = 0;
65
66 while(it != mShadowTextureParamsList.end())
67 {
68 it->mWorldViewProjMatrix->setGpuParameter(source->getTextureWorldViewProjMatrix(shadowIndex));
69 it->mInvTextureSize->setGpuParameter(source->getInverseTextureSize(it->mTextureSamplerIndex));
70
71 ++it;
72 ++shadowIndex;
73 }
74
75 Vector4 vSplitPoints;
76
77 vSplitPoints.x = mShadowTextureParamsList[0].mMaxRange;
78 vSplitPoints.y = mShadowTextureParamsList[1].mMaxRange;
79 vSplitPoints.z = 0.0;
80 vSplitPoints.w = 0.0;
81
82 mPSSplitPoints->setGpuParameter(vSplitPoints);
83
84 }
85
86 //-----------------------------------------------------------------------
copyFrom(const SubRenderState & rhs)87 void IntegratedPSSM3::copyFrom(const SubRenderState& rhs)
88 {
89 const IntegratedPSSM3& rhsPssm= static_cast<const IntegratedPSSM3&>(rhs);
90
91 mShadowTextureParamsList.resize(rhsPssm.mShadowTextureParamsList.size());
92
93 ShadowTextureParamsConstIterator itSrc = rhsPssm.mShadowTextureParamsList.begin();
94 ShadowTextureParamsIterator itDst = mShadowTextureParamsList.begin();
95
96 while(itDst != mShadowTextureParamsList.end())
97 {
98 itDst->mMaxRange = itSrc->mMaxRange;
99 ++itSrc;
100 ++itDst;
101 }
102 }
103
104 //-----------------------------------------------------------------------
preAddToRenderState(const RenderState * renderState,Pass * srcPass,Pass * dstPass)105 bool IntegratedPSSM3::preAddToRenderState(const RenderState* renderState,
106 Pass* srcPass, Pass* dstPass)
107 {
108 if (srcPass->getLightingEnabled() == false ||
109 srcPass->getParent()->getParent()->getReceiveShadows() == false)
110 return false;
111
112 ShadowTextureParamsIterator it = mShadowTextureParamsList.begin();
113
114 while(it != mShadowTextureParamsList.end())
115 {
116 TextureUnitState* curShadowTexture = dstPass->createTextureUnitState();
117
118 curShadowTexture->setContentType(TextureUnitState::CONTENT_SHADOW);
119 curShadowTexture->setTextureAddressingMode(TextureUnitState::TAM_BORDER);
120 curShadowTexture->setTextureBorderColour(ColourValue::White);
121 it->mTextureSamplerIndex = dstPass->getNumTextureUnitStates() - 1;
122 ++it;
123 }
124
125
126
127 return true;
128 }
129
130 //-----------------------------------------------------------------------
setSplitPoints(const SplitPointList & newSplitPoints)131 void IntegratedPSSM3::setSplitPoints(const SplitPointList& newSplitPoints)
132 {
133 if (newSplitPoints.size() != 4)
134 {
135 OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS,
136 "IntegratedPSSM3 sub render state requires 4 split points");
137 }
138
139 mShadowTextureParamsList.resize(newSplitPoints.size() - 1);
140
141 for (size_t i = 1; i < newSplitPoints.size(); ++i)
142 {
143 mShadowTextureParamsList[i - 1].mMaxRange = newSplitPoints[i];
144 }
145 }
146
147 //-----------------------------------------------------------------------
resolveParameters(ProgramSet * programSet)148 bool IntegratedPSSM3::resolveParameters(ProgramSet* programSet)
149 {
150 Program* vsProgram = programSet->getCpuProgram(GPT_VERTEX_PROGRAM);
151 Program* psProgram = programSet->getCpuProgram(GPT_FRAGMENT_PROGRAM);
152 Function* vsMain = vsProgram->getEntryPointFunction();
153 Function* psMain = psProgram->getEntryPointFunction();
154
155 // Get input position parameter.
156 mVSInPos = vsMain->getInputParameter(Parameter::SPC_POSITION_OBJECT_SPACE);
157
158 // Get output position parameter.
159 mVSOutPos = vsMain->getOutputParameter(Parameter::SPC_POSITION_PROJECTIVE_SPACE);
160
161 // Resolve vertex shader output depth.
162 mVSOutDepth = vsMain->resolveOutputParameter(Parameter::SPC_DEPTH_VIEW_SPACE);
163
164 // Resolve input depth parameter.
165 mPSInDepth = psMain->resolveInputParameter(mVSOutDepth);
166
167 // Get in/local diffuse parameter.
168 mPSDiffuse = psMain->getInputParameter(Parameter::SPC_COLOR_DIFFUSE);
169 if (mPSDiffuse.get() == NULL)
170 {
171 mPSDiffuse = psMain->getLocalParameter(Parameter::SPC_COLOR_DIFFUSE);
172 }
173
174 // Resolve output diffuse parameter.
175 mPSOutDiffuse = psMain->resolveOutputParameter(Parameter::SPC_COLOR_DIFFUSE);
176
177 // Get in/local specular parameter.
178 mPSSpecualr = psMain->getInputParameter(Parameter::SPC_COLOR_SPECULAR);
179 if (mPSSpecualr.get() == NULL)
180 {
181 mPSSpecualr = psMain->getLocalParameter(Parameter::SPC_COLOR_SPECULAR);
182 }
183
184 // Resolve computed local shadow colour parameter.
185 mPSLocalShadowFactor = psMain->resolveLocalParameter("lShadowFactor", GCT_FLOAT1);
186
187 // Resolve computed local shadow colour parameter.
188 mPSSplitPoints = psProgram->resolveParameter(GCT_FLOAT4, -1, (uint16)GPV_GLOBAL, "pssm_split_points");
189
190 // Get derived scene colour.
191 mPSDerivedSceneColour = psProgram->resolveParameter(GpuProgramParameters::ACT_DERIVED_SCENE_COLOUR);
192
193 ShadowTextureParamsIterator it = mShadowTextureParamsList.begin();
194 int lightIndex = 0;
195
196 while(it != mShadowTextureParamsList.end())
197 {
198 it->mWorldViewProjMatrix = vsProgram->resolveParameter(GCT_MATRIX_4X4, -1, (uint16)GPV_PER_OBJECT, "world_texture_view_proj");
199
200 it->mVSOutLightPosition = vsMain->resolveOutputParameter(Parameter::Content(Parameter::SPC_POSITION_LIGHT_SPACE0 + lightIndex));
201 it->mPSInLightPosition = psMain->resolveInputParameter(it->mVSOutLightPosition);
202 it->mTextureSampler = psProgram->resolveParameter(GCT_SAMPLER2D, it->mTextureSamplerIndex, (uint16)GPV_GLOBAL, "shadow_map");
203
204 it->mInvTextureSize = psProgram->resolveParameter(GCT_FLOAT4, -1, (uint16)GPV_GLOBAL, "inv_shadow_texture_size");
205
206 if (!(it->mInvTextureSize.get()) || !(it->mTextureSampler.get()) || !(it->mPSInLightPosition.get()) ||
207 !(it->mVSOutLightPosition.get()) || !(it->mWorldViewProjMatrix.get()))
208 {
209 OGRE_EXCEPT( Exception::ERR_INTERNAL_ERROR,
210 "Not all parameters could be constructed for the sub-render state.",
211 "IntegratedPSSM3::resolveParameters" );
212 }
213
214 ++lightIndex;
215 ++it;
216 }
217
218 if (!(mVSInPos.get()) || !(mVSOutPos.get()) || !(mVSOutDepth.get()) || !(mPSInDepth.get()) || !(mPSDiffuse.get()) || !(mPSOutDiffuse.get()) ||
219 !(mPSSpecualr.get()) || !(mPSLocalShadowFactor.get()) || !(mPSSplitPoints.get()) || !(mPSDerivedSceneColour.get()))
220 {
221 OGRE_EXCEPT( Exception::ERR_INTERNAL_ERROR,
222 "Not all parameters could be constructed for the sub-render state.",
223 "IntegratedPSSM3::resolveParameters" );
224 }
225
226 return true;
227 }
228
229 //-----------------------------------------------------------------------
resolveDependencies(ProgramSet * programSet)230 bool IntegratedPSSM3::resolveDependencies(ProgramSet* programSet)
231 {
232 Program* vsProgram = programSet->getCpuProgram(GPT_VERTEX_PROGRAM);
233 Program* psProgram = programSet->getCpuProgram(GPT_FRAGMENT_PROGRAM);
234
235 vsProgram->addDependency(FFP_LIB_COMMON);
236
237 psProgram->addDependency(FFP_LIB_COMMON);
238 psProgram->addDependency(SGX_LIB_INTEGRATEDPSSM);
239
240 return true;
241 }
242
243 //-----------------------------------------------------------------------
addFunctionInvocations(ProgramSet * programSet)244 bool IntegratedPSSM3::addFunctionInvocations(ProgramSet* programSet)
245 {
246 Program* vsProgram = programSet->getCpuProgram(GPT_VERTEX_PROGRAM);
247 Function* vsMain = vsProgram->getEntryPointFunction();
248 Program* psProgram = programSet->getCpuProgram(GPT_FRAGMENT_PROGRAM);
249
250 // Add vertex shader invocations.
251 if (false == addVSInvocation(vsMain, FFP_VS_TEXTURING + 1))
252 return false;
253
254 // Add pixel shader invocations.
255 if (false == addPSInvocation(psProgram, FFP_PS_COLOUR_BEGIN + 2))
256 return false;
257
258 return true;
259 }
260
261 //-----------------------------------------------------------------------
addVSInvocation(Function * vsMain,const int groupOrder)262 bool IntegratedPSSM3::addVSInvocation(Function* vsMain, const int groupOrder)
263 {
264 auto stage = vsMain->getStage(groupOrder);
265
266 // Output the vertex depth in camera space.
267 stage.assign(In(mVSOutPos).z(), mVSOutDepth);
268
269 // Compute world space position.
270 ShadowTextureParamsIterator it = mShadowTextureParamsList.begin();
271
272 while(it != mShadowTextureParamsList.end())
273 {
274 stage.callFunction(FFP_FUNC_TRANSFORM, it->mWorldViewProjMatrix, mVSInPos, it->mVSOutLightPosition);
275 ++it;
276 }
277
278 return true;
279 }
280
281 //-----------------------------------------------------------------------
addPSInvocation(Program * psProgram,const int groupOrder)282 bool IntegratedPSSM3::addPSInvocation(Program* psProgram, const int groupOrder)
283 {
284 Function* psMain = psProgram->getEntryPointFunction();
285 auto stage = psMain->getStage(groupOrder);
286
287 ShadowTextureParams& splitParams0 = mShadowTextureParamsList[0];
288 ShadowTextureParams& splitParams1 = mShadowTextureParamsList[1];
289 ShadowTextureParams& splitParams2 = mShadowTextureParamsList[2];
290
291 // Compute shadow factor.
292 stage.callFunction(SGX_FUNC_COMPUTE_SHADOW_COLOUR3,
293 {In(mPSInDepth), In(mPSSplitPoints), In(splitParams0.mPSInLightPosition),
294 In(splitParams1.mPSInLightPosition), In(splitParams2.mPSInLightPosition),
295 In(splitParams0.mTextureSampler), In(splitParams1.mTextureSampler),
296 In(splitParams2.mTextureSampler), In(splitParams0.mInvTextureSize),
297 In(splitParams1.mInvTextureSize), In(splitParams2.mInvTextureSize), Out(mPSLocalShadowFactor)});
298
299 // Apply shadow factor on diffuse colour.
300 stage.callFunction(SGX_FUNC_APPLYSHADOWFACTOR_DIFFUSE,
301 {In(mPSDerivedSceneColour), In(mPSDiffuse), In(mPSLocalShadowFactor), Out(mPSDiffuse)});
302
303 // Apply shadow factor on specular colour.
304 stage.callFunction(SGX_FUNC_MODULATE_SCALAR, mPSLocalShadowFactor, mPSSpecualr, mPSSpecualr);
305
306 // Assign the local diffuse to output diffuse.
307 stage.assign(mPSDiffuse, mPSOutDiffuse);
308
309 return true;
310 }
311
312
313
314 //-----------------------------------------------------------------------
getType() const315 const String& IntegratedPSSM3Factory::getType() const
316 {
317 return IntegratedPSSM3::Type;
318 }
319
320 //-----------------------------------------------------------------------
createInstance(ScriptCompiler * compiler,PropertyAbstractNode * prop,Pass * pass,SGScriptTranslator * translator)321 SubRenderState* IntegratedPSSM3Factory::createInstance(ScriptCompiler* compiler,
322 PropertyAbstractNode* prop, Pass* pass, SGScriptTranslator* translator)
323 {
324 if (prop->name == "integrated_pssm4")
325 {
326 if (prop->values.size() != 4)
327 {
328 compiler->addError(ScriptCompiler::CE_INVALIDPARAMETERS, prop->file, prop->line);
329 }
330 else
331 {
332 IntegratedPSSM3::SplitPointList splitPointList;
333
334 AbstractNodeList::const_iterator it = prop->values.begin();
335 AbstractNodeList::const_iterator itEnd = prop->values.end();
336
337 while(it != itEnd)
338 {
339 Real curSplitValue;
340
341 if (false == SGScriptTranslator::getReal(*it, &curSplitValue))
342 {
343 compiler->addError(ScriptCompiler::CE_INVALIDPARAMETERS, prop->file, prop->line);
344 break;
345 }
346
347 splitPointList.push_back(curSplitValue);
348
349 ++it;
350 }
351
352 if (splitPointList.size() == 4)
353 {
354 SubRenderState* subRenderState = createOrRetrieveInstance(translator);
355 IntegratedPSSM3* pssmSubRenderState = static_cast<IntegratedPSSM3*>(subRenderState);
356
357 pssmSubRenderState->setSplitPoints(splitPointList);
358
359 return pssmSubRenderState;
360 }
361 }
362 }
363
364 return NULL;
365 }
366
367 //-----------------------------------------------------------------------
createInstanceImpl()368 SubRenderState* IntegratedPSSM3Factory::createInstanceImpl()
369 {
370 return OGRE_NEW IntegratedPSSM3;
371 }
372
373 }
374 }
375
376 #endif
377