/// <summary> /// BRDFで使用するLUTを生成する(UE4方式) /// </summary> public static Texture CreateBRDFLookUpTable(GraphicsContext context, int w, int h) { var tex = new Texture(new Texture.InitDesc { bindFlag = TextureBuffer.BindFlag.IsRenderTarget, width = w, height = h, format = SlimDX.DXGI.Format.R16G16_Float, }); Lib.Rect rect = new Lib.Rect(new Vector3(-1.0f, 1.0f, 0.0f), new Vector3(1.0f, -1.0f, 0.0f)); var prim = new Prim("GenerateBRDF_LUT", (uint)Shader.VertexAttr.TEXCOORD0); prim.AddRect(ref rect); prim.GetMaterial().DepthState = RenderState.DepthState.None; GraphicsCore.FrameBuffer frameBuffer = new GraphicsCore.FrameBuffer(); frameBuffer.color_buffer_ = new Texture[1] { tex }; context.SetRenderTargets(frameBuffer.color_buffer_, null); prim.Draw(context); prim.Dispose(); return(tex); }
/// <summary> /// PBR用プレフィルタキューブマップを作成する /// </summary> /// <param name="output"></param> /// <param name="source"></param> public static void PrefilterRadiance(Texture output, Texture source) { Lib.Rect rect = new Lib.Rect(new Vector3(-1.0f, 1.0f, 0.0f), new Vector3(1.0f, -1.0f, 0.0f)); var prim = new Prim("PrefilterRadianceMap", (uint)Shader.VertexAttr.TEXCOORD0); prim.AddRect(ref rect); prim.GetMaterial().DepthState = RenderState.DepthState.None; prim.GetMaterial().SetShaderViewPS(0, source); int miplevel = 1; int size = source.Width; while (size > 1) { size = size >> 1; miplevel++; } // テクスチャを再生成 output.Dispose(); output.Initialize(new Texture.InitDesc() { bindFlag = TextureBuffer.BindFlag.IsRenderTarget, optionFlags = ResourceOptionFlags.TextureCube, width = source.Width, height = source.Height, mips = miplevel, format = SlimDX.DXGI.Format.R16G16B16A16_Float, }); GraphicsCore.FrameBuffer frameBuffer = new GraphicsCore.FrameBuffer(); frameBuffer.color_buffer_ = new Texture[1] { output }; frameBuffer.is_array_buffer_ = true; // 描画 for (int m = 0; m < miplevel; m++) { for (int i = 0; i < 6; i++) { // コンスタントバッファ Shader.SetConstantBufferUpdateFunc("CB_PrefilterCubeMap", (s, inst) => { dynamic cb = inst; cb.g_face = (float)i; cb.g_mipLevel = (float)m; cb.g_maxMipLevel = (float)miplevel; return(true); }); frameBuffer.array_buffer_index_ = m * 6 + i; // TODO: //GraphicsCore.BeginRender(frameBuffer); //prim.Draw(); //GraphicsCore.EndRender(); } } prim.Dispose(); }
/// <summary> /// /// </summary> public ShadowMap(int width, int height, Type type = Type.VSM) { type_ = type; shaderName_ = new string[] { "ConstructVSM", "ConstructEVSM" }; bufferFormat_ = new Format[] { Format.R16G16_Float, Format.R16G16B16A16_Float }; shadowMap_ = new Texture(new Texture.InitDesc { width = width, height = height, format = Format.R32_Typeless, bindFlag = TextureBuffer.BindFlag.IsDepthStencil, }); blurMap_ = new Texture[2]; for (int i = 0; i < blurMap_.Length; i++) { Texture.InitDesc desc = new Texture.InitDesc() { width = width / 2, height = height / 2, format = bufferFormat_[(int)type_], bindFlag = TextureBuffer.BindFlag.IsRenderTarget, }; blurMap_[i] = new Texture(desc); } frameBuffer_ = new GraphicsCore.FrameBuffer() { color_buffer_ = new Texture[0], depth_stencil_ = shadowMap_, }; blurFrameBuffer_ = new GraphicsCore.FrameBuffer() { color_buffer_ = new Texture[1], depth_stencil_ = null, }; Lib.Rect rect = new Lib.Rect(new Vector3(-1.0f, 1.0f, 0.0f), new Vector3(1.0f, -1.0f, 0.0f)); blurPrim_ = new Prim(shaderName_[(int)type_], (uint)Shader.VertexAttr.TEXCOORD0); blurPrim_.AddRect(ref rect); blurPrim_.GetMaterial().DepthState = RenderState.DepthState.None; camera_ = new Camera(); camera_.InitializeOrtho(new Vector3(0, 100, 0), new Vector3(0, 0, 0), new Vector3(0, 0, 1), 100, 100, 1, 100); shadowCastShader_ = ShaderManager.FindShader("DrawShadowMap", (uint)(Shader.VertexAttr.POSITION)); shadowMapDrawShaderFunc_ = (o) => { return(shadowCastShader_); }; }
/// <summary> /// /// </summary> public DepthOperation(int w, int h) { ConstructTexture(w, h); linearizeShader_ = ShaderManager.FindShader("LinearizeDepth", (uint)Shader.VertexAttr.TEXCOORD0); halfLinearizeShader_ = ShaderManager.FindShader("Downsample2x2LinealizeDepth", (uint)Shader.VertexAttr.TEXCOORD0); Shader.SetConstantBufferUpdateFunc("DepthParam", (s, i) => { dynamic cb = i; cb.g_ReprojectDepthScale = param_.g_ReprojectDepthScale; cb.g_ReprojectDepthBias = param_.g_ReprojectDepthBias; return(true); }); frameBuffer_ = new GraphicsCore.FrameBuffer(); }
/// <summary> /// キューブマップにレンダリング /// </summary> public static void RenderingCubeMap(GraphicsContext context, Texture cubemap, Texture depth, Vector3 position, Action sceneDrawFunc) { GraphicsCore.FrameBuffer frameBuffer = new GraphicsCore.FrameBuffer() { color_buffer_ = new Texture[1] { cubemap }, depth_stencil_ = depth, is_array_buffer_ = true, }; Camera backupCamera = GraphicsCore.CurrentDrawCamera; Camera camera = new Camera(); // 右手対応のためx反転している Matrix projection = Matrix.PerspectiveFovRH((float)System.Math.PI / 2.0f, 1.0f, 0.1f, 1000.0f) * Matrix.Scaling(-1, 1, 1); Matrix view = Matrix.LookAtRH(position, Vector3.Zero, Vector3.UnitZ); camera.InitializeExternal(view, projection); GraphicsCore.CurrentDrawCamera = camera; GraphicsCore.SetRasterizerState(RenderState.RasterizerState.CullFront); // 各面をレンダリング for (int i = 0; i < 6; ++i) { Vector3 lookAt = new Vector3(); Vector3 upVec = new Vector3(); switch (i) { case 0: lookAt = new Vector3(1.0f, 0.0f, 0.0f); upVec = new Vector3(0.0f, 1.0f, 0.0f); break; case 1: lookAt = new Vector3(-1.0f, 0.0f, 0.0f); upVec = new Vector3(0.0f, 1.0f, 0.0f); break; case 2: lookAt = new Vector3(0.0f, 1.0f, 0.0f); upVec = new Vector3(0.0f, 0.0f, -1.0f); break; case 3: lookAt = new Vector3(0.0f, -1.0f, 0.0f); upVec = new Vector3(0.0f, 0.0f, 1.0f); break; case 4: lookAt = new Vector3(0.0f, 0.0f, 1.0f); upVec = new Vector3(0.0f, 1.0f, 0.0f); break; case 5: lookAt = new Vector3(0.0f, 0.0f, -1.0f); upVec = new Vector3(0.0f, 1.0f, 0.0f); break; } frameBuffer.array_buffer_index_ = i; view = Matrix.LookAtRH(position, position + lookAt, upVec); camera.SetViewMatrix(ref view); camera.Update(); // TODO:要対応 //GraphicsCore.BeginRender(frameBuffer); //sceneDrawFunc(); //GraphicsCore.EndRender(); } GraphicsCore.CurrentDrawCamera = backupCamera; GraphicsCore.SetRasterizerState(RenderState.RasterizerState.CullBack); }
/// <summary> /// /// </summary> public ToneMap() { // サイズによってテクスチャを作り替える、ということをしたくないので // FullHD想定でテクスチャを作成しておく int w = 1920; int h = 1080; avgBuffer_ = new Texture[6]; var desc = new Texture.InitDesc() { bindFlag = TextureBuffer.BindFlag.IsRenderTarget, width = w / 4, height = h / 4, format = SlimDX.DXGI.Format.R16_Float, }; avgBuffer_[0] = new Texture(desc); desc.width = w / 16; desc.height = h / 16; avgBuffer_[1] = new Texture(desc); desc.width = w / 32; desc.height = h / 32; avgBuffer_[2] = new Texture(desc); desc.width = w / 64; desc.height = h / 64; avgBuffer_[3] = new Texture(desc); desc.width = w / 128; desc.height = h / 128; avgBuffer_[4] = new Texture(desc); desc.width = w / 256; desc.height = h / 256; avgBuffer_[5] = new Texture(desc); frameBuffer_ = new GraphicsCore.FrameBuffer() { color_buffer_ = new Texture[1], depth_stencil_ = null, }; var uavDesc_ = new Texture.InitDesc { bindFlag = TextureBuffer.BindFlag.IsUnorderedAccess | TextureBuffer.BindFlag.IsRenderTarget, width = 1, height = 1, format = SlimDX.DXGI.Format.R32_Float, // RWとして使うためには32bitにする必要がある }; luminanceAvg_ = new Texture(uavDesc_); Lib.Rect rect = new Lib.Rect(new Vector3(-1.0f, 1.0f, 0.0f), new Vector3(1.0f, -1.0f, 0.0f)); prim_ = new Prim("Downsample4x4CalcLuminance", (uint)Shader.VertexAttr.TEXCOORD0); prim_.AddRect(ref rect); prim_.GetMaterial().DepthState = RenderState.DepthState.None; downSample4Lum_ = ShaderManager.FindShader("Downsample4x4CalcLuminance", (uint)Shader.VertexAttr.TEXCOORD0); downSample4_ = ShaderManager.FindShader("Downsample4x4Luminance", (uint)Shader.VertexAttr.TEXCOORD0); downSample2_ = ShaderManager.FindShader("Downsample2x2Luminance", (uint)Shader.VertexAttr.TEXCOORD0); toneMap_ = ShaderManager.FindShader("ToneMap", (uint)Shader.VertexAttr.TEXCOORD0); resolveGamma_ = ShaderManager.FindShader("ResolveGamma", (uint)Shader.VertexAttr.TEXCOORD0); ComputeShader.InitDesc shaderDesc = new ComputeShader.InitDesc { file_name = "asset/shader/ToneMap.fx", id = 0, is_byte_code = false, main = "FinalCalculateAverageLuminance", }; lumResolveShader_ = new ComputeShader(shaderDesc); lumResolveShader_.SetUAVs(new Texture[] { luminanceAvg_ }); lumResolveShader_.SetResources(new Texture[] { avgBuffer_[5] }); initBuffer_ = false; KeyValue = 0.2f; Shader.SetConstantBufferUpdateFunc("CB_ToneMap", (s, i) => { dynamic cb = i; if (cb.g_keyValue != KeyValue) { cb.g_keyValue = KeyValue; return(true); } return(false); }); }