/// <summary> /// /// </summary> /// <param name="gameTime"></param> public void RenderRadiance() { var sw = new Stopwatch(); Log.Message("Radiance capture..."); sw.Start(); using (new PixEvent("Capture Radiance")) { var sun = SkySettings.SunGlowIntensity; SkySettings.SunGlowIntensity = 0; int index = 0; foreach (var envLight in LightSet.EnvLights) { for (int i = 0; i < 6; i++) { ClearBuffers(radianceFrame); var camera = new Camera(); camera.SetupCameraCubeFace(envLight.Position, (CubeFace)i, 0.125f, 5000); // render g-buffer : rs.SceneRenderer.RenderGBuffer(new GameTime(0, 0, 0), StereoEye.Mono, camera, radianceFrame, this, true); // render sky : rs.Sky.Render(camera, StereoEye.Mono, radianceFrame, SkySettings); // render lights : rs.LightRenderer.RenderLighting(StereoEye.Mono, camera, radianceFrame, this, rs.Sky.SkyCube); // downsample captured frame to cube face. rs.Filter.StretchRect4x4(Radiance.GetSurface(0, (CubeFace)i), radianceFrame.HdrBuffer, SamplerState.LinearClamp, true); } // prefilter cubemap : rs.Filter.PrefilterEnvMap(Radiance); RadianceCache.CopyFromRenderTargetCube(index, Radiance); index++; } sw.Stop(); SkySettings.SunGlowIntensity = sun; } Log.Message("{0} light probes - {1} ms", LightSet.EnvLights.Count, sw.ElapsedMilliseconds); }
/// <summary> /// /// </summary> /// <param name="dst"></param> /// <param name="cubeSrc"></param> /// <param name="sampleCount"></param> public void PrefilterEnvMap(RenderTargetCube envMap) { SetDefaultRenderStates(); int width = envMap.Width / 2; int height = envMap.Height / 2; using (new PixEvent("PrefilterEnvMap")) { var sides = new[] { ShaderFlags.PREFILTER_ENVMAP | ShaderFlags.POSX, ShaderFlags.PREFILTER_ENVMAP | ShaderFlags.NEGX, ShaderFlags.PREFILTER_ENVMAP | ShaderFlags.POSY, ShaderFlags.PREFILTER_ENVMAP | ShaderFlags.NEGY, ShaderFlags.PREFILTER_ENVMAP | ShaderFlags.POSZ, ShaderFlags.PREFILTER_ENVMAP | ShaderFlags.NEGZ }; // loop through mip levels from second to last specular mip level : for (int mip = 1; mip < RenderSystem.EnvMapSpecularMipCount; mip++) { float roughness = (float)mip / (float)(RenderSystem.EnvMapSpecularMipCount - 1); float step = 1.0f / width; vectorCB.SetData(new Vector4(roughness, step, 0, 0)); for (int face = 0; face < 6; face++) { device.SetTargets(null, envMap.GetSurface(mip, (CubeFace)face)); device.SetViewport(0, 0, width, height); device.PixelShaderConstants[0] = vectorCB; device.PipelineState = factory[(int)sides[face]]; device.VertexShaderResources[0] = envMap.GetCubeShaderResource(mip - 1); device.PixelShaderResources[0] = envMap.GetCubeShaderResource(mip - 1); device.PixelShaderSamplers[0] = SamplerState.LinearWrap; device.VertexShaderConstants[0] = matrixCB; device.Draw(3, 0); } width /= 2; height /= 2; } } device.ResetStates(); }