// #include "res://addons/rokojori_action_library/Runtime/Shading/Library/Billboard.gdshaderinc" #include "res://addons/rokojori_action_library/Runtime/Shading/Library/Transform.gdshaderinc" #include "res://addons/rokojori_action_library/Runtime/Shading/Library/Math.gdshaderinc" void applyBillboardBending( inout vec3 _VERTEX, vec3 _CAMERA_DIRECTION_WORLD, vec3 _CAMERA_POSITION_WORLD, mat4 _MODEL_MATRIX, mat4 _VIEW_MATRIX, mat4 _PROJECTION_MATRIX, mat4 _INV_VIEW_MATRIX, float _bendingAmount, float _maxBendingAmount, float _edgeScale, float _minY, float _maxY ) { float camDot = max( 0, dot( vec3( 0, 1, 0 ), _CAMERA_DIRECTION_WORLD ) ); camDot = camDot * camDot * camDot; vec3 worldPosition = localToView( _VERTEX, _MODEL_MATRIX ); vec3 directionToCam = worldPosition - _CAMERA_POSITION_WORLD; float d = length( directionToCam ); directionToCam.y = 0.0; float dScale = min( _bendingAmount / d, _maxBendingAmount ); vec3 view = worldToView( worldPosition, _VIEW_MATRIX ); vec2 clip = viewToClip( view, _PROJECTION_MATRIX ).xy; float sd = 1.0 / ( 1.0 + length( clip ) ); sd = mix( 1, sd, _edgeScale ); //directionToCam = normalize( directionToCam ); directionToCam = applyMatrixWithoutTranslation( vec3(0,-1,0), _INV_VIEW_MATRIX ); float am = camDot * mapClamped( _VERTEX.y, _minY, _maxY, 1, -1 ); am = am * am * am; _VERTEX += am * worldToLocalDirection( directionToCam, _MODEL_MATRIX ) * dScale * sd; } void applyBillboardBendingWithDirection( inout vec3 _VERTEX, vec3 _CAMERA_DIRECTION_WORLD, vec3 _CAMERA_POSITION_WORLD, mat4 _MODEL_MATRIX, mat4 _VIEW_MATRIX, mat4 _PROJECTION_MATRIX, mat4 _INV_VIEW_MATRIX, float _bendingAmount, float _maxBendingAmount, float _edgeScale, float _minY, float _maxY, vec3 _bendingDirection ) { float camDot = max( 0, dot( vec3( 0, 1, 0 ), _CAMERA_DIRECTION_WORLD ) ); camDot = camDot * camDot * camDot; vec3 worldPosition = localToView( _VERTEX, _MODEL_MATRIX ); vec3 directionToCam = worldPosition - _CAMERA_POSITION_WORLD; float d = length( directionToCam ); directionToCam.y = 0.0; float dScale = min( _bendingAmount / d, _maxBendingAmount ); vec3 view = worldToView( worldPosition, _VIEW_MATRIX ); vec2 clip = viewToClip( view, _PROJECTION_MATRIX ).xy; float sd = 1.0 / ( 1.0 + length( clip ) ); sd = mix( 1, sd, _edgeScale ); //directionToCam = normalize( directionToCam ); directionToCam = worldToViewDirection( _bendingDirection, _VIEW_MATRIX ); directionToCam.y = 0.0; directionToCam = viewToWorldDirection( _bendingDirection, _INV_VIEW_MATRIX ); float am = camDot * mapClamped( _VERTEX.y, _minY, _maxY, 1, -1 ); am = am * am * am; _VERTEX += am * worldToLocalDirection( directionToCam, _MODEL_MATRIX ) * dScale * sd; }