日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

          歡迎訪問 生活随笔!

          生活随笔

          當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

          编程问答

          opengl 教程(21) 聚光灯

          發布時間:2025/3/21 编程问答 45 豆豆
          生活随笔 收集整理的這篇文章主要介紹了 opengl 教程(21) 聚光灯 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

          原帖地址:http://ogldev.atspace.co.uk/www/tutorial21/tutorial21.html

          ???? 本篇教程中,我們來學習聚光燈的的光照效果,聚光燈有光源位置,也會隨著傳播距離增加而衰減,還有照射方向,另外聚光燈增加的特性是,它的照射范圍在一個圓錐內,類似探照燈的效果

          下圖顯示了聚光燈的效果:

          ?????? 聚光燈的方向用黑色的箭頭L表示,而我們的光照效果將會限制在兩條紅線內。我們可以通過光線方向,和紅線的夾角來定義光照范圍,對于視線向量V,我們可以用L和V進行點積,如果結果小于cone的角,則不會有聚光燈效果。

          主要代碼:

          lighting_technique.h

          struct SpotLight : public PointLight
          {
          Vector3f Direction;
          float Cutoff;
          SpotLight()
          {
          Direction = Vector3f(0.0f, 0.0f, 0.0f);
          Cutoff = 0.0f;
          }
          };

          在聚光燈類中,我們定義了2個新的屬性,光照方向以及光照圓錐夾角。

          lighting_technique.cpp

          struct SpotLight
          {
          struct PointLight Base;
          vec3 Direction;
          float Cutoff;
          };
          ...
          uniform int gNumSpotLights;
          ...
          uniform SpotLight gSpotLights[MAX_SPOT_LIGHTS];

          定義多個聚光燈光源。

          vec4 CalcPointLight(struct PointLight l, vec3 Normal)
          {
          vec3 LightDirection = WorldPos0 - l.Position;
          float Distance = length(LightDirection);
          LightDirection = normalize(LightDirection);
          vec4 Color = CalcLightInternal(l.Base, LightDirection, Normal);
          float Attenuation = l.Atten.Constant +
          l.Atten.Linear * Distance +
          l.Atten.Exp * Distance * Distance;
          return Color / Attenuation;
          }

          修改點光源shader代碼,使用結構作為參數。

          vec4 CalcSpotLight(struct SpotLight l, vec3 Normal)
          {
          vec3 LightToPixel = normalize(WorldPos0 - l.Base.Position);
          float SpotFactor = dot(LightToPixel, l.Direction);
          if (SpotFactor > l.Cutoff) {
          vec4 Color = CalcPointLight(l.Base, Normal);
          return Color * (1.0 - (1.0 - SpotFactor) * 1.0/(1.0 - l.Cutoff));
          }
          else {
          return vec4(0,0,0,0);
          }
          }

          上面是計算聚光燈效果的函數。

          ...
          for (int i = 0 ; i < gNumSpotLights ; i++) {
          TotalLight += CalcSpotLight(gSpotLights[i], Normal);
          }
          ...

          和點光源的光照的計算方式相同,對于多光源,我們可以累加聚光燈的效果,從而得到最終像素的光照顏色。

          lighting_technique.cpp

          void LightingTechnique::SetSpotLights(unsigned int NumLights, const SpotLight* pLights)
          {
          glUniform1i(m_numSpotLightsLocation, NumLights);
          for (unsigned int i = 0 ; i < NumLights ; i++) {
          glUniform3f(m_spotLightsLocation[i].Color, pLights[i].Color.x, pLights[i].Color.y, pLights[i].Color.z);
          glUniform1f(m_spotLightsLocation[i].AmbientIntensity, pLights[i].AmbientIntensity);
          glUniform1f(m_spotLightsLocation[i].DiffuseIntensity, pLights[i].DiffuseIntensity);
          glUniform3f(m_spotLightsLocation[i].Position, pLights[i].Position.x, pLights[i].Position.y, pLights[i].Position.z);
          Vector3f Direction = pLights[i].Direction;
          Direction.Normalize();
          glUniform3f(m_spotLightsLocation[i].Direction, Direction.x, Direction.y, Direction.z);
          glUniform1f(m_spotLightsLocation[i].Cutoff, cosf(ToRadian(pLights[i].Cutoff)));
          glUniform1f(m_spotLightsLocation[i].Atten.Constant, pLights[i].Attenuation.Constant);
          glUniform1f(m_spotLightsLocation[i].Atten.Linear, pLights[i].Attenuation.Linear);
          glUniform1f(m_spotLightsLocation[i].Atten.Exp, pLights[i].Attenuation.Exp);
          }
          }

          上面是給uniform變量賦值。

          程序執行后效果如下:

          總結

          以上是生活随笔為你收集整理的opengl 教程(21) 聚光灯的全部內容,希望文章能夠幫你解決所遇到的問題。

          如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。