paraboloidHLSL.cpp
Engine/source/shaderGen/HLSL/paraboloidHLSL.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/HLSL/paraboloidHLSL.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 ParaboloidVertTransformHLSL::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 RegisterType type = RT_SVPOSITION; 51 52 Var *outPosition = connectComp->getElement(type); 53 outPosition->setName("hpos"); 54 outPosition->setStructName("OUT"); 55 56 // Get the atlas scale. 57 Var *atlasScale = new Var; 58 atlasScale->setType( "float2" ); 59 atlasScale->setName( "atlasScale" ); 60 atlasScale->uniform = true; 61 atlasScale->constSortPos = cspPass; 62 63 // Transform into camera space 64 Var *worldViewOnly = getWorldView( componentList, fd.features[MFT_UseInstancing], meta ); 65 66 // So what we're doing here is transforming into camera space, and 67 // then directly manipulate into shadowmap space. 68 // 69 // http://www.gamedev.net/reference/articles/article2308.asp 70 71 // Swizzle z and y post-transform 72 meta->addStatement( new GenOp( " @ = mul(@, float4(@.xyz,1)).xzyw;\r\n", outPosition, worldViewOnly, inPosition ) ); 73 meta->addStatement( new GenOp( " float L = length(@.xyz);\r\n", outPosition ) ); 74 75 if ( isSinglePass ) 76 { 77 // Flip the z in the back case 78 Var *outIsBack = connectComp->getElement( RT_TEXCOORD ); 79 outIsBack->setType( "float" ); 80 outIsBack->setName( "isBack" ); 81 outIsBack->setStructName( "OUT" ); 82 83 meta->addStatement( new GenOp( " bool isBack = @.z < 0.0;\r\n", outPosition ) ); 84 meta->addStatement( new GenOp( " @ = isBack ? -1.0 : 1.0;\r\n", outIsBack ) ); 85 meta->addStatement( new GenOp( " if ( isBack ) @.z = -@.z;\r\n", outPosition, outPosition ) ); 86 } 87 88 meta->addStatement( new GenOp( " @ /= L;\r\n", outPosition ) ); 89 meta->addStatement( new GenOp( " @.z = @.z + 1.0;\r\n", outPosition, outPosition ) ); 90 meta->addStatement( new GenOp( " @.xy /= @.z;\r\n", outPosition, outPosition ) ); 91 92 // Get the light parameters. 93 Var *lightParams = new Var; 94 lightParams->setType( "float4" ); 95 lightParams->setName( "lightParams" ); 96 lightParams->uniform = true; 97 lightParams->constSortPos = cspPass; 98 99 // TODO: If we change other shadow shaders to write out 100 // linear depth, than fix this as well! 101 // 102 // (L - zNear)/(lightParams.x - zNear); 103 // 104 meta->addStatement( new GenOp( " @.z = L / @.x;\r\n", outPosition, lightParams ) ); 105 meta->addStatement( new GenOp( " @.w = 1.0;\r\n", outPosition ) ); 106 107 // Pass unmodified to pixel shader to allow it to clip properly. 108 Var *outPosXY = connectComp->getElement( RT_TEXCOORD ); 109 outPosXY->setType( "float2" ); 110 outPosXY->setName( "posXY" ); 111 outPosXY->setStructName( "OUT" ); 112 meta->addStatement( new GenOp( " @ = @.xy;\r\n", outPosXY, outPosition ) ); 113 114 // Scale and offset so it shows up in the atlas properly. 115 meta->addStatement( new GenOp( " @.xy *= @.xy;\r\n", outPosition, atlasScale ) ); 116 117 if ( isSinglePass ) 118 meta->addStatement( new GenOp( " @.x += isBack ? 0.5 : -0.5;\r\n", outPosition ) ); 119 else 120 { 121 Var *atlasOffset = new Var; 122 atlasOffset->setType( "float2" ); 123 atlasOffset->setName( "atlasXOffset" ); 124 atlasOffset->uniform = true; 125 atlasOffset->constSortPos = cspPass; 126 127 meta->addStatement( new GenOp( " @.xy += @;\r\n", outPosition, atlasOffset ) ); 128 } 129 130 output = meta; 131} 132 133void ParaboloidVertTransformHLSL::processPix( Vector<ShaderComponent*> &componentList, 134 const MaterialFeatureData &fd ) 135{ 136 ShaderConnector *connectComp = dynamic_cast<ShaderConnector *>( componentList[C_CONNECTOR] ); 137 138 MultiLine *meta = new MultiLine; 139 140 const bool isSinglePass = fd.features[ MFT_IsSinglePassParaboloid ]; 141 if ( isSinglePass ) 142 { 143 // Cull things on the back side of the map. 144 Var *isBack = connectComp->getElement( RT_TEXCOORD ); 145 isBack->setName( "isBack" ); 146 isBack->setStructName( "IN" ); 147 isBack->setType( "float" ); 148 meta->addStatement( new GenOp( " clip( abs( @ ) - 0.999 );\r\n", isBack ) ); 149 } 150 151 // Cull pixels outside of the valid paraboloid. 152 Var *posXY = connectComp->getElement( RT_TEXCOORD ); 153 posXY->setName( "posXY" ); 154 posXY->setStructName( "IN" ); 155 posXY->setType( "float2" ); 156 meta->addStatement( new GenOp( " clip( 1.0 - abs(@.x) );\r\n", posXY ) ); 157 158 output = meta; 159} 160 161ShaderFeature::Resources ParaboloidVertTransformHLSL::getResources( const MaterialFeatureData &fd ) 162{ 163 Resources temp; 164 temp.numTexReg = 2; 165 return temp; 166} 167