paraboloidGLSL.cpp
Engine/source/shaderGen/GLSL/paraboloidGLSL.cpp
Detailed Description
1 2//----------------------------------------------------------------------------- 3// Copyright (c) 2012 GarageGames, LLC 4// 5// Permission is hereby granted, free of charge, to any person obtaining a copy 6// of this software and associated documentation files (the "Software"), to 7// deal in the Software without restriction, including without limitation the 8// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 9// sell copies of the Software, and to permit persons to whom the Software is 10// furnished to do so, subject to the following conditions: 11// 12// The above copyright notice and this permission notice shall be included in 13// all copies or substantial portions of the Software. 14// 15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21// IN THE SOFTWARE. 22//----------------------------------------------------------------------------- 23 24#include "platform/platform.h" 25#include "shaderGen/GLSL/paraboloidGLSL.h" 26 27#include "lighting/lightInfo.h" 28#include "materials/sceneData.h" 29#include "materials/materialFeatureTypes.h" 30#include "materials/materialFeatureData.h" 31#include "gfx/gfxShader.h" 32 33 34void ParaboloidVertTransformGLSL::processVert( Vector<ShaderComponent*> &componentList, 35 const MaterialFeatureData &fd ) 36{ 37 MultiLine *meta = new MultiLine; 38 39 // First check for an input position from a previous feature 40 // then look for the default vertex position. 41 Var *inPosition = (Var*)LangElement::find( "inPosition" ); 42 if ( !inPosition ) 43 inPosition = (Var*)LangElement::find( "position" ); 44 45 const bool isSinglePass = fd.features[ MFT_IsSinglePassParaboloid ]; 46 47 ShaderConnector *connectComp = dynamic_cast<ShaderConnector *>( componentList[C_CONNECTOR] ); 48 49 // Grab connector out position. 50 Var *outPosition = connectComp->getElement( RT_POSITION ); 51 outPosition->setName( "gl_Position" ); 52 53 // Get the atlas scale. 54 Var *atlasScale = new Var; 55 atlasScale->setType( "vec2" ); 56 atlasScale->setName( "atlasScale" ); 57 atlasScale->uniform = true; 58 atlasScale->constSortPos = cspPass; 59 60 // Transform into camera space 61 Var *worldViewOnly = getWorldView( componentList, fd.features[MFT_UseInstancing], meta ); 62 63 // So what we're doing here is transforming into camera space, and 64 // then directly manipulate into shadowmap space. 65 // 66 // http://www.gamedev.net/reference/articles/article2308.asp 67 68 // Swizzle z and y post-transform 69 meta->addStatement( new GenOp( " @ = tMul(@, float4(@.xyz,1)).xzyw;\r\n", outPosition, worldViewOnly, inPosition ) ); 70 meta->addStatement( new GenOp( " float L = length(@.xyz);\r\n", outPosition ) ); 71 72 if ( isSinglePass ) 73 { 74 // Flip the z in the back case 75 Var *outIsBack = connectComp->getElement( RT_TEXCOORD ); 76 outIsBack->setType( "float" ); 77 outIsBack->setName( "isBack" ); 78 outIsBack->setStructName( "OUT" ); 79 80 meta->addStatement( new GenOp( " bool isBack = @.z < 0.0;\r\n", outPosition ) ); 81 meta->addStatement( new GenOp( " @ = isBack ? -1.0 : 1.0;\r\n", outIsBack ) ); 82 meta->addStatement( new GenOp( " if ( isBack ) @.z = -@.z;\r\n", outPosition, outPosition ) ); 83 } 84 85 meta->addStatement( new GenOp( " @ /= L;\r\n", outPosition ) ); 86 meta->addStatement( new GenOp( " @.z = @.z + 1.0;\r\n", outPosition, outPosition ) ); 87 meta->addStatement( new GenOp( " @.xy /= @.z;\r\n", outPosition, outPosition ) ); 88 89 // Get the light parameters. 90 Var *lightParams = new Var; 91 lightParams->setType( "vec4" ); 92 lightParams->setName( "lightParams" ); 93 lightParams->uniform = true; 94 lightParams->constSortPos = cspPass; 95 96 // TODO: If we change other shadow shaders to write out 97 // linear depth, than fix this as well! 98 // 99 // (L - zNear)/(lightParams.x - zNear); 100 // 101 meta->addStatement( new GenOp( " @.z = L / @.x;\r\n", outPosition, lightParams ) ); 102 meta->addStatement( new GenOp( " @.w = 1.0;\r\n", outPosition ) ); 103 104 // Pass unmodified to pixel shader to allow it to clip properly. 105 Var *outPosXY = connectComp->getElement( RT_TEXCOORD ); 106 outPosXY->setType( "float2" ); 107 outPosXY->setName( "posXY" ); 108 outPosXY->setStructName( "OUT" ); 109 meta->addStatement( new GenOp( " @ = @.xy;\r\n", outPosXY, outPosition ) ); 110 111 // Scale and offset so it shows up in the atlas properly. 112 meta->addStatement( new GenOp( " @.xy *= @.xy;\r\n", outPosition, atlasScale ) ); 113 114 if ( isSinglePass ) 115 meta->addStatement( new GenOp( " @.x += isBack ? 0.5 : -0.5;\r\n", outPosition ) ); 116 else 117 { 118 Var *atlasOffset = new Var; 119 atlasOffset->setType( "vec2" ); 120 atlasOffset->setName( "atlasXOffset" ); 121 atlasOffset->uniform = true; 122 atlasOffset->constSortPos = cspPass; 123 124 meta->addStatement( new GenOp( " @.xy += @;\r\n", outPosition, atlasOffset ) ); 125 } 126 127 output = meta; 128} 129 130void ParaboloidVertTransformGLSL::processPix( Vector<ShaderComponent*> &componentList, 131 const MaterialFeatureData &fd ) 132{ 133 ShaderConnector *connectComp = dynamic_cast<ShaderConnector *>( componentList[C_CONNECTOR] ); 134 135 MultiLine *meta = new MultiLine; 136 137 const bool isSinglePass = fd.features[ MFT_IsSinglePassParaboloid ]; 138 if ( isSinglePass ) 139 { 140 // Cull things on the back side of the map. 141 Var *isBack = connectComp->getElement( RT_TEXCOORD ); 142 isBack->setName( "isBack" ); 143 isBack->setStructName( "IN" ); 144 isBack->setType( "float" ); 145 meta->addStatement( new GenOp( " if ( ( abs( @ ) - 0.999 ) < 0 ) discard;\r\n", isBack ) ); 146 } 147 148 // Cull pixels outside of the valid paraboloid. 149 Var *posXY = connectComp->getElement( RT_TEXCOORD ); 150 posXY->setName( "posXY" ); 151 posXY->setStructName( "IN" ); 152 posXY->setType( "float2" ); 153 meta->addStatement( new GenOp( " clip( 1.0 - abs(@.x) );\r\n", posXY ) ); 154 155 output = meta; 156} 157 158ShaderFeature::Resources ParaboloidVertTransformGLSL::getResources( const MaterialFeatureData &fd ) 159{ 160 Resources temp; 161 temp.numTexReg = 2; 162 return temp; 163} 164