//private void OnRenderImage(RenderTexture source, RenderTexture destination) //{ // Graphics.Blit(source, destination,material); //} private void UpdateCommand() { var cam = camera; if (!cam) { return; } CmdBufferEntry buf = new CmdBufferEntry(); if (m_Cameras.ContainsKey(cam)) { // use existing command buffers: clear them buf = m_Cameras[cam]; buf.m_AfterScene.Clear(); } else { buf.m_AfterScene = new CommandBuffer(); buf.m_AfterScene.name = "DrawOutline"; m_Cameras[cam] = buf; cam.AddCommandBuffer(CameraEvent.AfterForwardOpaque, buf.m_AfterScene); } //outLineComputeShader.SetTexture(outLineComputeShader.FindKernel("CSMain"), "_OutlineTexture", m_OutlineTexture); //outLineComputeShader.SetTextureFromGlobal( // outLineComputeShader.FindKernel("CSMain"), // Shader.PropertyToID("_DepthTexture"), // Shader.PropertyToID("_DepthTexture")); int x = (int)(Screen.width / 10 + 0.5); int y = (int)(Screen.height / 10 + 0.5); //outLineComputeShader.Dispatch(outLineComputeShader.FindKernel("CSMain"), x, y, 1); var cb = buf.m_AfterScene; cb.Clear(); cb.SetGlobalTexture("_OutlineTexture", m_OutlineTexture); cb.SetGlobalTexture("_DepthTexture", cameraManager.GetDepthRTID()); cb.DispatchCompute(outLineComputeShader, outLineComputeShader.FindKernel("CSMain"), x, y, 1); cb.SetRenderTarget(cameraManager.GetColorRTID(), cameraManager.GetDepthRTID()); cb.DrawProcedural(Matrix4x4.identity, material, 0, MeshTopology.Triangles, 3); }
public void Update() { var act = gameObject.activeInHierarchy && enabled; if (!act) { OnDisable(); return; } var cam = Camera.current; if (!cam) { return; } // create material used to render lights if (!m_LightMaterial) { m_LightMaterial = new Material(m_LightShader); m_LightMaterial.hideFlags = HideFlags.HideAndDontSave; } CmdBufferEntry buf = new CmdBufferEntry(); if (m_Cameras.ContainsKey(cam)) { // use existing command buffers: clear them buf = m_Cameras[cam]; buf.m_AfterLighting.Clear(); buf.m_BeforeAlpha.Clear(); } else { // create new command buffers buf.m_AfterLighting = new CommandBuffer(); buf.m_AfterLighting.name = "Deferred custom lights"; buf.m_BeforeAlpha = new CommandBuffer(); buf.m_BeforeAlpha.name = "Draw light shapes"; m_Cameras[cam] = buf; cam.AddCommandBuffer(CameraEvent.AfterLighting, buf.m_AfterLighting); cam.AddCommandBuffer(CameraEvent.BeforeForwardAlpha, buf.m_BeforeAlpha); } //@TODO: in a real system should cull lights, and possibly only // recreate the command buffer when something has changed. var system = CustomLightSystem.instance; var propParams = Shader.PropertyToID("_CustomLightParams"); var propColor = Shader.PropertyToID("_CustomLightColor"); Vector4 param = Vector4.zero; Matrix4x4 trs = Matrix4x4.identity; // construct command buffer to draw lights and compute illumination on the scene foreach (var o in system.m_Lights) { // light parameters we'll use in the shader param.x = o.m_TubeLength; param.y = o.m_Size; param.z = 1.0f / (o.m_Range * o.m_Range); param.w = (float)o.m_Kind; buf.m_AfterLighting.SetGlobalVector(propParams, param); // light color buf.m_AfterLighting.SetGlobalColor(propColor, o.GetLinearColor()); // draw sphere that covers light area, with shader // pass that computes illumination on the scene trs = Matrix4x4.TRS(o.transform.position, o.transform.rotation, new Vector3(o.m_Range * 2, o.m_Range * 2, o.m_Range * 2)); buf.m_AfterLighting.DrawMesh(m_SphereMesh, trs, m_LightMaterial, 0, 0); } // construct buffer to draw light shapes themselves as simple objects in the scene /*foreach (var o in system.m_Lights) * { * // light color * buf.m_BeforeAlpha.SetGlobalColor (propColor, o.GetLinearColor()); * * // draw light "shape" itself as a small sphere/tube * if (o.m_Kind == CustomLight.Kind.Sphere) * { * trs = Matrix4x4.TRS(o.transform.position, o.transform.rotation, new Vector3(o.m_Size*2,o.m_Size*2,o.m_Size*2)); * buf.m_BeforeAlpha.DrawMesh (m_SphereMesh, trs, m_LightMaterial, 0, 1); * } * else if (o.m_Kind == CustomLight.Kind.Tube) * { * trs = Matrix4x4.TRS(o.transform.position, o.transform.rotation, new Vector3(o.m_TubeLength*2,o.m_Size*2,o.m_Size*2)); * buf.m_BeforeAlpha.DrawMesh (m_CubeMesh, trs, m_LightMaterial, 0, 1); * } * } */ }
public void Update() { var act = gameObject.activeInHierarchy && enabled; if (!act) { OnDisable(); return; } var cam = Camera.current; if (!cam) { return; } // create material used to render lights if (!m_CubeMaterial) { m_CubeMaterial = new Material(m_CubeShader); m_CubeMaterial.hideFlags = HideFlags.HideAndDontSave; } CmdBufferEntry buf = new CmdBufferEntry(); if (m_Cameras.ContainsKey(cam)) { // use existing command buffers: clear them buf = m_Cameras[cam]; buf.m_AfterLighting.Clear(); buf.m_BeforeAlpha.Clear(); } else { // create new command buffers buf.m_AfterLighting = new CommandBuffer(); buf.m_AfterLighting.name = "Deferred custom cubemaps"; buf.m_BeforeAlpha = new CommandBuffer(); buf.m_BeforeAlpha.name = "Draw cubet shapes"; m_Cameras[cam] = buf; cam.AddCommandBuffer(CameraEvent.AfterLighting, buf.m_AfterLighting); cam.AddCommandBuffer(CameraEvent.BeforeForwardAlpha, buf.m_BeforeAlpha); } //@TODO: in a real system should cull lights, and possibly only // recreate the command buffer when something has changed. var system = CustomCubemapEngine.instance; //var propParams = Shader.PropertyToID("_cubemapParams"); var propColor = Shader.PropertyToID("_customCubeTexture"); var propHDR = Shader.PropertyToID("_customCubeHDR"); var propPos = Shader.PropertyToID("_customCubePosition"); var propMin = Shader.PropertyToID("_customCubeMin"); var propMax = Shader.PropertyToID("_customCubeMax"); var propRot = Shader.PropertyToID("_customCubeRotation"); Vector4 param = Vector4.zero; Vector4 pos = Vector4.zero; Vector4 min = Vector4.zero; Vector4 max = Vector4.zero; Matrix4x4 trs = Matrix4x4.identity; // construct command buffer to draw lights and compute illumination on the scene foreach (var o in system.m_Cubes) { // light parameters we'll use in the shader /*param.x = o.m_TubeLength; * param.y = o.m_Size; * param.z = 1.0f / (o.m_Range * o.m_Range); * param.w = (float)o.m_Kind; * buf.m_AfterLighting.SetGlobalVector(propParams, param);*/ pos = o.cube.bounds.center; pos.w = o.cube.blendDistance; min = o.cube.bounds.min; max = o.cube.bounds.max; //buf.m_AfterLighting.SetGlobalVector(propParams, param); buf.m_AfterLighting.SetGlobalVector(propPos, pos); buf.m_AfterLighting.SetGlobalVector(propMin, min); buf.m_AfterLighting.SetGlobalVector(propMax, max); buf.m_AfterLighting.EnableShaderKeyword("UNITY_SPECCUBE_BOX_PROJECTION"); buf.m_AfterLighting.SetGlobalVector(propHDR, o.cube.textureHDRDecodeValues); buf.m_AfterLighting.SetGlobalTexture(propColor, o.cube.texture); buf.m_AfterLighting.SetGlobalVector(propRot, o.transform.forward); // draw sphere that covers light area, with shader // pass that computes illumination on the scene //trs = Matrix4x4.TRS(o.transform.position, o.transform.rotation, new Vector3(o.m_Range * 2, o.m_Range * 2, o.m_Range * 2)); Vector3 bounds = o.cube.bounds.size; bounds.x += o.cube.blendDistance * 2; bounds.y += o.cube.blendDistance * 2; bounds.z += o.cube.blendDistance * 2; trs = Matrix4x4.TRS(o.cube.bounds.center, Quaternion.identity, bounds); buf.m_AfterLighting.DrawMesh(m_Mesh, trs, m_CubeMaterial, 0, 0); } // construct buffer to draw light shapes themselves as simple objects in the scene /*foreach (var o in system.m_Lights) * { * // light color * buf.m_BeforeAlpha.SetGlobalColor (propColor, o.GetLinearColor()); * * // draw light "shape" itself as a small sphere/tube * if (o.m_Kind == CustomLight.Kind.Sphere) * { * trs = Matrix4x4.TRS(o.transform.position, o.transform.rotation, new Vector3(o.m_Size*2,o.m_Size*2,o.m_Size*2)); * buf.m_BeforeAlpha.DrawMesh (m_SphereMesh, trs, m_LightMaterial, 0, 1); * } * else if (o.m_Kind == CustomLight.Kind.Tube) * { * trs = Matrix4x4.TRS(o.transform.position, o.transform.rotation, new Vector3(o.m_TubeLength*2,o.m_Size*2,o.m_Size*2)); * buf.m_BeforeAlpha.DrawMesh (m_CubeMesh, trs, m_LightMaterial, 0, 1); * } * } */ }
/// <summary> /// 如果对象可见,则为每个相机调用一次此函数 /// </summary> private void OnWillRenderObject() { var act = gameObject.activeInHierarchy && enabled; if (!act) { OnDisable(); return; } var cam = Camera.current; if (!cam) { return; } if (!lightMaterial) { lightMaterial = new Material(lightShader) { hideFlags = HideFlags.HideAndDontSave }; } CmdBufferEntry buf = new CmdBufferEntry(); if (cameras.ContainsKey(cam)) {//如果存在 清除之前写的命令 buf = cameras[cam]; buf.afterLighting.Clear(); buf.beforeAlpha.Clear(); } else { buf.afterLighting = new CommandBuffer { name = "Deferred Custom Lights" }; buf.beforeAlpha = new CommandBuffer { name = "Draw light Shapes" }; cameras[cam] = buf; cam.AddCommandBuffer(CameraEvent.AfterLighting, buf.afterLighting); cam.AddCommandBuffer(CameraEvent.BeforeForwardAlpha, buf.beforeAlpha); } //TODO:在一个真正的系统中,应该剔除灯光,而且可能只有在发生更改时重新创建命令缓冲区 var system = CustomLightSystem.Instance; Vector4 param = Vector4.zero; Matrix4x4 trs = Matrix4x4.identity; foreach (var item in system.lights) { param.x = item.tubeLength; param.y = item.size; param.z = 1.0f / (item.range * item.range); param.w = (float)item.type; buf.afterLighting.SetGlobalColor(propParams, param); buf.afterLighting.SetGlobalColor(propColor, item.GetLinearColor()); trs = Matrix4x4.TRS(item.transform.position, item.transform.rotation, Vector3.one * item.range * 2); buf.afterLighting.DrawMesh(sphereMesh, trs, lightMaterial, 0, 0); } foreach (var item in system.lights) { buf.beforeAlpha.SetGlobalColor(propColor, item.GetLinearColor()); if (item.type == CustomLight.Kind.Sphere) { trs = Matrix4x4.TRS(item.transform.position, item.transform.rotation, Vector3.one * item.size * 2); buf.beforeAlpha.DrawMesh(sphereMesh, trs, lightMaterial, 0, 1); } else if (item.type == CustomLight.Kind.Tube) { trs = Matrix4x4.TRS(item.transform.position, item.transform.rotation, new Vector3(item.tubeLength * 2, item.size * 2, item.size * 2)); buf.beforeAlpha.DrawMesh(cubeMesh, trs, lightMaterial, 0, 1); } } }
public void OnWillRenderObject() { var act = gameObject.activeInHierarchy && enabled; if (!act) { OnDisable(); return; } var cam = Camera.current; if (!cam) { return; } // 创建光照材质 if (!m_LightMaterial) { m_LightMaterial = new Material(m_LightShader); m_LightMaterial.hideFlags = HideFlags.HideAndDontSave; } CmdBufferEntry buf = new CmdBufferEntry(); if (m_Cameras.ContainsKey(cam)) { // use existing command buffers: clear them // 如果已经存在这个命令,清除掉。 buf = m_Cameras[cam]; buf.m_AfterLighting.Clear(); buf.m_BeforeAlpha.Clear(); } else { // create new command buffers // 创建新的命令缓冲 buf.m_AfterLighting = new CommandBuffer(); buf.m_AfterLighting.name = "Deferred custom lights"; buf.m_BeforeAlpha = new CommandBuffer(); buf.m_BeforeAlpha.name = "Draw light shapes"; m_Cameras[cam] = buf; cam.AddCommandBuffer(CameraEvent.AfterLighting, buf.m_AfterLighting); cam.AddCommandBuffer(CameraEvent.BeforeForwardAlpha, buf.m_BeforeAlpha); } //@TODO: in a real system should cull lights, and possibly only // recreate the command buffer when something has changed. // 需要做的:在真实系统中需要剔除灯光,在一些变换出现时,需要重新创建命令缓冲 var system = CustomLightSystem.instance; var propParams = Shader.PropertyToID("_CustomLightParams"); var propColor = Shader.PropertyToID("_CustomLightColor"); var propShapeAlpha = Shader.PropertyToID("_CustomShapeAlpha"); Vector4 param = Vector4.zero; Matrix4x4 trs = Matrix4x4.identity; // construct command buffer to draw lights and compute illumination on the scene // 添加光照参数,绘制轮廓 foreach (var o in system.m_Lights) { // light parameters we'll use in the shader // x:灯光长度,y:光照大小,z:半径二次幂的倒数,w:灯光类型 param.x = o.m_TubeLength; param.y = o.m_Size; param.z = 1.0f / (o.m_Range * o.m_Range); param.w = (float)o.m_Kind; buf.m_AfterLighting.SetGlobalVector(propParams, param); buf.m_AfterLighting.SetGlobalColor(propColor, o.GetLinearColor()); // 设置光照颜色 // 计算场景位置,绘制光照区域球体。 // draw sphere that covers light area, with shader // pass that computes illumination on the scene trs = Matrix4x4.TRS(o.transform.position, o.transform.rotation, new Vector3(o.m_Range * 2, o.m_Range * 2, o.m_Range * 2)); buf.m_AfterLighting.DrawMesh(m_SphereMesh, trs, m_LightMaterial, 0, 0); } // construct buffer to draw light shapes themselves as simple objects in the scene // 绘制光照形状 foreach (var o in system.m_Lights) { buf.m_BeforeAlpha.SetGlobalColor(propColor, o.GetLinearColor()); buf.m_BeforeAlpha.SetGlobalFloat(propShapeAlpha, o.m_ShapeAlpha); if (o.m_Kind == CustomLight.Kind.Sphere) { trs = Matrix4x4.TRS(o.transform.position, o.transform.rotation, new Vector3(o.m_Size * 2, o.m_Size * 2, o.m_Size * 2)); buf.m_BeforeAlpha.DrawMesh(m_SphereMesh, trs, m_LightMaterial, 0, 1); } else if (o.m_Kind == CustomLight.Kind.Tube) { trs = Matrix4x4.TRS(o.transform.position, o.transform.rotation, new Vector3(o.m_TubeLength * 2, o.m_Size * 2, o.m_Size * 2)); buf.m_BeforeAlpha.DrawMesh(m_CubeMesh, trs, m_LightMaterial, 0, 1); } } }
public void OnWillRenderObject() { var act = gameObject.activeInHierarchy && enabled; if (!act) { OnDisable(); return; } var cam = Camera.current; if (!cam) return; // create material used to render lights if (!m_LightMaterial) { m_LightMaterial = new Material(m_LightShader); m_LightMaterial.hideFlags = HideFlags.HideAndDontSave; } CmdBufferEntry buf = new CmdBufferEntry(); if (m_Cameras.ContainsKey(cam)) { // use existing command buffers: clear them buf = m_Cameras[cam]; buf.m_AfterLighting.Clear (); buf.m_BeforeAlpha.Clear (); } else { // create new command buffers buf.m_AfterLighting = new CommandBuffer(); buf.m_AfterLighting.name = "Deferred custom lights"; buf.m_BeforeAlpha = new CommandBuffer(); buf.m_BeforeAlpha.name = "Draw light shapes"; m_Cameras[cam] = buf; cam.AddCommandBuffer (CameraEvent.AfterLighting, buf.m_AfterLighting); cam.AddCommandBuffer (CameraEvent.BeforeForwardAlpha, buf.m_BeforeAlpha); } //@TODO: in a real system should cull lights, and possibly only // recreate the command buffer when something has changed. var system = CustomLightSystem.instance; var propParams = Shader.PropertyToID("_CustomLightParams"); var propColor = Shader.PropertyToID("_CustomLightColor"); Vector4 param = Vector4.zero; Matrix4x4 trs = Matrix4x4.identity; // construct command buffer to draw lights and compute illumination on the scene foreach (var o in system.m_Lights) { // light parameters we'll use in the shader param.x = o.m_TubeLength; param.y = o.m_Size; param.z = 1.0f / (o.m_Range * o.m_Range); param.w = (float)o.m_Kind; buf.m_AfterLighting.SetGlobalVector (propParams, param); // light color buf.m_AfterLighting.SetGlobalColor (propColor, o.GetLinearColor()); // draw sphere that covers light area, with shader // pass that computes illumination on the scene trs = Matrix4x4.TRS(o.transform.position, o.transform.rotation, new Vector3(o.m_Range*2,o.m_Range*2,o.m_Range*2)); buf.m_AfterLighting.DrawMesh (m_SphereMesh, trs, m_LightMaterial, 0, 0); } // construct buffer to draw light shapes themselves as simple objects in the scene foreach (var o in system.m_Lights) { // light color buf.m_BeforeAlpha.SetGlobalColor (propColor, o.GetLinearColor()); // draw light "shape" itself as a small sphere/tube if (o.m_Kind == CustomLight.Kind.Sphere) { trs = Matrix4x4.TRS(o.transform.position, o.transform.rotation, new Vector3(o.m_Size*2,o.m_Size*2,o.m_Size*2)); buf.m_BeforeAlpha.DrawMesh (m_SphereMesh, trs, m_LightMaterial, 0, 1); } else if (o.m_Kind == CustomLight.Kind.Tube) { trs = Matrix4x4.TRS(o.transform.position, o.transform.rotation, new Vector3(o.m_TubeLength*2,o.m_Size*2,o.m_Size*2)); buf.m_BeforeAlpha.DrawMesh (m_CubeMesh, trs, m_LightMaterial, 0, 1); } } }
private void UpdateCommand() { var cam = _mainCamera; if (!cam) { return; } CmdBufferEntry buf = new CmdBufferEntry(); if (m_Cameras.ContainsKey(cam)) { // use existing command buffers: clear them buf = m_Cameras[cam]; buf.m_AfterScene.Clear(); } else { buf.m_AfterScene = new CommandBuffer(); buf.m_AfterScene.name = "DrawOutline"; m_Cameras[cam] = buf; cam.AddCommandBuffer(CameraEvent.AfterForwardOpaque, buf.m_AfterScene); } //outLineComputeShader.SetTexture(outLineComputeShader.FindKernel("CSMain"), "_OutlineTexture", m_OutlineTexture); //outLineComputeShader.SetTextureFromGlobal( // outLineComputeShader.FindKernel("CSMain"), // Shader.PropertyToID("_DepthTexture"), // Shader.PropertyToID("_DepthTexture")); int x = (int)(Screen.width / 10 + 0.5); int y = (int)(Screen.height / 10 + 0.5); //outLineComputeShader.Dispatch(outLineComputeShader.FindKernel("CSMain"), x, y, 1); var cb = buf.m_AfterScene; cb.Clear(); cb.SetGlobalTexture("_OutlineTexture", m_OutlineTexture); cb.SetGlobalTexture("_DepthTexture", GetDepthRTID()); int computeKenel = outLineComputeShader.FindKernel("CSMain"); cb.SetComputeVectorParam(outLineComputeShader, Shader.PropertyToID("cb1_65"), new Vector4(0, 0, 0.1f, 0)); cb.SetComputeVectorParam(outLineComputeShader, Shader.PropertyToID("cb0_data1"), new Vector4(-1, 1, -1, 1)); cb.SetComputeVectorParam(outLineComputeShader, Shader.PropertyToID("cb0_data2"), new Vector4(0, 0, -2, 2)); cb.SetComputeVectorParam(outLineComputeShader, Shader.PropertyToID("cb0_data3"), new Vector4(1, 1, -1, -1)); cb.SetComputeVectorParam(outLineComputeShader, Shader.PropertyToID("cb0_data4"), new Vector4(2, -2, 0, 0)); cb.SetComputeVectorParam(outLineComputeShader, Shader.PropertyToID("cb0_data10"), new Vector4(65000, 0, 2, 1)); cb.SetComputeVectorParam(outLineComputeShader, Shader.PropertyToID("unknownParam0"), new Vector4(0, 0, 0, 0)); Vector4 scparam = new Vector4(Screen.width, Screen.height, 1.0f / (float)Screen.width, 1.0f / (float)Screen.height); cb.SetComputeVectorParam(outLineComputeShader, Shader.PropertyToID("screenSizeParam"), scparam); cb.SetComputeTextureParam(outLineComputeShader, computeKenel, Shader.PropertyToID("_DepthTexture"), GetDepthRTID()); cb.SetComputeTextureParam(outLineComputeShader, computeKenel, Shader.PropertyToID("_OutlineTexture"), m_OutlineTexture); //cb //cb.SetComputeVectorParam(outLineComputeShader, Shader.PropertyToID("screenSize"), // new Vector4(Screen.width, Screen.height, 1.0f / Screen.width, 1.0f / Screen.height)); cb.DispatchCompute(outLineComputeShader, computeKenel, x, y, 1); //cb.SetRenderTarget(GetColorRTID(), GetDepthRTID()); //cb.DrawProcedural(Matrix4x4.identity, material, 0, MeshTopology.Triangles, 3); cb.SetGlobalVector("_FilterValue", new Vector4(1500, 10000, 0.9f, 0.374f)); cb.Blit(m_OutlineTexture, GetColorRTID(), material); }