windDeformationGLSL.cpp 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  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. if ( type != OpenGL )
  39. return;
  40. FEATUREMGR->registerFeature( MFT_WindEffect, new WindDeformationGLSL );
  41. }
  42. MODULE_BEGIN( WindDeformationGLSL )
  43. MODULE_INIT_AFTER( ShaderGen )
  44. MODULE_INIT
  45. {
  46. SHADERGEN->getFeatureInitSignal().notify( _onRegisterFeatures );
  47. }
  48. MODULE_END;
  49. WindDeformationGLSL::WindDeformationGLSL()
  50. : mDep(ShaderGen::smCommonShaderPath + String("/gl/wind.glsl" ))
  51. {
  52. addDependency( &mDep );
  53. }
  54. void WindDeformationGLSL::determineFeature( Material *material,
  55. const GFXVertexFormat *vertexFormat,
  56. U32 stageNum,
  57. const FeatureType &type,
  58. const FeatureSet &features,
  59. MaterialFeatureData *outFeatureData )
  60. {
  61. bool enabled = vertexFormat->hasColor() && features.hasFeature( MFT_WindEffect );
  62. outFeatureData->features.setFeature( type, enabled );
  63. }
  64. void WindDeformationGLSL::processVert( Vector<ShaderComponent*> &componentList,
  65. const MaterialFeatureData &fd )
  66. {
  67. MultiLine *meta = new MultiLine;
  68. output = meta;
  69. // We combined all the tree parameters into one float4 to
  70. // save constant space and reduce the memory copied to the
  71. // card.
  72. //
  73. // .x = bend scale
  74. // .y = branch amplitude
  75. // .z = detail amplitude
  76. // .w = detail frequency
  77. //
  78. Var *windParams = new Var( "windParams", "vec4" );
  79. windParams->uniform = true;
  80. windParams->constSortPos = cspPotentialPrimitive;
  81. // If we're instancing then we need to instance the wind direction
  82. // and speed as its unique for each tree instance.
  83. Var *windDirAndSpeed;
  84. if ( fd.features[MFT_UseInstancing] )
  85. {
  86. ShaderConnector *vertStruct = dynamic_cast<ShaderConnector *>( componentList[C_VERT_STRUCT] );
  87. windDirAndSpeed = vertStruct->getElement( RT_TEXCOORD );
  88. windDirAndSpeed->setStructName( "IN" );
  89. windDirAndSpeed->setName( "inst_windDirAndSpeed" );
  90. windDirAndSpeed->setType( "vec3" );
  91. mInstancingFormat->addElement( "windDirAndSpeed", GFXDeclType_Float3, windDirAndSpeed->constNum );
  92. }
  93. else
  94. {
  95. windDirAndSpeed = new Var( "windDirAndSpeed", "vec3" );
  96. windDirAndSpeed->uniform = true;
  97. windDirAndSpeed->constSortPos = cspPrimitive;
  98. }
  99. Var *accumTime = (Var*)LangElement::find( "accumTime" );
  100. if ( !accumTime )
  101. {
  102. accumTime = new Var( "accumTime", "float" );
  103. accumTime->uniform = true;
  104. accumTime->constSortPos = cspPass;
  105. }
  106. // Get the transform to world space.
  107. Var *objTrans = getObjTrans( componentList, fd.features[MFT_UseInstancing], meta );
  108. // First check for an input position from a previous feature
  109. // then look for the default vertex position.
  110. Var *inPosition = (Var*)LangElement::find( "inPosition" );
  111. if ( !inPosition )
  112. inPosition = (Var*)LangElement::find( "position" );
  113. // Copy the input position to the output first as
  114. // the wind effects are conditional.
  115. Var *outPosition = (Var*)LangElement::find( "inPosition" );
  116. if ( !outPosition )
  117. {
  118. outPosition = new Var;
  119. outPosition->setType( "vec3" );
  120. outPosition->setName( "inPosition" );
  121. meta->addStatement( new GenOp(" @ = @.xyz;\r\n", new DecOp( outPosition ), inPosition ) );
  122. }
  123. // Get the incoming color data
  124. Var *inColor = (Var*)LangElement::find( "diffuse" );
  125. // Do a dynamic branch based on wind force.
  126. if ( GFX->getPixelShaderVersion() >= 3.0f )
  127. meta->addStatement( new GenOp(" if ( any( bvec3(@) ) ) {\r\n", windDirAndSpeed ) );
  128. // Do the branch and detail bending first so that
  129. // it can work in pure object space of the tree.
  130. LangElement *effect =
  131. new GenOp( "windBranchBending( "
  132. "@, " // vPos
  133. "normalize( IN_normal ), " // vNormal
  134. "@, " // fTime
  135. "@.z, " // fWindSpeed
  136. "@.g, " // fBranchPhase
  137. "@.y, " // fBranchAmp
  138. "@.r, " // fBranchAtten
  139. "dot( @[3], vec4(1) ), " // fDetailPhase
  140. "@.z, " // fDetailAmp
  141. "@.w, " // fDetailFreq
  142. "@.b )", // fEdgeAtten
  143. outPosition, // vPos
  144. // vNormal
  145. accumTime, // fTime
  146. windDirAndSpeed, // fWindSpeed
  147. inColor, // fBranchPhase
  148. windParams, // fBranchAmp
  149. inColor, // fBranchAtten
  150. objTrans, // fDetailPhase
  151. windParams, // fDetailAmp
  152. windParams, // fDetailFreq
  153. inColor ); // fEdgeAtten
  154. meta->addStatement( new GenOp( " @ = @;\r\n", outPosition, effect ) );
  155. // Now do the trunk bending.
  156. meta->addStatement( new GenOp(" @ = windTrunkBending( @, @.xy, @.z * @.x );\r\n",
  157. outPosition, outPosition, windDirAndSpeed, outPosition, windParams ) );
  158. // End the dynamic branch.
  159. if ( GFX->getPixelShaderVersion() >= 3.0f )
  160. meta->addStatement( new GenOp(" } // [branch]\r\n" ) );
  161. }
  162. ShaderFeatureConstHandles* WindDeformationGLSL::createConstHandles( GFXShader *shader, SimObject *userObject )
  163. {
  164. WindDeformationConstHandles *handles = new WindDeformationConstHandles();
  165. handles->init( shader );
  166. return handles;
  167. }