diff options
| author | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
|---|---|---|
| committer | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
| commit | 3bf9df6b2785fa6d951086978a3e66f49427166a (patch) | |
| tree | 2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /utils/cubelight/cubelight.cpp | |
| download | archived-source-engine-2018-hl2-src-master.tar.xz archived-source-engine-2018-hl2-src-master.zip | |
Diffstat (limited to 'utils/cubelight/cubelight.cpp')
| -rw-r--r-- | utils/cubelight/cubelight.cpp | 169 |
1 files changed, 169 insertions, 0 deletions
diff --git a/utils/cubelight/cubelight.cpp b/utils/cubelight/cubelight.cpp new file mode 100644 index 0000000..647108b --- /dev/null +++ b/utils/cubelight/cubelight.cpp @@ -0,0 +1,169 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//===========================================================================// + +#include "tier0/platform.h" +#include <stdio.h> +#include "bitmap/float_bm.h" +#include "mathlib/mathlib.h" +#include "tier2/tier2.h" + +#define BRIGHT_THRESH 0.90 // pixels within this % of average are "bright" +#define GROUND_IMPORTANCE 0.2 // weight for downward pointing skymap pixels + +float Importance(Vector const &direction) +{ + // this returns a scale factor which can be used to recurd the importance of certain + // directions. in particular, this version makes the ground a lot less important than the sky + if (direction.z>.2) + return 1.0; + if (direction.z>0) + return FLerp(1.0,GROUND_IMPORTANCE,.2,0,direction.z); + else + return GROUND_IMPORTANCE; + +} + +void main(int argc,char **argv) +{ + InitCommandLineProgram(argc, argv); + if (argc!=2) + { + printf("format is %s basename\n",argv[0]); + } + else + { + FloatCubeMap_t cmap(argv[1]); + // find the brightest pixel. We will consider the pixels neat this to be the + // ones contrinbuting to the light source + float max_color=cmap.BrightestColor(); + float threshhold=max_color*.90; + // now, find average color of non-bright pixels + float sumweights=0.0; + Vector AverageColor(0,0,0); + for(int f=0;f<6;f++) + for(int y=0;y<cmap.face_maps[f].Height;y++) + for(int x=0;x<cmap.face_maps[f].Width;x++) + { + Vector clr( + cmap.face_maps[f].Pixel(x,y,0), + cmap.face_maps[f].Pixel(x,y,1), + cmap.face_maps[f].Pixel(x,y,2)); + float mag=clr.Length(); + if (mag<threshhold) + { + float weight=Importance(cmap.PixelDirection(f,x,y)); + sumweights+=weight; + AverageColor+=weight*clr; + } + } + AverageColor*=(1.0/sumweights); + + Vector avg_light_dir(0,0,0); + Vector AverageHue(0,0,0); + // now, find average direction and color of bright pixels + for(int f=0;f<6;f++) + for(int y=0;y<cmap.face_maps[f].Height;y++) + for(int x=0;x<cmap.face_maps[f].Width;x++) + { + Vector clr( + cmap.face_maps[f].Pixel(x,y,0), + cmap.face_maps[f].Pixel(x,y,1), + cmap.face_maps[f].Pixel(x,y,2)); + float mag=clr.Length(); + if (mag>threshhold) + { + clr-=AverageColor; + AverageHue+=clr; + Vector pdir=cmap.PixelDirection(f,x,y); + pdir*=clr.Length(); + avg_light_dir+=pdir; + } + } + VectorNormalize(AverageHue); + VectorNormalize(avg_light_dir); + + printf("Point light dir=%f %f %f\n",avg_light_dir.x,avg_light_dir.y,avg_light_dir.z); +// printf("Point light color=%f %f %f\n",AverageHue.x,AverageHue.y,AverageHue.z); + printf("Point light color=%d %d %d 255\n", + ( int )( 255 * pow( AverageHue.x, 1.0f / 2.2f ) ), + ( int )( 255 * pow( AverageHue.y, 1.0f / 2.2f ) ), + ( int )( 255 * pow( AverageHue.z, 1.0f / 2.2f ) ) ); + + // now, output ambient cube maps for image-based lighting. During this pass, we will also + // correct the ambient color + + FloatCubeMap_t conv(32,32); + + Vector AmbientColor(0,0,0); + float sumweights_amb=0; + + for(int f=0;f<6;f++) + for(int y=0;y<conv.face_maps[f].Height;y++) + for(int x=0;x<conv.face_maps[f].Width;x++) + { + Vector pdir=conv.PixelDirection(f,x,y); + float dot=pdir.Dot(avg_light_dir); + if (dot<0) dot=0; + + float sumdot=0; + Vector sumlight(0,0,0); + for(int f1=0;f1<6;f1++) + for(int y1=0;y1<cmap.face_maps[f].Height;y1+=20) + for(int x1=0;x1<cmap.face_maps[f].Width;x1+=20) + { + Vector sdir=cmap.PixelDirection(f1,x1,y1); + float dot_sphere=sdir.Dot(pdir); + if (dot_sphere>0) + { + sumdot+=dot_sphere; + for(int comp=0;comp<3;comp++) + sumlight[comp]+= + dot_sphere*cmap.face_maps[f1].Pixel(x1,y1,comp); + } + } + sumlight*=1.0/sumdot; + // sumlight is the desired lighting + + // use our calculated point light source to find the error + float weight=Importance(pdir); + sumweights_amb+=weight; + for(int comp=0;comp<3;comp++) + { + conv.face_maps[f].Pixel(x,y,comp)=sumlight[comp]; + AmbientColor[comp]+=weight*(sumlight[comp]-dot*AverageHue[comp]); + } + + } + AmbientColor*=1.0/sumweights_amb; + + conv.WritePFMs("ambient_cube_"); + + +// printf("Ambient color=%f %f %f\n",AmbientColor.x,AmbientColor.y,AmbientColor.z); + // convert to gamma space. . . + printf("Ambient color=%d %d %d 255\n", + ( int )( 255 * pow( AmbientColor.x, 1.0f/2.2f ) ), + ( int )( 255 * pow( AmbientColor.y, 1.0f/2.2f ) ), + ( int )( 255 * pow( AmbientColor.z, 1.0f/2.2f ) ) ); + + for(int f=0;f<6;f++) + for(int y=0;y<cmap.face_maps[f].Height;y++) + for(int x=0;x<cmap.face_maps[f].Width;x++) + { + Vector pdir=cmap.PixelDirection(f,x,y); + float dot=pdir.Dot(avg_light_dir); + if (dot<0) dot=0; + dot=pow(dot,7); + for(int comp=0;comp<3;comp++) + cmap.face_maps[f].Pixel(x,y,comp)=AmbientColor[comp]+dot*AverageHue[comp]; + } + cmap.WritePFMs("directional_plus_ambient_"); + } + + + +} + |