void EffectTranslucency::Render( float _Time, float _DeltaTime ) { float3 TorusPosition = float3( 0.8f * sinf( _TV(0.95f) * _Time ) * sinf( _TV(0.7f) * _Time ), 0.8f * sinf( _TV(0.83f) * _Time ) * sinf( _TV(-0.19f) * _Time ), 0.2f * cosf( _TV(0.5f) * _Time ) * sinf( _TV(-0.17f) * _Time ) ); // Oscillate within the quiche float4 TorusRotation = float4::QuatFromAngleAxis( _TV(1.35f) * _Time, float3::UnitY ); // Rotate, too m_EmissivePower = SATURATE( -4.0f * sinf( _TV(0.5f) * _Time ) ); float4 SphereNoise = float4( _Time * 0.2f * float3( 1.0f, -0.5f, 0.9f ), 0.2f ); float4 TorusNoise = float4( _Time * 0.2f * float3( 1.0f, -0.5f, 0.9f ), 0.0f ); ////////////////////////////////////////////////////////////////////////// // 1] Render the internal & external objects into the RGBA ZBuffer gs_Device.ClearRenderTarget( *m_pRTZBuffer, float4( 2.0f, 0.0f, 2.0f, 0.0f ) ); gs_Device.SetRenderTarget( *m_pRTZBuffer, m_pDepthStencil ); { USING_MATERIAL_START( *m_pMatBuildZBuffer ) // === Render external object === m_pCB_Object->m.Local2World.PRS( float3::Zero, float4::QuatFromAngleAxis( 0.0f, float3::UnitY ), float3::One ); m_pCB_Object->m.NoiseOffset = SphereNoise; m_pCB_Object->UpdateData(); // Front gs_Device.ClearDepthStencil( *m_pDepthStencil, 1.0f, 0 ); gs_Device.SetStates( gs_Device.m_pRS_CullBack, gs_Device.m_pDS_ReadWriteLess, gs_Device.m_pBS_Disabled_RedOnly ); m_pPrimSphereExternal->Render( *m_pMatBuildZBuffer ); // Back gs_Device.ClearDepthStencil( *m_pDepthStencil, 0.0f, 0 ); gs_Device.SetStates( gs_Device.m_pRS_CullFront, gs_Device.m_pDS_ReadWriteGreater, gs_Device.m_pBS_Disabled_GreenOnly ); m_pPrimSphereExternal->Render( *m_pMatBuildZBuffer ); // === Render rotating internal object === m_pCB_Object->m.Local2World.PRS( TorusPosition, TorusRotation, float3::One ); m_pCB_Object->m.NoiseOffset = TorusNoise; m_pCB_Object->UpdateData(); // Front gs_Device.ClearDepthStencil( *m_pDepthStencil, 1.0f, 0 ); gs_Device.SetStates( gs_Device.m_pRS_CullBack, gs_Device.m_pDS_ReadWriteLess, gs_Device.m_pBS_Disabled_BlueOnly ); m_pPrimTorusInternal->Render( *m_pMatBuildZBuffer ); // Back gs_Device.ClearDepthStencil( *m_pDepthStencil, 0.0f, 0 ); gs_Device.SetStates( gs_Device.m_pRS_CullFront, gs_Device.m_pDS_ReadWriteGreater, gs_Device.m_pBS_Disabled_AlphaOnly ); m_pPrimTorusInternal->Render( *m_pMatBuildZBuffer ); USING_MATERIAL_END } ////////////////////////////////////////////////////////////////////////// // 2] Render the irradiance map ? // LATER... Not sure it's necessary ////////////////////////////////////////////////////////////////////////// // 3] Perform diffusion gs_Device.SetStates( gs_Device.m_pRS_CullNone, gs_Device.m_pDS_Disabled, gs_Device.m_pBS_Disabled ); { USING_MATERIAL_START( *m_pMatDiffusion ) // Clear original irradiance map gs_Device.ClearRenderTarget( *m_ppRTDiffusion[0], float4( 0.0f, 0.0f, 0.0f, 0.0f ) ); // Setup our global diffusion parameters float BBoxSize = _TV(0.002f); // Size of the BBox containing our objects, in meter m_pCB_Diffusion->m.BBoxSize = BBoxSize; m_pCB_Diffusion->m.SliceThickness = BBoxSize / DIFFUSION_PASSES_COUNT; // Size of a single slice m_pCB_Diffusion->m.TexelSize = BBoxSize / DIFFUSION_SIZE; // Size of a single texel m_pCB_Diffusion->m.ExtinctionCoeff = _TV(1000.0f) * float3( 0.8f, 0.85f, 1.0f ); m_pCB_Diffusion->m.Albedo = _TV(0.8f) * float3::One; float3 ScatteringAnisotropy = _TV(0.0f) * float3::One; float PhaseFactor = _TV(4.6f); m_pCB_Diffusion->m.Phase0 = PhaseFactor * ComputePhase( ScatteringAnisotropy, 0, 1, m_pCB_Diffusion->m.TexelSize, m_pCB_Diffusion->m.SliceThickness ); m_pCB_Diffusion->m.Phase1 = PhaseFactor * ComputePhase( ScatteringAnisotropy, 1, 8, m_pCB_Diffusion->m.TexelSize, m_pCB_Diffusion->m.SliceThickness ); m_pCB_Diffusion->m.Phase2 = PhaseFactor * ComputePhase( ScatteringAnisotropy, 2, 12, m_pCB_Diffusion->m.TexelSize, m_pCB_Diffusion->m.SliceThickness ); // m_pCB_Diffusion->m.ExternalLight = _TV(2.0f) * NjFloat3( 1.0f, 1.0f, 1.0f ); m_pCB_Diffusion->m.ExternalLight = _TV(1.4f) * (1.4f - m_EmissivePower) * float3( 1.0f, 1.0f, 1.0f ); m_pCB_Diffusion->m.InternalEmissive = _TV(10.0f) * m_EmissivePower * float3( 1.0f, 0.8f, 0.2f ); m_pCB_Diffusion->UpdateData(); gs_Device.SetRenderTarget( gs_Device.DefaultRenderTarget(), NULL ); m_pRTZBuffer->SetPS( 10 ); // Diffuse light through multiple passes for ( int PassIndex=0; PassIndex <= DIFFUSION_PASSES_COUNT; PassIndex++ ) { gs_Device.SetRenderTarget( *m_ppRTDiffusion[1] ); m_pCB_Pass->m.PassIndex = float(PassIndex); m_pCB_Pass->m.CurrentZ = 2.0f * PassIndex / DIFFUSION_PASSES_COUNT; m_pCB_Pass->m.NextZ = 2.0f * (PassIndex+1) / DIFFUSION_PASSES_COUNT; m_pCB_Pass->UpdateData(); m_ppRTDiffusion[0]->SetPS( 11 ); gs_pPrimQuad->Render( *m_pMatDiffusion ); // Swap irradiance maps Texture2D* pTemp = m_ppRTDiffusion[0]; m_ppRTDiffusion[0] = m_ppRTDiffusion[1]; m_ppRTDiffusion[1] = pTemp; } USING_MATERIAL_END } ////////////////////////////////////////////////////////////////////////// // 4] Finally, render the object with a planar mapping of the irradiance map { USING_MATERIAL_START( *m_pMatDisplay ) gs_Device.SetRenderTarget( m_RTTarget, &gs_Device.DefaultDepthStencil() ); gs_Device.SetStates( gs_Device.m_pRS_CullBack, gs_Device.m_pDS_ReadWriteLess, NULL ); m_ppRTDiffusion[0]->SetPS( 10 ); // Render the sphere m_pCB_Object->m.Local2World.PRS( float3( 0, 1, 0 ), float4::QuatFromAngleAxis( _TV(0.0f) * _Time, float3::UnitY ), float3::One ); m_pCB_Object->m.EmissiveColor = float4::Zero; m_pCB_Object->m.NoiseOffset = SphereNoise; m_pCB_Object->UpdateData(); m_pPrimSphereExternal->Render( *m_pMatDisplay ); // Render the torus m_pCB_Object->m.Local2World.PRS( float3( 0, 1, 0 ) + TorusPosition, TorusRotation, float3::One ); m_pCB_Object->m.EmissiveColor = float4( 0.0f * float3::One + m_pCB_Diffusion->m.InternalEmissive, 1.0f ); m_pCB_Object->m.NoiseOffset = TorusNoise; m_pCB_Object->UpdateData(); m_pPrimTorusInternal->Render( *m_pMatDisplay ); USING_MATERIAL_END } }
void EffectParticles::Render( float _Time, float _DeltaTime ) { ////////////////////////////////////////////////////////////////////////// // 1] Update particles' positions { USING_MATERIAL_START( *m_pMatCompute ) ID3D11RenderTargetView* ppRenderTargets[3] = { m_ppRTParticlePositions[2]->GetTargetView( 0, 0, 1 ), m_ppRTParticleNormals[1]->GetTargetView( 0, 0, 1 ), m_ppRTParticleTangents[1]->GetTargetView( 0, 0, 1 ) }; gs_Device.SetRenderTargets( m_ppRTParticlePositions[2]->GetWidth(), m_ppRTParticlePositions[2]->GetHeight(), 3, ppRenderTargets ); gs_Device.SetStates( gs_Device.m_pRS_CullNone, gs_Device.m_pDS_Disabled, gs_Device.m_pBS_Disabled ); m_pCB_Render->m.dUV = m_ppRTParticlePositions[2]->GetdUV(); m_pCB_Render->m.DeltaTime.x = 10.0f * _DeltaTime; m_pCB_Render->UpdateData(); m_ppRTParticlePositions[0]->SetPS( 10 ); m_ppRTParticlePositions[1]->SetPS( 11 ); m_ppRTParticleNormals[0]->SetPS( 12 ); m_ppRTParticleTangents[0]->SetPS( 13 ); gs_pPrimQuad->Render( *m_pMatCompute ); // Scroll positions for integration next frame Texture2D* pTemp = m_ppRTParticlePositions[0]; m_ppRTParticlePositions[0] = m_ppRTParticlePositions[1]; m_ppRTParticlePositions[1] = m_ppRTParticlePositions[2]; m_ppRTParticlePositions[2] = pTemp; // Swap normals & tangents pTemp = m_ppRTParticleNormals[0]; m_ppRTParticleNormals[0] = m_ppRTParticleNormals[1]; m_ppRTParticleNormals[1] = pTemp; pTemp = m_ppRTParticleTangents[0]; m_ppRTParticleTangents[0] = m_ppRTParticleTangents[1]; m_ppRTParticleTangents[1] = pTemp; // Keep delta time for next time m_pCB_Render->m.DeltaTime.y = 1.0f;//_DeltaTime; USING_MATERIAL_END } ////////////////////////////////////////////////////////////////////////// // 2] Render the particles { USING_MATERIAL_START( *m_pMatDisplay ) gs_Device.SetRenderTarget( gs_Device.DefaultRenderTarget(), &gs_Device.DefaultDepthStencil() ); gs_Device.SetStates( gs_Device.m_pRS_CullNone, gs_Device.m_pDS_ReadWriteLess, gs_Device.m_pBS_Disabled ); m_ppRTParticlePositions[1]->SetVS( 10 ); m_ppRTParticleNormals[0]->SetVS( 11 ); m_ppRTParticleTangents[0]->SetVS( 12 ); m_pTexVoronoi->SetPS( 13 ); // m_pPrimParticle->RenderInstanced( *m_pMatDisplay, EFFECT_PARTICLES_COUNT*EFFECT_PARTICLES_COUNT ); m_pPrimParticle->Render( *m_pMatDisplay ); USING_MATERIAL_END } // DEBUG { USING_MATERIAL_START( *m_pMatDebugVoronoi ) D3D11_VIEWPORT Vp = { 0, // FLOAT TopLeftX; 0, // FLOAT TopLeftY; 0.2f * RESX, // FLOAT Width; 0.2f * RESX, // FLOAT Height; 0, // FLOAT MinDepth; 1, // FLOAT MaxDepth; }; gs_Device.SetRenderTarget( gs_Device.DefaultRenderTarget(), &gs_Device.DefaultDepthStencil(), &Vp ); gs_Device.SetStates( gs_Device.m_pRS_CullNone, gs_Device.m_pDS_Disabled, gs_Device.m_pBS_Disabled ); m_pTexVoronoi->SetPS( 10 ); gs_pPrimQuad->Render( *m_pMatDebugVoronoi ); USING_MATERIAL_END } // DEBUG }