Rendering/DayNight: Difference between revisions

From wowdev
Jump to navigation Jump to search
No edit summary
Line 81: Line 81:
   }
   }


  // D38B04: float DNInfo->dayProgression (0.0 to 1.0)
   float phi = DayNight::InterpTable(&DayNight::phiTable, 4u, DayNight::g_dnInfo.dayProgression);
   float phi = DayNight::InterpTable(&DayNight::phiTable, 4u, flt_D38B04);
   float theta = DayNight::InterpTable(&DayNight::thetaTable, 4u, DayNight::g_dnInfo.dayProgression);
   float theta = DayNight::InterpTable(&DayNight::thetaTable, 4u, flt_D38B04);


   // Convert from spherical coordinates to XYZ
   // Convert from spherical coordinates to XYZ
Line 96: Line 95:
   float cosTheta = CMath::cosoid(theta);
   float cosTheta = CMath::cosoid(theta);


   // D38C9C: C3Vector sunDir
   DayNight::g_dnInfo.lightInfo.dir.x = sinPhi * cosTheta;
  dword_D38C9C.x = sinPhi * cosTheta;
   DayNight::g_dnInfo.lightInfo.dir.y = sinPhi * sinTheta;
   dword_D38C9C.y = sinPhi * sinTheta;
   DayNight::g_dnInfo.lightInfo.dir.z = cosPhi;
   dword_D38C9C.z = cosPhi;


}
}

Revision as of 23:30, 8 October 2017

Overview

In World of Warcraft, the DayNight system governs most of the general appearance of the world.

Things like area lighting, zone lighting, clouds, the sky sphere (ie the color gradient of the sky), stars (ie sky boxes) are all managed by DayNight.

Utility Functions

DayNight::DarkenColor

CImVector DayNight::DarkenColor(CImVector const &clr, float amount) {

  C3Vector rgb;
  C3Vector hsv;

  rgb.x = clr->r / 255.0;
  rgb.y = clr->g / 255.0;
  rgb.z = clr->b / 255.0;

  hsv.x = 0.0;
  hsv.y = 0.0;
  hsv.z = 0.0;

  RGBtoHSV(&rgb, &hsv);

  hsv.z = hsv.z * amount;

  HSVtoRGB(&hsv, &rgb);

  CImVector result;

  CImVector::operator=(&result, &rgb);

  return result;

}

Lighting Functions

DayNight::SetDirection

DayNight::SetDirection calculates a C3Vector containing the direction vector for the global light, aka sunDir.

This direction vector is transformed by the view matrix prior to being uploaded to the shader.

void DayNight::SetDirection() {

  // Phi Table
  if ( !(dword_D39104 & 1) ) {

    dword_D39104 |= 1u;

    DayNight::phiTable = {

      { 0.0,  2.2165682 },
      { 0.25, 1.9198623 },
      { 0.5,  2.2165682 },
      { 0.75, 1.9198623 }

    };

  }

  // Theta Table
  if ( !(dword_D39104 & 2) ) {

    dword_D39104 |= 2;
    
    DayNight::thetaTable = {

      { 0.0,  3.926991 },
      { 0.25, 3.926991 },
      { 0.5,  3.926991 },
      { 0.75, 3.926991 }

    };

  }

  float phi = DayNight::InterpTable(&DayNight::phiTable, 4u, DayNight::g_dnInfo.dayProgression);
  float theta = DayNight::InterpTable(&DayNight::thetaTable, 4u, DayNight::g_dnInfo.dayProgression);

  // Convert from spherical coordinates to XYZ
  // x = rho * sin(phi) * cos(theta)
  // y = rho * sin(phi) * sin(theta)
  // z = rho * cos(phi)

  float sinPhi = CMath::sinoid(phi);
  float cosPhi = CMath::cosoid(phi);

  float sinTheta = CMath::sinoid(theta);
  float cosTheta = CMath::cosoid(theta);

  DayNight::g_dnInfo.lightInfo.dir.x = sinPhi * cosTheta;
  DayNight::g_dnInfo.lightInfo.dir.y = sinPhi * sinTheta;
  DayNight::g_dnInfo.lightInfo.dir.z = cosPhi;

}

DayNight::SetLightColors

Sets up lighting colors in DNInfo->lightInfo. The colors in DNInfo->lightInfo directly feed the lighting for ADTs, M2s, WMOs, etc.

For WMO materials with the F_WINDOW flag set, the windowAmbColor and <windowDirColor are used.

