Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/render/intern/source/pixelshading.c')
-rw-r--r--source/blender/render/intern/source/pixelshading.c154
1 files changed, 129 insertions, 25 deletions
diff --git a/source/blender/render/intern/source/pixelshading.c b/source/blender/render/intern/source/pixelshading.c
index cffed99c738..60723963af9 100644
--- a/source/blender/render/intern/source/pixelshading.c
+++ b/source/blender/render/intern/source/pixelshading.c
@@ -24,7 +24,9 @@
* ***** END GPL LICENSE BLOCK *****
*/
+#include <float.h>
#include <math.h>
+#include <string.h>
#include "BLI_arithb.h"
/* External modules: */
@@ -43,6 +45,7 @@
#include "BKE_image.h"
#include "BKE_global.h"
+#include "BKE_material.h"
#include "BKE_texture.h"
#include "BKE_utildefines.h"
@@ -55,6 +58,7 @@
#include "rendercore.h"
#include "shadbuf.h"
#include "pixelshading.h"
+#include "sunsky.h"
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
/* defined in pipeline.c, is hardcopy of active dynamic allocated Render */
@@ -130,9 +134,15 @@ static void render_lighting_halo(HaloRen *har, float *colf)
if(lar->mode & LA_TEXTURE) {
ShadeInput shi;
+
+ /* Warning, This is not that nice, and possibly a bit slow,
+ however some variables were not initialized properly in, unless using shade_input_initialize(...), we need to do a memset */
+ memset(&shi, 0, sizeof(ShadeInput));
+ /* end warning! - Campbell */
+
VECCOPY(shi.co, rco);
shi.osatex= 0;
- do_lamp_tex(lar, lv, &shi, lacol);
+ do_lamp_tex(lar, lv, &shi, lacol, LA_TEXTURE);
}
if(lar->type==LA_SPOT) {
@@ -175,7 +185,7 @@ static void render_lighting_halo(HaloRen *har, float *colf)
inp= vn[0]*lv[0] + vn[1]*lv[1] + vn[2]*lv[2];
if(inp>0.0) {
/* testshadowbuf==0.0 : 100% shadow */
- shadfac = testshadowbuf(lar->shb, rco, dco, dco, inp);
+ shadfac = testshadowbuf(&R, lar->shb, rco, dco, dco, inp, 0.0f);
if( shadfac>0.0 ) {
shadfac*= inp*soft*lar->energy;
ir -= shadfac;
@@ -212,7 +222,7 @@ static void render_lighting_halo(HaloRen *har, float *colf)
if(i> -0.41) { /* heuristic valua! */
shadfac= 1.0;
if(lar->shb) {
- shadfac = testshadowbuf(lar->shb, rco, dco, dco, inp);
+ shadfac = testshadowbuf(&R, lar->shb, rco, dco, dco, inp, 0.0f);
if(shadfac==0.0) continue;
i*= shadfac;
}
@@ -236,8 +246,36 @@ static void render_lighting_halo(HaloRen *har, float *colf)
}
+/**
+ * Converts a halo z-buffer value to distance from the camera's near plane
+ * @param z The z-buffer value to convert
+ * @return a distance from the camera's near plane in blender units
+ */
+static float haloZtoDist(int z)
+{
+ float zco = 0;
-void shadeHaloFloat(HaloRen *har, float *col, int zz,
+ if(z >= 0x7FFFFF)
+ return 10e10;
+ else {
+ zco = (float)z/(float)0x7FFFFF;
+ if(R.r.mode & R_ORTHO)
+ return (R.winmat[3][2] - zco*R.winmat[3][3])/(R.winmat[2][2]);
+ else
+ return (R.winmat[3][2])/(R.winmat[2][2] - R.winmat[2][3]*zco);
+ }
+}
+
+/**
+ * @param col (float[4]) Store the rgb color here (with alpha)
+ * The alpha is used to blend the color to the background
+ * color_new = (1-alpha)*color_background + color
+ * @param zz The current zbuffer value at the place of this pixel
+ * @param dist Distance of the pixel from the center of the halo squared. Given in pixels
+ * @param xn The x coordinate of the pixel relaticve to the center of the halo. given in pixels
+ * @param yn The y coordinate of the pixel relaticve to the center of the halo. given in pixels
+ */
+int shadeHaloFloat(HaloRen *har, float *col, int zz,
float dist, float xn, float yn, short flarec)
{
/* fill in col */
@@ -256,12 +294,40 @@ void shadeHaloFloat(HaloRen *har, float *col, int zz,
}
else alpha= har->alfa;
- if(alpha==0.0) {
- col[0] = 0.0;
- col[1] = 0.0;
- col[2] = 0.0;
- col[3] = 0.0;
- return;
+ if(alpha==0.0)
+ return 0;
+
+ /* soften the halo if it intersects geometry */
+ if(har->mat && har->mat->mode & MA_HALO_SOFT) {
+ float segment_length, halo_depth, distance_from_z, visible_depth, soften;
+
+ /* calculate halo depth */
+ segment_length= har->hasize*sasqrt(1.0f - dist/(har->rad*har->rad));
+ halo_depth= 2.0f*segment_length;
+
+ if(halo_depth < FLT_EPSILON)
+ return 0;
+
+ /* calculate how much of this depth is visible */
+ distance_from_z = haloZtoDist(zz) - haloZtoDist(har->zs);
+ visible_depth = halo_depth;
+ if(distance_from_z < segment_length) {
+ soften= (segment_length + distance_from_z)/halo_depth;
+
+ /* apply softening to alpha */
+ if(soften < 1.0f)
+ alpha *= soften;
+ if(alpha <= 0.0f)
+ return 0;
+ }
+ }
+ else {
+ /* not a soft halo. use the old softening code */
+ /* halo being intersected? */
+ if(har->zs> zz-har->zd) {
+ t= ((float)(zz-har->zs))/(float)har->zd;
+ alpha*= sqrt(sqrt(t));
+ }
}
radist= sqrt(dist);
@@ -359,21 +425,10 @@ void shadeHaloFloat(HaloRen *har, float *col, int zz,
if(ster<1.0) dist*= sqrt(ster);
}
}
-
- /* halo being intersected? */
- if(har->zs> zz-har->zd) {
- t= ((float)(zz-har->zs))/(float)har->zd;
- alpha*= sqrt(sqrt(t));
- }
/* disputable optimize... (ton) */
- if(dist<=0.00001) {
- col[0] = 0.0;
- col[1] = 0.0;
- col[2] = 0.0;
- col[3] = 0.0;
- return;
- }
+ if(dist<=0.00001)
+ return 0;
dist*= alpha;
ringf*= dist;
@@ -434,6 +489,8 @@ void shadeHaloFloat(HaloRen *har, float *col, int zz,
/* alpha requires clip, gives black dots */
if(col[3] > 1.0f)
col[3]= 1.0f;
+
+ return 1;
}
/* ------------------------------------------------------------------------- */
@@ -512,13 +569,48 @@ void shadeSkyView(float *colf, float *rco, float *view, float *dxyview)
}
}
+/* shade sky according to sun lamps, all parameters are like shadeSkyView except sunsky*/
+void shadeSunView(float *colf, float *view)
+{
+ GroupObject *go;
+ LampRen *lar;
+ float sview[3];
+ int do_init= 1;
+
+ for(go=R.lights.first; go; go= go->next) {
+ lar= go->lampren;
+ if(lar->type==LA_SUN && lar->sunsky && (lar->sunsky->effect_type & LA_SUN_EFFECT_SKY)){
+ float sun_collector[3];
+ float colorxyz[3];
+
+ if(do_init) {
+
+ VECCOPY(sview, view);
+ Normalize(sview);
+ MTC_Mat3MulVecfl(R.imat, sview);
+ if (sview[2] < 0.0)
+ sview[2] = 0.0;
+ Normalize(sview);
+ do_init= 0;
+ }
+
+ GetSkyXYZRadiancef(lar->sunsky, sview, colorxyz);
+ xyz_to_rgb(colorxyz[0], colorxyz[1], colorxyz[2], &sun_collector[0], &sun_collector[1], &sun_collector[2],
+ lar->sunsky->sky_colorspace);
+
+ ramp_blend(lar->sunsky->skyblendtype, colf, colf+1, colf+2, lar->sunsky->skyblendfac, sun_collector);
+ }
+ }
+}
+
+
/*
Stuff the sky color into the collector.
*/
void shadeSkyPixel(float *collector, float fx, float fy)
{
float view[3], dxyview[2];
-
+
/*
The rules for sky:
1. Draw an image, if a background image was provided. Stop
@@ -530,7 +622,6 @@ void shadeSkyPixel(float *collector, float fx, float fy)
/* 1. Do a backbuffer image: */
if(R.r.bufflag & 1) {
fillBackgroundImage(collector, fx, fy);
- return;
}
else if((R.wrld.skytype & (WO_SKYBLEND+WO_SKYTEX))==0) {
/* 2. solid color */
@@ -565,7 +656,20 @@ void shadeSkyPixel(float *collector, float fx, float fy)
shadeSkyView(collector, NULL, view, dxyview);
collector[3] = 0.0f;
}
+
+ calc_view_vector(view, fx, fy);
+ shadeSunView(collector, view);
}
+/* aerial perspective */
+void shadeAtmPixel(struct SunSky *sunsky, float *collector, float fx, float fy, float distance)
+{
+ float view[3];
+
+ calc_view_vector(view, fx, fy);
+ Normalize(view);
+ /*MTC_Mat3MulVecfl(R.imat, view);*/
+ AtmospherePixleShader(sunsky, view, distance, collector);
+}
/* eof */