bool CUIMpTradeWnd::OnKeyboard(int dik, EUIMessages keyboard_action) { #ifdef DEBUG //for debug only if(keyboard_action==WINDOW_KEY_PRESSED && dik==DIK_NUMPAD7) { if(GetRank()>0) SetRank( clampr(u32(GetRank()-1),u32(0),u32(4) ) ); } if(keyboard_action==WINDOW_KEY_PRESSED && dik==DIK_NUMPAD8) { SetRank( clampr(u32(GetRank()+1),u32(0),u32(4) ) ); } #endif if(!m_store_hierarchy->CurrentIsRoot()) { if (m_shop_wnd->OnKeyboard(dik, keyboard_action) ) return true; m_root_tab_control->SetAcceleratorsMode (false); } bool res = inherited::OnKeyboard(dik, keyboard_action); m_root_tab_control->SetAcceleratorsMode (true); return res; }
IC int PLC_calc (Fvector& P, Fvector& N, light* L, float energy, Fvector& O) { float E = PLC_energy(P,N,L,energy); float C1 = clampr(Device.vCameraPosition.distance_to_sqr(P)/S_distance2, 0.f,1.f); float C2 = clampr(O.distance_to_sqr(P)/S_fade2, 0.f,1.f); float A = 1.f-1.5f*E*(1.f-C1)*(1.f-C2); return iCeil(255.f*A); }
void CRenderTarget::phase_pp () { // combination/postprocess u_setrt ( Device.dwWidth,Device.dwHeight,HW.pBaseRT,NULL,NULL,HW.pBaseZB); // Element 0 for for normal post-process // Element 4 for color map post-process bool bCMap = u_need_CM(); //RCache.set_Element (s_postprocess->E[bCMap ? 4 : 0]); if( !RImplementation.o.dx10_msaa ) { // RCache.set_Shader (s_postprocess ); RCache.set_Element (s_postprocess->E[bCMap ? 4 : 0]); } else { // RCache.set_Shader( s_postprocess_msaa ); RCache.set_Element (s_postprocess_msaa->E[bCMap ? 4 : 0]); } int gblend = clampr (iFloor((1-param_gray)*255.f),0,255); int nblend = clampr (iFloor((1-param_noise)*255.f),0,255); u32 p_color = subst_alpha (param_color_base,nblend); u32 p_gray = subst_alpha (param_color_gray,gblend); Fvector p_brightness = param_color_add ; // Msg ("param_gray:%f(%d),param_noise:%f(%d)",param_gray,gblend,param_noise,nblend); // Msg ("base: %d,%d,%d", color_get_R(p_color), color_get_G(p_color), color_get_B(p_color)); // Msg ("gray: %d,%d,%d", color_get_R(p_gray), color_get_G(p_gray), color_get_B(p_gray)); // Msg ("add: %d,%d,%d", color_get_R(p_brightness), color_get_G(p_brightness), color_get_B(p_brightness)); // Draw full-screen quad textured with our scene image u32 Offset; float _w = float(Device.dwWidth); float _h = float(Device.dwHeight); Fvector2 n0,n1,r0,r1,l0,l1; u_calc_tc_duality_ss (r0,r1,l0,l1); u_calc_tc_noise (n0,n1); // Fill vertex buffer float du = ps_r1_pps_u, dv = ps_r1_pps_v; TL_2c3uv* pv = (TL_2c3uv*) RCache.Vertex.Lock (4,g_postprocess.stride(),Offset); pv->set(du+0, dv+float(_h), p_color, p_gray, r0.x, r1.y, l0.x, l1.y, n0.x, n1.y); pv++; pv->set(du+0, dv+0, p_color, p_gray, r0.x, r0.y, l0.x, l0.y, n0.x, n0.y); pv++; pv->set(du+float(_w), dv+float(_h), p_color, p_gray, r1.x, r1.y, l1.x, l1.y, n1.x, n1.y); pv++; pv->set(du+float(_w), dv+0, p_color, p_gray, r1.x, r0.y, l1.x, l0.y, n1.x, n0.y); pv++; RCache.Vertex.Unlock (4,g_postprocess.stride()); // Actual rendering static shared_str s_brightness = "c_brightness"; static shared_str s_colormap = "c_colormap"; RCache.set_c ( s_brightness, p_brightness.x, p_brightness.y, p_brightness.z, 0 ); RCache.set_c (s_colormap, param_color_map_influence,param_color_map_interpolate,0,0); RCache.set_Geometry (g_postprocess); RCache.Render (D3DPT_TRIANGLELIST,Offset,0,4,0,2); }
void CEffect_Thunderbolt::OnFrame(shared_str id, float period, float duration) { BOOL enabled = !!(id.size()); if (bEnabled!=enabled){ bEnabled = enabled; next_lightning_time = Device.fTimeGlobal+period+Random.randF(-period*0.5f,period*0.5f); }else if (bEnabled&&(Device.fTimeGlobal>next_lightning_time)){ if (state==stIdle && !!(id.size())) Bolt(id,period,duration); } if (state==stWorking){ if (current_time>life_time) state = stIdle; current_time += Device.fTimeDelta; Fvector fClr; int frame; u32 uClr = current->color_anim->CalculateRGB(current_time/life_time,frame); fClr.set ( clampr(float(color_get_R(uClr)/255.f), 0.f, 1.f), clampr(float(color_get_G(uClr)/255.f), 0.f, 1.f), clampr(float(color_get_B(uClr)/255.f), 0.f, 1.f) ); lightning_phase = 1.5f*(current_time/life_time); clamp (lightning_phase,0.f,1.f); CEnvironment& environment = g_pGamePersistent->Environment(); Fvector& sky_color = environment.CurrentEnv->sky_color; sky_color.mad ( fClr, environment.p_sky_color ); clamp ( sky_color.x, 0.f, 1.f ); clamp ( sky_color.y, 0.f, 1.f ); clamp ( sky_color.z, 0.f, 1.f ); environment.CurrentEnv->sun_color.mad(fClr,environment.p_sun_color); environment.CurrentEnv->fog_color.mad(fClr,environment.p_fog_color); if (::Render->get_generation()==IRender_interface::GENERATION_R2) { R_ASSERT ( _valid(current_direction) ); g_pGamePersistent->Environment().CurrentEnv->sun_dir = current_direction; VERIFY2(g_pGamePersistent->Environment().CurrentEnv->sun_dir.y<0,"Invalid sun direction settings while CEffect_Thunderbolt"); } } }
void CEnvironment::OnFrame() { #ifdef _EDITOR SetGameTime (fGameTime+Device.fTimeDelta*fTimeFactor,fTimeFactor); if (fsimilar(ed_to_time,DAY_LENGTH)&&fsimilar(ed_from_time,0.f)){ if (fGameTime>DAY_LENGTH) fGameTime-=DAY_LENGTH; }else{ if (fGameTime>ed_to_time){ fGameTime=fGameTime-ed_to_time+ed_from_time; Current[0]=Current[1]=0; } if (fGameTime<ed_from_time){ fGameTime=ed_from_time; Current[0]=Current[1]=0; } } if (!psDeviceFlags.is(rsEnvironment)) return; #else if (!g_pGameLevel) return; #endif // if (pInput->iGetAsyncKeyState(DIK_O)) SetWeatherFX("surge_day"); float current_weight; lerp (current_weight); // Igor. Dynamic sun position. if ( !::Render->is_sun_static()) calculate_dynamic_sun_dir(); #ifndef MASTER_GOLD if(CurrentEnv->sun_dir.y>0) { Log("CurrentEnv->sun_dir", CurrentEnv->sun_dir); // Log("current_weight", current_weight); // Log("mpower", mpower); Log("Current[0]->sun_dir", Current[0]->sun_dir); Log("Current[1]->sun_dir", Current[1]->sun_dir); } VERIFY2 (CurrentEnv->sun_dir.y<0,"Invalid sun direction settings in lerp"); #endif // #ifndef MASTER_GOLD PerlinNoise1D->SetFrequency (wind_gust_factor*MAX_NOISE_FREQ); wind_strength_factor = clampr(PerlinNoise1D->GetContinious(Device.fTimeGlobal)+0.5f,0.f,1.f); shared_str l_id = (current_weight<0.5f)?Current[0]->lens_flare_id:Current[1]->lens_flare_id; eff_LensFlare->OnFrame (l_id); shared_str t_id = (current_weight<0.5f)?Current[0]->tb_id:Current[1]->tb_id; eff_Thunderbolt->OnFrame (t_id,CurrentEnv->bolt_period,CurrentEnv->bolt_duration); eff_Rain->OnFrame (); // ******************** Environment params (setting) m_pRender->OnFrame(*this); }
r_aabb_ssa r_pixel_calculator::calculate (dxRender_Visual* V) { r_aabb_ssa result = {0}; float area = float(_sqr(rt_dimensions)); // u32 id [6] ; for (u32 face=0; face<6; face++) { // setup matrices Fmatrix mProject,mView ; Fvector vFrom ; Fbox aabb ; // camera - left-to-right mView.build_camera_dir (vFrom.invert(cmDir[face]).mul(100.f), cmDir[face], cmNorm[face]) ; aabb.xform (V->vis.box,mView); D3DXMatrixOrthoOffCenterLH ( (D3DXMATRIX*)&mProject, aabb.min.x, aabb.max.x, aabb.min.y, aabb.max.y, aabb.min.z, aabb.max.z ); RCache.set_xform_world (Fidentity); RCache.set_xform_view (mView); RCache.set_xform_project (mProject); // render-0 Device.Clear (); // clear-ZB RCache.set_Shader (V->shader); V->Render (1.f); // render-1 RImplementation.HWOCC.occq_begin (id[face]); V->Render (1.f); RImplementation.HWOCC.occq_end (id[face]); } // for (u32 it=0; it<6; it++) { float pixels = (float)RImplementation.HWOCC.occq_get (id[it]); float coeff = clampr(pixels/area,float(0),float(1)); Msg ("[%d]ssa_c: %1.3f,%f/%f",it,coeff,pixels,area); result.ssa [it]= (u8)clampr(iFloor(coeff*255.f+0.5f),int(0),int(255)); } return result ; }
void random_dir(Fvector& tgt_dir, const Fvector& src_dir, float dispersion) { float sigma = dispersion/3.f; float alpha = clampr (_nrand(sigma),-dispersion,dispersion); float theta = Random.randF (0,PI); float r = tan (alpha); Fvector U,V,T; Fvector::generate_orthonormal_basis (src_dir,U,V); U.mul (r*_sin(theta)); V.mul (r*_cos(theta)); T.add (U,V); tgt_dir.add (src_dir,T).normalize(); }
void FProgressive::Render (float LOD) { #if RENDER==R_R2 if (m_fast && RImplementation.phase==CRender::PHASE_SMAP) { int lod_id = iFloor((1.f-clampr(LOD,0.f,1.f))*float(xSWI->count-1)+0.5f); VERIFY (lod_id>=0 && lod_id<int(xSWI->count)); FSlideWindow& SW = xSWI->sw[lod_id]; RCache.set_Geometry (m_fast->rm_geom); RCache.Render (D3DPT_TRIANGLELIST,m_fast->vBase,0,SW.num_verts,m_fast->iBase+SW.offset,SW.num_tris); RCache.stat.r.s_static.add (SW.num_verts); } else { int lod_id = last_lod; if (LOD>=0.f){ clamp (LOD,0.f,1.f); lod_id = iFloor((1.f-LOD)*float(nSWI.count-1)+0.5f); last_lod = lod_id; } VERIFY (lod_id>=0 && lod_id<int(nSWI.count)); FSlideWindow& SW = nSWI.sw[lod_id]; RCache.set_Geometry (rm_geom); RCache.Render (D3DPT_TRIANGLELIST,vBase,0,SW.num_verts,iBase+SW.offset,SW.num_tris); RCache.stat.r.s_static.add (SW.num_verts); } #else int lod_id = last_lod; if (LOD>=0.f){ clamp (LOD,0.f,1.f); lod_id = iFloor((1.f-LOD)*float(nSWI.count-1)+0.5f); last_lod = lod_id; } VERIFY (lod_id>=0 && lod_id<int(nSWI.count)); FSlideWindow& SW = nSWI.sw[lod_id]; RCache.set_Geometry (rm_geom); RCache.Render (D3DPT_TRIANGLELIST,vBase,0,SW.num_verts,iBase+SW.offset,SW.num_tris); RCache.stat.r.s_static.add (SW.num_verts); #endif }
CRenderTarget::CRenderTarget () { param_blur = 0.f; param_gray = 0.f; param_noise = 0.f; param_duality_h = 0.f; param_duality_v = 0.f; param_noise_fps = 25.f; param_noise_scale = 1.f; im_noise_time = 1/100; im_noise_shift_w = 0; im_noise_shift_h = 0; param_color_base = color_rgba(127,127,127, 0); param_color_gray = color_rgba(85,85,85, 0); param_color_add = color_rgba(0,0,0, 0); dwAccumulatorClearMark = 0; Device.Resources->Evict (); // Blenders b_occq = xr_new<CBlender_light_occq> (); b_accum_mask = xr_new<CBlender_accum_direct_mask> (); b_accum_direct = xr_new<CBlender_accum_direct> (); b_accum_point = xr_new<CBlender_accum_point> (); b_accum_spot = xr_new<CBlender_accum_spot> (); b_accum_reflected = xr_new<CBlender_accum_reflected> (); b_bloom = xr_new<CBlender_bloom_build> (); b_luminance = xr_new<CBlender_luminance> (); b_combine = xr_new<CBlender_combine> (); // NORMAL { u32 w=Device.dwWidth, h=Device.dwHeight; rt_Position.create (r2_RT_P, w,h,D3DFMT_A16B16G16R16F); rt_Normal.create (r2_RT_N, w,h,D3DFMT_A16B16G16R16F); // select albedo & accum if (RImplementation.o.mrtmixdepth) { // NV50 rt_Color.create (r2_RT_albedo, w,h,D3DFMT_A8R8G8B8 ); rt_Accumulator.create (r2_RT_accum, w,h,D3DFMT_A16B16G16R16F); } else { // can't - mix-depth if (RImplementation.o.fp16_blend) { // NV40 rt_Color.create (r2_RT_albedo, w,h,D3DFMT_A16B16G16R16F); // expand to full rt_Accumulator.create (r2_RT_accum, w,h,D3DFMT_A16B16G16R16F); } else { // R4xx, no-fp-blend,-> albedo_wo VERIFY (RImplementation.o.albedo_wo); rt_Color.create (r2_RT_albedo, w,h,D3DFMT_A8R8G8B8 ); // normal rt_Accumulator.create (r2_RT_accum, w,h,D3DFMT_A16B16G16R16F); rt_Accumulator_temp.create (r2_RT_accum_temp, w,h,D3DFMT_A16B16G16R16F); } } // generic(LDR) RTs rt_Generic_0.create (r2_RT_generic0,w,h,D3DFMT_A8R8G8B8 ); rt_Generic_1.create (r2_RT_generic1,w,h,D3DFMT_A8R8G8B8 ); } // OCCLUSION s_occq.create (b_occq, "r2\\occq"); // DIRECT (spot) D3DFORMAT depth_format = (D3DFORMAT)RImplementation.o.HW_smap_FORMAT; if (RImplementation.o.HW_smap) { D3DFORMAT nullrt = D3DFMT_R5G6B5; if (RImplementation.o.nullrt) nullrt = (D3DFORMAT)MAKEFOURCC('N','U','L','L'); u32 size =RImplementation.o.smapsize ; rt_smap_depth.create (r2_RT_smap_depth, size,size,depth_format ); rt_smap_surf.create (r2_RT_smap_surf, size,size,nullrt ); rt_smap_ZB = NULL; s_accum_mask.create (b_accum_mask, "r2\\accum_mask"); s_accum_direct.create (b_accum_direct, "r2\\accum_direct"); } else { u32 size =RImplementation.o.smapsize ; rt_smap_surf.create (r2_RT_smap_surf, size,size,D3DFMT_R32F); rt_smap_depth = NULL; R_CHK (HW.pDevice->CreateDepthStencilSurface (size,size,D3DFMT_D24X8,D3DMULTISAMPLE_NONE,0,TRUE,&rt_smap_ZB,NULL)); s_accum_mask.create (b_accum_mask, "r2\\accum_mask"); s_accum_direct.create (b_accum_direct, "r2\\accum_direct"); } // POINT { s_accum_point.create (b_accum_point, "r2\\accum_point_s"); accum_point_geom_create (); g_accum_point.create (D3DFVF_XYZ, g_accum_point_vb, g_accum_point_ib); accum_omnip_geom_create (); g_accum_omnipart.create (D3DFVF_XYZ, g_accum_omnip_vb, g_accum_omnip_ib); } // SPOT { s_accum_spot.create (b_accum_spot, "r2\\accum_spot_s", "lights\\lights_spot01"); accum_spot_geom_create (); g_accum_spot.create (D3DFVF_XYZ, g_accum_spot_vb, g_accum_spot_ib); } // REFLECTED { s_accum_reflected.create (b_accum_reflected, "r2\\accum_refl"); } // BLOOM { D3DFORMAT fmt = D3DFMT_A8R8G8B8; //; // D3DFMT_X8R8G8B8 u32 w=BLOOM_size_X, h=BLOOM_size_Y; u32 fvf_build = D3DFVF_XYZRHW|D3DFVF_TEX4|D3DFVF_TEXCOORDSIZE2(0)|D3DFVF_TEXCOORDSIZE2(1)|D3DFVF_TEXCOORDSIZE2(2)|D3DFVF_TEXCOORDSIZE2(3); u32 fvf_filter = (u32)D3DFVF_XYZRHW|D3DFVF_TEX8|D3DFVF_TEXCOORDSIZE4(0)|D3DFVF_TEXCOORDSIZE4(1)|D3DFVF_TEXCOORDSIZE4(2)|D3DFVF_TEXCOORDSIZE4(3)|D3DFVF_TEXCOORDSIZE4(4)|D3DFVF_TEXCOORDSIZE4(5)|D3DFVF_TEXCOORDSIZE4(6)|D3DFVF_TEXCOORDSIZE4(7); rt_Bloom_1.create (r2_RT_bloom1, w,h, fmt); rt_Bloom_2.create (r2_RT_bloom2, w,h, fmt); g_bloom_build.create (fvf_build, RCache.Vertex.Buffer(), RCache.QuadIB); g_bloom_filter.create (fvf_filter, RCache.Vertex.Buffer(), RCache.QuadIB); s_bloom_dbg_1.create ("effects\\screen_set", r2_RT_bloom1); s_bloom_dbg_2.create ("effects\\screen_set", r2_RT_bloom2); s_bloom.create (b_bloom, "r2\\bloom"); f_bloom_factor = 0.5f; } // TONEMAP { rt_LUM_64.create (r2_RT_luminance_t64, 64, 64, D3DFMT_A16B16G16R16F ); rt_LUM_8.create (r2_RT_luminance_t8, 8, 8, D3DFMT_A16B16G16R16F ); s_luminance.create (b_luminance, "r2\\luminance"); f_luminance_adapt = 0.5f; t_LUM_src.create (r2_RT_luminance_src); t_LUM_dest.create (r2_RT_luminance_cur); // create pool for (u32 it=0; it<4; it++) { string256 name; sprintf (name,"%s_%d", r2_RT_luminance_pool,it ); rt_LUM_pool[it].create (name, 1, 1, D3DFMT_R32F ); u_setrt (rt_LUM_pool[it], 0, 0, 0 ); CHK_DX (HW.pDevice->Clear( 0L, NULL, D3DCLEAR_TARGET, 0x7f7f7f7f, 1.0f, 0L)); } u_setrt ( Device.dwWidth,Device.dwHeight,HW.pBaseRT,NULL,NULL,HW.pBaseZB); } // COMBINE { static D3DVERTEXELEMENT9 dwDecl[] = { { 0, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 }, // pos+uv D3DDECL_END() }; s_combine.create (b_combine, "r2\\combine"); s_combine_dbg_0.create ("effects\\screen_set", r2_RT_smap_surf ); s_combine_dbg_1.create ("effects\\screen_set", r2_RT_luminance_t8 ); s_combine_dbg_Accumulator.create ("effects\\screen_set", r2_RT_accum ); g_combine_VP.create (dwDecl, RCache.Vertex.Buffer(), RCache.QuadIB); g_combine.create (FVF::F_TL, RCache.Vertex.Buffer(), RCache.QuadIB); g_combine_2UV.create (FVF::F_TL2uv, RCache.Vertex.Buffer(), RCache.QuadIB); u32 fvf_aa_blur = D3DFVF_XYZRHW|D3DFVF_TEX4|D3DFVF_TEXCOORDSIZE2(0)|D3DFVF_TEXCOORDSIZE2(1)|D3DFVF_TEXCOORDSIZE2(2)|D3DFVF_TEXCOORDSIZE2(3); g_aa_blur.create (fvf_aa_blur, RCache.Vertex.Buffer(), RCache.QuadIB); u32 fvf_aa_AA = D3DFVF_XYZRHW|D3DFVF_TEX7|D3DFVF_TEXCOORDSIZE2(0)|D3DFVF_TEXCOORDSIZE2(1)|D3DFVF_TEXCOORDSIZE2(2)|D3DFVF_TEXCOORDSIZE2(3)|D3DFVF_TEXCOORDSIZE2(4)|D3DFVF_TEXCOORDSIZE4(5)|D3DFVF_TEXCOORDSIZE4(6); g_aa_AA.create (fvf_aa_AA, RCache.Vertex.Buffer(), RCache.QuadIB); t_envmap_0.create (r2_T_envs0); t_envmap_1.create (r2_T_envs1); } // Build textures { // Build material(s) { // Surface R_CHK (D3DXCreateVolumeTexture(HW.pDevice,TEX_material_LdotN,TEX_material_LdotH,4,1,0,D3DFMT_A8L8,D3DPOOL_MANAGED,&t_material_surf)); t_material = Device.Resources->_CreateTexture(r2_material); t_material->surface_set (t_material_surf); // Fill it (addr: x=dot(L,N),y=dot(L,H)) D3DLOCKED_BOX R; R_CHK (t_material_surf->LockBox (0,&R,0,0)); for (u32 slice=0; slice<4; slice++) { for (u32 y=0; y<TEX_material_LdotH; y++) { for (u32 x=0; x<TEX_material_LdotN; x++) { u16* p = (u16*) (LPBYTE (R.pBits) + slice*R.SlicePitch + y*R.RowPitch + x*2); float ld = float(x) / float (TEX_material_LdotN-1); float ls = float(y) / float (TEX_material_LdotH-1) + EPS_S; ls *= powf(ld,1/32.f); float fd,fs; switch (slice) { case 0: { // looks like OrenNayar fd = powf(ld,0.75f); // 0.75 fs = powf(ls,16.f)*.5f; } break; case 1: {// looks like Blinn fd = powf(ld,0.90f); // 0.90 fs = powf(ls,24.f); } break; case 2: { // looks like Phong fd = ld; // 1.0 fs = powf(ls*1.01f,128.f ); } break; case 3: { // looks like Metal float s0 = _abs (1-_abs (0.05f*_sin(33.f*ld)+ld-ls)); float s1 = _abs (1-_abs (0.05f*_cos(33.f*ld*ls)+ld-ls)); float s2 = _abs (1-_abs (ld-ls)); fd = ld; // 1.0 fs = powf (_max(_max(s0,s1),s2), 24.f); fs *= powf (ld,1/7.f); } break; default: fd = fs = 0; } s32 _d = clampr (iFloor (fd*255.5f), 0,255); s32 _s = clampr (iFloor (fs*255.5f), 0,255); if ((y==(TEX_material_LdotH-1)) && (x==(TEX_material_LdotN-1))) { _d = 255; _s=255; } *p = u16 (_s*256 + _d); } } } R_CHK (t_material_surf->UnlockBox (0)); // #ifdef DEBUG // R_CHK (D3DXSaveTextureToFile ("x:\\r2_material.dds",D3DXIFF_DDS,t_material_surf,0)); // #endif } // Build noise table if (1) { // Surfaces D3DLOCKED_RECT R[TEX_jitter_count]; for (int it=0; it<TEX_jitter_count; it++) { string_path name; sprintf (name,"%s%d",r2_jitter,it); R_CHK (D3DXCreateTexture (HW.pDevice,TEX_jitter,TEX_jitter,1,0,D3DFMT_Q8W8V8U8,D3DPOOL_MANAGED,&t_noise_surf[it])); t_noise[it] = Device.Resources->_CreateTexture (name); t_noise[it]->surface_set (t_noise_surf[it]); R_CHK (t_noise_surf[it]->LockRect (0,&R[it],0,0)); } // Fill it, for (u32 y=0; y<TEX_jitter; y++) { for (u32 x=0; x<TEX_jitter; x++) { DWORD data [TEX_jitter_count]; generate_jitter (data,TEX_jitter_count); for (u32 it=0; it<TEX_jitter_count; it++) { u32* p = (u32*) (LPBYTE (R[it].pBits) + y*R[it].Pitch + x*4); *p = data [it]; } } } for (int it=0; it<TEX_jitter_count; it++) { R_CHK (t_noise_surf[it]->UnlockRect(0)); } } } // PP s_postprocess.create ("postprocess"); g_postprocess.create (D3DFVF_XYZRHW|D3DFVF_DIFFUSE|D3DFVF_SPECULAR|D3DFVF_TEX3,RCache.Vertex.Buffer(),RCache.QuadIB); // Menu s_menu.create ("distort"); g_menu.create (FVF::F_TL,RCache.Vertex.Buffer(),RCache.QuadIB); // dwWidth = Device.dwWidth; dwHeight = Device.dwHeight; }
void CEnvironment::OnFrame() { #ifdef _EDITOR SetGameTime (fGameTime+Device.fTimeDelta*fTimeFactor,fTimeFactor); if (fsimilar(ed_to_time,DAY_LENGTH)&&fsimilar(ed_from_time,0.f)){ if (fGameTime>DAY_LENGTH) fGameTime-=DAY_LENGTH; }else{ if (fGameTime>ed_to_time){ fGameTime=fGameTime-ed_to_time+ed_from_time; Current[0]=Current[1]=0; } if (fGameTime<ed_from_time){ fGameTime=ed_from_time; Current[0]=Current[1]=0; } } if (!psDeviceFlags.is(rsEnvironment)) return; #else if (!g_pGameLevel) return; #endif // if (pInput->iGetAsyncKeyState(DIK_O)) SetWeatherFX("surge_day"); if (bWFX&&(wfx_time<=0.f)) StopWFX(); SelectEnvs (fGameTime); VERIFY (Current[0]&&Current[1]); float current_weight = TimeWeight(fGameTime,Current[0]->exec_time,Current[1]->exec_time); // modifiers CEnvModifier EM; EM.far_plane = 0; EM.fog_color.set ( 0,0,0 ); EM.fog_density = 0; EM.ambient.set ( 0,0,0 ); EM.sky_color.set ( 0,0,0 ); EM.hemi_color.set ( 0,0,0 ); Fvector view = Device.vCameraPosition; float mpower = 0; for (xr_vector<CEnvModifier>::iterator mit=Modifiers.begin(); mit!=Modifiers.end(); mit++) mpower += EM.sum(*mit,view); // final lerp CurrentEnv.lerp (this,*Current[0],*Current[1],current_weight,EM,mpower); #ifndef SUN_DIR_NOT_DEBUG if(CurrentEnv.sun_dir.y>0) { Log("CurrentEnv.sun_dir", CurrentEnv.sun_dir); Log("current_weight", current_weight); Log("mpower", mpower); Log("Current[0]->sun_dir", Current[0]->sun_dir); Log("Current[1]->sun_dir", Current[1]->sun_dir); } #endif VERIFY2 (CurrentEnv.sun_dir.y<0,"Invalid sun direction settings in lerp"); if (::Render->get_generation()==IRender_interface::GENERATION_R2){ //. very very ugly hack if (HW.Caps.raster_major >= 3 && HW.Caps.geometry.bVTF){ // tonemapping in VS CurrentEnv.sky_r_textures.push_back (mk_pair(u32(D3DVERTEXTEXTURESAMPLER0),tonemap)); //. hack CurrentEnv.sky_r_textures_env.push_back (mk_pair(u32(D3DVERTEXTEXTURESAMPLER0),tonemap)); //. hack CurrentEnv.clouds_r_textures.push_back (mk_pair(u32(D3DVERTEXTEXTURESAMPLER0),tonemap)); //. hack } else { // tonemapping in PS CurrentEnv.sky_r_textures.push_back (mk_pair(2,tonemap)); //. hack CurrentEnv.sky_r_textures_env.push_back (mk_pair(2,tonemap)); //. hack CurrentEnv.clouds_r_textures.push_back (mk_pair(2,tonemap)); //. hack } } //. Setup skybox textures, somewhat ugly IDirect3DBaseTexture9* e0 = CurrentEnv.sky_r_textures[0].second->surface_get(); IDirect3DBaseTexture9* e1 = CurrentEnv.sky_r_textures[1].second->surface_get(); tsky0->surface_set (e0); _RELEASE(e0); tsky1->surface_set (e1); _RELEASE(e1); PerlinNoise1D->SetFrequency (wind_gust_factor*MAX_NOISE_FREQ); wind_strength_factor = clampr(PerlinNoise1D->GetContinious(Device.fTimeGlobal)+0.5f,0.f,1.f); int l_id = (current_weight<0.5f)?Current[0]->lens_flare_id:Current[1]->lens_flare_id; eff_LensFlare->OnFrame (l_id); int t_id = (current_weight<0.5f)?Current[0]->tb_id:Current[1]->tb_id; eff_Thunderbolt->OnFrame (t_id,CurrentEnv.bolt_period,CurrentEnv.bolt_duration); eff_Rain->OnFrame (); // ******************** Environment params (setting) CHK_DX(HW.pDevice->SetRenderState( D3DRS_FOGCOLOR, color_rgba_f(CurrentEnv.fog_color.x,CurrentEnv.fog_color.y,CurrentEnv.fog_color.z,0) )); CHK_DX(HW.pDevice->SetRenderState( D3DRS_FOGSTART, *(u32 *)(&CurrentEnv.fog_near) )); CHK_DX(HW.pDevice->SetRenderState( D3DRS_FOGEND, *(u32 *)(&CurrentEnv.fog_far) )); }
CRenderTarget::CRenderTarget () { param_blur = 0.f; param_gray = 0.f; param_noise = 0.f; param_duality_h = 0.f; param_duality_v = 0.f; param_noise_fps = 25.f; param_noise_scale = 1.f; im_noise_time = 1/100; im_noise_shift_w = 0; im_noise_shift_h = 0; param_color_base = color_rgba(127,127,127, 0); param_color_gray = color_rgba(85,85,85, 0); param_color_add.set( 0.0f, 0.0f, 0.0f ); dwAccumulatorClearMark = 0; dxRenderDeviceRender::Instance().Resources->Evict (); // Blenders b_occq = new CBlender_light_occq(); b_accum_mask = new CBlender_accum_direct_mask(); b_accum_direct = new CBlender_accum_direct(); b_accum_point = new CBlender_accum_point(); b_accum_spot = new CBlender_accum_spot(); b_accum_reflected = new CBlender_accum_reflected(); b_bloom = new CBlender_bloom_build(); b_ssao = new CBlender_SSAO(); b_luminance = new CBlender_luminance(); b_combine = new CBlender_combine(); // NORMAL { u32 w=Device.dwWidth, h=Device.dwHeight; rt_Position.create (r2_RT_P, w,h,D3DFMT_A16B16G16R16F); rt_Normal.create (r2_RT_N, w,h,D3DFMT_A16B16G16R16F); // select albedo & accum if (RImplementation.o.mrtmixdepth) { // NV50 rt_Color.create (r2_RT_albedo, w,h,D3DFMT_A8R8G8B8 ); rt_Accumulator.create (r2_RT_accum, w,h,D3DFMT_A16B16G16R16F); } else { // can't - mix-depth if (RImplementation.o.fp16_blend) { // NV40 rt_Color.create (r2_RT_albedo, w,h,D3DFMT_A16B16G16R16F); // expand to full rt_Accumulator.create (r2_RT_accum, w,h,D3DFMT_A16B16G16R16F); } else { // R4xx, no-fp-blend,-> albedo_wo VERIFY (RImplementation.o.albedo_wo); rt_Color.create (r2_RT_albedo, w,h,D3DFMT_A8R8G8B8 ); // normal rt_Accumulator.create (r2_RT_accum, w,h,D3DFMT_A16B16G16R16F); rt_Accumulator_temp.create (r2_RT_accum_temp, w,h,D3DFMT_A16B16G16R16F); } } // generic(LDR) RTs rt_Generic_0.create (r2_RT_generic0,w,h,D3DFMT_A8R8G8B8 ); rt_Generic_1.create (r2_RT_generic1,w,h,D3DFMT_A8R8G8B8 ); // Igor: for volumetric lights //rt_Generic_2.create (r2_RT_generic2,w,h,D3DFMT_A8R8G8B8 ); // temp: for higher quality blends if (RImplementation.o.advancedpp) rt_Generic_2.create (r2_RT_generic2,w,h,D3DFMT_A16B16G16R16F); } // OCCLUSION s_occq.create (b_occq, "r2\\occq"); // DIRECT (spot) D3DFORMAT depth_format = (D3DFORMAT)RImplementation.o.HW_smap_FORMAT; if (RImplementation.o.HW_smap) { D3DFORMAT nullrt = D3DFMT_R5G6B5; if (RImplementation.o.nullrt) nullrt = (D3DFORMAT)MAKEFOURCC('N','U','L','L'); u32 size =RImplementation.o.smapsize ; rt_smap_depth.create (r2_RT_smap_depth, size,size,depth_format ); rt_smap_surf.create (r2_RT_smap_surf, size,size,nullrt ); rt_smap_ZB = NULL; s_accum_mask.create (b_accum_mask, "r2\\accum_mask"); s_accum_direct.create (b_accum_direct, "r2\\accum_direct"); if (RImplementation.o.advancedpp) s_accum_direct_volumetric.create("accum_volumetric_sun"); } else { u32 size =RImplementation.o.smapsize ; rt_smap_surf.create (r2_RT_smap_surf, size,size,D3DFMT_R32F); rt_smap_depth = NULL; R_CHK (HW.pDevice->CreateDepthStencilSurface (size,size,D3DFMT_D24X8,D3DMULTISAMPLE_NONE,0,TRUE,&rt_smap_ZB,NULL)); s_accum_mask.create (b_accum_mask, "r2\\accum_mask"); s_accum_direct.create (b_accum_direct, "r2\\accum_direct"); if (RImplementation.o.advancedpp) s_accum_direct_volumetric.create("accum_volumetric_sun"); } // POINT { s_accum_point.create (b_accum_point, "r2\\accum_point_s"); accum_point_geom_create (); g_accum_point.create (D3DFVF_XYZ, g_accum_point_vb, g_accum_point_ib); accum_omnip_geom_create (); g_accum_omnipart.create (D3DFVF_XYZ, g_accum_omnip_vb, g_accum_omnip_ib); } // SPOT { s_accum_spot.create (b_accum_spot, "r2\\accum_spot_s", "lights\\lights_spot01"); accum_spot_geom_create (); g_accum_spot.create (D3DFVF_XYZ, g_accum_spot_vb, g_accum_spot_ib); } { s_accum_volume.create("accum_volumetric", "lights\\lights_spot01"); accum_volumetric_geom_create(); g_accum_volumetric.create( D3DFVF_XYZ, g_accum_volumetric_vb, g_accum_volumetric_ib); } // REFLECTED { s_accum_reflected.create (b_accum_reflected, "r2\\accum_refl"); } // BLOOM { D3DFORMAT fmt = D3DFMT_A8R8G8B8; //; // D3DFMT_X8R8G8B8 u32 w=BLOOM_size_X, h=BLOOM_size_Y; u32 fvf_build = D3DFVF_XYZRHW|D3DFVF_TEX4|D3DFVF_TEXCOORDSIZE2(0)|D3DFVF_TEXCOORDSIZE2(1)|D3DFVF_TEXCOORDSIZE2(2)|D3DFVF_TEXCOORDSIZE2(3); u32 fvf_filter = (u32)D3DFVF_XYZRHW|D3DFVF_TEX8|D3DFVF_TEXCOORDSIZE4(0)|D3DFVF_TEXCOORDSIZE4(1)|D3DFVF_TEXCOORDSIZE4(2)|D3DFVF_TEXCOORDSIZE4(3)|D3DFVF_TEXCOORDSIZE4(4)|D3DFVF_TEXCOORDSIZE4(5)|D3DFVF_TEXCOORDSIZE4(6)|D3DFVF_TEXCOORDSIZE4(7); rt_Bloom_1.create (r2_RT_bloom1, w,h, fmt); rt_Bloom_2.create (r2_RT_bloom2, w,h, fmt); g_bloom_build.create (fvf_build, RCache.Vertex.Buffer(), RCache.QuadIB); g_bloom_filter.create (fvf_filter, RCache.Vertex.Buffer(), RCache.QuadIB); s_bloom_dbg_1.create ("effects\\screen_set", r2_RT_bloom1); s_bloom_dbg_2.create ("effects\\screen_set", r2_RT_bloom2); s_bloom.create (b_bloom, "r2\\bloom"); f_bloom_factor = 0.5f; } //HBAO if (RImplementation.o.ssao_opt_data) { u32 w = 0; u32 h = 0; if (RImplementation.o.ssao_half_data) { w = Device.dwWidth / 2; h = Device.dwHeight / 2; } else { w = Device.dwWidth; h = Device.dwHeight; } D3DFORMAT fmt = HW.Caps.id_vendor==0x10DE?D3DFMT_R32F:D3DFMT_R16F; rt_half_depth.create (r2_RT_half_depth, w, h, fmt); s_ssao.create (b_ssao, "r2\\ssao"); } //SSAO if (RImplementation.o.ssao_blur_on) { u32 w = Device.dwWidth, h = Device.dwHeight; rt_ssao_temp.create (r2_RT_ssao_temp, w, h, D3DFMT_G16R16F); s_ssao.create (b_ssao, "r2\\ssao"); } // TONEMAP { rt_LUM_64.create (r2_RT_luminance_t64, 64, 64, D3DFMT_A16B16G16R16F ); rt_LUM_8.create (r2_RT_luminance_t8, 8, 8, D3DFMT_A16B16G16R16F ); s_luminance.create (b_luminance, "r2\\luminance"); f_luminance_adapt = 0.5f; t_LUM_src.create (r2_RT_luminance_src); t_LUM_dest.create (r2_RT_luminance_cur); // create pool for (u32 it=0; it<HW.Caps.iGPUNum*2; it++) { string256 name; sprintf (name,"%s_%d", r2_RT_luminance_pool,it ); rt_LUM_pool[it].create (name, 1, 1, D3DFMT_R32F ); u_setrt (rt_LUM_pool[it], 0, 0, 0 ); CHK_DX (HW.pDevice->Clear( 0L, NULL, D3DCLEAR_TARGET, 0x7f7f7f7f, 1.0f, 0L)); } u_setrt ( Device.dwWidth,Device.dwHeight,HW.pBaseRT,NULL,NULL,HW.pBaseZB); } // COMBINE { static D3DVERTEXELEMENT9 dwDecl[] = { { 0, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 }, // pos+uv { 0, 16, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0 }, { 0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 }, D3DDECL_END() }; s_combine.create (b_combine, "r2\\combine"); s_combine_volumetric.create ("combine_volumetric"); s_combine_dbg_0.create ("effects\\screen_set", r2_RT_smap_surf ); s_combine_dbg_1.create ("effects\\screen_set", r2_RT_luminance_t8 ); s_combine_dbg_Accumulator.create ("effects\\screen_set", r2_RT_accum ); g_combine_VP.create (dwDecl, RCache.Vertex.Buffer(), RCache.QuadIB); g_combine.create (FVF::F_TL, RCache.Vertex.Buffer(), RCache.QuadIB); g_combine_2UV.create (FVF::F_TL2uv, RCache.Vertex.Buffer(), RCache.QuadIB); u32 fvf_aa_blur = D3DFVF_XYZRHW|D3DFVF_TEX4|D3DFVF_TEXCOORDSIZE2(0)|D3DFVF_TEXCOORDSIZE2(1)|D3DFVF_TEXCOORDSIZE2(2)|D3DFVF_TEXCOORDSIZE2(3); g_aa_blur.create (fvf_aa_blur, RCache.Vertex.Buffer(), RCache.QuadIB); u32 fvf_aa_AA = D3DFVF_XYZRHW|D3DFVF_TEX7|D3DFVF_TEXCOORDSIZE2(0)|D3DFVF_TEXCOORDSIZE2(1)|D3DFVF_TEXCOORDSIZE2(2)|D3DFVF_TEXCOORDSIZE2(3)|D3DFVF_TEXCOORDSIZE2(4)|D3DFVF_TEXCOORDSIZE4(5)|D3DFVF_TEXCOORDSIZE4(6); g_aa_AA.create (fvf_aa_AA, RCache.Vertex.Buffer(), RCache.QuadIB); t_envmap_0.create (r2_T_envs0); t_envmap_1.create (r2_T_envs1); } // Build textures { // Build material(s) { // Surface R_CHK (D3DXCreateVolumeTexture(HW.pDevice,TEX_material_LdotN,TEX_material_LdotH,4,1,0,D3DFMT_A8L8,D3DPOOL_MANAGED,&t_material_surf)); t_material = dxRenderDeviceRender::Instance().Resources->_CreateTexture(r2_material); t_material->surface_set (t_material_surf); // Fill it (addr: x=dot(L,N),y=dot(L,H)) D3DLOCKED_BOX R; R_CHK (t_material_surf->LockBox (0,&R,0,0)); for (u32 slice=0; slice<4; slice++) { for (u32 y=0; y<TEX_material_LdotH; y++) { for (u32 x=0; x<TEX_material_LdotN; x++) { u16* p = (u16*) (LPBYTE (R.pBits) + slice*R.SlicePitch + y*R.RowPitch + x*2); float ld = float(x) / float (TEX_material_LdotN-1); float ls = float(y) / float (TEX_material_LdotH-1) + EPS_S; ls *= powf(ld,1/32.f); float fd,fs; switch (slice) { case 0: { // looks like OrenNayar fd = powf(ld,0.75f); // 0.75 fs = powf(ls,16.f)*.5f; } break; case 1: {// looks like Blinn fd = powf(ld,0.90f); // 0.90 fs = powf(ls,24.f); } break; case 2: { // looks like Phong fd = ld; // 1.0 fs = powf(ls*1.01f,128.f ); } break; case 3: { // looks like Metal float s0 = _abs (1-_abs (0.05f*_sin(33.f*ld)+ld-ls)); float s1 = _abs (1-_abs (0.05f*_cos(33.f*ld*ls)+ld-ls)); float s2 = _abs (1-_abs (ld-ls)); fd = ld; // 1.0 fs = powf (_max(_max(s0,s1),s2), 24.f); fs *= powf (ld,1/7.f); } break; default: fd = fs = 0; } s32 _d = clampr (iFloor (fd*255.5f), 0,255); s32 _s = clampr (iFloor (fs*255.5f), 0,255); if ((y==(TEX_material_LdotH-1)) && (x==(TEX_material_LdotN-1))) { _d = 255; _s=255; } *p = u16 (_s*256 + _d); } } } R_CHK (t_material_surf->UnlockBox (0)); // #ifdef DEBUG // R_CHK (D3DXSaveTextureToFile ("x:\\r2_material.dds",D3DXIFF_DDS,t_material_surf,0)); // #endif } // Build noise table if (1) { // Surfaces D3DLOCKED_RECT R[TEX_jitter_count]; for (int it1=0; it1<TEX_jitter_count-1; it1++) { string_path name; sprintf (name,"%s%d",r2_jitter,it1); R_CHK (D3DXCreateTexture (HW.pDevice,TEX_jitter,TEX_jitter,1,0,D3DFMT_Q8W8V8U8,D3DPOOL_MANAGED,&t_noise_surf[it1])); t_noise[it1] = dxRenderDeviceRender::Instance().Resources->_CreateTexture (name); t_noise[it1]->surface_set (t_noise_surf[it1]); R_CHK (t_noise_surf[it1]->LockRect (0,&R[it1],0,0)); } // Fill it, for (u32 y=0; y<TEX_jitter; y++) { for (u32 x=0; x<TEX_jitter; x++) { DWORD data [TEX_jitter_count-1]; generate_jitter (data,TEX_jitter_count-1); for (u32 it2=0; it2<TEX_jitter_count-1; it2++) { u32* p = (u32*) (LPBYTE (R[it2].pBits) + y*R[it2].Pitch + x*4); *p = data [it2]; } } } for (int it3=0; it3<TEX_jitter_count-1; it3++) { R_CHK (t_noise_surf[it3]->UnlockRect(0)); } // generate HBAO jitter texture (last) int it = TEX_jitter_count - 1; string_path name; sprintf (name,"%s%d",r2_jitter,it); R_CHK (D3DXCreateTexture (HW.pDevice,TEX_jitter,TEX_jitter,1,0,D3DFMT_A32B32G32R32F,D3DPOOL_MANAGED,&t_noise_surf[it])); t_noise[it] = dxRenderDeviceRender::Instance().Resources->_CreateTexture (name); t_noise[it]->surface_set (t_noise_surf[it]); R_CHK (t_noise_surf[it]->LockRect (0,&R[it],0,0)); // Fill it, for (u32 y=0; y<TEX_jitter; y++) { for (u32 x=0; x<TEX_jitter; x++) { float numDir = 1.0f; switch (ps_r_ssao) { case 1: numDir = 4.0f; break; case 2: numDir = 6.0f; break; case 3: numDir = 8.0f; break; } float angle = 2 * PI * ::Random.randF(0.0f, 1.0f) / numDir; float dist = ::Random.randF(0.0f, 1.0f); //float dest[4]; float* p = (float*) (LPBYTE (R[it].pBits) + y*R[it].Pitch + x*4*sizeof(float)); *p = (float)(_cos(angle)); *(p+1) = (float)(_sin(angle)); *(p+2) = (float)(dist); *(p+3) = 0; //generate_hbao_jitter (data,TEX_jitter*TEX_jitter); } } R_CHK (t_noise_surf[it]->UnlockRect(0)); } } // PP s_postprocess.create ("postprocess"); g_postprocess.create (D3DFVF_XYZRHW|D3DFVF_DIFFUSE|D3DFVF_SPECULAR|D3DFVF_TEX3,RCache.Vertex.Buffer(),RCache.QuadIB); // Menu s_menu.create ("distort"); g_menu.create (FVF::F_TL,RCache.Vertex.Buffer(),RCache.QuadIB); // Igor: TMP // Create an RT for online screenshot makining //u32 w = Device.dwWidth, h = Device.dwHeight; //HW.pDevice->CreateOffscreenPlainSurface(Device.dwWidth,Device.dwHeight,D3DFMT_A8R8G8B8,D3DPOOL_SYSTEMMEM,&pFB,NULL); //HW.pDevice->CreateOffscreenPlainSurface(Device.dwWidth,Device.dwHeight,rt_Color->fmt,D3DPOOL_SYSTEMMEM,&pFB,NULL); D3DSURFACE_DESC desc; HW.pBaseRT->GetDesc(&desc); HW.pDevice->CreateOffscreenPlainSurface(Device.dwWidth,Device.dwHeight,desc.Format,D3DPOOL_SYSTEMMEM,&pFB,NULL); // dwWidth = Device.dwWidth; dwHeight = Device.dwHeight; }
void dx103DFluidRenderer::CalculateLighting(const dx103DFluidData &FluidData, FogLighting &LightData) { m_lstRenderables.clear_not_free(); LightData.Reset(); const dx103DFluidData::Settings &VolumeSettings = FluidData.GetSettings(); Fvector4 hemi_color = g_pGamePersistent->Environment().CurrentEnv->hemi_color; //hemi_color.mul(0.2f); hemi_color.mul(VolumeSettings.m_fHemi); LightData.m_vLightIntencity.set(hemi_color.x, hemi_color.y, hemi_color.z); LightData.m_vLightIntencity.add(g_pGamePersistent->Environment().CurrentEnv->ambient); const Fmatrix &Transform = FluidData.GetTransform(); Fbox box; box.min = Fvector3().set(-0.5f, -0.5f, -0.5f); box.max = Fvector3().set( 0.5f, 0.5f, 0.5f); box.xform(Transform); Fvector3 center; Fvector3 size; box.getcenter(center); box.getradius(size); // Traverse object database g_SpatialSpace->q_box ( m_lstRenderables, 0, //ISpatial_DB::O_ORDERED, STYPE_LIGHTSOURCE, center, size ); u32 iNumRenderables = m_lstRenderables.size(); // Determine visibility for dynamic part of scene for (u32 i=0; i<iNumRenderables; ++i) { ISpatial* spatial = m_lstRenderables[i]; // Light light* pLight = (light*) spatial->dcast_Light(); VERIFY(pLight); if (pLight->flags.bStatic) continue; float d = pLight->position.distance_to(Transform.c); float R = pLight->range + _max( size.x, _max( size.y, size.z ) ); if ( d >= R ) continue; Fvector3 LightIntencity; LightIntencity.set(pLight->color.r, pLight->color.g, pLight->color.b); //LightIntencity.mul(0.5f); //if (!pLight->flags.bStatic) // LightIntencity.mul(0.5f); float r = pLight->range; float a = clampr(1.f - d/(r+EPS),0.f,1.f)*(pLight->flags.bStatic?1.f:2.f); LightIntencity.mul(a); LightData.m_vLightIntencity.add(LightIntencity); } //LightData.m_vLightIntencity.set( 1.0f, 0.5f, 0.0f); //LightData.m_vLightIntencity.set( 1.0f, 1.0f, 1.0f); }
void CSheduler::ProcessStep () { // Normal priority u32 dwTime = Device.dwTimeGlobal; CTimer eTimer; for (int i=0;!Items.empty() && Top().dwTimeForExecute < dwTime; ++i) { u32 delta_ms = dwTime - Top().dwTimeForExecute; // Update Item T = Top (); #ifdef DEBUG_SCHEDULER Msg ("SCHEDULER: process step [%s][%x][false]",*T.scheduled_name,T.Object); #endif // DEBUG_SCHEDULER u32 Elapsed = dwTime-T.dwTimeOfLastExecute; bool condition; condition = (NULL==T.Object || !T.Object->shedule_Needed()); if (condition) { // Erase element #ifdef DEBUG_SCHEDULER Msg ("SCHEDULER: process unregister [%s][%x][%s]",*T.scheduled_name,T.Object,"false"); #endif // DEBUG_SCHEDULER // if (T.Object) // Msg ("0x%08x UNREGISTERS because shedule_Needed() returned false",T.Object); // else // Msg ("UNREGISTERS unknown object"); Pop (); continue; } // Insert into priority Queue Pop (); // Real update call // Msg ("------- %d:",Device.dwFrame); #ifdef DEBUG T.Object->dbg_startframe = Device.dwFrame; eTimer.Start (); // LPCSTR _obj_name = T.Object->shedule_Name().c_str(); #endif // DEBUG // Calc next update interval u32 dwMin = _max(u32(30),T.Object->shedule.t_min); u32 dwMax = (1000+T.Object->shedule.t_max)/2; float scale = T.Object->shedule_Scale (); u32 dwUpdate = dwMin+iFloor(float(dwMax-dwMin)*scale); clamp (dwUpdate,u32(_max(dwMin,u32(20))),dwMax); m_current_step_obj = T.Object; // try { T.Object->shedule_Update (clampr(Elapsed,u32(1),u32(_max(u32(T.Object->shedule.t_max),u32(1000)))) ); if (!m_current_step_obj) { #ifdef DEBUG_SCHEDULER Msg ("SCHEDULER: process unregister (self unregistering) [%s][%x][%s]",*T.scheduled_name,T.Object,"false"); #endif // DEBUG_SCHEDULER continue; } // } catch (...) { #ifdef DEBUG // Msg ("! xrSheduler: object '%s' raised an exception", _obj_name); // throw ; #endif // DEBUG // } m_current_step_obj = NULL; #ifdef DEBUG // u32 execTime = eTimer.GetElapsed_ms (); #endif // DEBUG // Fill item structure Item TNext; TNext.dwTimeForExecute = dwTime+dwUpdate; TNext.dwTimeOfLastExecute = dwTime; TNext.Object = T.Object; TNext.scheduled_name = T.Object->shedule_Name(); ItemsProcessed.push_back (TNext); #ifdef DEBUG // u32 execTime = eTimer.GetElapsed_ms (); // VERIFY3 (T.Object->dbg_update_shedule == T.Object->dbg_startframe, "Broken sequence of calls to 'shedule_Update'", _obj_name ); if (delta_ms> 3*dwUpdate) { //Msg ("! xrSheduler: failed to shedule object [%s] (%dms)", _obj_name, delta_ms ); } // if (execTime> 15) { // Msg ("* xrSheduler: too much time consumed by object [%s] (%dms)", _obj_name, execTime ); // } #endif // DEBUG // if ((i % 3) != (3 - 1)) continue; if (Device.dwPrecacheFrame==0 && CPU::QPC() > cycles_limit) { // we have maxed out the load - increase heap psShedulerTarget += (psShedulerReaction * 3); break; } } // Push "processed" back while (ItemsProcessed.size()) { Push (ItemsProcessed.back()) ; ItemsProcessed.pop_back () ; } // always try to decrease target psShedulerTarget -= psShedulerReaction; }
CRenderTarget::CRenderTarget () { u32 SampleCount = 1; if (ps_r_ssao_mode!=2/*hdao*/) ps_r_ssao = _min(ps_r_ssao, 3); if( RImplementation.o.dx10_msaa ) SampleCount = RImplementation.o.dx10_msaa_samples; #ifdef DEBUG Msg ("MSAA samples = %d", SampleCount ); if( RImplementation.o.dx10_msaa_opt ) Msg ("dx10_MSAA_opt = on" ); if( RImplementation.o.dx10_gbuffer_opt ) Msg ("dx10_gbuffer_opt = on" ); #endif // DEBUG param_blur = 0.f; param_gray = 0.f; param_noise = 0.f; param_duality_h = 0.f; param_duality_v = 0.f; param_noise_fps = 25.f; param_noise_scale = 1.f; im_noise_time = 1/100; im_noise_shift_w = 0; im_noise_shift_h = 0; param_color_base = color_rgba(127,127,127, 0); param_color_gray = color_rgba(85,85,85, 0); //param_color_add = color_rgba(0,0,0, 0); param_color_add.set( 0.0f, 0.0f, 0.0f ); dwAccumulatorClearMark = 0; dxRenderDeviceRender::Instance().Resources->Evict (); // Blenders b_occq = xr_new<CBlender_light_occq> (); b_accum_mask = xr_new<CBlender_accum_direct_mask> (); b_accum_direct = xr_new<CBlender_accum_direct> (); b_accum_point = xr_new<CBlender_accum_point> (); b_accum_spot = xr_new<CBlender_accum_spot> (); b_accum_reflected = xr_new<CBlender_accum_reflected> (); b_bloom = xr_new<CBlender_bloom_build> (); if( RImplementation.o.dx10_msaa ) { b_bloom_msaa = xr_new<CBlender_bloom_build_msaa> (); b_postprocess_msaa = xr_new<CBlender_postprocess_msaa> (); } b_luminance = xr_new<CBlender_luminance> (); b_combine = xr_new<CBlender_combine> (); b_ssao = xr_new<CBlender_SSAO_noMSAA> (); if( RImplementation.o.dx10_msaa ) { int bound = RImplementation.o.dx10_msaa_samples; if( RImplementation.o.dx10_msaa_opt ) bound = 1; for( int i = 0; i < bound; ++i ) { static LPCSTR SampleDefs[] = { "0","1","2","3","4","5","6","7" }; b_combine_msaa[i] = xr_new<CBlender_combine_msaa> (); b_accum_mask_msaa[i] = xr_new<CBlender_accum_direct_mask_msaa> (); b_accum_direct_msaa[i] = xr_new<CBlender_accum_direct_msaa> (); b_accum_direct_volumetric_msaa[i] = xr_new<CBlender_accum_direct_volumetric_msaa> (); //b_accum_direct_volumetric_sun_msaa[i] = xr_new<CBlender_accum_direct_volumetric_sun_msaa> (); b_accum_spot_msaa[i] = xr_new<CBlender_accum_spot_msaa> (); b_accum_volumetric_msaa[i] = xr_new<CBlender_accum_volumetric_msaa> (); b_accum_point_msaa[i] = xr_new<CBlender_accum_point_msaa> (); b_accum_reflected_msaa[i] = xr_new<CBlender_accum_reflected_msaa> (); b_ssao_msaa[i] = xr_new<CBlender_SSAO_MSAA> (); static_cast<CBlender_accum_direct_mask_msaa*>( b_accum_mask_msaa[i] )->SetDefine( "ISAMPLE", SampleDefs[i]); static_cast<CBlender_accum_direct_volumetric_msaa*>(b_accum_direct_volumetric_msaa[i])->SetDefine( "ISAMPLE", SampleDefs[i]); //static_cast<CBlender_accum_direct_volumetric_sun_msaa*>(b_accum_direct_volumetric_sun_msaa[i])->SetDefine( "ISAMPLE", SampleDefs[i]); static_cast<CBlender_accum_direct_msaa*>(b_accum_direct_msaa[i])->SetDefine( "ISAMPLE", SampleDefs[i]); static_cast<CBlender_accum_volumetric_msaa*>(b_accum_volumetric_msaa[i])->SetDefine( "ISAMPLE", SampleDefs[i]); static_cast<CBlender_accum_spot_msaa*>(b_accum_spot_msaa[i])->SetDefine( "ISAMPLE", SampleDefs[i]); static_cast<CBlender_accum_point_msaa*>(b_accum_point_msaa[i])->SetDefine( "ISAMPLE", SampleDefs[i]); static_cast<CBlender_accum_reflected_msaa*>(b_accum_reflected_msaa[i])->SetDefine( "ISAMPLE", SampleDefs[i]); static_cast<CBlender_combine_msaa*>(b_combine_msaa[i])->SetDefine( "ISAMPLE", SampleDefs[i]); static_cast<CBlender_SSAO_MSAA*>(b_ssao_msaa[i])->SetDefine("ISAMPLE", SampleDefs[i]); } } // NORMAL { u32 w=Device.dwWidth, h=Device.dwHeight; rt_Position.create (r2_RT_P, w,h,D3DFMT_A16B16G16R16F, SampleCount ); if( RImplementation.o.dx10_msaa ) rt_MSAADepth.create( r2_RT_MSAAdepth, w, h, D3DFMT_D24S8, SampleCount ); if( !RImplementation.o.dx10_gbuffer_opt ) rt_Normal.create (r2_RT_N, w,h,D3DFMT_A16B16G16R16F, SampleCount ); // select albedo & accum if (RImplementation.o.mrtmixdepth) { // NV50 rt_Color.create (r2_RT_albedo, w,h,D3DFMT_A8R8G8B8 , SampleCount ); rt_Accumulator.create (r2_RT_accum, w,h,D3DFMT_A16B16G16R16F, SampleCount ); } else { // can't - mix-depth if (RImplementation.o.fp16_blend) { // NV40 if( !RImplementation.o.dx10_gbuffer_opt ) { rt_Color.create (r2_RT_albedo, w,h,D3DFMT_A16B16G16R16F, SampleCount ); // expand to full rt_Accumulator.create (r2_RT_accum, w,h,D3DFMT_A16B16G16R16F, SampleCount ); } else { rt_Color.create (r2_RT_albedo, w,h,D3DFMT_A8R8G8B8, SampleCount ); // expand to full rt_Accumulator.create (r2_RT_accum, w,h,D3DFMT_A16B16G16R16F, SampleCount ); } } else { // R4xx, no-fp-blend,-> albedo_wo VERIFY (RImplementation.o.albedo_wo); rt_Color.create (r2_RT_albedo, w,h,D3DFMT_A8R8G8B8 , SampleCount ); // normal rt_Accumulator.create (r2_RT_accum, w,h,D3DFMT_A16B16G16R16F, SampleCount ); rt_Accumulator_temp.create (r2_RT_accum_temp, w,h,D3DFMT_A16B16G16R16F, SampleCount ); } } // generic(LDR) RTs rt_Generic_0.create (r2_RT_generic0,w,h,D3DFMT_A8R8G8B8, 1 ); rt_Generic_1.create (r2_RT_generic1,w,h,D3DFMT_A8R8G8B8, 1 ); if( RImplementation.o.dx10_msaa ) { rt_Generic_0_r.create(r2_RT_generic0_r,w,h,D3DFMT_A8R8G8B8, SampleCount ); rt_Generic_1_r.create(r2_RT_generic1_r,w,h,D3DFMT_A8R8G8B8, SampleCount ); rt_Generic.create (r2_RT_generic,w,h, D3DFMT_A8R8G8B8, 1 ); } // Igor: for volumetric lights //rt_Generic_2.create (r2_RT_generic2,w,h,D3DFMT_A8R8G8B8 ); // temp: for higher quality blends if (RImplementation.o.advancedpp) rt_Generic_2.create (r2_RT_generic2,w,h,D3DFMT_A16B16G16R16F, SampleCount ); } // OCCLUSION s_occq.create (b_occq, "r2\\occq"); // DIRECT (spot) D3DFORMAT depth_format = (D3DFORMAT)RImplementation.o.HW_smap_FORMAT; if (RImplementation.o.HW_smap) { D3DFORMAT nullrt = D3DFMT_R5G6B5; if (RImplementation.o.nullrt) nullrt = (D3DFORMAT)MAKEFOURCC('N','U','L','L'); u32 size =RImplementation.o.smapsize ; rt_smap_depth.create (r2_RT_smap_depth, size,size,depth_format ); if (RImplementation.o.dx10_minmax_sm) { rt_smap_depth_minmax.create( r2_RT_smap_depth_minmax, size/4,size/4, D3DFMT_R32F ); CBlender_createminmax TempBlender; s_create_minmax_sm.create( &TempBlender, "null" ); } //rt_smap_surf.create (r2_RT_smap_surf, size,size,nullrt ); //rt_smap_ZB = NULL; s_accum_mask.create (b_accum_mask, "r3\\accum_mask"); s_accum_direct.create (b_accum_direct, "r3\\accum_direct"); if( RImplementation.o.dx10_msaa ) { int bound = RImplementation.o.dx10_msaa_samples; if( RImplementation.o.dx10_msaa_opt ) bound = 1; for( int i = 0; i < bound; ++i ) { s_accum_direct_msaa[i].create (b_accum_direct_msaa[i], "r3\\accum_direct"); s_accum_mask_msaa[i].create (b_accum_mask_msaa[i], "r3\\accum_direct"); } } if (RImplementation.o.advancedpp) { s_accum_direct_volumetric.create("accum_volumetric_sun_nomsaa"); if (RImplementation.o.dx10_minmax_sm) s_accum_direct_volumetric_minmax.create("accum_volumetric_sun_nomsaa_minmax"); if( RImplementation.o.dx10_msaa ) { static LPCSTR snames[] = { "accum_volumetric_sun_msaa0", "accum_volumetric_sun_msaa1", "accum_volumetric_sun_msaa2", "accum_volumetric_sun_msaa3", "accum_volumetric_sun_msaa4", "accum_volumetric_sun_msaa5", "accum_volumetric_sun_msaa6", "accum_volumetric_sun_msaa7" }; int bound = RImplementation.o.dx10_msaa_samples; if( RImplementation.o.dx10_msaa_opt ) bound = 1; for( int i = 0; i < bound; ++i ) { //s_accum_direct_volumetric_msaa[i].create (b_accum_direct_volumetric_sun_msaa[i], "r3\\accum_direct"); s_accum_direct_volumetric_msaa[i].create (snames[i]); } } } } else { // TODO: DX10: Check if we need old-style SMap VERIFY(!"Use HW SMAPs only!"); //u32 size =RImplementation.o.smapsize ; //rt_smap_surf.create (r2_RT_smap_surf, size,size,D3DFMT_R32F); //rt_smap_depth = NULL; //R_CHK (HW.pDevice->CreateDepthStencilSurface (size,size,D3DFMT_D24X8,D3DMULTISAMPLE_NONE,0,TRUE,&rt_smap_ZB,NULL)); //s_accum_mask.create (b_accum_mask, "r2\\accum_mask"); //s_accum_direct.create (b_accum_direct, "r2\\accum_direct"); //if (RImplementation.o.advancedpp) // s_accum_direct_volumetric.create("accum_volumetric_sun"); } // RAIN // TODO: DX10: Create resources only when DX10 rain is enabled. // Or make DX10 rain switch dynamic? { CBlender_rain TempBlender; s_rain.create( &TempBlender, "null"); if( RImplementation.o.dx10_msaa ) { static LPCSTR SampleDefs[] = { "0","1","2","3","4","5","6","7" }; CBlender_rain_msaa TempBlender[8]; int bound = RImplementation.o.dx10_msaa_samples; if( RImplementation.o.dx10_msaa_opt ) bound = 1; for( int i = 0; i < bound; ++i ) { TempBlender[i].SetDefine( "ISAMPLE", SampleDefs[i] ); s_rain_msaa[i].create( &TempBlender[i], "null"); s_accum_spot_msaa[i].create (b_accum_spot_msaa[i], "r2\\accum_spot_s", "lights\\lights_spot01"); s_accum_point_msaa[i].create (b_accum_point_msaa[i], "r2\\accum_point_s"); //s_accum_volume_msaa[i].create(b_accum_direct_volumetric_msaa[i], "lights\\lights_spot01"); s_accum_volume_msaa[i].create(b_accum_volumetric_msaa[i], "lights\\lights_spot01"); s_combine_msaa[i].create (b_combine_msaa[i], "r2\\combine"); } } } if( RImplementation.o.dx10_msaa ) { CBlender_msaa TempBlender; s_mark_msaa_edges.create( &TempBlender, "null" ); } // POINT { s_accum_point.create (b_accum_point, "r2\\accum_point_s"); accum_point_geom_create (); g_accum_point.create (D3DFVF_XYZ, g_accum_point_vb, g_accum_point_ib); accum_omnip_geom_create (); g_accum_omnipart.create (D3DFVF_XYZ, g_accum_omnip_vb, g_accum_omnip_ib); } // SPOT { s_accum_spot.create (b_accum_spot, "r2\\accum_spot_s", "lights\\lights_spot01"); accum_spot_geom_create (); g_accum_spot.create (D3DFVF_XYZ, g_accum_spot_vb, g_accum_spot_ib); } { s_accum_volume.create("accum_volumetric", "lights\\lights_spot01"); accum_volumetric_geom_create(); g_accum_volumetric.create( D3DFVF_XYZ, g_accum_volumetric_vb, g_accum_volumetric_ib); } // REFLECTED { s_accum_reflected.create (b_accum_reflected, "r2\\accum_refl"); if( RImplementation.o.dx10_msaa ) { int bound = RImplementation.o.dx10_msaa_samples; if( RImplementation.o.dx10_msaa_opt ) bound = 1; for( int i = 0; i < bound; ++i ) { s_accum_reflected_msaa[i].create( b_accum_reflected_msaa[i], "null"); } } } // BLOOM { D3DFORMAT fmt = D3DFMT_A8R8G8B8; //; // D3DFMT_X8R8G8B8 u32 w=BLOOM_size_X, h=BLOOM_size_Y; u32 fvf_build = D3DFVF_XYZRHW|D3DFVF_TEX4|D3DFVF_TEXCOORDSIZE2(0)|D3DFVF_TEXCOORDSIZE2(1)|D3DFVF_TEXCOORDSIZE2(2)|D3DFVF_TEXCOORDSIZE2(3); u32 fvf_filter = (u32)D3DFVF_XYZRHW|D3DFVF_TEX8|D3DFVF_TEXCOORDSIZE4(0)|D3DFVF_TEXCOORDSIZE4(1)|D3DFVF_TEXCOORDSIZE4(2)|D3DFVF_TEXCOORDSIZE4(3)|D3DFVF_TEXCOORDSIZE4(4)|D3DFVF_TEXCOORDSIZE4(5)|D3DFVF_TEXCOORDSIZE4(6)|D3DFVF_TEXCOORDSIZE4(7); rt_Bloom_1.create (r2_RT_bloom1, w,h, fmt); rt_Bloom_2.create (r2_RT_bloom2, w,h, fmt); g_bloom_build.create (fvf_build, RCache.Vertex.Buffer(), RCache.QuadIB); g_bloom_filter.create (fvf_filter, RCache.Vertex.Buffer(), RCache.QuadIB); s_bloom_dbg_1.create ("effects\\screen_set", r2_RT_bloom1); s_bloom_dbg_2.create ("effects\\screen_set", r2_RT_bloom2); s_bloom.create (b_bloom, "r2\\bloom"); if( RImplementation.o.dx10_msaa ) { s_bloom_msaa.create (b_bloom_msaa, "r2\\bloom"); s_postprocess_msaa.create(b_postprocess_msaa, "r2\\post"); } f_bloom_factor = 0.5f; } // TONEMAP { rt_LUM_64.create (r2_RT_luminance_t64, 64, 64, D3DFMT_A16B16G16R16F ); rt_LUM_8.create (r2_RT_luminance_t8, 8, 8, D3DFMT_A16B16G16R16F ); s_luminance.create (b_luminance, "r2\\luminance"); f_luminance_adapt = 0.5f; t_LUM_src.create (r2_RT_luminance_src); t_LUM_dest.create (r2_RT_luminance_cur); // create pool for (u32 it=0; it<HW.Caps.iGPUNum*2; it++) { string256 name; xr_sprintf (name,"%s_%d", r2_RT_luminance_pool,it ); rt_LUM_pool[it].create (name, 1, 1, D3DFMT_R32F ); //u_setrt (rt_LUM_pool[it], 0, 0, 0 ); //CHK_DX (HW.pDevice->Clear( 0L, NULL, D3DCLEAR_TARGET, 0x7f7f7f7f, 1.0f, 0L)); FLOAT ColorRGBA[4] = { 127.0f/255.0f, 127.0f/255.0f, 127.0f/255.0f, 127.0f/255.0f}; HW.pDevice->ClearRenderTargetView(rt_LUM_pool[it]->pRT, ColorRGBA); } u_setrt ( Device.dwWidth,Device.dwHeight,HW.pBaseRT,NULL,NULL,HW.pBaseZB); } // HBAO if (RImplementation.o.ssao_opt_data) { u32 w = 0; u32 h = 0; if (RImplementation.o.ssao_half_data) { w = Device.dwWidth / 2; h = Device.dwHeight / 2; } else { w = Device.dwWidth; h = Device.dwHeight; } D3DFORMAT fmt = HW.Caps.id_vendor==0x10DE?D3DFMT_R32F:D3DFMT_R16F; rt_half_depth.create (r2_RT_half_depth, w, h, fmt); s_ssao.create (b_ssao, "r2\\ssao"); } if (RImplementation.o.ssao_blur_on) { u32 w = Device.dwWidth, h = Device.dwHeight; rt_ssao_temp.create (r2_RT_ssao_temp, w, h, D3DFMT_G16R16F, SampleCount); s_ssao.create (b_ssao, "r2\\ssao"); if( RImplementation.o.dx10_msaa ) { int bound = RImplementation.o.dx10_msaa_opt ? 1 : RImplementation.o.dx10_msaa_samples; for( int i = 0; i < bound; ++i ) { s_ssao_msaa[i].create( b_ssao_msaa[i], "null"); } } } // COMBINE { static D3DVERTEXELEMENT9 dwDecl[] = { { 0, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 }, // pos+uv D3DDECL_END() }; s_combine.create (b_combine, "r2\\combine"); s_combine_volumetric.create ("combine_volumetric"); s_combine_dbg_0.create ("effects\\screen_set", r2_RT_smap_surf ); s_combine_dbg_1.create ("effects\\screen_set", r2_RT_luminance_t8 ); s_combine_dbg_Accumulator.create ("effects\\screen_set", r2_RT_accum ); g_combine_VP.create (dwDecl, RCache.Vertex.Buffer(), RCache.QuadIB); g_combine.create (FVF::F_TL, RCache.Vertex.Buffer(), RCache.QuadIB); g_combine_2UV.create (FVF::F_TL2uv, RCache.Vertex.Buffer(), RCache.QuadIB); g_combine_cuboid.create (dwDecl, RCache.Vertex.Buffer(), RCache.Index.Buffer()); u32 fvf_aa_blur = D3DFVF_XYZRHW|D3DFVF_TEX4|D3DFVF_TEXCOORDSIZE2(0)|D3DFVF_TEXCOORDSIZE2(1)|D3DFVF_TEXCOORDSIZE2(2)|D3DFVF_TEXCOORDSIZE2(3); g_aa_blur.create (fvf_aa_blur, RCache.Vertex.Buffer(), RCache.QuadIB); u32 fvf_aa_AA = D3DFVF_XYZRHW|D3DFVF_TEX7|D3DFVF_TEXCOORDSIZE2(0)|D3DFVF_TEXCOORDSIZE2(1)|D3DFVF_TEXCOORDSIZE2(2)|D3DFVF_TEXCOORDSIZE2(3)|D3DFVF_TEXCOORDSIZE2(4)|D3DFVF_TEXCOORDSIZE4(5)|D3DFVF_TEXCOORDSIZE4(6); g_aa_AA.create (fvf_aa_AA, RCache.Vertex.Buffer(), RCache.QuadIB); t_envmap_0.create (r2_T_envs0); t_envmap_1.create (r2_T_envs1); } // Build textures { // Testure for async sreenshots { D3D10_TEXTURE2D_DESC desc; desc.Width = Device.dwWidth; desc.Height = Device.dwHeight; desc.MipLevels = 1; desc.ArraySize = 1; desc.SampleDesc.Count = 1; desc.SampleDesc.Quality = 0; desc.Format = DXGI_FORMAT_R8G8B8A8_SNORM; desc.Usage = D3D10_USAGE_STAGING; desc.BindFlags = 0; desc.CPUAccessFlags = D3D10_CPU_ACCESS_READ; desc.MiscFlags = 0; R_CHK( HW.pDevice->CreateTexture2D(&desc, 0, &t_ss_async) ); } // Build material(s) { // Create immutable texture. // So we need to init data _before_ the creation. // Surface //R_CHK (D3DXCreateVolumeTexture(HW.pDevice,TEX_material_LdotN,TEX_material_LdotH,4,1,0,D3DFMT_A8L8,D3DPOOL_MANAGED,&t_material_surf)); //t_material = dxRenderDeviceRender::Instance().Resources->_CreateTexture(r2_material); //t_material->surface_set (t_material_surf); // Use DXGI_FORMAT_R8G8_UNORM u16 tempData[TEX_material_LdotN*TEX_material_LdotH*TEX_material_Count]; D3D10_TEXTURE3D_DESC desc; desc.Width = TEX_material_LdotN; desc.Height = TEX_material_LdotH; desc.Depth = TEX_material_Count; desc.MipLevels = 1; desc.Format = DXGI_FORMAT_R8G8_UNORM; desc.Usage = D3D10_USAGE_IMMUTABLE; desc.BindFlags = D3D10_BIND_SHADER_RESOURCE; desc.CPUAccessFlags = 0; desc.MiscFlags = 0; D3D10_SUBRESOURCE_DATA subData; subData.pSysMem = tempData; subData.SysMemPitch = desc.Width*2; subData.SysMemSlicePitch = desc.Height*subData.SysMemPitch; // Fill it (addr: x=dot(L,N),y=dot(L,H)) //D3DLOCKED_BOX R; //R_CHK (t_material_surf->LockBox (0,&R,0,0)); for (u32 slice=0; slice<TEX_material_Count; slice++) { for (u32 y=0; y<TEX_material_LdotH; y++) { for (u32 x=0; x<TEX_material_LdotN; x++) { u16* p = (u16*) (LPBYTE (subData.pSysMem) + slice*subData.SysMemSlicePitch + y*subData.SysMemPitch + x*2); float ld = float(x) / float (TEX_material_LdotN-1); float ls = float(y) / float (TEX_material_LdotH-1) + EPS_S; ls *= powf(ld,1/32.f); float fd,fs; switch (slice) { case 0: { // looks like OrenNayar fd = powf(ld,0.75f); // 0.75 fs = powf(ls,16.f)*.5f; } break; case 1: {// looks like Blinn fd = powf(ld,0.90f); // 0.90 fs = powf(ls,24.f); } break; case 2: { // looks like Phong fd = ld; // 1.0 fs = powf(ls*1.01f,128.f ); } break; case 3: { // looks like Metal float s0 = _abs (1-_abs (0.05f*_sin(33.f*ld)+ld-ls)); float s1 = _abs (1-_abs (0.05f*_cos(33.f*ld*ls)+ld-ls)); float s2 = _abs (1-_abs (ld-ls)); fd = ld; // 1.0 fs = powf (_max(_max(s0,s1),s2), 24.f); fs *= powf (ld,1/7.f); } break; default: fd = fs = 0; } s32 _d = clampr (iFloor (fd*255.5f), 0,255); s32 _s = clampr (iFloor (fs*255.5f), 0,255); if ((y==(TEX_material_LdotH-1)) && (x==(TEX_material_LdotN-1))) { _d = 255; _s=255; } *p = u16 (_s*256 + _d); } } } //R_CHK (t_material_surf->UnlockBox (0)); R_CHK(HW.pDevice->CreateTexture3D(&desc, &subData, &t_material_surf)); t_material = dxRenderDeviceRender::Instance().Resources->_CreateTexture(r2_material); t_material->surface_set (t_material_surf); //R_CHK (D3DXCreateVolumeTexture(HW.pDevice,TEX_material_LdotN,TEX_material_LdotH,4,1,0,D3DFMT_A8L8,D3DPOOL_MANAGED,&t_material_surf)); //t_material = dxRenderDeviceRender::Instance().Resources->_CreateTexture(r2_material); //t_material->surface_set (t_material_surf); // #ifdef DEBUG // R_CHK (D3DXSaveTextureToFile ("x:\\r2_material.dds",D3DXIFF_DDS,t_material_surf,0)); // #endif } // Build noise table if (1) { // Surfaces //D3DLOCKED_RECT R[TEX_jitter_count]; //for (int it=0; it<TEX_jitter_count; it++) //{ // string_path name; // xr_sprintf (name,"%s%d",r2_jitter,it); // R_CHK (D3DXCreateTexture (HW.pDevice,TEX_jitter,TEX_jitter,1,0,D3DFMT_Q8W8V8U8,D3DPOOL_MANAGED,&t_noise_surf[it])); // t_noise[it] = dxRenderDeviceRender::Instance().Resources->_CreateTexture (name); // t_noise[it]->surface_set (t_noise_surf[it]); // R_CHK (t_noise_surf[it]->LockRect (0,&R[it],0,0)); //} // Use DXGI_FORMAT_R8G8B8A8_SNORM static const int sampleSize = 4; u32 tempData[TEX_jitter_count][TEX_jitter*TEX_jitter]; D3D10_TEXTURE2D_DESC desc; desc.Width = TEX_jitter; desc.Height = TEX_jitter; desc.MipLevels = 1; desc.ArraySize = 1; desc.SampleDesc.Count = 1; desc.SampleDesc.Quality = 0; desc.Format = DXGI_FORMAT_R8G8B8A8_SNORM; //desc.Usage = D3D10_USAGE_IMMUTABLE; desc.Usage = D3D10_USAGE_DEFAULT; desc.BindFlags = D3D10_BIND_SHADER_RESOURCE; desc.CPUAccessFlags = 0; desc.MiscFlags = 0; D3D10_SUBRESOURCE_DATA subData[TEX_jitter_count]; for (int it=0; it<TEX_jitter_count-1; it++) { subData[it].pSysMem = tempData[it]; subData[it].SysMemPitch = desc.Width*sampleSize; } // Fill it, for (u32 y=0; y<TEX_jitter; y++) { for (u32 x=0; x<TEX_jitter; x++) { DWORD data [TEX_jitter_count-1]; generate_jitter (data,TEX_jitter_count-1); for (u32 it=0; it<TEX_jitter_count-1; it++) { u32* p = (u32*) (LPBYTE (subData[it].pSysMem) + y*subData[it].SysMemPitch + x*4); *p = data [it]; } } } //for (int it=0; it<TEX_jitter_count; it++) { // R_CHK (t_noise_surf[it]->UnlockRect(0)); //} for (int it=0; it<TEX_jitter_count-1; it++) { string_path name; xr_sprintf (name,"%s%d",r2_jitter,it); //R_CHK (D3DXCreateTexture (HW.pDevice,TEX_jitter,TEX_jitter,1,0,D3DFMT_Q8W8V8U8,D3DPOOL_MANAGED,&t_noise_surf[it])); R_CHK( HW.pDevice->CreateTexture2D(&desc, &subData[it], &t_noise_surf[it]) ); t_noise[it] = dxRenderDeviceRender::Instance().Resources->_CreateTexture (name); t_noise[it]->surface_set (t_noise_surf[it]); //R_CHK (t_noise_surf[it]->LockRect (0,&R[it],0,0)); } float tempDataHBAO[TEX_jitter*TEX_jitter*4]; // generate HBAO jitter texture (last) D3D10_TEXTURE2D_DESC descHBAO; descHBAO.Width = TEX_jitter; descHBAO.Height = TEX_jitter; descHBAO.MipLevels = 1; descHBAO.ArraySize = 1; descHBAO.SampleDesc.Count = 1; descHBAO.SampleDesc.Quality = 0; descHBAO.Format = DXGI_FORMAT_R32G32B32A32_FLOAT; //desc.Usage = D3D10_USAGE_IMMUTABLE; descHBAO.Usage = D3D10_USAGE_DEFAULT; descHBAO.BindFlags = D3D10_BIND_SHADER_RESOURCE; descHBAO.CPUAccessFlags = 0; descHBAO.MiscFlags = 0; it = TEX_jitter_count-1; subData[it].pSysMem = tempDataHBAO; subData[it].SysMemPitch = descHBAO.Width*sampleSize * sizeof(float); // Fill it, for (u32 y=0; y<TEX_jitter; y++) { for (u32 x=0; x<TEX_jitter; x++) { float numDir = 1.0f; switch (ps_r_ssao) { case 1: numDir = 4.0f; break; case 2: numDir = 6.0f; break; case 3: numDir = 8.0f; break; case 4: numDir = 8.0f; break; } float angle = 2 * PI * ::Random.randF(0.0f, 1.0f) / numDir; float dist = ::Random.randF(0.0f, 1.0f); float *p = (float*) (LPBYTE (subData[it].pSysMem) + y*subData[it].SysMemPitch + x*4*sizeof(float)); *p = (float)(_cos(angle)); *(p+1) = (float)(_sin(angle)); *(p+2) = (float)(dist); *(p+3) = 0; } } string_path name; xr_sprintf (name,"%s%d",r2_jitter,it); //R_CHK (D3DXCreateTexture (HW.pDevice,TEX_jitter,TEX_jitter,1,0,D3DFMT_Q8W8V8U8,D3DPOOL_MANAGED,&t_noise_surf[it])); R_CHK( HW.pDevice->CreateTexture2D(&descHBAO, &subData[it], &t_noise_surf[it]) ); t_noise[it] = dxRenderDeviceRender::Instance().Resources->_CreateTexture (name); t_noise[it]->surface_set (t_noise_surf[it]); // Create noise mipped { // Autogen mipmaps desc.MipLevels = 0; R_CHK( HW.pDevice->CreateTexture2D(&desc, 0, &t_noise_surf_mipped) ); t_noise_mipped = dxRenderDeviceRender::Instance().Resources->_CreateTexture(r2_jitter_mipped); t_noise_mipped->surface_set(t_noise_surf_mipped); // Update texture. Generate mips. HW.pDevice->CopySubresourceRegion( t_noise_surf_mipped, 0, 0, 0, 0, t_noise_surf[0], 0, 0 ); D3DX10FilterTexture(t_noise_surf_mipped, 0, D3DX10_FILTER_POINT); } } } // PP s_postprocess.create ("postprocess"); g_postprocess.create (D3DFVF_XYZRHW|D3DFVF_DIFFUSE|D3DFVF_SPECULAR|D3DFVF_TEX3,RCache.Vertex.Buffer(),RCache.QuadIB); // Menu s_menu.create ("distort"); g_menu.create (FVF::F_TL,RCache.Vertex.Buffer(),RCache.QuadIB); // dwWidth = Device.dwWidth; dwHeight = Device.dwHeight; }
void CLight_Compute_XFORM_and_VIS::compute_xf_spot (light* L) { // Build EYE-space xform Fvector L_dir,L_up,L_right,L_pos; L_dir.set (L->direction); L_dir.normalize (); if (L->right.square_magnitude()>EPS) { // use specified 'up' and 'right', just enshure ortho-normalization L_right.set (L->right); L_right.normalize (); L_up.crossproduct (L_dir,L_right); L_up.normalize (); L_right.crossproduct (L_up,L_dir); L_right.normalize (); } else { // auto find 'up' and 'right' vectors L_up.set (0,1,0); if (_abs(L_up.dotproduct(L_dir))>.99f) L_up.set(0,0,1); L_right.crossproduct (L_up,L_dir); L_right.normalize (); L_up.crossproduct (L_dir,L_right); L_up.normalize (); } L_pos.set (L->position); // int _cached_size = L->X.S.size; L->X.S.posX = L->X.S.posY = 0; L->X.S.size = SMAP_adapt_max; L->X.S.transluent = FALSE; // Compute approximate screen area (treating it as an point light) - R*R/dist_sq // Note: we clamp screen space area to ONE, although it is not correct at all float dist = Device.vCameraPosition.distance_to(L->spatial.sphere.P)-L->spatial.sphere.R; if (dist<0) dist = 0; float ssa = clampr (L->range*L->range / (1.f+dist*dist),0.f,1.f); // compute intensity float intensity0 = (L->color.r + L->color.g + L->color.b)/3.f; float intensity1 = (L->color.r * 0.2125f + L->color.g * 0.7154f + L->color.b * 0.0721f); float intensity = (intensity0+intensity1)/2.f; // intensity1 tends to underestimate... // compute how much duelling frusta occurs [-1..1]-> 1 + [-0.5 .. +0.5] float duel_dot = 1.f - 0.5f*Device.vCameraDirection.dotproduct(L_dir); // compute how large the light is - give more texels to larger lights, assume 8m as being optimal radius float sizefactor = L->range/8.f; // 4m = .5, 8m=1.f, 16m=2.f, 32m=4.f // compute how wide the light frustum is - assume 90deg as being optimal float widefactor = L->cone/deg2rad(90.f); // // factors float factor0 = powf (ssa, 1.f/2.f); // ssa is quadratic float factor1 = powf (intensity, 1.f/16.f); // less perceptually important? float factor2 = powf (duel_dot, 1.f/4.f); // difficult to fast-change this -> visible float factor3 = powf (sizefactor,1.f/4.f); // this shouldn't make much difference float factor4 = powf (widefactor,1.f/2.f); // make it linear ??? float factor = ps_r2_ls_squality * factor0 * factor1 * factor2 * factor3 * factor4; // final size calc u32 _size = iFloor( factor * SMAP_adapt_optimal ); if (_size<SMAP_adapt_min) _size = SMAP_adapt_min; if (_size>SMAP_adapt_max) _size = SMAP_adapt_max; int _epsilon = iCeil (float(_size)*0.01f); int _diff = _abs (int(_size)-int(_cached_size)); L->X.S.size = (_diff>=_epsilon)?_size:_cached_size; // make N pixel border L->X.S.view.build_camera_dir (L_pos,L_dir,L_up); //float n = 2.f ; //float x = float(L->X.S.size) ; //float alpha = L->cone/2 ; //float tan_beta = (x+2*n)*tanf(alpha) / x ; //float g_alpha = 2*rad2deg (alpha); //float g_beta = 2*rad2deg (atanf(tan_beta)); //Msg ("x(%f) : a(%f), b(%f)",x,g_alpha,g_beta); /************************************************** added by Ray Twitty (aka Shadows) START **************************************************/ // только для поинта меняем на 11.5 float tan_shift; if (L->flags.type == IRender_Light::POINT) tan_shift = deg2rad(11.5f); else tan_shift = deg2rad(3.5f); /*************************************************** added by Ray Twitty (aka Shadows) END ***************************************************/ L->X.S.project.build_projection (L->cone + tan_shift, 1.f,/*SMAP_near_plane*/L->virtual_size,L->range+EPS_S); L->X.S.combine.mul (L->X.S.project,L->X.S.view); }
IC void Dequantize(CKey& K,const CBlend& BD,const CMotion& M) { CKey* D = &K; const CBlend* B = &BD; float time = B->timeCurrent*float(SAMPLE_FPS); u32 frame = iFloor(time); float delta = time-float(frame); u32 count = M.get_count(); // rotation if (M.test_flag(flRKeyAbsent)){ const CKeyQR * K = &M._keysR[0]; QR2Quat(*K,D->Q); }else{ const CKeyQR* K1r = &M._keysR[(frame+0)%count]; const CKeyQR* K2r = &M._keysR[(frame+1)%count]; Fquaternion Q1,Q2; QR2Quat(*K1r,Q1); QR2Quat(*K2r,Q2); D->Q.slerp (Q1,Q2,clampr(delta,0.f,1.f)); } // translate if (M.test_flag(flTKeyPresent)) { const CKeyQT* K1t = &M._keysT[(frame+0)%count]; const CKeyQT* K2t = &M._keysT[(frame+1)%count]; Fvector T1,T2; QT2T(*K1t,M,T1); QT2T(*K2t,M,T2); /* T1.x = float(K1t->x)*M._sizeT.x+M._initT.x; T1.y = float(K1t->y)*M._sizeT.y+M._initT.y; T1.z = float(K1t->z)*M._sizeT.z+M._initT.z; T2.x = float(K2t->x)*M._sizeT.x+M._initT.x; T2.y = float(K2t->y)*M._sizeT.y+M._initT.y; T2.z = float(K2t->z)*M._sizeT.z+M._initT.z; */ D->T.lerp (T1,T2,delta); /* if ((_abs(D->T.y)>10000) || (_abs(D->T.x)>10000) || (_abs(D->T.z)>10000)) { Log("xxx"); Log("Blend--------"); Log("blendAmount", B->blendAmount); Log("timeCurrent", B->timeCurrent); Log("timeTotal", B->timeTotal); Log("bone_or_part", B->bone_or_part); Log("blendAccrue", B->blendAccrue); Log("blendFalloff", B->blendFalloff); Log("blendPower", B->blendPower); Log("speed", B->speed); Log("playing", B->playing); Log("stop_at_end", B->stop_at_end); Log("motionID", (u32)B->motionID.idx); Log("blend", B->blend); Log("dwFrame", B->dwFrame); Log("Device.dwFrame", Device.dwFrame); Log("Blend-------end"); Log("Bone",LL_BoneName_dbg(SelfID)); Log("parent",*parent); Msg("K1t %d,%d,%d",K1t->x,K1t->y,K1t->z); Msg("K2t %d,%d,%d",K2t->x,K2t->y,K2t->z); Log("count",count); Log("time",time); Log("frame",frame); Log("T1",T1); Log("T2",T2); Log("delta",delta); Log("Dt",D->T); VERIFY(0); } */ } //if (M.test_flag(flTKeyPresent)) else { D->T.set (M._initT); } }
IC void MixInterlerp( CKey &Result, const CKey *R, const float* BA, int b_count ) { VERIFY(MAX_BLENDED>=b_count); switch (b_count) { case 0: Result.Q.set (0,0,0,0); Result.T.set (0,0,0); break; case 1: Result = R[0]; /* if(Result.T.y>10000){ Log("1"); Log("BLEND_INST",BLEND_INST.Blend.size()); Log("Bone",LL_BoneName_dbg(SelfID)); Msg("Result.Q %f,%f,%f,%f",Result.Q.x,Result.Q.y,Result.Q.z,Result.Q.w); Log("Result.T",Result.T); VERIFY(0); } */ break; case 2: { float w0 = BA[0]; float w1 = BA[1]; float ws = w0+w1; float w; if (fis_zero(ws)) w = 0; else w = w1/ws; #ifdef DEBUG //. if (fis_zero(w0+w1) || (!_valid(w))){ //. Debug.fatal (DEBUG_INFO,"TO ALEXMX VERY IMPORTANT: (TOTAL: %f) w: %f, w0: %f, w1: %f, ws:%f, BIS: %d",w0+w1,w,w0,w1,ws,BLEND_INST.Blend.size()); //. } #endif KEY_Interp (Result,R[0],R[1], clampr(w,0.f,1.f)); /* if(Result.T.y>10000){ Log("2"); Log("BLEND_INST",BLEND_INST.Blend.size()); Log("Bone",LL_BoneName_dbg(SelfID)); Msg("Result.Q %f,%f,%f,%f",Result.Q.x,Result.Q.y,Result.Q.z,Result.Q.w); Log("Result.T",Result.T); Log("parent",*parent); VERIFY(0); } */ } break; default: { //int count = Blend.size(); float total = 0; ConsistantKey S[MAX_BLENDED]; for (int i=0; i<b_count; i++) S[i].set (R+i,BA[i]); std::sort (S,S+b_count); CKey tmp; total = S[0].w; tmp = *S[0].K; for (int cnt=1; cnt<b_count; cnt++){ total += S[cnt].w; float d; if (fis_zero(total)) d = 0.0f; else d = S[cnt].w/total; clampr(d,0.f,1.f); #ifdef DEBUG //. if ((total==0) || (!_valid(S[cnt].w/total))){ //. Debug.fatal (DEBUG_INFO,"TO ALEXMX VERY IMPORTANT: (TOTAL: %f) w: %f, total: %f, count: %d, real count: %d",total,S[cnt].w,total,count,BLEND_INST.Blend.size()); //. } #endif KEY_Interp (Result,tmp, *S[cnt].K, d ); tmp = Result; } } break; } }
void CROS_impl::update (IRenderable* O) { // clip & verify if (dwFrame==Device.dwFrame) return; dwFrame = Device.dwFrame; if (0==O) return; if (0==O->renderable.visual) return; VERIFY (dynamic_cast<CROS_impl*> (O->renderable_ROS())); float dt = Device.fTimeDelta; CObject* _object = dynamic_cast<CObject*> (O); // select sample, randomize position inside object Fvector position; O->renderable.xform.transform_tiny (position,O->renderable.visual->vis.sphere.P); float radius; radius = O->renderable.visual->vis.sphere.R; position.y += .3f * radius; Fvector direction; direction.random_dir(); //. position.mad(direction,0.25f*radius); //. position.mad(direction,0.025f*radius); // sun-tracing #if RENDER==R_R1 light* sun = (light*)RImplementation.L_DB->sun_adapted._get() ; #else light* sun = (light*)RImplementation.Lights.sun_adapted._get() ; #endif if (MODE & IRender_ObjectSpecific::TRACE_SUN) { if (--result_sun < 0) { result_sun += ::Random.randI(lt_hemisamples/4,lt_hemisamples/2) ; Fvector direction; direction.set (sun->direction).invert().normalize (); sun_value = !(g_pGameLevel->ObjectSpace.RayTest(position,direction,500.f,collide::rqtBoth,&cache_sun,_object))?1.f:0.f; } } // hemi-tracing bool bFirstTime = (0==result_count); if (MODE & IRender_ObjectSpecific::TRACE_HEMI) { for (u32 it=0; it<(u32)ps_r2_dhemi_count; it++) { // five samples per one frame u32 sample = 0 ; if (result_count<lt_hemisamples) { sample=result_count; result_count++; } else { sample=(result_iterator%lt_hemisamples); result_iterator++; } // take sample Fvector direction; direction.set (hdir[sample][0],hdir[sample][1],hdir[sample][2]).normalize (); //. result[sample] = !g_pGameLevel->ObjectSpace.RayTest(position,direction,50.f,collide::rqtBoth,&cache[sample],_object); result[sample] = !g_pGameLevel->ObjectSpace.RayTest(position,direction,50.f,collide::rqtStatic,&cache[sample],_object); // Msg ("%d:-- %s",sample,result[sample]?"true":"false"); } } // hemi & sun: update and smooth // float l_f = dt*lt_smooth; // float l_i = 1.f-l_f; int _pass = 0; for (int it=0; it<result_count; it++) if (result[it]) _pass ++; hemi_value = float (_pass)/float(result_count?result_count:1); hemi_value *= ps_r2_dhemi_scale; if (bFirstTime) hemi_smooth = hemi_value; update_smooth () ; // light-tracing BOOL bTraceLights = MODE & IRender_ObjectSpecific::TRACE_LIGHTS; if ((!O->renderable_ShadowGenerate()) && (!O->renderable_ShadowReceive())) bTraceLights = FALSE; if (bTraceLights) { // Select nearest lights Fvector bb_size = {radius,radius,radius}; g_SpatialSpace->q_box (RImplementation.lstSpatial,0,STYPE_LIGHTSOURCE,position,bb_size); for (u32 o_it=0; o_it<RImplementation.lstSpatial.size(); o_it++) { ISpatial* spatial = RImplementation.lstSpatial[o_it]; light* source = (light*) (spatial->dcast_Light()); VERIFY (source); // sanity check float R = radius+source->range; if (position.distance_to(source->position) < R) add (source); } // Trace visibility lights.clear (); float traceR = radius*.5f; for (s32 id=0; id<s32(track.size()); id++) { // remove untouched lights xr_vector<CROS_impl::Item>::iterator I = track.begin()+id; if (I->frame_touched!=Device.dwFrame) { track.erase(I) ; id-- ; continue ; } // Trace visibility Fvector P,D; float amount = 0; light* xrL = I->source; Fvector& LP = xrL->position; P.mad (position,P.random_dir(),traceR); // Random point inside range // point/spot float f = D.sub(P,LP).magnitude(); if (g_pGameLevel->ObjectSpace.RayTest(LP,D.div(f),f,collide::rqtStatic,&I->cache,_object)) amount -= lt_dec; else amount += lt_inc; I->test += amount * dt; clamp (I->test,-.5f,1.f); I->energy = .9f*I->energy + .1f*I->test; // float E = I->energy * xrL->color.intensity (); if (E > EPS) { // Select light lights.push_back (CROS_impl::Light()) ; CROS_impl::Light& L = lights.back() ; L.source = xrL ; L.color.mul_rgb (xrL->color,I->energy/2) ; L.energy = I->energy/2 ; if (!xrL->flags.bStatic) { L.color.mul_rgb(.5f); L.energy *= .5f; } } } // Sun float E = sun_smooth * sun->color.intensity (); if (E > EPS) { // Select light lights.push_back (CROS_impl::Light()) ; CROS_impl::Light& L = lights.back() ; L.source = sun ; L.color.mul_rgb (sun->color,sun_smooth/2) ; L.energy = sun_smooth ; } // Sort lights by importance - important for R1-shadows std::sort (lights.begin(),lights.end(), pred_energy); } // Process ambient lighting and approximate average lighting // Process our lights to find average luminiscense CEnvDescriptor& desc = g_pGamePersistent->Environment().CurrentEnv; Fvector accum = { desc.ambient.x, desc.ambient.y, desc.ambient.z }; Fvector hemi = { desc.hemi_color.x, desc.hemi_color.y, desc.hemi_color.z }; Fvector sun_ = { desc.sun_color.x, desc.sun_color.y, desc.sun_color.z }; if (MODE & IRender_ObjectSpecific::TRACE_HEMI ) hemi.mul(hemi_smooth); else hemi.mul(.2f); accum.add ( hemi ); if (MODE & IRender_ObjectSpecific::TRACE_SUN ) sun_.mul(sun_smooth); else sun_.mul(.2f); accum.add ( sun_ ); if (MODE & IRender_ObjectSpecific::TRACE_LIGHTS ) { Fvector lacc = { 0,0,0 }; for (u32 lit=0; lit<lights.size(); lit++) { float d = lights[lit].source->position.distance_to(position); float r = lights[lit].source->range; float a = clampr(1.f - d/(r+EPS),0.f,1.f)*(lights[lit].source->flags.bStatic?1.f:2.f); lacc.x += lights[lit].color.r*a; lacc.y += lights[lit].color.g*a; lacc.z += lights[lit].color.b*a; } // lacc.x *= desc.lmap_color.x; // lacc.y *= desc.lmap_color.y; // lacc.z *= desc.lmap_color.z; // Msg ("- rgb[%f,%f,%f]",lacc.x,lacc.y,lacc.z); accum.add (lacc); } else accum.set ( .1f, .1f, .1f ); approximate = accum; }