forked from bartvdbraak/blender
Approximate Ambient Occlusion
============================= A new approximate ambient occlusion method has been added, next to the existing one based on raytracing. This method is specifically targetted at use in animations, since it is inherently noise free, and so will not flicker across frames. http://www.blender.org/development/current-projects/changes-since-244/approximate-ambient-occlusion/ http://peach.blender.org/index.php/approximate-ambient-occlusion/ Further improvements are still needed, but it can be tested already. There are still a number of known issues: - Bias errors on backfaces. - For performance, instanced object do not occlude currently. - Sky textures don't work well, the derivatives for texture evaluation are not correct. - Multiple passes do not work entirely correct (they are not accurate to begin with, but could be better).
This commit is contained in:
parent
9af3b8a07e
commit
8cdfe865ec
@ -98,12 +98,12 @@ World *add_world(char *name)
|
||||
wrld->exp= 0.0f;
|
||||
wrld->exposure=wrld->range= 1.0f;
|
||||
|
||||
wrld->aodist= 5.0;
|
||||
wrld->aodist= 5.0f;
|
||||
wrld->aosamp= 5;
|
||||
wrld->aoenergy= 1.0;
|
||||
wrld->aobias= 0.05;
|
||||
wrld->aoenergy= 1.0f;
|
||||
wrld->aobias= 0.05f;
|
||||
wrld->ao_samp_method = WO_AOSAMP_HAMMERSLEY;
|
||||
|
||||
wrld->ao_approx_error= 0.25f;
|
||||
|
||||
wrld->physicsEngine= WOPHY_BULLET;//WOPHY_SUMO; Bullet by default
|
||||
wrld->preview = NULL;
|
||||
|
@ -6698,6 +6698,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
|
||||
Lamp *la;
|
||||
Material *ma;
|
||||
ParticleSettings *part;
|
||||
World *wrld;
|
||||
Mesh *me;
|
||||
|
||||
/* unless the file was created 2.44.3 but not 2.45, update the constraints */
|
||||
@ -6878,6 +6879,11 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
|
||||
}
|
||||
}
|
||||
|
||||
for(wrld=main->world.first; wrld; wrld= wrld->id.next) {
|
||||
if(wrld->ao_approx_error == 0.0f)
|
||||
wrld->ao_approx_error= 0.25f;
|
||||
}
|
||||
|
||||
if (main->versionfile < 245 || main->subversionfile < 12)
|
||||
{
|
||||
/* initialize skeleton generation toolsettings */
|
||||
|
@ -104,9 +104,8 @@ typedef struct World {
|
||||
float aodist, aodistfac, aoenergy, aobias;
|
||||
short aomode, aosamp, aomix, aocolor;
|
||||
float ao_adapt_thresh, ao_adapt_speed_fac;
|
||||
float pad2[2];
|
||||
short ao_samp_method;
|
||||
short pad1[3];
|
||||
float ao_approx_error, ao_approx_correction;
|
||||
short ao_samp_method, ao_gather_method, ao_approx_passes, pad1;
|
||||
|
||||
float *aosphere, *aotables;
|
||||
|
||||
@ -151,12 +150,17 @@ typedef struct World {
|
||||
/* aomode (use distances & random sampling modes) */
|
||||
#define WO_AODIST 1
|
||||
#define WO_AORNDSMP 2
|
||||
#define WO_AOCACHE 4
|
||||
|
||||
/* aocolor */
|
||||
#define WO_AOPLAIN 0
|
||||
#define WO_AOSKYCOL 1
|
||||
#define WO_AOSKYTEX 2
|
||||
|
||||
/* ao_gather_method */
|
||||
#define WO_AOGATHER_RAYTRACE 0
|
||||
#define WO_AOGATHER_APPROX 1
|
||||
|
||||
/* texco (also in DNA_material_types.h) */
|
||||
#define TEXCO_ANGMAP 64
|
||||
#define TEXCO_H_SPHEREMAP 256
|
||||
|
@ -64,6 +64,7 @@ struct ShadeInputCopy {
|
||||
|
||||
struct Material *mat;
|
||||
struct VlakRen *vlr;
|
||||
struct StrandRen *strand;
|
||||
struct ObjectInstanceRen *obi;
|
||||
struct ObjectRen *obr;
|
||||
int facenr;
|
||||
@ -96,6 +97,7 @@ typedef struct ShadeInput
|
||||
|
||||
struct Material *mat;
|
||||
struct VlakRen *vlr;
|
||||
struct StrandRen *strand;
|
||||
struct ObjectInstanceRen *obi;
|
||||
struct ObjectRen *obr;
|
||||
int facenr;
|
||||
@ -132,7 +134,7 @@ typedef struct ShadeInput
|
||||
/* texture coordinates */
|
||||
float lo[3], gl[3], ref[3], orn[3], winco[3], sticky[3], vcol[4], rad[3];
|
||||
float refcol[4], displace[3];
|
||||
float strand, tang[3], stress, winspeed[4];
|
||||
float strandco, tang[3], stress, winspeed[4];
|
||||
float duplilo[3], dupliuv[3];
|
||||
|
||||
ShadeInputUV uv[8]; /* 8 = MAX_MTFACE */
|
||||
|
51
source/blender/render/intern/include/occlusion.h
Normal file
51
source/blender/render/intern/include/occlusion.h
Normal file
@ -0,0 +1,51 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2008 Blender Foundation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): Brecht Van Lommel.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#ifndef OCCLUSION_H
|
||||
#define OCCLUSION_H
|
||||
|
||||
struct Render;
|
||||
struct ShadeInput;
|
||||
struct ShadeResult;
|
||||
struct RenderPart;
|
||||
struct ShadeSample;
|
||||
struct DerivedMesh;
|
||||
struct ObjectRen;
|
||||
|
||||
void make_occ_tree(struct Render *re);
|
||||
void free_occ(struct Render *re);
|
||||
void sample_occ(struct Render *re, struct ShadeInput *shi);
|
||||
|
||||
void cache_occ_samples(struct Render *re, struct RenderPart *pa, struct ShadeSample *ssamp);
|
||||
void free_occ_samples(struct Render *re, struct RenderPart *pa);
|
||||
|
||||
void *cache_occ_mesh(struct Render *re, struct ObjectRen *obr, struct DerivedMesh *dm, float mat[][4]);
|
||||
|
||||
#endif
|
||||
|
@ -159,6 +159,10 @@ struct Render
|
||||
/* octree tables and variables for raytrace */
|
||||
void *raytree;
|
||||
|
||||
/* occlusion tree */
|
||||
void *occlusiontree;
|
||||
ListBase occlusionmesh;
|
||||
|
||||
/* use this instead of R.r.cfra */
|
||||
float cfra;
|
||||
|
||||
@ -341,6 +345,7 @@ typedef struct StrandBuffer {
|
||||
|
||||
struct ObjectRen *obr;
|
||||
struct Material *ma;
|
||||
void *occlusionmesh;
|
||||
unsigned int lay;
|
||||
int overrideuv;
|
||||
int flag, maxdepth;
|
||||
|
@ -70,6 +70,7 @@ typedef struct StrandTableNode {
|
||||
float *winspeed;
|
||||
float *surfnor;
|
||||
float *simplify;
|
||||
int *face;
|
||||
struct MCol *mcol;
|
||||
float *uv;
|
||||
int totuv, totmcol;
|
||||
@ -114,6 +115,7 @@ float *RE_strandren_get_surfnor(struct ObjectRen *obr, struct StrandRen *strand,
|
||||
float *RE_strandren_get_uv(struct ObjectRen *obr, struct StrandRen *strand, int n, char **name, int verify);
|
||||
struct MCol *RE_strandren_get_mcol(struct ObjectRen *obr, struct StrandRen *strand, int n, char **name, int verify);
|
||||
float *RE_strandren_get_simplify(struct ObjectRen *obr, struct StrandRen *strand, int verify);
|
||||
int *RE_strandren_get_face(struct ObjectRen *obr, struct StrandRen *strand, int verify);
|
||||
float *RE_strandren_get_winspeed(struct ObjectInstanceRen *obi, struct StrandRen *strand, int verify);
|
||||
|
||||
struct VertRen *RE_vertren_copy(struct ObjectRen *obr, struct VertRen *ver);
|
||||
|
@ -69,6 +69,7 @@ void shade_input_initialize(struct ShadeInput *shi, struct RenderPart *pa, struc
|
||||
|
||||
void shade_sample_initialize(struct ShadeSample *ssamp, struct RenderPart *pa, struct RenderLayer *rl);
|
||||
void shade_samples_do_AO(struct ShadeSample *ssamp);
|
||||
void shade_samples_fill_with_ps(struct ShadeSample *ssamp, struct PixStr *ps, int x, int y);
|
||||
int shade_samples(struct ShadeSample *ssamp, struct PixStr *ps, int x, int y);
|
||||
|
||||
void vlr_set_uv_indices(struct VlakRen *vlr, int *i1, int *i2, int *i3);
|
||||
|
@ -100,6 +100,7 @@
|
||||
|
||||
#include "envmap.h"
|
||||
#include "multires.h"
|
||||
#include "occlusion.h"
|
||||
#include "render_types.h"
|
||||
#include "rendercore.h"
|
||||
#include "renderdatabase.h"
|
||||
@ -1497,7 +1498,7 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem
|
||||
float *orco=0,*surfnor=0,*uvco=0, strandlen=0.0f, curlen=0.0f;
|
||||
float hasize, pa_size, pa_time, r_tilt, cfra=bsystem_time(ob,(float)CFRA,0.0);
|
||||
float adapt_angle=0.0, adapt_pix=0.0, random, simplify[2];
|
||||
int i, a, k, max_k=0, totpart, totuv=0, override_uv=-1, dosimplify = 0;
|
||||
int i, a, k, max_k=0, totpart, totuv=0, override_uv=-1, dosimplify = 0, doapproxao = 0;
|
||||
int path_possible=0, keys_possible=0, baked_keys=0, totchild=psys->totchild;
|
||||
int seed, path_nbr=0, path=0, orco1=0, adapt=0, uv[3]={0,0,0}, num;
|
||||
char **uv_name=0;
|
||||
@ -1656,6 +1657,10 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem
|
||||
strandbuf->flag |= R_STRAND_B_UNITS;
|
||||
|
||||
svert= strandbuf->vert;
|
||||
|
||||
if((re->wrld.mode & WO_AMB_OCC) && (re->wrld.ao_gather_method == WO_AOGATHER_APPROX))
|
||||
if(ma->amb != 0.0f)
|
||||
doapproxao= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1704,15 +1709,15 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem
|
||||
else
|
||||
psys_particle_on_emitter(ob, psmd,part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,co,nor,0,0,orco,0);
|
||||
|
||||
if(uvco && ELEM(part->from,PART_FROM_FACE,PART_FROM_VOLUME)){
|
||||
layer=psmd->dm->faceData.layers + CustomData_get_layer_index(&psmd->dm->faceData,CD_MFACE);
|
||||
|
||||
num= pa->num_dmcache;
|
||||
|
||||
if(num == DMCACHE_NOTFOUND)
|
||||
if(pa->num < psmd->dm->getNumFaces(psmd->dm))
|
||||
num= pa->num;
|
||||
|
||||
if(uvco && ELEM(part->from,PART_FROM_FACE,PART_FROM_VOLUME)){
|
||||
layer=psmd->dm->faceData.layers + CustomData_get_layer_index(&psmd->dm->faceData,CD_MFACE);
|
||||
|
||||
for(i=0; i<totuv; i++){
|
||||
if(num != DMCACHE_NOTFOUND) {
|
||||
MFace *mface=psmd->dm->getFaceData(psmd->dm,num,CD_MFACE);
|
||||
@ -1761,6 +1766,8 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem
|
||||
|
||||
r_tilt=2.0f*cpa->rand[2];
|
||||
|
||||
num= cpa->num;
|
||||
|
||||
/* get orco */
|
||||
psys_particle_on_emitter(ob, psmd,
|
||||
(part->childtype == PART_CHILD_FACES)? PART_FROM_FACE: PART_FROM_PARTICLE,
|
||||
@ -1831,6 +1838,11 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem
|
||||
VECCOPY(snor, surfnor);
|
||||
}
|
||||
|
||||
if(doapproxao && num >= 0) {
|
||||
int *facenum= RE_strandren_get_face(obr, strand, 1);
|
||||
*facenum= num;
|
||||
}
|
||||
|
||||
if(uvco){
|
||||
for(i=0; i<totuv; i++){
|
||||
if(i != override_uv) {
|
||||
@ -1930,6 +1942,9 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem
|
||||
break;
|
||||
}
|
||||
|
||||
if(doapproxao)
|
||||
strandbuf->occlusionmesh= cache_occ_mesh(re, obr, psmd->dm, mat);
|
||||
|
||||
/* 4. clean up */
|
||||
if(ma) do_mat_ipo(ma);
|
||||
|
||||
@ -3636,7 +3651,7 @@ void init_render_world(Render *re)
|
||||
if(re->osa)
|
||||
while(re->wrld.aosamp*re->wrld.aosamp < re->osa)
|
||||
re->wrld.aosamp++;
|
||||
if(!(re->r.mode & R_RAYTRACE))
|
||||
if(!(re->r.mode & R_RAYTRACE) && (re->wrld.ao_gather_method == WO_AOGATHER_RAYTRACE))
|
||||
re->wrld.mode &= ~WO_AMB_OCC;
|
||||
}
|
||||
else {
|
||||
@ -4069,6 +4084,7 @@ void RE_Database_Free(Render *re)
|
||||
if(re->r.mode & R_RAYTRACE) freeraytree(re);
|
||||
|
||||
free_sss(re);
|
||||
free_occ(re);
|
||||
|
||||
re->totvlak=re->totvert=re->totstrand=re->totlamp=re->tothalo= 0;
|
||||
re->i.convertdone= 0;
|
||||
@ -4289,7 +4305,7 @@ void RE_Database_FromScene(Render *re, Scene *scene, int use_camera_view)
|
||||
}
|
||||
|
||||
init_render_world(re); /* do first, because of ambient. also requires re->osa set correct */
|
||||
if(re->wrld.mode & WO_AMB_OCC) {
|
||||
if((re->r.mode & R_RAYTRACE) && (re->wrld.mode & WO_AMB_OCC)) {
|
||||
if (re->wrld.ao_samp_method == WO_AOSAMP_HAMMERSLEY)
|
||||
init_render_hammersley(re);
|
||||
else if (re->wrld.ao_samp_method == WO_AOSAMP_CONSTANT)
|
||||
@ -4355,6 +4371,12 @@ void RE_Database_FromScene(Render *re, Scene *scene, int use_camera_view)
|
||||
if(!re->test_break())
|
||||
project_renderdata(re, projectverto, re->r.mode & R_PANORAMA, 0, 1);
|
||||
|
||||
/* Occlusion */
|
||||
if((re->wrld.mode & WO_AMB_OCC) && !re->test_break())
|
||||
if(re->wrld.ao_gather_method == WO_AOGATHER_APPROX)
|
||||
if(re->r.renderer==R_INTERN)
|
||||
make_occ_tree(re);
|
||||
|
||||
/* SSS */
|
||||
if((re->r.mode & R_SSS) && !re->test_break())
|
||||
if(re->r.renderer==R_INTERN)
|
||||
@ -4837,7 +4859,7 @@ void RE_Database_Baking(Render *re, Scene *scene, int type, Object *actob)
|
||||
}
|
||||
|
||||
init_render_world(re); /* do first, because of ambient. also requires re->osa set correct */
|
||||
if(re->wrld.mode & WO_AMB_OCC) {
|
||||
if((re->r.mode & R_RAYTRACE) && (re->wrld.mode & WO_AMB_OCC)) {
|
||||
if (re->wrld.ao_samp_method == WO_AOSAMP_HAMMERSLEY)
|
||||
init_render_hammersley(re);
|
||||
else if (re->wrld.ao_samp_method == WO_AOSAMP_CONSTANT)
|
||||
|
1694
source/blender/render/intern/source/occlusion.c
Normal file
1694
source/blender/render/intern/source/occlusion.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -538,6 +538,9 @@ static RenderResult *new_render_result(Render *re, rcti *partrct, int crop, int
|
||||
if(srl->passflag & SCE_PASS_REFRACT)
|
||||
render_layer_add_pass(rr, rl, 3, SCE_PASS_REFRACT);
|
||||
}
|
||||
else if(re->wrld.mode & WO_AMB_OCC)
|
||||
if(re->wrld.ao_gather_method == WO_AOGATHER_APPROX)
|
||||
render_layer_add_pass(rr, rl, 3, SCE_PASS_AO);
|
||||
if(re->r.mode & R_RADIO)
|
||||
if(srl->passflag & SCE_PASS_RADIO)
|
||||
render_layer_add_pass(rr, rl, 3, SCE_PASS_RADIO);
|
||||
|
@ -60,6 +60,7 @@
|
||||
#include "renderpipeline.h"
|
||||
#include "render_types.h"
|
||||
#include "renderdatabase.h"
|
||||
#include "occlusion.h"
|
||||
#include "pixelblending.h"
|
||||
#include "pixelshading.h"
|
||||
#include "shadbuf.h"
|
||||
@ -535,6 +536,10 @@ static void shadeDA_tile(RenderPart *pa, RenderLayer *rl)
|
||||
shade_sample_initialize(&ssamp, pa, rl);
|
||||
addpassflag= rl->passflag & ~(SCE_PASS_Z|SCE_PASS_COMBINED);
|
||||
|
||||
/* occlusion caching */
|
||||
if(R.occlusiontree)
|
||||
cache_occ_samples(&R, pa, &ssamp);
|
||||
|
||||
/* filtered render, for now we assume only 1 filter size */
|
||||
if(pa->crop) {
|
||||
crop= 1;
|
||||
@ -582,6 +587,9 @@ static void shadeDA_tile(RenderPart *pa, RenderLayer *rl)
|
||||
|
||||
if(R.r.mode & R_SHADOW)
|
||||
ISB_free(pa);
|
||||
|
||||
if(R.occlusiontree)
|
||||
free_occ_samples(&R, pa);
|
||||
}
|
||||
|
||||
/* ************* pixel struct ******** */
|
||||
@ -1073,6 +1081,9 @@ void zbufshade_tile(RenderPart *pa)
|
||||
if(R.r.mode & R_SHADOW)
|
||||
ISB_create(pa, NULL);
|
||||
|
||||
if(R.occlusiontree)
|
||||
cache_occ_samples(&R, pa, &ssamp);
|
||||
|
||||
for(y=pa->disprect.ymin; y<pa->disprect.ymax; y++, rr->renrect.ymax++) {
|
||||
for(x=pa->disprect.xmin; x<pa->disprect.xmax; x++, ro++, rz++, rp++, fcol+=4, offs++) {
|
||||
/* per pixel fixed seed */
|
||||
@ -1085,9 +1096,6 @@ void zbufshade_tile(RenderPart *pa)
|
||||
if(shade_samples(&ssamp, &ps, x, y)) {
|
||||
QUATCOPY(fcol, ssamp.shr[0].combined);
|
||||
|
||||
if(!(fcol[0] == fcol[0]))
|
||||
printvecf("fudgecol", fcol);
|
||||
|
||||
/* passes */
|
||||
if(addpassflag)
|
||||
add_passes(rl, offs, ssamp.shi, ssamp.shr);
|
||||
@ -1098,6 +1106,9 @@ void zbufshade_tile(RenderPart *pa)
|
||||
if(R.test_break()) break;
|
||||
}
|
||||
|
||||
if(R.occlusiontree)
|
||||
free_occ_samples(&R, pa);
|
||||
|
||||
if(R.r.mode & R_SHADOW)
|
||||
ISB_free(pa);
|
||||
}
|
||||
|
@ -105,6 +105,7 @@
|
||||
#define RE_UV_ELEMS 2
|
||||
#define RE_SURFNOR_ELEMS 3
|
||||
#define RE_SIMPLIFY_ELEMS 2
|
||||
#define RE_FACE_ELEMS 1
|
||||
|
||||
float *RE_vertren_get_sticky(ObjectRen *obr, VertRen *ver, int verify)
|
||||
{
|
||||
@ -607,6 +608,21 @@ float *RE_strandren_get_simplify(struct ObjectRen *obr, struct StrandRen *strand
|
||||
return simplify + (strand->index & 255)*RE_SIMPLIFY_ELEMS;
|
||||
}
|
||||
|
||||
int *RE_strandren_get_face(ObjectRen *obr, StrandRen *strand, int verify)
|
||||
{
|
||||
int *face;
|
||||
int nr= strand->index>>8;
|
||||
|
||||
face= obr->strandnodes[nr].face;
|
||||
if(face==NULL) {
|
||||
if(verify)
|
||||
face= obr->strandnodes[nr].face= MEM_callocN(256*RE_FACE_ELEMS*sizeof(int), "face table");
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
return face + (strand->index & 255)*RE_FACE_ELEMS;
|
||||
}
|
||||
|
||||
/* winspeed is exception, it is stored per instance */
|
||||
float *RE_strandren_get_winspeed(ObjectInstanceRen *obi, StrandRen *strand, int verify)
|
||||
{
|
||||
@ -757,6 +773,8 @@ void free_renderdata_strandnodes(StrandTableNode *strandnodes)
|
||||
MEM_freeN(strandnodes[a].surfnor);
|
||||
if(strandnodes[a].simplify)
|
||||
MEM_freeN(strandnodes[a].simplify);
|
||||
if(strandnodes[a].face)
|
||||
MEM_freeN(strandnodes[a].face);
|
||||
}
|
||||
|
||||
MEM_freeN(strandnodes);
|
||||
|
@ -422,7 +422,7 @@ void shade_input_set_strand_texco(ShadeInput *shi, StrandRen *strand, StrandVert
|
||||
}
|
||||
|
||||
if(texco & TEXCO_STRAND) {
|
||||
shi->strand= spoint->strandco;
|
||||
shi->strandco= spoint->strandco;
|
||||
|
||||
if(shi->osatex) {
|
||||
shi->dxstrand= spoint->dtstrandco;
|
||||
@ -935,7 +935,7 @@ void shade_input_set_shade_texco(ShadeInput *shi)
|
||||
}
|
||||
|
||||
if(texco & TEXCO_STRAND) {
|
||||
shi->strand= (l*v3->accum - u*v1->accum - v*v2->accum);
|
||||
shi->strandco= (l*v3->accum - u*v1->accum - v*v2->accum);
|
||||
if(shi->osatex) {
|
||||
dl= shi->dx_u+shi->dx_v;
|
||||
shi->dxstrand= dl*v3->accum-shi->dx_u*v1->accum-shi->dx_v*v2->accum;
|
||||
@ -1236,7 +1236,7 @@ void shade_samples_do_AO(ShadeSample *ssamp)
|
||||
|
||||
if(!(R.r.mode & R_SHADOW))
|
||||
return;
|
||||
if(!(R.r.mode & R_RAYTRACE))
|
||||
if(!(R.r.mode & R_RAYTRACE) && !(R.wrld.ao_gather_method == WO_AOGATHER_APPROX))
|
||||
return;
|
||||
|
||||
if(R.wrld.mode & WO_AMB_OCC)
|
||||
@ -1248,7 +1248,7 @@ void shade_samples_do_AO(ShadeSample *ssamp)
|
||||
}
|
||||
|
||||
|
||||
static void shade_samples_fill_with_ps(ShadeSample *ssamp, PixStr *ps, int x, int y)
|
||||
void shade_samples_fill_with_ps(ShadeSample *ssamp, PixStr *ps, int x, int y)
|
||||
{
|
||||
ShadeInput *shi;
|
||||
float xs, ys;
|
||||
|
@ -43,6 +43,7 @@
|
||||
#include "DNA_material_types.h"
|
||||
|
||||
/* local include */
|
||||
#include "occlusion.h"
|
||||
#include "renderpipeline.h"
|
||||
#include "render_types.h"
|
||||
#include "pixelblending.h"
|
||||
@ -1006,8 +1007,9 @@ static void do_specular_ramp(ShadeInput *shi, float is, float t, float *spec)
|
||||
/* pure AO, check for raytrace and world should have been done */
|
||||
void ambient_occlusion(ShadeInput *shi)
|
||||
{
|
||||
|
||||
if((R.r.mode & R_RAYTRACE) && shi->mat->amb!=0.0f)
|
||||
if((R.wrld.ao_gather_method == WO_AOGATHER_APPROX) && shi->mat->amb!=0.0f)
|
||||
sample_occ(&R, shi);
|
||||
else if((R.r.mode & R_RAYTRACE) && shi->mat->amb!=0.0f)
|
||||
ray_ao(shi, shi->ao);
|
||||
else
|
||||
shi->ao[0]= shi->ao[1]= shi->ao[2]= 1.0f;
|
||||
@ -1017,8 +1019,8 @@ void ambient_occlusion(ShadeInput *shi)
|
||||
/* wrld mode was checked for */
|
||||
void ambient_occlusion_to_diffuse(ShadeInput *shi, float *diff)
|
||||
{
|
||||
|
||||
if((R.r.mode & R_RAYTRACE) && shi->mat->amb!=0.0f) {
|
||||
if((R.r.mode & R_RAYTRACE) || R.wrld.ao_gather_method == WO_AOGATHER_APPROX) {
|
||||
if(shi->mat->amb!=0.0f) {
|
||||
float f= R.wrld.aoenergy*shi->mat->amb;
|
||||
|
||||
if (R.wrld.aomix==WO_AOADDSUB) {
|
||||
@ -1040,6 +1042,9 @@ void ambient_occlusion_to_diffuse(ShadeInput *shi, float *diff)
|
||||
else
|
||||
diff[0]= diff[1]= diff[2]= 0.0f;
|
||||
}
|
||||
else
|
||||
diff[0]= diff[1]= diff[2]= 0.0f;
|
||||
}
|
||||
|
||||
/* result written in shadfac */
|
||||
void lamp_get_shadow(LampRen *lar, ShadeInput *shi, float inp, float *shadfac, int do_real)
|
||||
|
@ -685,6 +685,7 @@ static void strand_shade_point(Render *re, ShadeSample *ssamp, StrandSegment *ss
|
||||
vlr.flag |= R_TANGENT;
|
||||
|
||||
shi->vlr= &vlr;
|
||||
shi->strand= sseg->strand;
|
||||
shi->obi= sseg->obi;
|
||||
shi->obr= sseg->obi->obr;
|
||||
|
||||
|
@ -1521,7 +1521,7 @@ void do_material_tex(ShadeInput *shi)
|
||||
}
|
||||
else if(mtex->texco==TEXCO_STRAND) {
|
||||
co= tempvec; dx= dxt; dy= dyt;
|
||||
co[0]= shi->strand;
|
||||
co[0]= shi->strandco;
|
||||
co[1]= co[2]= 0.0f;
|
||||
dx[0]= shi->dxstrand;
|
||||
dx[1]= dx[2]= 0.0f;
|
||||
|
@ -2155,6 +2155,7 @@ static void world_panel_amb_occ(World *wrld)
|
||||
|
||||
yco -= YSPACE;
|
||||
|
||||
if(wrld->ao_gather_method == WO_AOGATHER_RAYTRACE) {
|
||||
uiDefButS(block, NUM, B_REDR, "Samples:",
|
||||
X2CLM1, yco-=BUTH, BUTW2, BUTH, &wrld->aosamp, 1.0, 32.0, 100, 0, "Sets the number of samples used for AO (actual number: squared)");
|
||||
|
||||
@ -2162,9 +2163,17 @@ static void world_panel_amb_occ(World *wrld)
|
||||
|
||||
uiDefButF(block, NUM, B_REDR, "Max Dist:",
|
||||
X2CLM1, yco-=BUTH, BUTW2, BUTH, &wrld->aodist, 0.001, 5000.0, 100, 0, "Sets length of AO rays, defines how far away other faces give occlusion effect");
|
||||
}
|
||||
else {
|
||||
uiDefButS(block, NUM, B_REDR, "Passes:",
|
||||
X2CLM1, yco-=BUTH, BUTW2, BUTH, &wrld->ao_approx_passes, 0.0, 10.0, 0, 0, "Sets the number of preprocessing passes to reduce overocclusion");
|
||||
|
||||
yco -= YSPACE;
|
||||
|
||||
uiDefButF(block, NUM, B_REDR, "Correction:",
|
||||
X2CLM1, yco-=BUTH, BUTW2, BUTH, &wrld->ao_approx_correction, 0.0, 1.0, 0, 0, "Ad-hoc correction for over-occlusion due to the approximation.");
|
||||
}
|
||||
|
||||
uiBlockBeginAlign(block);
|
||||
uiDefButBitS(block, TOG, WO_AODIST, B_AO_FALLOFF, "Use Falloff",
|
||||
X2CLM1, yco-=BUTH, BUTW2, BUTH, &wrld->aomode, 0, 0, 0, 0, "When enabled, distances to objects will be used to attenuate shadows. Only for Plain AO.");
|
||||
@ -2176,6 +2185,12 @@ static void world_panel_amb_occ(World *wrld)
|
||||
/* column 2 */
|
||||
yco = PANEL_YMAX - BUTH - YSPACE;
|
||||
|
||||
uiDefButS(block, MENU, B_REDR, "Gather Method%t|Raytrace %x0|Approximate %x1",
|
||||
X2CLM2, yco-=BUTH, BUTW2, BUTH, &wrld->ao_gather_method, 0, 0, 0, 0, "Method for occlusion gathering: Raytrace: slow when noise free results are required, but accurate, Approximate: faster and without noise, but inaccurate");
|
||||
|
||||
yco -= YSPACE;
|
||||
|
||||
if(wrld->ao_gather_method == WO_AOGATHER_RAYTRACE) {
|
||||
uiDefButS(block, MENU, B_REDR, "Constant QMC %x2|Adaptive QMC %x1|Constant Jittered %x0",
|
||||
X2CLM2, yco-=BUTH, BUTW2, BUTH, &wrld->ao_samp_method, 0, 0, 0, 0, "Method for generating shadow samples: Constant QMC: best quality, Adaptive QMC: fast in high contrast areas");
|
||||
|
||||
@ -2192,7 +2207,16 @@ static void world_panel_amb_occ(World *wrld)
|
||||
uiDefButF(block, NUMSLI, B_REDR, "Bias:",
|
||||
X2CLM2, yco-=BUTH, BUTW2, BUTH, &wrld->aobias, 0.0, 0.5, 10, 0, "Sets bias to prevent smoothed faces to show banding (in radians)");
|
||||
}
|
||||
}
|
||||
else {
|
||||
uiBlockBeginAlign(block);
|
||||
uiDefButF(block, NUM, B_REDR, "Error:",
|
||||
X2CLM2, yco-=BUTH, BUTW2, BUTH, &wrld->ao_approx_error, 0.0001, 10.0, 0, 0, "Error tolerance (low values are slower and higher quality)");
|
||||
|
||||
uiDefButBitS(block, TOG, WO_AOCACHE, B_REDR, "Pixel Cache",
|
||||
X2CLM2, yco-=BUTH, BUTW2, BUTH, &wrld->aomode, 0, 0, 0, 0, "Cache AO results in pixels and interpolate over neighbouring pixels for speedup.");
|
||||
uiBlockEndAlign(block);
|
||||
}
|
||||
|
||||
yco = PANEL_YMAX - (5*BUTH+4*YSPACE);
|
||||
|
||||
@ -2204,6 +2228,7 @@ static void world_panel_amb_occ(World *wrld)
|
||||
X3CLM2, yco, BUTW3, BUTH, &wrld->aomix, 1.0, (float)WO_AOSUB, 0, 0, "subtracts light/shadows (needs at least one normal light to make anything visible)");
|
||||
uiDefButS(block, ROW, B_REDR, "Both",
|
||||
X3CLM3, yco, BUTW3, BUTH, &wrld->aomix, 1.0, (float)WO_AOADDSUB, 0, 0, "both lightens & darkens");
|
||||
uiBlockEndAlign(block);
|
||||
|
||||
yco -= YSPACE;
|
||||
|
||||
@ -2221,7 +2246,6 @@ static void world_panel_amb_occ(World *wrld)
|
||||
|
||||
uiDefButF(block, NUMSLI, B_REDR, "Energy:",
|
||||
X2CLM1, yco-=BUTH, BUTW2, BUTH, &wrld->aoenergy, 0.01, 3.0, 100, 0, "Sets global energy scale for AO");
|
||||
|
||||
}
|
||||
|
||||
static void world_panel_world(World *wrld)
|
||||
|
Loading…
Reference in New Issue
Block a user