/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 |