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-2013 Torus Knot Software Ltd
8 Also see acknowledgements in Readme.html
9 
10 You may use this sample code for anything you like, it is not covered by the
11 same license as the rest of the engine.
12 -----------------------------------------------------------------------------
13 */
14 
15 
16 #include "GBufferMaterialGenerator.h"
17 
18 #include "OgreMaterialManager.h"
19 #include "OgreGpuProgramManager.h"
20 #include "OgreRoot.h"
21 #include "OgreStringConverter.h"
22 #include "OgreHighLevelGpuProgramManager.h"
23 #include "OgreTechnique.h"
24 
25 using namespace Ogre;
26 
27 //Use this directive to control whether you are writing projective (regular) or linear depth.
28 #define WRITE_LINEAR_DEPTH
29 
30 //This is the concrete implementation of the material generator.
31 class GBufferMaterialGeneratorImpl : public MaterialGenerator::Impl
32 {
33 public:
GBufferMaterialGeneratorImpl(const String & baseName)34 	GBufferMaterialGeneratorImpl(const String& baseName) :
35       mBaseName(baseName)
36       {
37           mIsSm4 = GpuProgramManager::getSingleton().isSyntaxSupported("vs_4_0_level_9_1");
38           mIsGLSL = (GpuProgramManager::getSingleton().isSyntaxSupported("glsl") || GpuProgramManager::getSingleton().isSyntaxSupported("glsles")) &&
39                     !(GpuProgramManager::getSingleton().isSyntaxSupported("vs_1_1") || GpuProgramManager::getSingleton().isSyntaxSupported("arbvp1"));
40       }
41 
42 protected:
43 	String mBaseName;
44     bool mIsSm4;
45     bool mIsGLSL;
46 	virtual GpuProgramPtr generateVertexShader(MaterialGenerator::Perm permutation);
47 	virtual GpuProgramPtr generateFragmentShader(MaterialGenerator::Perm permutation);
48 	virtual MaterialPtr generateTemplateMaterial(MaterialGenerator::Perm permutation);
49 
50 };
51 
GBufferMaterialGenerator()52 GBufferMaterialGenerator::GBufferMaterialGenerator() {
53     vsMask = VS_MASK;
54 	fsMask = FS_MASK;
55 	matMask = MAT_MASK;
56 	materialBaseName = "DeferredShading/GBuffer/";
57 	mImpl = new GBufferMaterialGeneratorImpl(materialBaseName);
58 }
59 
generateVertexShader(MaterialGenerator::Perm permutation)60 GpuProgramPtr GBufferMaterialGeneratorImpl::generateVertexShader(MaterialGenerator::Perm permutation)
61 {
62 	StringStream ss;
63 
64     if(mIsGLSL)
65     {
66         int shadingLangVersion = Root::getSingleton().getRenderSystem()->getNativeShadingLanguageVersion();
67         const char *inSemantic = shadingLangVersion >= 150 ? "in" : "attribute";
68         const char *outSemantic = shadingLangVersion >= 150 ? "out" : "varying";
69 
70         if(GpuProgramManager::getSingleton().isSyntaxSupported("glsles"))
71         {
72             ss << "#version 300 es" << std::endl;
73             ss << "precision mediump int;" << std::endl;
74             ss << "precision mediump float;" << std::endl;
75         }
76         else
77             ss << "#version " << shadingLangVersion << std::endl;
78 
79         ss << inSemantic << " vec4 vertex;" << std::endl;
80         ss << inSemantic << " vec3 normal;" << std::endl;
81 
82         uint32 numTexCoords = (permutation & GBufferMaterialGenerator::GBP_TEXCOORD_MASK) >> 8;
83         for (uint32 i = 0; i < numTexCoords; i++)
84         {
85             ss << inSemantic << " vec2 uv" << i << ';' << std::endl;
86         }
87 
88         if (permutation & GBufferMaterialGenerator::GBP_NORMAL_MAP)
89         {
90             ss << inSemantic << " vec3 tangent;" << std::endl;
91         }
92 
93         //TODO : Skinning inputs
94         ss << std::endl;
95 
96 #ifdef WRITE_LINEAR_DEPTH
97         ss << outSemantic << " vec3 oViewPos;" << std::endl;
98 #else
99         ss << outSemantic << " float oDepth;" << std::endl;
100 #endif
101         ss << outSemantic << " vec3 oNormal;" << std::endl;
102         if (permutation & GBufferMaterialGenerator::GBP_NORMAL_MAP)
103         {
104             ss << outSemantic << " vec3 oTangent;" << std::endl;
105             ss << outSemantic << " vec3 oBiNormal;" << std::endl;
106         }
107         for (uint32 i = 0; i < numTexCoords; i++)
108         {
109             ss << outSemantic << " vec2 oUv" << i << ";" << std::endl;
110         }
111 
112         ss << std::endl;
113 
114         ss << "uniform mat4 cWorldViewProj;" << std::endl;
115         ss << "uniform mat4 cWorldView;" << std::endl;
116 
117         ss << "void main()" << std::endl;
118 
119         ss << "{" << std::endl;
120         ss << "	gl_Position = cWorldViewProj * vertex;" << std::endl;
121         ss << "	oNormal = (cWorldView * vec4(normal,0)).xyz;" << std::endl;
122         if (permutation & GBufferMaterialGenerator::GBP_NORMAL_MAP)
123         {
124             ss << "	oTangent = (cWorldView * vec4(tangent,0)).xyz;" << std::endl;
125             ss << "	oBiNormal = cross(oNormal, oTangent);" << std::endl;
126         }
127 
128 #ifdef WRITE_LINEAR_DEPTH
129         ss << "	oViewPos = (cWorldView * vertex).xyz;" << std::endl;
130 #else
131         ss << "	oDepth = gl_Position.w;" << std::endl;
132 #endif
133 
134         for (uint32 i=0; i<numTexCoords; i++) {
135             ss << "	oUv" << i << " = uv" << i << ';' << std::endl;
136         }
137 
138         ss << "}" << std::endl;
139 
140         String programSource = ss.str();
141         String programName = mBaseName + "VP_" + StringConverter::toString(permutation);
142 
143 #if OGRE_DEBUG_MODE
144         LogManager::getSingleton().getDefaultLog()->logMessage(programSource);
145 #endif
146 
147         // Create shader object
148         HighLevelGpuProgramPtr ptrProgram;
149         if(GpuProgramManager::getSingleton().isSyntaxSupported("glsles"))
150         {
151             ptrProgram = HighLevelGpuProgramManager::getSingleton().createProgram(programName,
152                                                                                   ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
153                                                                                   "glsles", GPT_VERTEX_PROGRAM);
154             ptrProgram->setParameter("syntax", "glsles");
155         }
156         else
157         {
158             ptrProgram = HighLevelGpuProgramManager::getSingleton().createProgram(programName,
159                                                                                   ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
160                                                                                   "glsl", GPT_VERTEX_PROGRAM);
161         }
162         ptrProgram->setSource(programSource);
163 
164         const GpuProgramParametersSharedPtr& params = ptrProgram->getDefaultParameters();
165         params->setNamedAutoConstant("cWorldViewProj", GpuProgramParameters::ACT_WORLDVIEWPROJ_MATRIX);
166         params->setNamedAutoConstant("cWorldView", GpuProgramParameters::ACT_WORLDVIEW_MATRIX);
167         ptrProgram->load();
168 
169         return GpuProgramPtr(ptrProgram);
170     }
171     else
172     {
173         ss << "void ToGBufferVP(" << std::endl;
174         ss << "	float4 iPosition : POSITION," << std::endl;
175         ss << "	float3 iNormal   : NORMAL," << std::endl;
176 
177         uint32 numTexCoords = (permutation & GBufferMaterialGenerator::GBP_TEXCOORD_MASK) >> 8;
178         for (uint32 i=0; i<numTexCoords; i++)
179         {
180             ss << "	float2 iUV" << i << " : TEXCOORD" << i << ',' << std::endl;
181         }
182 
183         if (permutation & GBufferMaterialGenerator::GBP_NORMAL_MAP)
184         {
185             if(mIsSm4)
186             {
187                 ss << "	float3 iTangent : TANGENT," << std::endl;
188             }
189             else
190             {
191                 ss << "	float3 iTangent : TANGENT0," << std::endl;
192             }
193         }
194 
195         //TODO : Skinning inputs
196         ss << std::endl;
197 
198 
199 
200         ss << "	out float4 oPosition : " ;
201         if(mIsSm4)
202         {
203             ss << "SV_";
204         }
205         ss << "POSITION," << std::endl;
206     #ifdef WRITE_LINEAR_DEPTH
207         ss << "	out float3 oViewPos : TEXCOORD0," << std::endl;
208     #else
209         ss << "	out float oDepth : TEXCOORD0," << std::endl;
210     #endif
211         ss << "	out float3 oNormal : TEXCOORD1," << std::endl;
212         int texCoordNum = 2;
213         if (permutation & GBufferMaterialGenerator::GBP_NORMAL_MAP)
214         {
215             ss << "	out float3 oTangent : TEXCOORD" << texCoordNum++ << ',' << std::endl;
216             ss << "	out float3 oBiNormal : TEXCOORD" << texCoordNum++ << ',' << std::endl;
217         }
218         for (uint32 i=0; i<numTexCoords; i++)
219         {
220             ss << "	out float2 oUV" << i << " : TEXCOORD" << texCoordNum++ << ',' << std::endl;
221         }
222 
223         ss << std::endl;
224 
225         ss << "	uniform float4x4 cWorldViewProj," << std::endl;
226         ss << "	uniform float4x4 cWorldView" << std::endl;
227 
228         ss << "	)" << std::endl;
229 
230 
231         ss << "{" << std::endl;
232         ss << "	oPosition = mul(cWorldViewProj, iPosition);" << std::endl;
233         ss << "	oNormal = mul(cWorldView, float4(iNormal,0)).xyz;" << std::endl;
234         if (permutation & GBufferMaterialGenerator::GBP_NORMAL_MAP)
235         {
236             ss << "	oTangent = mul(cWorldView, float4(iTangent,0)).xyz;" << std::endl;
237             ss << "	oBiNormal = cross(oNormal, oTangent);" << std::endl;
238         }
239 
240     #ifdef WRITE_LINEAR_DEPTH
241         ss << "	oViewPos = mul(cWorldView, iPosition).xyz;" << std::endl;
242     #else
243         ss << "	oDepth = oPosition.w;" << std::endl;
244     #endif
245 
246         for (uint32 i=0; i<numTexCoords; i++) {
247             ss << "	oUV" << i << " = iUV" << i << ';' << std::endl;
248         }
249 
250         ss << "}" << std::endl;
251 
252         String programSource = ss.str();
253         String programName = mBaseName + "VP_" + StringConverter::toString(permutation);
254 
255     #if OGRE_DEBUG_MODE
256         LogManager::getSingleton().getDefaultLog()->logMessage(programSource);
257     #endif
258 
259         // Create shader object
260         HighLevelGpuProgramPtr ptrProgram = HighLevelGpuProgramManager::getSingleton().createProgram(
261             programName, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
262             "cg", GPT_VERTEX_PROGRAM);
263         ptrProgram->setSource(programSource);
264         ptrProgram->setParameter("entry_point","ToGBufferVP");
265         if(mIsSm4)
266         {
267             ptrProgram->setParameter("profiles","vs_4_0");
268         }
269         else
270         {
271             ptrProgram->setParameter("profiles","vs_1_1 arbvp1");
272         }
273 
274         const GpuProgramParametersSharedPtr& params = ptrProgram->getDefaultParameters();
275         params->setNamedAutoConstant("cWorldViewProj", GpuProgramParameters::ACT_WORLDVIEWPROJ_MATRIX);
276         params->setNamedAutoConstant("cWorldView", GpuProgramParameters::ACT_WORLDVIEW_MATRIX);
277         ptrProgram->load();
278 
279         return GpuProgramPtr(ptrProgram);
280     }
281 }
282 
generateFragmentShader(MaterialGenerator::Perm permutation)283 GpuProgramPtr GBufferMaterialGeneratorImpl::generateFragmentShader(MaterialGenerator::Perm permutation)
284 {
285 	StringStream ss;
286 
287     if(mIsGLSL)
288     {
289         int shadingLangVersion = Root::getSingleton().getRenderSystem()->getNativeShadingLanguageVersion();
290         const char *inSemantic = shadingLangVersion >= 150 ? "in" : "varying";
291         const char *outData = shadingLangVersion >= 150 ? "fragData" : "gl_FragData";
292         const char *textureFunc = shadingLangVersion >= 150 ? "texture" : "texture2D";
293         if(GpuProgramManager::getSingleton().isSyntaxSupported("glsles"))
294         {
295             ss << "#version 300 es" << std::endl;
296             ss << "precision mediump int;" << std::endl;
297             ss << "precision mediump float;" << std::endl;
298         }
299         else
300         {
301             ss << "#version " << shadingLangVersion << std::endl;
302             if(shadingLangVersion >= 150)
303             {
304                 ss << "out vec4 fragData[2];";
305             }
306         }
307 #ifdef WRITE_LINEAR_DEPTH
308         ss << inSemantic << " vec3 oViewPos;" << std::endl;
309 #else
310         ss << inSemantic << " float oDepth;" << std::endl;
311 #endif
312         ss << inSemantic << " vec3 oNormal;" << std::endl;
313 
314         if (permutation & GBufferMaterialGenerator::GBP_NORMAL_MAP)
315         {
316             ss << inSemantic << " vec3 oTangent;" << std::endl;
317             ss << inSemantic << " vec3 oBiNormal;" << std::endl;
318         }
319 
320         uint32 numTexCoords = (permutation & GBufferMaterialGenerator::GBP_TEXCOORD_MASK) >> 8;
321         for (uint32 i = 0; i < numTexCoords; i++)
322         {
323             ss << inSemantic << " vec2 oUv" << i << ';' << std::endl;
324         }
325 
326         ss << std::endl;
327 
328         if (permutation & GBufferMaterialGenerator::GBP_NORMAL_MAP)
329         {
330             ss << "uniform sampler2D sNormalMap;" << std::endl;
331         }
332 
333         uint32 numTextures = permutation & GBufferMaterialGenerator::GBP_TEXTURE_MASK;
334         for (uint32 i = 0; i < numTextures; i++)
335         {
336             ss << "uniform sampler2D sTex" << i << ";" << std::endl;
337         }
338         if (numTextures == 0 || permutation & GBufferMaterialGenerator::GBP_HAS_DIFFUSE_COLOUR)
339         {
340             ss << "uniform vec4 cDiffuseColour;" << std::endl;
341         }
342 
343 #ifdef WRITE_LINEAR_DEPTH
344         ss << "uniform float cFarDistance;" << std::endl;
345 #endif
346 
347         ss << "uniform float cSpecularity;" << std::endl;
348 
349         ss << "void main()" << std::endl;
350         ss << "{" << std::endl;
351 
352         if (numTexCoords > 0 && numTextures > 0)
353         {
354             ss << outData << "[0].rgb = " << textureFunc << "(sTex0, oUv0).rgb;" << std::endl;
355             if (permutation & GBufferMaterialGenerator::GBP_HAS_DIFFUSE_COLOUR)
356             {
357                 ss << outData << "[0].rgb *= cDiffuseColour.rgb;" << std::endl;
358             }
359         }
360         else
361         {
362             ss << outData << "[0].rgb = cDiffuseColour.rgb;" << std::endl;
363         }
364 
365         ss << outData << "[0].a = cSpecularity;" << std::endl;
366         if (permutation & GBufferMaterialGenerator::GBP_NORMAL_MAP)
367         {
368             ss << "	vec3 texNormal = (" << textureFunc << "(sNormalMap, oUv0).rgb-0.5)*2.0;" << std::endl;
369             ss << "	mat3 normalRotation = mat3(oTangent, oBiNormal, oNormal);" << std::endl;
370             ss << outData << "[1].rgb = normalize(texNormal * normalRotation);" << std::endl;
371         }
372         else
373         {
374             ss << outData << "[1].rgb = normalize(oNormal);" << std::endl;
375         }
376         ss << outData << "[1].rgb = normalize(oNormal);" << std::endl;
377 #ifdef WRITE_LINEAR_DEPTH
378         ss << outData << "[1].a = length(oViewPos) / cFarDistance;" << std::endl;
379 #else
380         ss << outData << "[1].a = oDepth;" << std::endl;
381 #endif
382 
383         ss << "}" << std::endl;
384 
385         String programSource = ss.str();
386         String programName = mBaseName + "FP_" + StringConverter::toString(permutation);
387 
388 #if OGRE_DEBUG_MODE
389         LogManager::getSingleton().getDefaultLog()->logMessage(programSource);
390 #endif
391 
392         // Create shader object
393         HighLevelGpuProgramPtr ptrProgram;
394         if(GpuProgramManager::getSingleton().isSyntaxSupported("glsles"))
395         {
396             ptrProgram = HighLevelGpuProgramManager::getSingleton().createProgram(programName,
397                                                                                   ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
398                                                                                   "glsles", GPT_FRAGMENT_PROGRAM);
399             ptrProgram->setParameter("syntax", "glsles");
400         }
401         else
402         {
403             ptrProgram = HighLevelGpuProgramManager::getSingleton().createProgram(programName,
404                                                                                   ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
405                                                                                   "glsl", GPT_FRAGMENT_PROGRAM);
406         }
407         ptrProgram->setSource(programSource);
408 
409         const GpuProgramParametersSharedPtr& params = ptrProgram->getDefaultParameters();
410         params->setNamedAutoConstant("cSpecularity", GpuProgramParameters::ACT_SURFACE_SHININESS);
411         if (numTextures == 0 || permutation & GBufferMaterialGenerator::GBP_HAS_DIFFUSE_COLOUR)
412         {
413             params->setNamedAutoConstant("cDiffuseColour", GpuProgramParameters::ACT_SURFACE_DIFFUSE_COLOUR);
414         }
415 
416         // Bind samplers
417         int samplerNum = 0;
418         if (permutation & GBufferMaterialGenerator::GBP_NORMAL_MAP)
419         {
420             params->setNamedConstant("sNormalMap", samplerNum++);
421         }
422         for (uint32 i = 0; i < numTextures; i++, samplerNum++)
423         {
424             params->setNamedConstant("sTex" + StringConverter::toString(i), samplerNum);
425         }
426 
427 #ifdef WRITE_LINEAR_DEPTH
428         //TODO : Should this be the distance to the far corner, not the far clip distance?
429         params->setNamedAutoConstant("cFarDistance", GpuProgramParameters::ACT_FAR_CLIP_DISTANCE);
430 #endif
431 
432         ptrProgram->load();
433         return GpuProgramPtr(ptrProgram);
434     }
435     else
436     {
437         ss << "void ToGBufferFP(" << std::endl;
438         if(mIsSm4)
439         {
440             ss << "float4 oPosition : SV_POSITION," << std::endl;
441         }
442 
443     #ifdef WRITE_LINEAR_DEPTH
444         ss << "	float3 iViewPos : TEXCOORD0," << std::endl;
445     #else
446         ss << "	float1 iDepth : TEXCOORD0," << std::endl;
447     #endif
448         ss << "	float3 iNormal   : TEXCOORD1," << std::endl;
449 
450         int texCoordNum = 2;
451         if (permutation & GBufferMaterialGenerator::GBP_NORMAL_MAP)
452         {
453             ss << "	float3 iTangent : TEXCOORD" << texCoordNum++ << ',' << std::endl;
454             ss << "	float3 iBiNormal : TEXCOORD" << texCoordNum++ << ',' << std::endl;
455         }
456 
457         uint32 numTexCoords = (permutation & GBufferMaterialGenerator::GBP_TEXCOORD_MASK) >> 8;
458         for (uint32 i=0; i<numTexCoords; i++)
459         {
460             ss << "	float2 iUV" << i << " : TEXCOORD" << texCoordNum++ << ',' << std::endl;
461         }
462 
463         ss << std::endl;
464 
465         ss << "	out float4 oColor0 : COLOR0," << std::endl;
466         ss << "	out float4 oColor1 : COLOR1," << std::endl;
467 
468         ss << std::endl;
469 
470         int samplerNum = 0;
471         if (permutation & GBufferMaterialGenerator::GBP_NORMAL_MAP)
472         {
473             if(mIsSm4)
474             {
475                 ss << "	uniform sampler2D sNormalMap : register(s" << samplerNum++ << ")," << std::endl;
476             }
477             else
478             {
479                 ss << "	uniform sampler sNormalMap : register(s" << samplerNum++ << ")," << std::endl;
480             }
481         }
482         uint32 numTextures = permutation & GBufferMaterialGenerator::GBP_TEXTURE_MASK;
483         for (uint32 i=0; i<numTextures; i++) {
484             if(mIsSm4)
485             {
486                 ss << "	uniform sampler2D sTex" << i << " : register(s" << samplerNum++ << ")," << std::endl;
487             }
488             else
489             {
490                 ss << "	uniform sampler sTex" << i << " : register(s" << samplerNum++ << ")," << std::endl;
491             }
492         }
493         if (numTextures == 0 || permutation & GBufferMaterialGenerator::GBP_HAS_DIFFUSE_COLOUR)
494         {
495             ss << "	uniform float4 cDiffuseColour," << std::endl;
496         }
497 
498     #ifdef WRITE_LINEAR_DEPTH
499         ss << "	uniform float cFarDistance," << std::endl;
500     #endif
501 
502         ss << "	uniform float cSpecularity" << std::endl;
503 
504         ss << "	)" << std::endl;
505 
506 
507         ss << "{" << std::endl;
508 
509         if (numTexCoords > 0 && numTextures > 0)
510         {
511             ss << "	oColor0.rgb = tex2D(sTex0, iUV0).rgb;" << std::endl;
512             if (permutation & GBufferMaterialGenerator::GBP_HAS_DIFFUSE_COLOUR)
513             {
514                 ss << "	oColor0.rgb *= cDiffuseColour.rgb;" << std::endl;
515             }
516         }
517         else
518         {
519             ss << "	oColor0.rgb = cDiffuseColour.rgb;" << std::endl;
520         }
521 
522 
523         ss << "	oColor0.a = cSpecularity;" << std::endl;
524         if (permutation & GBufferMaterialGenerator::GBP_NORMAL_MAP)
525         {
526             ss << "	float3 texNormal = (tex2D(sNormalMap, iUV0).rgb-0.5)*2;" << std::endl;
527             ss << "	float3x3 normalRotation = float3x3(iTangent, iBiNormal, iNormal);" << std::endl;
528             ss << "	oColor1.rgb = normalize(mul(texNormal, normalRotation));" << std::endl;
529         } else
530         {
531             ss << "	oColor1.rgb = normalize(iNormal);" << std::endl;
532         }
533     #ifdef WRITE_LINEAR_DEPTH
534         ss << "	oColor1.a = length(iViewPos) / cFarDistance;" << std::endl;
535     #else
536         ss << "	oColor1.a = iDepth;" << std::endl;
537     #endif
538 
539         ss << "}" << std::endl;
540 
541         String programSource = ss.str();
542         String programName = mBaseName + "FP_" + StringConverter::toString(permutation);
543 
544     #if OGRE_DEBUG_MODE
545         LogManager::getSingleton().getDefaultLog()->logMessage(programSource);
546     #endif
547 
548         // Create shader object
549         HighLevelGpuProgramPtr ptrProgram = HighLevelGpuProgramManager::getSingleton().createProgram(
550             programName, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
551             "cg", GPT_FRAGMENT_PROGRAM);
552         ptrProgram->setSource(programSource);
553         ptrProgram->setParameter("entry_point","ToGBufferFP");
554         if(mIsSm4)
555         {
556             ptrProgram->setParameter("profiles","ps_4_0");
557         }
558         else
559         {
560             ptrProgram->setParameter("profiles","ps_2_0 arbfp1");
561         }
562 
563         const GpuProgramParametersSharedPtr& params = ptrProgram->getDefaultParameters();
564         params->setNamedAutoConstant("cSpecularity", GpuProgramParameters::ACT_SURFACE_SHININESS);
565         if (numTextures == 0 || permutation & GBufferMaterialGenerator::GBP_HAS_DIFFUSE_COLOUR)
566         {
567             params->setNamedAutoConstant("cDiffuseColour", GpuProgramParameters::ACT_SURFACE_DIFFUSE_COLOUR);
568         }
569 
570     #ifdef WRITE_LINEAR_DEPTH
571         //TODO : Should this be the distance to the far corner, not the far clip distance?
572         params->setNamedAutoConstant("cFarDistance", GpuProgramParameters::ACT_FAR_CLIP_DISTANCE);
573     #endif
574 
575         ptrProgram->load();
576         return GpuProgramPtr(ptrProgram);
577     }
578 }
579 
generateTemplateMaterial(MaterialGenerator::Perm permutation)580 MaterialPtr GBufferMaterialGeneratorImpl::generateTemplateMaterial(MaterialGenerator::Perm permutation)
581 {
582 	String matName = mBaseName + "Mat_" + StringConverter::toString(permutation);
583 
584 	MaterialPtr matPtr = MaterialManager::getSingleton().create
585 		(matName, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
586 	Pass* pass = matPtr->getTechnique(0)->getPass(0);
587 	pass->setName(mBaseName + "Pass_" + StringConverter::toString(permutation));
588 	pass->setLightingEnabled(false);
589 	if (permutation & GBufferMaterialGenerator::GBP_NORMAL_MAP)
590 	{
591 		pass->createTextureUnitState();
592 	}
593 	uint32 numTextures = permutation & GBufferMaterialGenerator::GBP_TEXTURE_MASK;
594 	for (uint32 i=0; i<numTextures; i++)
595 	{
596 		pass->createTextureUnitState();
597 	}
598 
599 	return matPtr;
600 }
601