Team Fortress 2 Source Code as on 22/4/2020
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

169 lines
4.9 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. //===========================================================================//
  6. #include "tier0/platform.h"
  7. #include <stdio.h>
  8. #include "bitmap/float_bm.h"
  9. #include "mathlib/mathlib.h"
  10. #include "tier2/tier2.h"
  11. #define BRIGHT_THRESH 0.90 // pixels within this % of average are "bright"
  12. #define GROUND_IMPORTANCE 0.2 // weight for downward pointing skymap pixels
  13. float Importance(Vector const &direction)
  14. {
  15. // this returns a scale factor which can be used to recurd the importance of certain
  16. // directions. in particular, this version makes the ground a lot less important than the sky
  17. if (direction.z>.2)
  18. return 1.0;
  19. if (direction.z>0)
  20. return FLerp(1.0,GROUND_IMPORTANCE,.2,0,direction.z);
  21. else
  22. return GROUND_IMPORTANCE;
  23. }
  24. void main(int argc,char **argv)
  25. {
  26. InitCommandLineProgram(argc, argv);
  27. if (argc!=2)
  28. {
  29. printf("format is %s basename\n",argv[0]);
  30. }
  31. else
  32. {
  33. FloatCubeMap_t cmap(argv[1]);
  34. // find the brightest pixel. We will consider the pixels neat this to be the
  35. // ones contrinbuting to the light source
  36. float max_color=cmap.BrightestColor();
  37. float threshhold=max_color*.90;
  38. // now, find average color of non-bright pixels
  39. float sumweights=0.0;
  40. Vector AverageColor(0,0,0);
  41. for(int f=0;f<6;f++)
  42. for(int y=0;y<cmap.face_maps[f].Height;y++)
  43. for(int x=0;x<cmap.face_maps[f].Width;x++)
  44. {
  45. Vector clr(
  46. cmap.face_maps[f].Pixel(x,y,0),
  47. cmap.face_maps[f].Pixel(x,y,1),
  48. cmap.face_maps[f].Pixel(x,y,2));
  49. float mag=clr.Length();
  50. if (mag<threshhold)
  51. {
  52. float weight=Importance(cmap.PixelDirection(f,x,y));
  53. sumweights+=weight;
  54. AverageColor+=weight*clr;
  55. }
  56. }
  57. AverageColor*=(1.0/sumweights);
  58. Vector avg_light_dir(0,0,0);
  59. Vector AverageHue(0,0,0);
  60. // now, find average direction and color of bright pixels
  61. for(int f=0;f<6;f++)
  62. for(int y=0;y<cmap.face_maps[f].Height;y++)
  63. for(int x=0;x<cmap.face_maps[f].Width;x++)
  64. {
  65. Vector clr(
  66. cmap.face_maps[f].Pixel(x,y,0),
  67. cmap.face_maps[f].Pixel(x,y,1),
  68. cmap.face_maps[f].Pixel(x,y,2));
  69. float mag=clr.Length();
  70. if (mag>threshhold)
  71. {
  72. clr-=AverageColor;
  73. AverageHue+=clr;
  74. Vector pdir=cmap.PixelDirection(f,x,y);
  75. pdir*=clr.Length();
  76. avg_light_dir+=pdir;
  77. }
  78. }
  79. VectorNormalize(AverageHue);
  80. VectorNormalize(avg_light_dir);
  81. printf("Point light dir=%f %f %f\n",avg_light_dir.x,avg_light_dir.y,avg_light_dir.z);
  82. // printf("Point light color=%f %f %f\n",AverageHue.x,AverageHue.y,AverageHue.z);
  83. printf("Point light color=%d %d %d 255\n",
  84. ( int )( 255 * pow( AverageHue.x, 1.0f / 2.2f ) ),
  85. ( int )( 255 * pow( AverageHue.y, 1.0f / 2.2f ) ),
  86. ( int )( 255 * pow( AverageHue.z, 1.0f / 2.2f ) ) );
  87. // now, output ambient cube maps for image-based lighting. During this pass, we will also
  88. // correct the ambient color
  89. FloatCubeMap_t conv(32,32);
  90. Vector AmbientColor(0,0,0);
  91. float sumweights_amb=0;
  92. for(int f=0;f<6;f++)
  93. for(int y=0;y<conv.face_maps[f].Height;y++)
  94. for(int x=0;x<conv.face_maps[f].Width;x++)
  95. {
  96. Vector pdir=conv.PixelDirection(f,x,y);
  97. float dot=pdir.Dot(avg_light_dir);
  98. if (dot<0) dot=0;
  99. float sumdot=0;
  100. Vector sumlight(0,0,0);
  101. for(int f1=0;f1<6;f1++)
  102. for(int y1=0;y1<cmap.face_maps[f].Height;y1+=20)
  103. for(int x1=0;x1<cmap.face_maps[f].Width;x1+=20)
  104. {
  105. Vector sdir=cmap.PixelDirection(f1,x1,y1);
  106. float dot_sphere=sdir.Dot(pdir);
  107. if (dot_sphere>0)
  108. {
  109. sumdot+=dot_sphere;
  110. for(int comp=0;comp<3;comp++)
  111. sumlight[comp]+=
  112. dot_sphere*cmap.face_maps[f1].Pixel(x1,y1,comp);
  113. }
  114. }
  115. sumlight*=1.0/sumdot;
  116. // sumlight is the desired lighting
  117. // use our calculated point light source to find the error
  118. float weight=Importance(pdir);
  119. sumweights_amb+=weight;
  120. for(int comp=0;comp<3;comp++)
  121. {
  122. conv.face_maps[f].Pixel(x,y,comp)=sumlight[comp];
  123. AmbientColor[comp]+=weight*(sumlight[comp]-dot*AverageHue[comp]);
  124. }
  125. }
  126. AmbientColor*=1.0/sumweights_amb;
  127. conv.WritePFMs("ambient_cube_");
  128. // printf("Ambient color=%f %f %f\n",AmbientColor.x,AmbientColor.y,AmbientColor.z);
  129. // convert to gamma space. . .
  130. printf("Ambient color=%d %d %d 255\n",
  131. ( int )( 255 * pow( AmbientColor.x, 1.0f/2.2f ) ),
  132. ( int )( 255 * pow( AmbientColor.y, 1.0f/2.2f ) ),
  133. ( int )( 255 * pow( AmbientColor.z, 1.0f/2.2f ) ) );
  134. for(int f=0;f<6;f++)
  135. for(int y=0;y<cmap.face_maps[f].Height;y++)
  136. for(int x=0;x<cmap.face_maps[f].Width;x++)
  137. {
  138. Vector pdir=cmap.PixelDirection(f,x,y);
  139. float dot=pdir.Dot(avg_light_dir);
  140. if (dot<0) dot=0;
  141. dot=pow(dot,7);
  142. for(int comp=0;comp<3;comp++)
  143. cmap.face_maps[f].Pixel(x,y,comp)=AmbientColor[comp]+dot*AverageHue[comp];
  144. }
  145. cmap.WritePFMs("directional_plus_ambient_");
  146. }
  147. }