void DayNight::SetLightColors() {

  // Light colors

  DayNight::g_dnInfo.lightInfo.dirColor = DayNight::g_dnInfo.light.dirColor;

  DayNight::g_dnInfo.lightInfo.ambColor = DayNight::g_dnInfo.light.ambColor;

  // Window light colors
  // MOMT.flags & F_WINDOW

  CImVector windowDirColor = DayNight::g_dnInfo.light.dirColor;

  CImVector::Blend255_(&windowDirColor, 128u, &DayNight::g_dnInfo.light.ambColor);

  CImVector windowAmbColor = DayNight::g_dnInfo.light.ambColor;

  CImVector::Blend255_(&windowAmbColor, 128u, &DayNight::g_dnInfo.light.dirColor);

  windowAmbColor.r = std::min(windowAmbColor.r, 16u);
  windowAmbColor.g = std::min(windowAmbColor.g, 16u);
  windowAmbColor.b = std::min(windowAmbColor.b, 16u);
  windowAmbColor.a = windowAmbColor.a - 1;            // 0 wraps to 255

  DayNight::g_dnInfo.lightInfo.windowDirColor = windowDirColor;

  DayNight::g_dnInfo.lightInfo.windowAmbColor = windowAmbColor;

  // Shadow color
  // TODO: Clean up

  int v1;

  BYTE1(v1) = (unsigned __int16)(85 * (DayNight::g_dnInfo.light.ambColor.r + 3)) >> 8;
  LOBYTE(v1) = (unsigned __int16)(85 * (DayNight::g_dnInfo.light.ambColor.g + 3)) >> 8;
  DayNight::g_dnInfo.shadowColor = (CImVector)(*(_DWORD *)&DayNight::g_dnInfo.light.ambColor & 0xFF000000 | ((unsigned __int16)(85 * (DayNight::g_dnInfo.light.ambColor.b + 3)) >> 8) | ((unsigned __int16)v1 << 8));
  DayNight::g_dnInfo.shadowColor.a = DayNight::g_dnInfo.light.shadowOpacity.r;

  // TODO: What is unkLightInfo?

  DayNight::g_dnInfo.unkLightInfo.dir.x = DayNight::g_dnInfo.lightInfo.dir.x;
  DayNight::g_dnInfo.unkLightInfo.dir.y = DayNight::g_dnInfo.lightInfo.dir.y;
  DayNight::g_dnInfo.unkLightInfo.dir.z = DayNight::g_dnInfo.lightInfo.dir.z;

  DayNight::g_dnInfo.unkLightInfo.dirColor = DayNight::g_dnInfo.light.dirColor;

  DayNight::g_dnInfo.unkLightInfo.ambColor = DayNight::g_dnInfo.light.ambColor;

  DayNight::g_dnInfo.unkLightInfo.windowDirColor = DayNight::g_dnInfo.lightInfo.windowDirColor;

  DayNight::g_dnInfo.unkLightInfo.windowAmbColor = DayNight::g_dnInfo.lightInfo.windowAmbColor;

  DayNight::g_dnInfo.unkLightInfo.shaderShadowColor.x = DayNight::g_dnInfo.lightInfo.shaderShadowColor.x;
  DayNight::g_dnInfo.unkLightInfo.shaderShadowColor.y = DayNight::g_dnInfo.lightInfo.shaderShadowColor.y;
  DayNight::g_dnInfo.unkLightInfo.shaderShadowColor.z = DayNight::g_dnInfo.lightInfo.shaderShadowColor.z;
  DayNight::g_dnInfo.unkLightInfo.shaderShadowColor.w = DayNight::g_dnInfo.lightInfo.shaderShadowColor.w;

  // Shader shadow color

  C3Vector rgb;

  rgb.x = DayNight::g_dnInfo.light.ambColor.r / 255.0f;
  rgb.y = DayNight::g_dnInfo.light.ambColor.g / 255.0f;
  rgb.z = DayNight::g_dnInfo.light.ambColor.b / 255.0f;

  C3Vector hsv;

  hsv.x = 0.0;
  hsv.y = 0.0;
  hsv.z = 0.0;

  RGBtoHSV(&rgb, &hsv);

  hsv.y = hsv.y * 0.33000001;
  hsv.z = hsv.z * 1.25;

  HSVtoRGB(&hsv, &rgb);

  DayNight::g_dnInfo.lightInfo.shaderShadowColor.x = rgb.x;
  DayNight::g_dnInfo.lightInfo.shaderShadowColor.y = rgb.y;
  DayNight::g_dnInfo.lightInfo.shaderShadowColor.z = rgb.z;
  DayNight::g_dnInfo.lightInfo.shaderShadowColor.w = 1.0;

}