windDeformationGLSL.cpp 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) 2012 GarageGames, LLC
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to
  6. // deal in the Software without restriction, including without limitation the
  7. // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  8. // sell copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  19. // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  20. // IN THE SOFTWARE.
  21. //-----------------------------------------------------------------------------
  22. #include "platform/platform.h"
  23. #include "forest/glsl/windDeformationGLSL.h"
  24. #include "forest/windDeformation.h"
  25. #include "forest/forestItem.h"
  26. #include "forest/forestWindMgr.h"
  27. #include "materials/sceneData.h"
  28. #include "scene/sceneRenderState.h"
  29. #include "shaderGen/shaderGen.h"
  30. #include "shaderGen/featureMgr.h"
  31. #include "shaderGen/langElement.h"
  32. #include "shaderGen/shaderOp.h"
  33. #include "shaderGen/shaderGenVars.h"
  34. #include "gfx/gfxStructs.h"
  35. #include "core/module.h"
  36. static void _onRegisterFeatures( GFXAdapterType type )
  37. {
  38. FEATUREMGR->registerFeature( MFT_WindEffect, new WindDeformationGLSL );
  39. }
  40. MODULE_BEGIN( WindDeformationGLSL )
  41. MODULE_INIT_AFTER( ShaderGen )
  42. MODULE_INIT
  43. {
  44. SHADERGEN->getFeatureInitSignal().notify( _onRegisterFeatures );
  45. }
  46. MODULE_END;
  47. WindDeformationGLSL::WindDeformationGLSL()
  48. : mDep( "shaders/common/gl/wind.glsl" )
  49. {
  50. addDependency( &mDep );
  51. }
  52. void WindDeformationGLSL::determineFeature( Material *material,
  53. const GFXVertexFormat *vertexFormat,
  54. U32 stageNum,
  55. const FeatureType &type,
  56. const FeatureSet &features,
  57. MaterialFeatureData *outFeatureData )
  58. {
  59. bool enabled = vertexFormat->hasColor() && features.hasFeature( MFT_WindEffect );
  60. outFeatureData->features.setFeature( type, enabled );
  61. }
  62. void WindDeformationGLSL::processVert( Vector<ShaderComponent*> &componentList,
  63. const MaterialFeatureData &fd )
  64. {
  65. MultiLine *meta = new MultiLine;
  66. output = meta;
  67. // We combined all the tree parameters into one float4 to
  68. // save constant space and reduce the memory copied to the
  69. // card.
  70. //
  71. // This in particular helps when we're instancing.
  72. //
  73. // .x = bend scale
  74. // .y = branch amplitude
  75. // .z = detail amplitude
  76. // .w = detail frequency
  77. //
  78. Var *windParams;
  79. if ( fd.features[MFT_UseInstancing] )
  80. {
  81. ShaderConnector *vertStruct = dynamic_cast<ShaderConnector *>( componentList[C_VERT_STRUCT] );
  82. windParams = vertStruct->getElement( RT_TEXCOORD );
  83. windParams->setName( "inst_windParams" );
  84. windParams->setType( "vec4" );
  85. mInstancingFormat->addElement( "windParams", GFXDeclType_Float4, windParams->constNum );
  86. }
  87. else
  88. {
  89. windParams = new Var( "windParams", "vec4" );
  90. windParams->uniform = true;
  91. windParams->constSortPos = cspPotentialPrimitive;
  92. }
  93. // If we're instancing then we need to instance the wind direction
  94. // and speed as its unique for each tree instance.
  95. Var *windDirAndSpeed;
  96. if ( fd.features[MFT_UseInstancing] )
  97. {
  98. ShaderConnector *vertStruct = dynamic_cast<ShaderConnector *>( componentList[C_VERT_STRUCT] );
  99. windDirAndSpeed = vertStruct->getElement( RT_TEXCOORD );
  100. windDirAndSpeed->setName( "inst_windDirAndSpeed" );
  101. windDirAndSpeed->setType( "vec3" );
  102. mInstancingFormat->addElement( "windDirAndSpeed", GFXDeclType_Float3, windDirAndSpeed->constNum );
  103. }
  104. else
  105. {
  106. windDirAndSpeed = new Var( "windDirAndSpeed", "vec3" );
  107. windDirAndSpeed->uniform = true;
  108. windDirAndSpeed->constSortPos = cspPrimitive;
  109. }
  110. Var *accumTime = (Var*)LangElement::find( "accumTime" );
  111. if ( !accumTime )
  112. {
  113. accumTime = new Var( "accumTime", "float" );
  114. accumTime->uniform = true;
  115. accumTime->constSortPos = cspPass;
  116. }
  117. // Get the transform to world space.
  118. Var *objTrans = getObjTrans( componentList, fd.features[MFT_UseInstancing], meta );
  119. // First check for an input position from a previous feature
  120. // then look for the default vertex position.
  121. Var *inPosition = (Var*)LangElement::find( "inPosition" );
  122. if ( !inPosition )
  123. inPosition = (Var*)LangElement::find( "position" );
  124. // Get the incoming color data
  125. Var *inColor = (Var*)LangElement::find( "diffuse" );
  126. // Do the branch and detail bending first so that
  127. // it can work in pure object space of the tree.
  128. LangElement *effect =
  129. new GenOp( "windBranchBending( "
  130. "@.xyz, " // vPos
  131. "normalize( normal ), " // vNormal
  132. "@, " // fTime
  133. "@.z, " // fWindSpeed
  134. "@.g, " // fBranchPhase
  135. "@.y, " // fBranchAmp
  136. "@.r, " // fBranchAtten
  137. "dot( @[3], vec4( 1.0 ) ), " // fDetailPhase
  138. "@.z, " // fDetailAmp
  139. "@.w, " // fDetailFreq
  140. "@.b )", // fEdgeAtten
  141. inPosition, // vPos
  142. // vNormal
  143. accumTime, // fTime
  144. windDirAndSpeed, // fWindSpeed
  145. inColor, // fBranchPhase
  146. windParams, // fBranchAmp
  147. inColor, // fBranchAtten
  148. objTrans, // fDetailPhase
  149. windParams, // fDetailAmp
  150. windParams, // fDetailFreq
  151. inColor ); // fEdgeAtten
  152. Var *outPosition = (Var*)LangElement::find( "inPosition" );
  153. if ( outPosition )
  154. meta->addStatement( new GenOp( " @.xyz = @;\r\n", outPosition, effect, inPosition ) );
  155. else
  156. {
  157. outPosition = new Var;
  158. outPosition->setType( "vec3" );
  159. outPosition->setName( "inPosition" );
  160. meta->addStatement( new GenOp(" vec3 inPosition = @;\r\n", effect, inPosition ) );
  161. }
  162. // Now do the trunk bending.
  163. effect = new GenOp( "windTrunkBending( @, @.xy, @.z * @.x )",
  164. outPosition, windDirAndSpeed, outPosition, windParams );
  165. meta->addStatement( new GenOp(" @ = @;\r\n", outPosition, effect ) );
  166. }
  167. ShaderFeatureConstHandles* WindDeformationGLSL::createConstHandles( GFXShader *shader, SimObject *userObject )
  168. {
  169. WindDeformationConstHandles *handles = new WindDeformationConstHandles();
  170. handles->init( shader );
  171. return handles;
  172. }