<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      (翻譯 gafferongames)Networked Physics

      原文:

       https://gafferongames.com/post/networked_physics_2004/

      針對First FPS游戲

      這篇文章主要說了三點:

      1.Server端怎么處理Client發送過來的Input行為 

      2.ClientB怎么模擬Server發送過來的ClientA的State(Position和Rotation)

      3.本地客戶端ClientA的State預測以及在收到Server數據后進行的修正

      當然這里很多細節沒有說明,只是給了思路。

      First Person Shooters

      First person shooter physics are usually very simple. The world is static and players are limited to running around and jumping and shooting.

      第一人稱射擊(FPS)游戲的物理通常非常簡單。游戲世界是靜態的,玩家只能跑動、跳躍和射擊。(這篇文章在這個前提下展開)

      Because of cheating, first person shooters typically operate on a client-server model where the server is authoritative over physics. This means that the true physics simulation runs on the server and the clients display an approximation of the server physics to the player.

      FPS 游戲通常采用客戶端-服務器(client-server)模型,其中服務器對物理計算具有權威性(authoritative)。也就是說,真正的物理模擬運行在服務器端,而客戶端只是向玩家展示服務器物理計算的近似結果

      The problem then is how to allow each client to control his own character while displaying a reasonable approximation of the motion of the other players.

      問題是如何讓每個客戶端控制自己的角色,同時合理地顯示其他玩家的運動?

      In order to do this elegantly and simply, we structure the physics simulation as follows:

      1. Character physics are completely driven from input data.

      2. Physics state is fully encapsulated in a state structure.

      為了以優雅且簡單的方式解決這個問題,我們對物理模擬進行如下結構化設計:

      1. 角色的物理完全由輸入數據驅動。
      2. 物理狀態被完全封裝在一個狀態結構體中。

      To do this we need to gather all the user input that drives the physics simulation into a single structure and the state representing each player character into another.

      Here is an example from a simple run and jump shooter:

          struct Input
          {
               bool left;
               bool right;
               bool forward;
               bool back;
               bool jump;
          };
      
          struct State
          {
               Vector position;
               Vector velocity;
          };
      

        

      Next we need to make sure that the simulation gives the same result given the same initial state and inputs over time. Or at least, that the results are as close as possible. I’m not talking about perfect floating point determinism here, just a reasonable 1/2 second prediction giving approximately the same result.

       這里并不要求完美的浮點數確定性(floating point determinism),但至少要保證大約0.5 秒的預測能夠給出相似的結果

       

      Network Fundamentals 網絡基礎

      I will briefly discuss actually networking issues in this section before moving on to the important information of what to send over the pipe. It is after all just a pipe after all, networking is nothing special right? Beware! Ignorance of how the pipe works will really bite you. Here are the two networking fundamentals that you absolutely need to know:

      在本節中,我會先簡要討論實際的網絡問題,然后再深入講解該在網絡上傳輸哪些數據。畢竟,網絡本質上就像一根管道(pipe),對吧?沒什么特別的?

      Number one. If your network programmer is any good at all he will use UDP, which is an unreliable data protocol, and build some sort of application specific networking layer on top of this. The important thing that you as the physics programmer need to know is that you absolutely must design your physics communication over the network so that you can receive the most recent input and state without waiting for lost packets to be resent. This is important because otherwise your physics simulation will stall out under bad networking conditions.

      1. 使用 UDP,并設計適用于應用層的網絡架構

      你的物理數據通信必須支持直接接收最新的輸入和狀態,而不能依賴丟失的數據包被重新傳輸

      **為什么?**因為如果你等待丟失的數據包被重發,物理模擬可能會在糟糕的網絡環境下卡死,嚴重影響游戲體驗。

      Two. You will be very limited in what can be sent across the network due to bandwidth limitations. Compression is a fact of life when sending data across the network. As physics programmer you need to be very careful what data is compressed and how it is done. For the sake of determinism, some data must not be compressed, while other data is safe. Any data that is compressed in a lossy fashion should have the same quantization applied locally where possible, so that the result is the same on both machines. Bottom line you’ll need to be involved in this compression in order to make it as efficient as possible without breaking your simulation.

      2. 受限的帶寬與數據壓縮

      網絡帶寬極為有限,因此你無法隨意發送所有數據,而數據壓縮是必須面對的現實

      你需要非常小心哪些數據可以被壓縮,以及如何進行壓縮

      • 某些數據不能被壓縮,否則會破壞確定性(determinism)。
      • 某些數據可以安全壓縮,但如果是有損壓縮(lossy compression),那么在本地也應該應用相同的量化處理(quantization),確保不同機器上的計算結果一致。

      總結

      你必須深度參與數據壓縮的設計,以確保在盡可能提高傳輸效率的同時,不破壞物理模擬的穩定性

       

      Physics Runs On The Server

      The fundamental primitive we will use when sending data between the client and the server is an unreliable data block, or if you prefer, an unreliable non-blocking remote procedure call (rpc). Non-blocking means that the client sends the rpc to the server then continues immediately executing other code, it does not wait for the rpc to execute on the server! Unreliable means that if you call the rpc is continuously on the the server from a client, some of these calls will not reach the server, and others will arrive in a different order than they were called. We design our communications around this primitive because it suits the transport layer (UDP).

      客戶端與服務器之間發送數據時,我們使用的基本通信方式不可靠的數據塊(unreliable data block),或者說是不可靠的非阻塞遠程過程調用(non-blocking RPC)

      • 非阻塞(non-blocking):客戶端向服務器發送 RPC 后,不會等待服務器執行完成,而是立刻繼續執行其他代碼
      • 不可靠(unreliable):如果客戶端持續向服務器調用 RPC,部分調用可能丟失,而另一些可能以不同的順序到達服務器。

      我們的通信方案基于這種方式設計,因為它最適合 UDP 傳輸層

      The communication between the client and the server is then structured as what I call a “stream of input” sent via repeated rpc calls. The key to making this input stream tolerant of packet loss and out of order delivery is the inclusion of a floating point time in seconds value with every input rpc sent. The server keeps track of the current time on the server and ignores any input received with a time value less than the current time. This effectively drops any input that is received out of order. Lost packets are ignored.

      客戶端與服務器的通信采用輸入數據流(stream of input)的方式,即客戶端不斷通過 RPC 發送輸入數據

      為了使輸入流能夠容忍數據包丟失和亂序每個輸入 RPC 調用都附帶一個 浮點數時間戳(秒)

      • 服務器記錄當前時間,并忽略所有時間戳小于當前時間的輸入,這可以丟棄亂序到達的數據
      • 丟失的數據包不會被重傳,直接忽略

      Thinking in terms of our standard first person shooter, the input we send from client to server is the input structure that we defined earlier:

          struct Input
          {
               bool left;
               bool right;
               bool forward;
               bool back;
               bool jump;
          };
      
          class Character
          {
          public:
      
               void processInput( double time,
                                  Input input );
          };
      

        

      Thats the bare minimum data required for sending a simple ground based movement plus jumping across the network. If you are going to allow your clients to shoot you’ll need to add mouse input as part of the input structure as well because weapon firing needs to be done server side.

      Notice how I define the rpc as a method inside an object? I assume your network programmer has a channel structure built on top of UDP, eg. some way to indicate that a certain rpc call is directed as a specific object instance on the remote machine.

      So how does the server process these rpc calls? It basically sits in a loop waiting for input from each of the clients. Each character object has its physics advanced ahead in time individually as input rpcs are received from the client that owns it. This means that the physics state of different client characters are slightly out of phase on the server, some clients being a little bit ahead and others a little bit behind in time. Overall however, the different client characters advance ahead roughly in sync with each other.

      那么,服務器如何處理這些 RPC 調用?

      • 服務器在循環監聽來自客戶端的輸入
      • 每個角色對象的物理狀態會在接收到對應客戶端的輸入時向前推進(也就是說,Server針對每個Client數據是獨立處理的)
      • 由于客戶端數據到達時間不同,服務器上的各個角色對象的物理狀態可能稍有時間偏差,有些客戶端可能略超前,有些可能略滯后,但總體上它們是大致同步的

      Lets see how this rpc call is implemented in code on the server:

          void processInput( double time, Input input )
          {
              if ( time < currentTime )
                  return;
      
              float deltaTime = currentTime - time;
      
              updatePhysics( currentTime, deltaTime, input );
          }
      

        The key to the code above is that by advancing the server physics simulation for the client character is performed only as we receive input from that client. This makes sure that the simulation is tolerant of random delays and jitter when sending the input rpc across the network.

      • 服務器僅在收到客戶端輸入時推進該角色的物理模擬不會等待丟失的數據包
      • 這樣可以容忍網絡延遲和抖動(jitter),確保物理模擬的穩定性

      Clients Approximate Physics Locally

      Now for the communication from the server back to the clients. This is where the bulk of the server bandwidth kicks in because the information needs to be broadcast to all the clients.

      接下來,我們討論服務器如何向客戶端發送數據

      這一部分通常占用服務器的大部分帶寬因為服務器需要將信息廣播給所有客戶端

      What happens now is that after every physics update on the server that occurs in response to an input rpc from a client, the server broadcasts out the physics state at the end of that physics update and the current input just received from the rpc.

      服務器向客戶端發送物理狀態

      當服務器處理完某個客戶端的輸入 RPC 并完成物理更新后,它會廣播當前物理狀態以及剛剛收到的輸入給所有客戶端。

      This is sent to all clients in the form of an unreliable rpc:

      這種更新是通過不可靠的 RPC(unreliable RPC) 進行的,例如:

         void clientUpdate( float time, Input input, State state )
          {
              Vector difference = state.position - 
                                  current.position;
      
              float distance = difference.length();
      
              if ( distance > 2.0f )
                  current.position = state.position;
              else if ( distance > 0.1 )
                  current.position += difference * 0.1f;
      
              current.velocity = velocity;
      
              current.input = input;
          } 

      What is being done here is this: if the two positions are significantly different (>2m apart) just snap to the corrected position, otherwise if the distance between the server position and the current position on the client is more than 10cms, move 10% of the distance between the current position and the correct position. Otherwise do nothing.

      客戶端如何處理服務器狀態更新?

      1. 如果客戶端位置和服務器位置相差過大(> 2m),直接校正到服務器位置
      2. 如果位置誤差在 10cm 以上,則按 10% 的比例逐漸靠近正確位置(平滑修正)。
      3. 如果誤差小于 10cm,則不進行修正
      4. 速度(velocity)直接采用服務器值,而不進行平滑修正
      5. 同步服務器端輸入狀態(input),以便客戶端內部邏輯保持一致

      Since server update rpcs are being broadcast continually from the server to the the clients, moving only a fraction towards the snap position has the effect of smoothing the correction out with what is called an exponentially smoothed moving average.

      This trades a bit of extra latency for smoothness because only moving some percent towards the snapped position means that the position will be a bit behind where it should really be. You don’t get anything for free.

      為什么要逐步靠近正確位置?

      服務器會不斷廣播更新,如果直接瞬間同步位置,玩家會看到角色瞬移(teleporting)。

      所以,我們采用指數平滑移動平均(Exponentially Smoothed Moving Average, ESMA)的方式來平滑校正,避免突兀的跳躍:

      • 缺點:由于每次只移動部分距離,客戶端的角色位置會比服務器位置稍微滯后,增加了一點延遲。
      • 優點:大幅提升平滑度,減少視覺抖動角色瞬移

       I recommend that you perform this smoothing for immediate quantities such as position and orientation, while directly snapping derivative quantities such as velocity, angular velocity because the effect of abruptly changing derivative quantities is not as noticeable.

      Of course, these are just rules of thumb. Make sure you experiment to find out what works best for your simulation.

      哪些數據應該平滑修正,哪些應該直接同步?

      • 位置(Position)、方向(Orientation)逐步平滑修正(減少視覺突變)。
      • 速度(Velocity)、角速度(Angular Velocity)直接同步(因為這些變化較快,突變不明顯)。

      這只是一個經驗法則,具體實現應根據模擬需求調整不斷測試和優化,找到最合適的平衡點

      Client-Side Prediction

      So far we have a developed a solution for driving the physics on the server from client input, then broadcasting the physics to each of the clients so they can maintain a local approximation of the physics on the server. This works perfectly however it has one major disadvantage. Latency!

      When the user holds down the forward input it is only when that input makes a round trip to the server and back to the client that the client’s character starts moving forward locally. Those who remember the original Quake netcode would be familiar with this effect. The solution to this problem was discovered and first applied in the followup QuakeWorld and is called client side prediction. This technique completely eliminates movement lag for the client and has since become a standard technique used in first person shooter netcode.

      在《QuakeWorld》中,id Software 率先引入了“客戶端預測(Client-Side Prediction)”技術,徹底消除了移動延遲問題。這種技術已經成為現代 FPS 游戲的標準

      Client side prediction works by predicting physics ahead locally using the player’s input, simulating ahead without waiting for the server round trip. The server periodically sends corrections to the client which are required to ensure that the client stays in sync with the server physics. At all times the server is authoritative over the physics of the character so even if the client attempts to cheat all they are doing is fooling themselves locally while the server physics remains unaffected. Seeing as all game logic runs on the server according to server physics state, client side movement cheating is basically eliminated.

      原理:

      • 客戶端在本地提前預測物理模擬,基于玩家輸入進行自主計算不等待服務器的返回
      • 服務器定期發送校正數據,確保客戶端與服務器保持同步
      • 服務器始終擁有物理權威性,即使客戶端試圖作弊,也只能欺騙自己,服務器的物理模擬不會受到影響。
      • 所有游戲邏輯仍然在服務器端執行,因此客戶端修改數據不會影響游戲進程,基本上消除了基于移動的作弊可能

      The most complicated part of client side prediction is handling the correction from the server. This is difficult, because the corrections from the server arrive in the past due to client/server communication latency. We need to apply this correction in the past, then calculate the resulting corrected position at present time on the client.

      客戶端如何處理服務器校正?

      客戶端預測的最大難點如何處理服務器的物理校正

      • 由于網絡延遲,服務器的校正數據實際上是過去的狀態
      • 客戶端必須去應用校正,然后重新計算當前的正確位置

      The standard technique to do this is to store a circular buffer of saved moves on the client where each move in the buffer corresponds to an input rpc call sent from the client to the server:

      客戶端維護一個循環緩沖區(circular buffer),存儲每次輸入對應的物理狀態

        struct Move
          {
              double time;
              Input input;
              State state;
          };

      When the client receives a correction it looks through the saved move buffer to compare its physics state at that time with the corrected physics state sent from the server. If the two physics states differ above some threshold then the client rewinds to the corrected physics state and time and replays the stored moves starting from the corrected state in the past, the result of this re-simulation being the corrected physics state at the current time on the client.

      當客戶端收到服務器的校正數據時,它會:

      1. 緩沖區中找到對應時間的存檔,并比較當前狀態與服務器校正狀態
      2. 如果兩者之間的誤差超過某個閾值,客戶端回溯到服務器提供的正確狀態
      3. 從該校正狀態開始,重新執行存儲的輸入操作,重新模擬物理運動,計算當前的正確狀態

      Sometimes packet loss or out of order delivery occurs and the server input differs from that stored on the client. In this case the server snaps the client to the correct position automatically via rewind and replay. This snapping is quite noticeable to the player, so we reduce it with the same smoothing technique we used above for the other player characters. This smoothing is done after recalculating the corrected position via rewind and replay.

      如何處理丟包與亂序數據?

      • 有時數據包丟失或亂序,導致服務器的輸入狀態與客戶端存儲的不同
      • 在這種情況下,服務器會強制讓客戶端回溯到正確的位置,然后進行回放(rewind & replay)。
      • 但這種“瞬間修正”可能會讓玩家感覺到突兀的“位置跳變”(Snap Correction)。

      解決方案:平滑處理

      • 在回放結束后,對最終的修正狀態應用指數平滑移動平均(ESMA),就像我們之前對其他玩家角色位置所做的那樣。
      • 這減少了視覺上的突兀感,讓修正過程更加平滑自然。

      Conclusion

      We can easily apply the client side prediction techniques used in first person shooters to network a physics simulation, but only if there is a clear ownership of objects by clients and these object interact mostly with a static world.

      • 客戶端預測可以顯著減少輸入延遲,讓玩家的操作更加流暢。
      • 服務器仍然是最終權威,即使客戶端試圖作弊,服務器仍然保持正確狀態。
      • 回溯與重放(Rewind & Replay) 機制用于處理服務器校正,但需要平滑處理以避免突兀跳變。
      • 客戶端預測適用于第一人稱射擊(FPS)等游戲,但前提是游戲對象的所有權是明確的,并且主要與靜態世界交互

       

      posted @ 2025-02-26 23:12  sun_dust_shadow  閱讀(24)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 天堂网亚洲综合在线| 无码h片在线观看网站| 国产精品人一区二区三区| 亚洲色精品VR一区二区三区| 少妇一边呻吟一边说使劲视频 | 色婷婷欧美在线播放内射 | 久久久久久综合网天天| 婷婷丁香五月深爱憿情网| 国产精品福利中文字幕| 国产欧美日韩高清在线不卡| 94人妻少妇偷人精品| 国产性色av高清在线观看| 亚洲国产综合精品2020| 成人网站免费观看永久视频下载| 久久人人妻人人做人人爽| 亚洲第一无码专区天堂| 97中文字幕在线观看| 亚洲精品有码在线观看| 在线观看潮喷失禁大喷水无码| 色吊丝一区二区中文字幕| 国产一区二区三区色噜噜| 国产精品亚洲片夜色在线| 一级做a爰片在线播放| 久久精品国产精品亚洲毛片| 亚洲精品三区二区一区一| 日韩一区在线中文字幕| 成 人 色 网 站免费观看| 日韩女同一区二区三区久久 | 国产精品视频午夜福利| 中文字幕乱码中文乱码毛片| 国产精品线在线精品国语| 深夜在线观看免费av| 人妻少妇偷人一区二区| 国产欧美日韩精品丝袜高跟鞋| 国产精品一在线观看| 99在线精品国自产拍中文字幕| 国产欧美亚洲精品第一页在线 | 波多野结av衣东京热无码专区| 精品人妻中文字幕av| 岛国岛国免费v片在线观看| 性欧美老妇另类xxxx|