Project

General

Profile

SO3Engine
SO3DeferredLightAmbientMaterialGenerator.cpp
Go to the documentation of this file.
1/*
2-----------------------------------------------------------------------------
3This source file is part of OpenSpace3D
4For the latest info, see http://www.openspace3d.com
5
6Copyright (c) 2012 I-maginer
7
8This program is free software; you can redistribute it and/or modify it under
9the terms of the GNU Lesser General Public License as published by the Free Software
10Foundation; either version 2 of the License, or (at your option) any later
11version.
12
13This program is distributed in the hope that it will be useful, but WITHOUT
14ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
15FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
16
17You should have received a copy of the GNU Lesser General Public License along with
18this program; if not, write to the Free Software Foundation, Inc., 59 Temple
19Place - Suite 330, Boston, MA 02111-1307, USA, or go to
20http://www.gnu.org/copyleft/lesser.txt
21
22-----------------------------------------------------------------------------
23*/
24
26
27namespace SO3
28{
29
33
37
38Ogre::GpuProgramPtr SDeferredLightAmbientMaterialGenerator::GenerateVertexShader(SGBuffer* gbuffer, Ogre::uint32 permutationValue)
39{
40 Ogre::StringStream ss;
41
42 ss << "void SO3_DeferredLightAmbient_vs(float4 Pos: POSITION," << std::endl;
43 ss << " out float4 oPos: POSITION," << std::endl;
44 ss << " out float2 oTexCoord: TEXCOORD0," << std::endl;
45 ss << " out float3 oRay : TEXCOORD1," << std::endl;
46 ss << " uniform float3 farCorner," << std::endl;
47 ss << " uniform float flip" << std::endl;
48 ss << ")" << std::endl;
49 ss << "{" << std::endl;
50
51 // Clean up inaccuracies
52 ss << " Pos.xy = sign(Pos.xy);" << std::endl;
53
54 // View space
55 ss << " oPos = float4(Pos.xy, 0, 1);" << std::endl;
56 ss << " oPos.y *= flip;" << std::endl;
57
58 // Image-space
59 ss << " oTexCoord.x = 0.5 * (1 + Pos.x);" << std::endl;
60 ss << " oTexCoord.y = 0.5 * (1 - Pos.y);" << std::endl;
61
62 // This ray will be interpolated and will be the ray from the camera
63 // to the far clip plane, per pixel
64 ss << " oRay = farCorner * float3(Pos.xy, 1);" << std::endl;
65 ss << "}" << std::endl;
66
67
68 // Prepare shader generation
69 Ogre::String programSource = ss.str();
70 Ogre::String programName = materialBaseName +"Shaders/Vertex/"+ gbuffer->GetName();
71
72#if SO3_DEBUG
73 // Show the generated vertex program in the log.
74 Ogre::LogManager::getSingleton().getDefaultLog()->logMessage(programSource, Ogre::LML_CRITICAL);
75#endif
76
77 // Create shader object
78 // TODO in another group than Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME?
79 Ogre::HighLevelGpuProgramPtr ptrProgram = Ogre::HighLevelGpuProgramManager::getSingleton().createProgram(programName, Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, "cg", Ogre::GPT_VERTEX_PROGRAM);
80 ptrProgram->setSource(programSource);
81 ptrProgram->setParameter("entry_point", "SO3_DeferredLightAmbient_vs");
82 ptrProgram->setParameter("profiles", "vs_1_1 arbvp1");
83
84 // Bind our function parameters to Ogre's related values.
85 const Ogre::GpuProgramParametersSharedPtr& params = ptrProgram->getDefaultParameters();
86
87 if (params->_findNamedConstantDefinition("flip"))
88 params->setNamedAutoConstant("flip", Ogre::GpuProgramParameters::ACT_RENDER_TARGET_FLIPPING);
89
90 if (params->_findNamedConstantDefinition("farCorner"))
91 params->setNamedConstant("farCorner", Ogre::Vector3::UNIT_SCALE);
92
93 // Return light vertex shader
94 ptrProgram->load();
95 return Ogre::GpuProgramPtr(ptrProgram);
96}
97
98Ogre::GpuProgramPtr SDeferredLightAmbientMaterialGenerator::GenerateFragmentShader(SGBuffer* gbuffer, Ogre::uint32 permutationValue)
99{
100 Ogre::StringStream ss;
101
102 // Structures defines
104
105 //GL and DX expect a different value, GL needs it in [0..1]
106 ss << "arbfp1 float finalDepth(float4 p)" << std::endl;
107 ss << "{" << std::endl;
108 ss << " return (p.z / p.w) * 0.5 + 0.5;" << std::endl;
109 ss << "}" << std::endl;
110
111 // normally it's in [-1..1]
112 ss << "float finalDepth(float4 p)" << std::endl;
113 ss << "{" << std::endl;
114 ss << " return p.z / p.w;" << std::endl;
115 ss << "}" << std::endl;
116
117 ss << "void SO3_DeferredLightAmbient_ps(float2 texCoord : TEXCOORD0, " << std::endl;
118 ss << " float3 ray : TEXCOORD1," << std::endl;
119 ss << " out float4 oColour : COLOR," << std::endl;
120 ss << " out float oDepth : DEPTH," << std::endl;
121 ss << " " << gbuffer->GetGBufferCompositorPixelInputStructureTypeName() << " gBuffer," << std::endl; // Input parameters (list of mrts)
122 ss << " uniform float4x4 proj," << std::endl;
123 ss << " uniform float4 ambientColor," << std::endl;
124 ss << " uniform float farClipDistance" << std::endl;
125 ss << " )" << std::endl;
126 ss << "{" << std::endl;
127
128 // Clip fragment if depth is too close, so the skybox can be rendered on the background
129 ss << " float depth = gBuffer.GetDepth(texCoord);" << std::endl;
130 ss << " clip(depth - 0.0001);" << std::endl; // TODO clip(depth - (1 / (farClipDistance - nearClipDistance))
131
132 // Get diffuse colour
133 ss << "float4 diffuseColour = float4(gBuffer.GetDiffuse(texCoord), 0);" << std::endl;
134
135 // If texel got emissive power, and the gbuffer supports emissive channel.
137 {
138 ss << " float emissivePower = gBuffer.GetEmissive(texCoord);" << std::endl;
139 ss << " if(emissivePower != 0)" << std::endl;
140 ss << " oColour = diffuseColour * emissivePower;" << std::endl;
141 ss << " else" << std::endl;
142 // Only non-emissive texels takes ambient colour.
143 }
144
145 // Calculate ambient colour of fragment
146 ss << " oColour = float4(ambientColor*diffuseColour);" << std::endl;
147
148 // Calculate depth of fragment;
149 ss << " float3 viewPos = normalize(ray) * farClipDistance * depth;" << std::endl;
150 ss << " float4 projPos = mul(proj, float4(viewPos, 1));" << std::endl;
151 ss << " oDepth = finalDepth(projPos);" << std::endl;
152 ss << "}" << std::endl;
153
154 // Prepare shader generation
155 Ogre::String programSource = ss.str();
156 Ogre::String programName = materialBaseName +"Shaders/Pixel/"+ gbuffer->GetName();
157
158#if SO3_DEBUG
159 // Show the generated vertex program in the log.
160 Ogre::LogManager::getSingleton().getDefaultLog()->logMessage(programSource, Ogre::LML_CRITICAL);
161#endif
162
163 // Create shader object
164 // TODO in another group than Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME?
165 Ogre::HighLevelGpuProgramPtr ptrProgram = Ogre::HighLevelGpuProgramManager::getSingleton().createProgram(programName, Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, "cg", Ogre::GPT_FRAGMENT_PROGRAM);
166 ptrProgram->setSource(programSource);
167 ptrProgram->setParameter("entry_point", "SO3_DeferredLightAmbient_ps");
168 ptrProgram->setParameter("profiles", "ps_2_0 arbfp1");
169
170 // Bind our function parameters to Ogre's related values.
171 const Ogre::GpuProgramParametersSharedPtr& params = ptrProgram->getDefaultParameters();
172
173 if (params->_findNamedConstantDefinition("ambientColor"))
174 params->setNamedAutoConstant("ambientColor", Ogre::GpuProgramParameters::ACT_AMBIENT_LIGHT_COLOUR, 0);
175
176 if (params->_findNamedConstantDefinition("proj"))
177 params->setNamedAutoConstant("proj", Ogre::GpuProgramParameters::ACT_PROJECTION_MATRIX);
178
179 if (params->_findNamedConstantDefinition("farClipDistance"))
180 params->setNamedAutoConstant("farClipDistance", Ogre::GpuProgramParameters::ACT_FAR_CLIP_DISTANCE);
181
182 // Return compositor pixel shader
183 ptrProgram->load();
184 return Ogre::GpuProgramPtr(ptrProgram);
185}
186
187Ogre::MaterialPtr SDeferredLightAmbientMaterialGenerator::GenerateTemplateMaterial(SGBuffer* gbuffer, Ogre::uint32 permutationValue)
188{
189 Ogre::MaterialPtr matPtr = SDeferredLightMaterialGenerator::GenerateTemplateMaterial(gbuffer, permutationValue);
190 Ogre::Pass* ogrePass = matPtr->getTechnique(0)->getPass(0);
191 ogrePass->setDepthWriteEnabled(true);
192 return matPtr;
193}
194
195}
std::string GetName() const
virtual Ogre::MaterialPtr GenerateTemplateMaterial(SGBuffer *gbuffer, Ogre::uint32 permutationValue)
virtual Ogre::GpuProgramPtr GenerateFragmentShader(SGBuffer *gbuffer, Ogre::uint32 permutationValue)
virtual Ogre::GpuProgramPtr GenerateVertexShader(SGBuffer *gbuffer, Ogre::uint32 permutationValue)
virtual Ogre::MaterialPtr GenerateTemplateMaterial(SGBuffer *gbuffer, Ogre::uint32 permutationValue)
Ogre::uint32 GetChannels()
Ogre::String GenerateGBufferCompositorPixelInputStructure()
Ogre::String GetGBufferCompositorPixelInputStructureTypeName()
const Ogre::String materialBaseName
Base name of materials generated by this.