Merge pull request #3889 from akohlmey/image-anti-alias
Implement anti-aliasing for dump image (and dump movie)
This commit is contained in:
BIN
doc/src/JPG/image.both.png
Normal file
BIN
doc/src/JPG/image.both.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 23 KiB |
BIN
doc/src/JPG/image.default.png
Normal file
BIN
doc/src/JPG/image.default.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 22 KiB |
BIN
doc/src/JPG/image.fsaa.png
Normal file
BIN
doc/src/JPG/image.fsaa.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 23 KiB |
BIN
doc/src/JPG/image.ssao.png
Normal file
BIN
doc/src/JPG/image.ssao.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 22 KiB |
@ -24,7 +24,7 @@ Syntax
|
||||
* color = atom attribute that determines color of each atom
|
||||
* diameter = atom attribute that determines size of each atom
|
||||
* zero or more keyword/value pairs may be appended
|
||||
* keyword = *atom* or *adiam* or *bond* or *grid* or *line* or *tri* or *body* or *fix* or *size* or *view* or *center* or *up* or *zoom* or *box* or *axes* or *subbox* or *shiny* or *ssao*
|
||||
* keyword = *atom* or *adiam* or *bond* or *grid* or *line* or *tri* or *body* or *fix* or *size* or *view* or *center* or *up* or *zoom* or *box* or *axes* or *subbox* or *shiny* or *fsaa* or *ssao*
|
||||
|
||||
.. parsed-literal::
|
||||
|
||||
@ -85,6 +85,8 @@ Syntax
|
||||
diam = diameter of subdomain lines as fraction of shortest box length
|
||||
*shiny* value = sfactor = shinyness of spheres and cylinders
|
||||
sfactor = shinyness of spheres and cylinders from 0.0 to 1.0
|
||||
*fsaa* arg = yes/no
|
||||
yes/no = do or do not apply anti-aliasing
|
||||
*ssao* value = shading seed dfactor = SSAO depth shading
|
||||
shading = *yes* or *no* = turn depth shading on/off
|
||||
seed = random # seed (positive integer)
|
||||
@ -227,7 +229,7 @@ details have to be looked up in the `FFmpeg documentation
|
||||
described below.
|
||||
|
||||
To write out JPEG and PNG format files, you must build LAMMPS with
|
||||
support for the corresponding JPEG or PNG library. To convert images
|
||||
support for the corresponding JPEG or PNG library. To convert images
|
||||
into movies, LAMMPS has to be compiled with the -DLAMMPS_FFMPEG
|
||||
flag. See the :doc:`Build settings <Build_settings>` page for
|
||||
details.
|
||||
@ -597,13 +599,47 @@ image will appear. The *sfactor* value must be a value 0.0 <=
|
||||
*sfactor* <= 1.0, where *sfactor* = 1 is a highly reflective surface
|
||||
and *sfactor* = 0 is a rough non-shiny surface.
|
||||
|
||||
The *ssao* keyword turns on/off a screen space ambient occlusion
|
||||
(SSAO) model for depth shading. If *yes* is set, then atoms further
|
||||
away from the viewer are darkened via a randomized process, which is
|
||||
perceived as depth. The calculation of this effect can increase the
|
||||
cost of computing the image by roughly 2x. The strength of the effect
|
||||
can be scaled by the *dfactor* parameter. If *no* is set, no depth
|
||||
shading is performed.
|
||||
.. versionadded:: TBD
|
||||
|
||||
The *fsaa* keyword can be used with the dump image command to improve
|
||||
the image quality by enabling full scene anti-aliasing. Internally the
|
||||
image is rendered at twice the width and height and then scaled down by
|
||||
computing the average of each 2x2 block of pixels to produce a single
|
||||
pixel in the final image at the original size. This produces images with
|
||||
smoother, less ragged edges. The application of this algorithm can
|
||||
increase the cost of computing the image by about 3x or more.
|
||||
|
||||
The *ssao* keyword turns on/off a screen space ambient occlusion (SSAO)
|
||||
model for depth shading. If *yes* is set, then atoms further away from
|
||||
the viewer are darkened via a randomized process, which is perceived as
|
||||
depth. The strength of the effect can be scaled by the *dfactor*
|
||||
parameter. If *no* is set, no depth shading is performed. The
|
||||
calculation of this effect can increase the cost of computing the image
|
||||
substantially by 5x or more, especially with larger images. When used
|
||||
in combination with the *fsaa* keyword the computational cost of depth
|
||||
shading is particularly large.
|
||||
|
||||
----------
|
||||
|
||||
Image Quality Settings
|
||||
""""""""""""""""""""""
|
||||
|
||||
The two keywords *fsaa* and *ssao* can be used to improve the image
|
||||
quality at the expense of additional computational cost to render the
|
||||
images. The images below show from left to right the same render with
|
||||
default settings, with *fsaa* added, with *ssao* added, and with both
|
||||
keywords added.
|
||||
|
||||
.. |imagequality1| image:: JPG/image.default.png
|
||||
:width: 24%
|
||||
.. |imagequality2| image:: JPG/image.fsaa.png
|
||||
:width: 24%
|
||||
.. |imagequality3| image:: JPG/image.ssao.png
|
||||
:width: 24%
|
||||
.. |imagequality4| image:: JPG/image.both.png
|
||||
:width: 24%
|
||||
|
||||
|imagequality1| |imagequality2| |imagequality3| |imagequality4|
|
||||
|
||||
----------
|
||||
|
||||
@ -1051,6 +1087,7 @@ The defaults for the dump_modify keywords specific to dump image and dump movie
|
||||
* boxcolor = yellow
|
||||
* color = 140 color names are pre-defined as listed below
|
||||
* framerate = 24
|
||||
* fsaa = no
|
||||
* gmap = min max cf 0.0 2 min blue max red
|
||||
|
||||
----------
|
||||
|
||||
@ -1195,6 +1195,7 @@ Freitas
|
||||
Frenkel
|
||||
Friedrichs
|
||||
fs
|
||||
fsaa
|
||||
fsh
|
||||
fstyle
|
||||
fsw
|
||||
|
||||
@ -248,10 +248,14 @@ DumpImage::DumpImage(LAMMPS *lmp, int narg, char **arg) :
|
||||
if (iarg+3 > narg) error->all(FLERR,"Illegal dump image command");
|
||||
int width = utils::inumeric(FLERR,arg[iarg+1],false,lmp);
|
||||
int height = utils::inumeric(FLERR,arg[iarg+2],false,lmp);
|
||||
if (width <= 0 || height <= 0)
|
||||
error->all(FLERR,"Illegal dump image command");
|
||||
image->width = width;
|
||||
image->height = height;
|
||||
if (width <= 0 || height <= 0) error->all(FLERR,"Illegal dump image command");
|
||||
if (image->fsaa) {
|
||||
image->width = width*2;
|
||||
image->height = height*2;
|
||||
} else {
|
||||
image->width = width;
|
||||
image->height = height;
|
||||
}
|
||||
iarg += 3;
|
||||
|
||||
} else if (strcmp(arg[iarg],"view") == 0) {
|
||||
@ -345,6 +349,23 @@ DumpImage::DumpImage(LAMMPS *lmp, int narg, char **arg) :
|
||||
image->shiny = shiny;
|
||||
iarg += 2;
|
||||
|
||||
} else if (strcmp(arg[iarg],"fsaa") == 0) {
|
||||
if (iarg+2 > narg) error->all(FLERR,"Illegal dump_modify command");
|
||||
int aa = utils::logical(FLERR, arg[iarg+1], false, lmp);
|
||||
if (aa) {
|
||||
if (!image->fsaa) {
|
||||
image->width = image->width*2;
|
||||
image->height = image->height*2;
|
||||
}
|
||||
} else {
|
||||
if (image->fsaa) {
|
||||
image->width = image->width/2;
|
||||
image->height = image->height/2;
|
||||
}
|
||||
}
|
||||
image->fsaa = aa;
|
||||
iarg += 2;
|
||||
|
||||
} else if (strcmp(arg[iarg],"ssao") == 0) {
|
||||
if (iarg+4 > narg) error->all(FLERR,"Illegal dump image command");
|
||||
image->ssao = utils::logical(FLERR,arg[iarg+1],false,lmp);
|
||||
|
||||
@ -55,7 +55,9 @@ enum{NO,YES};
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
Image::Image(LAMMPS *lmp, int nmap_caller) : Pointers(lmp)
|
||||
Image::Image(LAMMPS *lmp, int nmap_caller) :
|
||||
Pointers(lmp), depthBuffer(nullptr), surfaceBuffer(nullptr), depthcopy(nullptr),
|
||||
surfacecopy(nullptr), imageBuffer(nullptr), rgbcopy(nullptr), writeBuffer(nullptr)
|
||||
{
|
||||
MPI_Comm_rank(world,&me);
|
||||
MPI_Comm_size(world,&nprocs);
|
||||
@ -69,6 +71,7 @@ Image::Image(LAMMPS *lmp, int nmap_caller) : Pointers(lmp)
|
||||
persp = 0.0;
|
||||
shiny = 1.0;
|
||||
ssao = NO;
|
||||
fsaa = NO;
|
||||
|
||||
up[0] = 0.0;
|
||||
up[1] = 0.0;
|
||||
@ -154,6 +157,13 @@ Image::~Image()
|
||||
|
||||
void Image::buffers()
|
||||
{
|
||||
memory->destroy(depthBuffer);
|
||||
memory->destroy(surfaceBuffer);
|
||||
memory->destroy(imageBuffer);
|
||||
memory->destroy(depthcopy);
|
||||
memory->destroy(surfacecopy);
|
||||
memory->destroy(rgbcopy);
|
||||
|
||||
npixels = width * height;
|
||||
memory->create(depthBuffer,npixels,"image:depthBuffer");
|
||||
memory->create(surfaceBuffer,2*npixels,"image:surfaceBuffer");
|
||||
@ -380,6 +390,26 @@ void Image::merge()
|
||||
} else {
|
||||
writeBuffer = imageBuffer;
|
||||
}
|
||||
|
||||
// scale down image for antialiasing. can be done in place with simple averaging
|
||||
if (fsaa) {
|
||||
for (int h=0; h < height; h += 2) {
|
||||
for (int w=0; w < width; w +=2) {
|
||||
int idx1 = 3*height*h + 3*w;
|
||||
int idx2 = 3*height*h + 3*(w+1);
|
||||
int idx3 = 3*height*(h+1) + 3*w;
|
||||
int idx4 = 3*height*(h+1) + 3*(w+1);
|
||||
|
||||
int out = 3*(height/2)*(h/2) + 3*(w/2);
|
||||
for (int i=0; i < 3; ++i) {
|
||||
writeBuffer[out+i] = (unsigned char) (0.25*((int)writeBuffer[idx1+i]
|
||||
+(int)writeBuffer[idx2+i]
|
||||
+(int)writeBuffer[idx3+i]
|
||||
+(int)writeBuffer[idx4+i]));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
@ -1037,6 +1067,7 @@ void Image::compute_SSAO()
|
||||
void Image::write_JPG(FILE *fp)
|
||||
{
|
||||
#ifdef LAMMPS_JPEG
|
||||
int aafactor = fsaa ? 2 : 1;
|
||||
struct jpeg_compress_struct cinfo;
|
||||
struct jpeg_error_mgr jerr;
|
||||
JSAMPROW row_pointer;
|
||||
@ -1044,8 +1075,8 @@ void Image::write_JPG(FILE *fp)
|
||||
cinfo.err = jpeg_std_error(&jerr);
|
||||
jpeg_create_compress(&cinfo);
|
||||
jpeg_stdio_dest(&cinfo,fp);
|
||||
cinfo.image_width = width;
|
||||
cinfo.image_height = height;
|
||||
cinfo.image_width = width/aafactor;
|
||||
cinfo.image_height = height/aafactor;
|
||||
cinfo.input_components = 3;
|
||||
cinfo.in_color_space = JCS_RGB;
|
||||
|
||||
@ -1055,7 +1086,7 @@ void Image::write_JPG(FILE *fp)
|
||||
|
||||
while (cinfo.next_scanline < cinfo.image_height) {
|
||||
row_pointer = (JSAMPROW)
|
||||
&writeBuffer[(cinfo.image_height - 1 - cinfo.next_scanline) * 3 * width];
|
||||
&writeBuffer[(cinfo.image_height - 1 - cinfo.next_scanline) * 3 * (width/aafactor)];
|
||||
jpeg_write_scanlines(&cinfo,&row_pointer,1);
|
||||
}
|
||||
|
||||
@ -1071,6 +1102,7 @@ void Image::write_JPG(FILE *fp)
|
||||
void Image::write_PNG(FILE *fp)
|
||||
{
|
||||
#ifdef LAMMPS_PNG
|
||||
int aafactor = fsaa ? 2 : 1;
|
||||
png_structp png_ptr;
|
||||
png_infop info_ptr;
|
||||
|
||||
@ -1090,8 +1122,8 @@ void Image::write_PNG(FILE *fp)
|
||||
}
|
||||
|
||||
png_init_io(png_ptr, fp);
|
||||
png_set_compression_level(png_ptr,Z_BEST_COMPRESSION);
|
||||
png_set_IHDR(png_ptr,info_ptr,width,height,8,PNG_COLOR_TYPE_RGB,
|
||||
png_set_compression_level(png_ptr,Z_BEST_SPEED);
|
||||
png_set_IHDR(png_ptr,info_ptr,width/aafactor,height/aafactor,8,PNG_COLOR_TYPE_RGB,
|
||||
PNG_INTERLACE_NONE,PNG_COMPRESSION_TYPE_DEFAULT,PNG_FILTER_TYPE_DEFAULT);
|
||||
|
||||
png_text text_ptr[2];
|
||||
@ -1111,9 +1143,9 @@ void Image::write_PNG(FILE *fp)
|
||||
png_set_text(png_ptr,info_ptr,text_ptr,1);
|
||||
png_write_info(png_ptr,info_ptr);
|
||||
|
||||
auto row_pointers = new png_bytep[height];
|
||||
for (int i=0; i < height; ++i)
|
||||
row_pointers[i] = (png_bytep) &writeBuffer[(height-i-1)*3*width];
|
||||
auto row_pointers = new png_bytep[height/aafactor];
|
||||
for (int i=0; i < height/aafactor; ++i)
|
||||
row_pointers[i] = (png_bytep) &writeBuffer[((height/aafactor)-i-1)*3*(width/aafactor)];
|
||||
|
||||
png_write_image(png_ptr, row_pointers);
|
||||
png_write_end(png_ptr, info_ptr);
|
||||
@ -1129,11 +1161,12 @@ void Image::write_PNG(FILE *fp)
|
||||
|
||||
void Image::write_PPM(FILE *fp)
|
||||
{
|
||||
fprintf(fp,"P6\n%d %d\n255\n",width,height);
|
||||
int aafactor = fsaa ? 2 : 1;
|
||||
fprintf(fp,"P6\n%d %d\n255\n",width/aafactor,height/aafactor);
|
||||
|
||||
int y;
|
||||
for (y = height-1; y >= 0; y--)
|
||||
fwrite(&writeBuffer[y*width*3],3,width,fp);
|
||||
for (y = (height/aafactor)-1; y >= 0; y--)
|
||||
fwrite(&writeBuffer[y*(width/aafactor)*3],3,width/aafactor,fp);
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
|
||||
@ -28,13 +28,14 @@ class Image : protected Pointers {
|
||||
double zoom; // zoom factor
|
||||
double persp; // perspective factor
|
||||
double shiny; // shininess of objects
|
||||
int fsaa; // antialiasing on or off
|
||||
int ssao; // SSAO on or off
|
||||
int seed; // RN seed for SSAO
|
||||
double ssaoint; // strength of shading from 0 to 1
|
||||
double *boxcolor; // color to draw box outline with
|
||||
int background[3]; // RGB values of background
|
||||
|
||||
double ambientColor[3]; // light color settings (adjustable by caller)
|
||||
double ambientColor[3]; // light color settings (adjustable by caller)
|
||||
double keyLightColor[3];
|
||||
double fillLightColor[3];
|
||||
double backLightColor[3];
|
||||
|
||||
Reference in New Issue
Block a user