windDeformationHLSL.cpp
Engine/source/forest/hlsl/windDeformationHLSL.cpp
Public Variables
Public Functions
Detailed Description
Public Variables
MODULE_END
MODULE_INIT
Public Functions
_onRegisterFeatures(GFXAdapterType type)
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 "forest/hlsl/windDeformationHLSL.h" 26#include "forest/windDeformation.h" 27 28#include "forest/forestItem.h" 29#include "forest/forestWindMgr.h" 30#include "materials/sceneData.h" 31#include "scene/sceneRenderState.h" 32 33#include "shaderGen/shaderGen.h" 34#include "shaderGen/featureMgr.h" 35#include "shaderGen/langElement.h" 36#include "shaderGen/shaderOp.h" 37#include "shaderGen/shaderGenVars.h" 38#include "gfx/gfxStructs.h" 39#include "core/module.h" 40 41 42static void _onRegisterFeatures( GFXAdapterType type ) 43{ 44 if ( type == OpenGL ) 45 return; 46 47 FEATUREMGR->registerFeature( MFT_WindEffect, new WindDeformationHLSL ); 48} 49 50 51MODULE_BEGIN( WindDeformationHLSL ) 52 53 MODULE_INIT_AFTER( ShaderGen ) 54 55 MODULE_INIT 56 { 57 SHADERGEN->getFeatureInitSignal().notify( _onRegisterFeatures ); 58 } 59 60MODULE_END; 61 62 63WindDeformationHLSL::WindDeformationHLSL() 64 : mDep(ShaderGen::smCommonShaderPath + String("/wind.hlsl" )) 65{ 66 addDependency( &mDep ); 67} 68 69void WindDeformationHLSL::determineFeature( Material *material, 70 const GFXVertexFormat *vertexFormat, 71 U32 stageNum, 72 const FeatureType &type, 73 const FeatureSet &features, 74 MaterialFeatureData *outFeatureData ) 75{ 76 bool enabled = vertexFormat->hasColor() && features.hasFeature( MFT_WindEffect ); 77 outFeatureData->features.setFeature( type, enabled ); 78} 79 80void WindDeformationHLSL::processVert( Vector<ShaderComponent*> &componentList, 81 const MaterialFeatureData &fd ) 82{ 83 MultiLine *meta = new MultiLine; 84 output = meta; 85 86 // We combined all the tree parameters into one float4 to 87 // save constant space and reduce the memory copied to the 88 // card. 89 // 90 // .x = bend scale 91 // .y = branch amplitude 92 // .z = detail amplitude 93 // .w = detail frequency 94 // 95 Var *windParams = new Var( "windParams", "float4" ); 96 windParams->uniform = true; 97 windParams->constSortPos = cspPotentialPrimitive; 98 99 // If we're instancing then we need to instance the wind direction 100 // and speed as its unique for each tree instance. 101 Var *windDirAndSpeed; 102 if ( fd.features[MFT_UseInstancing] ) 103 { 104 ShaderConnector *vertStruct = dynamic_cast<ShaderConnector *>( componentList[C_VERT_STRUCT] ); 105 windDirAndSpeed = vertStruct->getElement( RT_TEXCOORD ); 106 windDirAndSpeed->setStructName( "IN" ); 107 windDirAndSpeed->setName( "inst_windDirAndSpeed" ); 108 windDirAndSpeed->setType( "float3" ); 109 110 mInstancingFormat->addElement( "windDirAndSpeed", GFXDeclType_Float3, windDirAndSpeed->constNum ); 111 } 112 else 113 { 114 windDirAndSpeed = new Var( "windDirAndSpeed", "float3" ); 115 windDirAndSpeed->uniform = true; 116 windDirAndSpeed->constSortPos = cspPrimitive; 117 } 118 119 Var *accumTime = (Var*)LangElement::find( "accumTime" ); 120 if ( !accumTime ) 121 { 122 accumTime = new Var( "accumTime", "float" ); 123 accumTime->uniform = true; 124 accumTime->constSortPos = cspPass; 125 } 126 127 // Get the transform to world space. 128 Var *objTrans = getObjTrans( componentList, fd.features[MFT_UseInstancing], meta ); 129 130 // First check for an input position from a previous feature 131 // then look for the default vertex position. 132 Var *inPosition = (Var*)LangElement::find( "inPosition" ); 133 if ( !inPosition ) 134 inPosition = (Var*)LangElement::find( "position" ); 135 136 // Copy the input position to the output first as 137 // the wind effects are conditional. 138 Var *outPosition = (Var*)LangElement::find( "inPosition" ); 139 if ( !outPosition ) 140 { 141 outPosition = new Var; 142 outPosition->setType( "float3" ); 143 outPosition->setName( "inPosition" ); 144 meta->addStatement( new GenOp(" @ = @.xyz;\r\n", new DecOp( outPosition ), inPosition ) ); 145 } 146 147 // Get the incoming color data 148 Var *inColor = (Var*)LangElement::find( "diffuse" ); 149 150 // Do a dynamic branch based on wind force. 151 if ( GFX->getPixelShaderVersion() >= 3.0f ) 152 meta->addStatement( new GenOp(" [branch] if ( any( @ ) ) {\r\n", windDirAndSpeed ) ); 153 154 // Do the branch and detail bending first so that 155 // it can work in pure object space of the tree. 156 LangElement *effect = 157 new GenOp( "windBranchBending( " 158 159 "@, " // vPos 160 "normalize( IN.normal ), " // vNormal 161 162 "@, " // fTime 163 "@.z, " // fWindSpeed 164 165 "@.g, " // fBranchPhase 166 "@.y, " // fBranchAmp 167 "@.r, " // fBranchAtten 168 169 "dot( @[3], 1 ), " // fDetailPhase 170 "@.z, " // fDetailAmp 171 "@.w, " // fDetailFreq 172 173 "@.b )", // fEdgeAtten 174 175 outPosition, // vPos 176 // vNormal 177 178 accumTime, // fTime 179 windDirAndSpeed, // fWindSpeed 180 181 inColor, // fBranchPhase 182 windParams, // fBranchAmp 183 inColor, // fBranchAtten 184 185 objTrans, // fDetailPhase 186 windParams, // fDetailAmp 187 windParams, // fDetailFreq 188 189 inColor ); // fEdgeAtten 190 191 meta->addStatement( new GenOp( " @ = @;\r\n", outPosition, effect ) ); 192 193 // Now do the trunk bending. 194 meta->addStatement( new GenOp(" @ = windTrunkBending( @, @.xy, @.z * @.x );\r\n", 195 outPosition, outPosition, windDirAndSpeed, outPosition, windParams ) ); 196 197 // End the dynamic branch. 198 if ( GFX->getPixelShaderVersion() >= 3.0f ) 199 meta->addStatement( new GenOp(" } // [branch]\r\n" ) ); 200} 201 202ShaderFeatureConstHandles* WindDeformationHLSL::createConstHandles( GFXShader *shader, SimObject *userObject ) 203{ 204 WindDeformationConstHandles *handles = new WindDeformationConstHandles(); 205 handles->init( shader ); 206 207 return handles; 208} 209