void Render(VoxelTexture colorTex, VoxelCameraDirection.DirectionEnum cameraDirectionMode) { Shader.SetGlobalVector(shaderConstants.PROP_VOXEL_SIZE, colorTex.ResolutionVector); cameraDirection.Direction = cameraDirectionMode; Shader.SetGlobalMatrix(shaderConstants.PROP_VOXEL_ROTATION_MAT, cameraDirection.VoxelDirection); var targetTex = RenderTexture.GetTemporary(colorTex.CurrentResolution, colorTex.CurrentResolution); try { Graphics.SetRandomWriteTarget(1, colorTex.Texture); renderCam.RenderWithShader(targetTex, voxelizer, null); Graphics.ClearRandomWriteTargets(); } finally { RenderTexture.ReleaseTemporary(targetTex); } }
public TriadVoxelizer(ComputeShaderLinker csLinker, Shader voxelizer, AbstractVoxelBounds voxelBounds, int prefferedResolution) { this.csLinker = csLinker; this.voxelizer = voxelizer; this.shaderConstants = ShaderConstants.Instance; this.cameraDirection = new VoxelCameraDirection(); this.renderCam = new ManuallyRenderCamera((cam) => cameraDirection.FitCameraToVoxelBounds(cam, voxelBounds)); this.colorTextures = new VoxelTexture[DIRECTIONS.Length]; for (var i = 0; i < colorTextures.Length; i++) { colorTextures [i] = GenerateVoxelTexture(prefferedResolution); } this.resultTex = GenerateVoxelTexture(prefferedResolution); }
private void LateUpdate() { voxelSize = Mathf.Clamp(voxelSize, 4, 64); propogationSteps = Mathf.Clamp(propogationSteps, 0, voxelSize); fluxRes = Mathf.Clamp(fluxRes, 16, 2048); if (multiplyColor) { Shader.EnableKeyword("MULTIPLY_COLOR"); Shader.DisableKeyword("MULTIPLY_COLOR_OFF"); } else { Shader.DisableKeyword("MULTIPLY_COLOR"); Shader.EnableKeyword("MULTIPLY_COLOR_OFF"); } if (on) { Shader.EnableKeyword("ENABLE_BLEED"); Shader.DisableKeyword("DISABLE_BLEED"); if (pointSample) { Shader.EnableKeyword("VOXEL_POINT_SAMPLE"); Shader.DisableKeyword("VOXEL_TRILINEAR_SAMPLE"); } else { Shader.DisableKeyword("VOXEL_POINT_SAMPLE"); Shader.EnableKeyword("VOXEL_TRILINEAR_SAMPLE"); } } else { Shader.DisableKeyword("ENABLE_BLEED"); Shader.EnableKeyword("DISABLE_BLEED"); return; } if (camera.isOrthoGraphic) { Shader.EnableKeyword("ORTHOGRAPHIC"); Shader.DisableKeyword("PERSPECTIVE"); } else { Shader.DisableKeyword("ORTHOGRAPHIC"); Shader.EnableKeyword("PERSPECTIVE"); } var lpoints = RecalculateFrustrumPoints(camera); Shader.SetGlobalVector("_LightDir", transform.forward); Shader.SetGlobalFloat("_LPVDimensions", voxelSize); Shader.SetGlobalFloat("_LPVDimensionsSquared", voxelSize * voxelSize); Shader.SetGlobalVector("_LPV_AABBMin", volumeBounds.min); Shader.SetGlobalVector("_LPV_AABBMax", volumeBounds.max); Shader.SetGlobalVector("_LPV_Extents", volumeBounds.max - volumeBounds.min); Shader.SetGlobalTexture("_VoxelTex", _voxelTexture); VoxelMaterial.SetFloat("_LightCameraNear", camera.nearClipPlane); VoxelMaterial.SetFloat("_LightCameraFar", camera.farClipPlane); VoxelMaterial.SetFloat("_NormalOffset", normalOffset); VoxelMaterial.SetFloat("_FallOff", colorStrength * 3); VoxelMaterial.SetFloat("_BlendSpeed", Time.renderedFrameCount == 1 ? 1 : blendSpeed); VoxelMaterial.SetVector("_FrustrumPoints", new Vector4( lpoints[4].x, lpoints[5].x, lpoints[5].y, lpoints[6].y)); VoxelMaterial.SetMatrix("_WorldToView", camera.worldToCameraMatrix); VoxelMaterial.SetMatrix("_ViewToWorld", camera.cameraToWorldMatrix); camera.targetTexture = AlbedoTexture; Shader.EnableKeyword("DISABLE_BLEED"); Shader.DisableKeyword("ENABLED_BLEED"); camera.Render(); Shader.DisableKeyword("DISABLE_BLEED"); Shader.EnableKeyword("ENABLED_BLEED"); VoxelMaterial.SetTexture("_MainTex", AlbedoTexture); RenderTexture depthHalf = null; RenderTexture depthQuarter = null; RenderTexture albedoHalf = null; RenderTexture albedoQuarter = null; if (downSampleRSM) { VoxelMaterial.SetFloat("_VPLMergeLimit", vplMergeLimit); albedoHalf = GetTempPointTexture(AlbedoTexture.width / 2); depthHalf = GetTempPointTexture(AlbedoTexture.width / 2); albedoQuarter = GetTempPointTexture(AlbedoTexture.width / 4); depthQuarter = GetTempPointTexture(AlbedoTexture.width / 4); RenderMRT(new RenderBuffer [] { albedoHalf.colorBuffer, depthHalf.colorBuffer }, albedoHalf.depthBuffer); RenderMRT(new RenderBuffer [] { albedoQuarter.colorBuffer, depthQuarter.colorBuffer }, albedoQuarter.depthBuffer); VoxelMaterial.SetTexture("_MainTex", albedoQuarter); VoxelMaterial.SetTexture("_CameraDepthNormalsTextureManual", depthQuarter); Shader.EnableKeyword("DEPTH_TEXTURE_MANUAL"); Shader.DisableKeyword("DEPTH_TEXTURE_UNITY"); } else { Shader.DisableKeyword("DEPTH_TEXTURE_MANUAL"); Shader.EnableKeyword("DEPTH_TEXTURE_UNITY"); } Shader.EnableKeyword("SAMPLE_COLOR"); Shader.DisableKeyword("SAMPLE_NORMAL"); RenderTexture.active = VoxelTexture; GL.Clear(false, true, Color.black); RenderVolume(VoxelMaterial, 0, voxelSize); RenderTexture.active = null; var blurBuffer = RenderTexture.GetTemporary(voxelSize * voxelSize, voxelSize, 0); for (int k = 0; k < propogationSteps; k++) { Graphics.Blit(VoxelTexture, blurBuffer, VoxelMaterial, 1); VoxelTexture.DiscardContents(); Graphics.Blit(blurBuffer, VoxelTexture, VoxelMaterial, 2); blurBuffer.DiscardContents(); Graphics.Blit(VoxelTexture, blurBuffer, VoxelMaterial, 3); VoxelTexture.DiscardContents(); Graphics.Blit(blurBuffer, VoxelTexture); blurBuffer.DiscardContents(); } RenderTexture.ReleaseTemporary(blurBuffer); if (Application.isPlaying) { Shader.EnableKeyword("FRAME_BLEND"); Shader.DisableKeyword("FRAME_BLEND_DISABLED"); VoxelMaterial.SetTexture("_PrevTex", PrevTexture); var temp = RenderTexture.GetTemporary(voxelSize * voxelSize, voxelSize, 0); Graphics.Blit(VoxelTexture, temp, VoxelMaterial, 4); Graphics.Blit(temp, VoxelTexture); Graphics.Blit(temp, PrevTexture); RenderTexture.ReleaseTemporary(temp); } else { Shader.DisableKeyword("FRAME_BLEND"); Shader.EnableKeyword("FRAME_BLEND_DISABLED"); } if (downSampleRSM) { RenderTexture.ReleaseTemporary(depthHalf); RenderTexture.ReleaseTemporary(depthQuarter); RenderTexture.ReleaseTemporary(albedoHalf); RenderTexture.ReleaseTemporary(albedoQuarter); } }
void OnEnable() { resultTex = new VoxelTexture(0, RenderTextureFormat.ARGBHalf, FilterMode.Point, TextureWrapMode.Clamp, RenderTextureReadWrite.Linear); }
public static int n = 16; // Number of cells in one row of the texture atlas public static ChunkMeshObject BuildChunk(Chunk c) { List <Vector3> verts = new List <Vector3> (); List <int> tris = new List <int> (); List <Vector2> uvs = new List <Vector2> (); float oneNth = 1f / (float)n; for (int i = 0; i < c.voxels.GetLength(0); i++) { for (int j = 0; j < c.voxels.GetLength(1); j++) { for (int k = 0; k < c.voxels.GetLength(2); k++) { List <int> openFaces = c.voxels[i, j, k].GetOpenFaces(); int id = c.voxels[i, j, k].id; VoxelTexture v = World.instance.textureScriptable.texturePositions[id]; for (int l = 0; l < openFaces.Count; l++) { int si = verts.Count; // Start index for the triangles switch (openFaces[l]) { case 0: // Bottom verts.Add(new Vector3(i, j, k)); verts.Add(new Vector3(i + 1, j, k)); verts.Add(new Vector3(i, j, k + 1)); verts.Add(new Vector3(i + 1, j, k + 1)); uvs.Add(new Vector2((v.bottom.x + 1) / 16f, v.bottom.y / 16f)); uvs.Add(new Vector2((v.bottom.x + 1) / 16f, (v.bottom.y + 1) / 16f)); uvs.Add(new Vector2(v.bottom.x / 16f, v.bottom.y / 16f)); uvs.Add(new Vector2(v.bottom.x / 16f, (v.bottom.y + 1) / 16f)); tris.Add(si + 0); tris.Add(si + 1); tris.Add(si + 3); tris.Add(si + 0); tris.Add(si + 3); tris.Add(si + 2); break; case 1: // Top verts.Add(new Vector3(i, j + 1, k)); verts.Add(new Vector3(i, j + 1, k + 1)); verts.Add(new Vector3(i + 1, j + 1, k)); verts.Add(new Vector3(i + 1, j + 1, k + 1)); uvs.Add(new Vector2((v.top.x) / 16f, (v.top.y) / 16f)); uvs.Add(new Vector2((v.top.x) / 16f, (v.top.y + 1) / 16f)); uvs.Add(new Vector2((v.top.x + 1) / 16f, (v.top.y) / 16f)); uvs.Add(new Vector2((v.top.x + 1) / 16f, (v.top.y + 1) / 16f)); tris.Add(si + 0); tris.Add(si + 1); tris.Add(si + 3); tris.Add(si + 0); tris.Add(si + 3); tris.Add(si + 2); break; case 2: // Left verts.Add(new Vector3(i, j, k)); verts.Add(new Vector3(i, j, k + 1)); verts.Add(new Vector3(i, j + 1, k)); verts.Add(new Vector3(i, j + 1, k + 1)); uvs.Add(new Vector2((v.left.x + 1) / 16f, v.left.y / 16f)); uvs.Add(new Vector2(v.left.x / 16f, v.left.y / 16f)); uvs.Add(new Vector2((v.left.x + 1) / 16f, (v.left.y + 1) / 16f)); uvs.Add(new Vector2(v.left.x / 16f, (v.left.y + 1) / 16f)); tris.Add(si + 0); tris.Add(si + 1); tris.Add(si + 3); tris.Add(si + 0); tris.Add(si + 3); tris.Add(si + 2); break; case 3: // Right verts.Add(new Vector3(i + 1, j, k)); verts.Add(new Vector3(i + 1, j + 1, k)); verts.Add(new Vector3(i + 1, j, k + 1)); verts.Add(new Vector3(i + 1, j + 1, k + 1)); uvs.Add(new Vector2(v.right.x / 16f, v.right.y / 16f)); uvs.Add(new Vector2(v.right.x / 16f, (v.right.y + 1) / 16f)); uvs.Add(new Vector2((v.right.x + 1) / 16f, v.right.y / 16f)); uvs.Add(new Vector2((v.right.x + 1) / 16f, (v.right.y + 1) / 16f)); tris.Add(si + 0); tris.Add(si + 1); tris.Add(si + 3); tris.Add(si + 0); tris.Add(si + 3); tris.Add(si + 2); break; case 4: // Back verts.Add(new Vector3(i, j, k)); verts.Add(new Vector3(i, j + 1, k)); verts.Add(new Vector3(i + 1, j, k)); verts.Add(new Vector3(i + 1, j + 1, k)); uvs.Add(new Vector2(v.back.x / 16f, v.back.y / 16f)); uvs.Add(new Vector2(v.back.x / 16f, (v.back.y + 1) / 16f)); uvs.Add(new Vector2((v.back.x + 1) / 16f, v.back.y / 16f)); uvs.Add(new Vector2((v.back.x + 1) / 16f, (v.back.y + 1) / 16f)); tris.Add(si + 0); tris.Add(si + 1); tris.Add(si + 3); tris.Add(si + 0); tris.Add(si + 3); tris.Add(si + 2); break; case 5: // Front verts.Add(new Vector3(i, j, k + 1)); verts.Add(new Vector3(i + 1, j, k + 1)); verts.Add(new Vector3(i, j + 1, k + 1)); verts.Add(new Vector3(i + 1, j + 1, k + 1)); uvs.Add(new Vector2((v.front.x + 1) / 16f, v.front.y / 16f)); uvs.Add(new Vector2(v.front.x / 16f, v.front.y / 16f)); uvs.Add(new Vector2((v.front.x + 1) / 16f, (v.front.y + 1) / 16f)); uvs.Add(new Vector2(v.front.x / 16f, (v.front.y + 1) / 16f)); tris.Add(si + 0); tris.Add(si + 1); tris.Add(si + 3); tris.Add(si + 0); tris.Add(si + 3); tris.Add(si + 2); break; } } } } } return(new ChunkMeshObject(verts, tris, uvs)); }