Reference
- Processing
- "Spherical Gaussian approximation for Blinn-Phong, Phong and Fresnel"
// // Schlick fresnel vs SG approx by processing // // x/y float g_min_x = 0.0; float g_max_x = 1.0; float g_min_y = 0.0; float g_max_y = 1.0; // graph int g_row_count = 100; int g_column_count = 100; float g_row_sub_grid = 10.0; float g_column_sub_grid = 10.0; float g_plot_x1, g_plot_y1; float g_plot_x2, g_plot_y2; float g_label_x, g_label_y; PFont g_plot_font; void setup() { size(480, 480); // Corners of the plotted time series g_plot_x1 = 100; g_plot_x2 = width - 80; g_label_x = 50; g_plot_y1 = 100; g_plot_y2 = height - 80; g_label_y = height - 25; g_plot_font = createFont("SansSerif", 20); textFont( g_plot_font ); smooth(); } void draw() { background(224); // Show the plot area as a white box fill(255); rectMode(CORNERS); noStroke(); rect( g_plot_x1, g_plot_y1, g_plot_x2, g_plot_y2 ); drawTitle(); drawAxisLabels(); drawSubGrid(); // stroke(#5679C1); colorMode(RGB, 256); stroke( 255.0, 0.0, 0.0 ); strokeWeight(1); noFill(); drawDataLine(); stroke( 0.0, 255.0, 0.0 ); drawDataLine2(); } String g_row_label = "dot(l, n)"; String g_column_label = "fresnel"; String g_graph_title0 = "Schlick Fresnel"; String g_graph_title1 = "SG approx"; float g_f0 = 0.04; // value is between 0 and 1. float getX( float value ) { float x = value; return x; } // value is between 0 and 1. float getY( float x ) { float f0 = g_f0; float fresnel = f0 + ( 1 - f0 ) * pow( 1.0 - x, 5.0 ); float y = fresnel; return y; } // value is between 0 and 1. float getY2( float x ) { float f0 = g_f0; float sphg = pow( 2.0, ( - 5.55473 * x - 6.98316 ) * x ); float fresnel = f0 + ( 1.0 - f0 ) * sphg; float y = fresnel; return y; } void drawTitle() { fill(0); textSize(20); textAlign(LEFT); fill( 255, 0, 0 ); text( g_graph_title0, g_plot_x1, g_plot_y1 - 40); fill( 0, 255, 0 ); text( g_graph_title1, g_plot_x1, g_plot_y1 - 20); } void drawAxisLabels() { fill(0); textSize(13); textLeading(15); textAlign(CENTER, CENTER); text( g_column_label, g_label_x, ( g_plot_y1 + g_plot_y2 )/2); textAlign(CENTER); text( g_row_label, ( g_plot_x1 + g_plot_x2)/2, g_label_y); // String str = "f0 = " + Float.toString( g_f0 ); String str = "f0 = " + nf( g_f0, 1, 3 ); text( str, g_label_x, ( g_plot_y1 + g_plot_y2 )/2 + 20 ); } void drawDataLine() { beginShape(); for (int row = 0; row < g_row_count; row++) { float value = float( row ) / float( g_row_count ); float x = getX( value ); float y = getY( x ); float draw_x = map( x, g_min_x, g_max_x, g_plot_x1, g_plot_x2 ); float draw_y = map( y, g_min_y, g_max_y, g_plot_y2, g_plot_y1 ); vertex( draw_x, draw_y); } endShape(); } void drawDataLine2() { beginShape(); for (int row = 0; row < g_row_count; row++) { float value = float( row ) / float( g_row_count ); float x = getX( value ); float y = getY2( x ); float draw_x = map( x, g_min_x, g_max_x, g_plot_x1, g_plot_x2 ); float draw_y = map( y, g_min_y, g_max_y, g_plot_y2, g_plot_y1 ); vertex( draw_x, draw_y); } endShape(); } void drawSubGrid() { fill(0); textSize(10); textAlign(CENTER); // Use thin, gray lines to draw the grid stroke(224); strokeWeight(1); for (int row = 0; row < g_row_count; row += int( g_row_sub_grid ) ) { float x = map( g_row_sub_grid * row, 0.0, g_row_sub_grid * g_row_count, g_plot_x1, g_plot_x2 ); line(x, g_plot_y1, x, g_plot_y2); } for (int column = 0; column < g_column_count; column += int( g_column_sub_grid ) ) { float y = map( g_column_sub_grid * column, 0.0, g_column_sub_grid * g_column_count, g_plot_y2, g_plot_y1 ); line( g_plot_x1, y, g_plot_x2, y ); } } void keyPressed() { if (key == CODED ) { if ( keyCode == UP ) { g_f0 += 0.1; if ( g_f0 >= 1.0 ) { g_f0 = 1.0; } } else if ( keyCode == DOWN ) { g_f0 -= 0.1; if ( g_f0 < 0.04 ) { g_f0 = 0.04; } } } }