implement anti-aliasing for dump image (and dump movie)
This commit is contained in:
@ -103,7 +103,7 @@ Syntax
|
|||||||
dump_modify dump-ID keyword values ...
|
dump_modify dump-ID keyword values ...
|
||||||
|
|
||||||
* these keywords apply only to the *image* and *movie* styles and are documented on this page
|
* these keywords apply only to the *image* and *movie* styles and are documented on this page
|
||||||
* keyword = *acolor* or *adiam* or *amap* or *gmap* or *backcolor* or *bcolor* or *bdiam* or *bitrate* or *boxcolor* or *color* or *framerate* or *gmap*
|
* keyword = *acolor* or *adiam* or *amap* or *gmap* or *backcolor* or *bcolor* or *bdiam* or *bitrate* or *boxcolor* or *color* or *framerate* or *fsaa* or *gmap*
|
||||||
* see the :doc:`dump modify <dump_modify>` doc page for more general keywords
|
* see the :doc:`dump modify <dump_modify>` doc page for more general keywords
|
||||||
|
|
||||||
.. parsed-literal::
|
.. parsed-literal::
|
||||||
@ -151,6 +151,8 @@ Syntax
|
|||||||
R,G,B = red/green/blue numeric values from 0.0 to 1.0
|
R,G,B = red/green/blue numeric values from 0.0 to 1.0
|
||||||
*framerate* arg = fps
|
*framerate* arg = fps
|
||||||
fps = frames per second for movie
|
fps = frames per second for movie
|
||||||
|
*fsaa* arg = yes/no
|
||||||
|
yes/no = do or do not apply anti-aliasing
|
||||||
*gmap* args = identical to *amap* args
|
*gmap* args = identical to *amap* args
|
||||||
|
|
||||||
Examples
|
Examples
|
||||||
@ -957,6 +959,17 @@ frequently.
|
|||||||
|
|
||||||
----------
|
----------
|
||||||
|
|
||||||
|
.. 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 smoother,
|
||||||
|
less ragged edges.
|
||||||
|
|
||||||
|
----------
|
||||||
|
|
||||||
The *gmap* keyword can be used with the dump image command, with its
|
The *gmap* keyword can be used with the dump image command, with its
|
||||||
*grid* keyword, to setup a color map. The color map is used to assign
|
*grid* keyword, to setup a color map. The color map is used to assign
|
||||||
a specific RGB (red/green/blue) color value to an individual grid cell
|
a specific RGB (red/green/blue) color value to an individual grid cell
|
||||||
|
|||||||
@ -1555,6 +1555,35 @@ int DumpImage::modify_param(int narg, char **arg)
|
|||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if antialias state changes, we need to increase the buffer space
|
||||||
|
// change the (internal) image dimensions and reset the view parameters
|
||||||
|
if (strcmp(arg[0],"fsaa") == 0) {
|
||||||
|
if (narg < 2) error->all(FLERR,"Illegal dump_modify command");
|
||||||
|
int aa = utils::logical(FLERR, arg[1], false, lmp);
|
||||||
|
if (image->fsaa == NO) {
|
||||||
|
if (aa == YES) {
|
||||||
|
image->width = image->width*2;
|
||||||
|
image->height = image->height*2;
|
||||||
|
// reallocate buffers to make room
|
||||||
|
image->buffers();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (aa == NO) {
|
||||||
|
image->width = image->width/2;
|
||||||
|
image->height = image->height/2;
|
||||||
|
box_bounds();
|
||||||
|
box_center();
|
||||||
|
view_params();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
image->fsaa = aa;
|
||||||
|
// reset size based parameters
|
||||||
|
box_bounds();
|
||||||
|
box_center();
|
||||||
|
view_params();
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
if (strcmp(arg[0],"bcolor") == 0) {
|
if (strcmp(arg[0],"bcolor") == 0) {
|
||||||
if (narg < 3) error->all(FLERR,"Illegal dump_modify command");
|
if (narg < 3) error->all(FLERR,"Illegal dump_modify command");
|
||||||
if (atom->nbondtypes == 0)
|
if (atom->nbondtypes == 0)
|
||||||
|
|||||||
@ -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), imageBuffer(nullptr),
|
||||||
|
depthcopy(nullptr),surfacecopy(nullptr),rgbcopy(nullptr)
|
||||||
{
|
{
|
||||||
MPI_Comm_rank(world,&me);
|
MPI_Comm_rank(world,&me);
|
||||||
MPI_Comm_size(world,&nprocs);
|
MPI_Comm_size(world,&nprocs);
|
||||||
@ -69,6 +71,7 @@ Image::Image(LAMMPS *lmp, int nmap_caller) : Pointers(lmp)
|
|||||||
persp = 0.0;
|
persp = 0.0;
|
||||||
shiny = 1.0;
|
shiny = 1.0;
|
||||||
ssao = NO;
|
ssao = NO;
|
||||||
|
fsaa = NO;
|
||||||
|
|
||||||
up[0] = 0.0;
|
up[0] = 0.0;
|
||||||
up[1] = 0.0;
|
up[1] = 0.0;
|
||||||
@ -154,6 +157,13 @@ Image::~Image()
|
|||||||
|
|
||||||
void Image::buffers()
|
void Image::buffers()
|
||||||
{
|
{
|
||||||
|
memory->destroy(depthBuffer);
|
||||||
|
memory->destroy(surfaceBuffer);
|
||||||
|
memory->destroy(imageBuffer);
|
||||||
|
memory->destroy(depthcopy);
|
||||||
|
memory->destroy(surfacecopy);
|
||||||
|
memory->destroy(rgbcopy);
|
||||||
|
|
||||||
npixels = width * height;
|
npixels = width * height;
|
||||||
memory->create(depthBuffer,npixels,"image:depthBuffer");
|
memory->create(depthBuffer,npixels,"image:depthBuffer");
|
||||||
memory->create(surfaceBuffer,2*npixels,"image:surfaceBuffer");
|
memory->create(surfaceBuffer,2*npixels,"image:surfaceBuffer");
|
||||||
@ -380,6 +390,26 @@ void Image::merge()
|
|||||||
} else {
|
} else {
|
||||||
writeBuffer = imageBuffer;
|
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)
|
void Image::write_JPG(FILE *fp)
|
||||||
{
|
{
|
||||||
#ifdef LAMMPS_JPEG
|
#ifdef LAMMPS_JPEG
|
||||||
|
int aafactor = fsaa ? 2 : 1;
|
||||||
struct jpeg_compress_struct cinfo;
|
struct jpeg_compress_struct cinfo;
|
||||||
struct jpeg_error_mgr jerr;
|
struct jpeg_error_mgr jerr;
|
||||||
JSAMPROW row_pointer;
|
JSAMPROW row_pointer;
|
||||||
@ -1044,8 +1075,8 @@ void Image::write_JPG(FILE *fp)
|
|||||||
cinfo.err = jpeg_std_error(&jerr);
|
cinfo.err = jpeg_std_error(&jerr);
|
||||||
jpeg_create_compress(&cinfo);
|
jpeg_create_compress(&cinfo);
|
||||||
jpeg_stdio_dest(&cinfo,fp);
|
jpeg_stdio_dest(&cinfo,fp);
|
||||||
cinfo.image_width = width;
|
cinfo.image_width = width/aafactor;
|
||||||
cinfo.image_height = height;
|
cinfo.image_height = height/aafactor;
|
||||||
cinfo.input_components = 3;
|
cinfo.input_components = 3;
|
||||||
cinfo.in_color_space = JCS_RGB;
|
cinfo.in_color_space = JCS_RGB;
|
||||||
|
|
||||||
@ -1055,7 +1086,7 @@ void Image::write_JPG(FILE *fp)
|
|||||||
|
|
||||||
while (cinfo.next_scanline < cinfo.image_height) {
|
while (cinfo.next_scanline < cinfo.image_height) {
|
||||||
row_pointer = (JSAMPROW)
|
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);
|
jpeg_write_scanlines(&cinfo,&row_pointer,1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1071,6 +1102,7 @@ void Image::write_JPG(FILE *fp)
|
|||||||
void Image::write_PNG(FILE *fp)
|
void Image::write_PNG(FILE *fp)
|
||||||
{
|
{
|
||||||
#ifdef LAMMPS_PNG
|
#ifdef LAMMPS_PNG
|
||||||
|
int aafactor = fsaa ? 2 : 1;
|
||||||
png_structp png_ptr;
|
png_structp png_ptr;
|
||||||
png_infop info_ptr;
|
png_infop info_ptr;
|
||||||
|
|
||||||
@ -1091,7 +1123,7 @@ void Image::write_PNG(FILE *fp)
|
|||||||
|
|
||||||
png_init_io(png_ptr, fp);
|
png_init_io(png_ptr, fp);
|
||||||
png_set_compression_level(png_ptr,Z_BEST_COMPRESSION);
|
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_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_INTERLACE_NONE,PNG_COMPRESSION_TYPE_DEFAULT,PNG_FILTER_TYPE_DEFAULT);
|
||||||
|
|
||||||
png_text text_ptr[2];
|
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_set_text(png_ptr,info_ptr,text_ptr,1);
|
||||||
png_write_info(png_ptr,info_ptr);
|
png_write_info(png_ptr,info_ptr);
|
||||||
|
|
||||||
auto row_pointers = new png_bytep[height];
|
auto row_pointers = new png_bytep[height/aafactor];
|
||||||
for (int i=0; i < height; ++i)
|
for (int i=0; i < height/aafactor; ++i)
|
||||||
row_pointers[i] = (png_bytep) &writeBuffer[(height-i-1)*3*width];
|
row_pointers[i] = (png_bytep) &writeBuffer[((height/aafactor)-i-1)*3*(width/aafactor)];
|
||||||
|
|
||||||
png_write_image(png_ptr, row_pointers);
|
png_write_image(png_ptr, row_pointers);
|
||||||
png_write_end(png_ptr, info_ptr);
|
png_write_end(png_ptr, info_ptr);
|
||||||
@ -1129,11 +1161,12 @@ void Image::write_PNG(FILE *fp)
|
|||||||
|
|
||||||
void Image::write_PPM(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;
|
int y;
|
||||||
for (y = height-1; y >= 0; y--)
|
for (y = (height/aafactor)-1; y >= 0; y--)
|
||||||
fwrite(&writeBuffer[y*width*3],3,width,fp);
|
fwrite(&writeBuffer[y*(width/aafactor)*3],3,width/aafactor,fp);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------
|
/* ----------------------------------------------------------------------
|
||||||
|
|||||||
@ -28,6 +28,7 @@ class Image : protected Pointers {
|
|||||||
double zoom; // zoom factor
|
double zoom; // zoom factor
|
||||||
double persp; // perspective factor
|
double persp; // perspective factor
|
||||||
double shiny; // shininess of objects
|
double shiny; // shininess of objects
|
||||||
|
int fsaa; // antialiasing on or off
|
||||||
int ssao; // SSAO on or off
|
int ssao; // SSAO on or off
|
||||||
int seed; // RN seed for SSAO
|
int seed; // RN seed for SSAO
|
||||||
double ssaoint; // strength of shading from 0 to 1
|
double ssaoint; // strength of shading from 0 to 1
|
||||||
|
|||||||
Reference in New Issue
Block a user