protected override void Update() { base.Update(); if (maskReader == null) { maskReader = new P3dReader(); maskReader.OnComplete += HandleCompleteMask; } if (maskReader.Requested == false && registeredPaintableTexture != null && registeredPaintableTexture.Activated == true) { if (P3dReader.NeedsUpdating(maskReader, maskPixels, registeredPaintableTexture.Current, downsampleSteps) == true || maskDirty == true) { maskDirty = false; var desc = registeredPaintableTexture.Current.descriptor; desc.useMipMap = false; var renderTexture = P3dHelper.GetRenderTexture(desc); if (maskTexture != null) { P3dBlit.Texture(renderTexture, P3dHelper.GetQuadMesh(), 0, maskTexture, P3dCoord.First); } else { P3dBlit.White(renderTexture, maskMesh, 0, registeredPaintableTexture.Coord); } // Request new mask maskReader.Request(renderTexture, DownsampleSteps, Async); P3dHelper.ReleaseRenderTexture(renderTexture); } } maskReader.UpdateRequest(); }
public void Paint(P3dCommand command, List <P3dWindowPaintable> paintables) { var commandMaterial = command.Material; //if (bounds.Intersects(lastBounds) == true) { for (var i = PaintableTextures.Count - 1; i >= 0; i--) { var paintableTexture = PaintableTextures[i]; var renderTexture = paintableTexture.PreparePaint(); // Prepare the paint regardless, to sync undo states if (P3dHelper.IndexInMask(paintableTexture.Group, command.Groups) == true) { var oldActive = RenderTexture.active; var swap = default(RenderTexture); RenderTexture.active = renderTexture; if (true) // TODO { swap = P3dHelper.GetRenderTexture(renderTexture.width, renderTexture.height, renderTexture.depth, renderTexture.format); P3dHelper.Blit(swap, renderTexture); commandMaterial.SetTexture(P3dShader._Buffer, swap); } command.Apply(); if (command.RequireMesh == true) { for (var j = paintables.Count - 1; j >= 0; j--) { var otherP = paintables[j]; for (var k = otherP.PaintableTextures.Count - 1; k >= 0; k--) { var otherT = otherP.PaintableTextures[k]; if (otherT.OldTexture == paintableTexture.OldTexture) { switch (otherT.Channel) { case P3dChannel.UV: commandMaterial.SetVector(P3dShader._Channel, new Vector4(1.0f, 0.0f, 0.0f, 0.0f)); break; case P3dChannel.UV2: commandMaterial.SetVector(P3dShader._Channel, new Vector4(0.0f, 1.0f, 0.0f, 0.0f)); break; case P3dChannel.UV3: commandMaterial.SetVector(P3dShader._Channel, new Vector4(0.0f, 0.0f, 1.0f, 0.0f)); break; case P3dChannel.UV4: commandMaterial.SetVector(P3dShader._Channel, new Vector4(0.0f, 0.0f, 0.0f, 1.0f)); break; } commandMaterial.SetPass(0); Graphics.DrawMeshNow(otherP.lastMesh, otherP.lastMatrix, otherT.MaterialIndex); } } } } else { Graphics.Blit(default(Texture), renderTexture, commandMaterial); } RenderTexture.active = oldActive; if (swap != null) { P3dHelper.ReleaseRenderTexture(swap); } } } } }
/// <summary>This allows you to manually execute all commands in the paint stack. /// This is useful if you need to modify the state of your object before the end of the frame.</summary> public void ExecuteCommands(bool sendNotifications) { if (activated == true) { var hidePreview = true; if (CommandsPending == true) { var oldActive = RenderTexture.active; var swap = P3dHelper.GetRenderTexture(current.width, current.height, current.depth, current.format); var preparedMesh = default(Mesh); var preparedMatrix = default(Matrix4x4); swap.DiscardContents(); Graphics.Blit(current, swap); // Paint if (paintCommands.Count > 0) { ExecuteCommands(paintCommands, sendNotifications, ref current, ref swap, ref preparedMesh, ref preparedMatrix); } // Preview if (previewCommands.Count > 0) { if (previewSet == false) { preview = P3dHelper.GetRenderTexture(current.width, current.height, current.depth, current.format); previewSet = true; } hidePreview = false; preview.DiscardContents(); Graphics.Blit(current, preview); ExecuteCommands(previewCommands, sendNotifications, ref preview, ref swap, ref preparedMesh, ref preparedMatrix); } P3dHelper.ReleaseRenderTexture(swap); RenderTexture.active = oldActive; } if (hidePreview == true && previewSet == true) { P3dHelper.ReleaseRenderTexture(preview); preview = null; previewSet = false; } if (materialSet == false) { UpdateMaterial(); } material.SetTexture(slot.Name, previewSet == true ? preview : current); } }
private void BakeOverlap() { var desc = new RenderTextureDescriptor(1024, 1024, RenderTextureFormat.ARGB32, 0); var renderTexture = P3dHelper.GetRenderTexture(desc); if (overlapMaterial == null) { overlapMaterial = P3dShader.BuildMaterial("Hidden/Paint in 3D/Overlap"); } overlapMaterial.SetVector(P3dShader._Coord, P3dHelper.IndexToVector(coord)); var oldActive = RenderTexture.active; RenderTexture.active = renderTexture; GL.Clear(true, true, Color.black); overlapMaterial.SetPass(0); Graphics.DrawMeshNow(mesh, Matrix4x4.identity, submesh); foreach (var obj in Selection.objects) { var otherMesh = obj as Mesh; if (otherMesh != null && otherMesh != mesh) { Graphics.DrawMeshNow(otherMesh, Matrix4x4.identity, submesh); } } RenderTexture.active = oldActive; overlapTex = P3dHelper.GetReadableCopy(renderTexture); P3dHelper.ReleaseRenderTexture(renderTexture); var utilizationCount = 0; var overlapCount = 0; for (var y = 0; y < overlapTex.height; y++) { for (var x = 0; x < overlapTex.width; x++) { var pixel = overlapTex.GetPixel(x, y); if (pixel.r > 0.0f) { if (pixel.r > 1.5 / 255.0f) { pixel = Color.red; overlapCount += 1; } else { pixel = Color.gray; } utilizationCount += 1; overlapTex.SetPixel(x, y, pixel); } } } var total = overlapTex.width * overlapTex.height * 0.01f; utilizationPercent = utilizationCount / total; overlapPercent = overlapCount / total; overlapTex.Apply(); }
/// <summary>This allows you to manually execute all commands in the paint stack. /// This is useful if you need to modify the state of your object before the end of the frame.</summary> public void ExecuteCommands(bool sendNotifications) { if (activated == true) { var commandCount = commands.Count; var swap = default(RenderTexture); var swapSet = false; // Revert snapshot if (previewSet == true) { P3dHelper.ReleaseRenderTexture(preview); previewSet = false; } if (commandCount > 0) { var oldActive = RenderTexture.active; var preparedMesh = default(Mesh); var preparedMatrix = default(Matrix4x4); RenderTexture.active = current; for (var i = 0; i < commandCount; i++) { var command = commands[i]; var commandMaterial = command.Material; if (command.Preview != previewSet) { // Skip sending notifications for the first command, because if this is a preview and the previous frame ended with a preview then this would otherwise get triggered if (sendNotifications == true && i > 0) { NotifyOnModified(previewSet); } if (previewSet == true) { P3dHelper.ReleaseRenderTexture(preview); previewSet = false; RenderTexture.active = current; } else { preview = P3dHelper.GetRenderTexture(current.width, current.height, current.depth, current.format); previewSet = true; P3dHelper.Blit(preview, current); RenderTexture.active = preview; } } if (command.Swap == true) { if (swapSet == false) { swap = P3dHelper.GetRenderTexture(current.width, current.height, current.depth, current.format); swapSet = true; } RenderTexture.active = swap; if (previewSet == true) { swap = preview; preview = RenderTexture.active; } else { swap = current; current = RenderTexture.active; } command.Material.SetTexture(P3dShader._Buffer, swap); } command.Apply(); if (command.RequireMesh == true) { command.Model.GetPrepared(ref preparedMesh, ref preparedMatrix); switch (channel) { case P3dChannel.UV: commandMaterial.SetVector(P3dShader._Channel, new Vector4(1.0f, 0.0f, 0.0f, 0.0f)); break; case P3dChannel.UV2: commandMaterial.SetVector(P3dShader._Channel, new Vector4(0.0f, 1.0f, 0.0f, 0.0f)); break; case P3dChannel.UV3: commandMaterial.SetVector(P3dShader._Channel, new Vector4(0.0f, 0.0f, 1.0f, 0.0f)); break; case P3dChannel.UV4: commandMaterial.SetVector(P3dShader._Channel, new Vector4(0.0f, 0.0f, 0.0f, 1.0f)); break; } commandMaterial.SetPass(0); Graphics.DrawMeshNow(preparedMesh, preparedMatrix, slot.Index); } else { if (previewSet == true) { Graphics.Blit(default(Texture), preview, commandMaterial); } else { Graphics.Blit(default(Texture), current, commandMaterial); } } command.Pool(); } RenderTexture.active = oldActive; commands.Clear(); } if (swapSet == true) { P3dHelper.ReleaseRenderTexture(swap); swapSet = false; } if (sendNotifications == true && commandCount > 0) { NotifyOnModified(previewSet); } if (materialSet == false) { UpdateMaterial(); } if (previewSet == true) { material.SetTexture(slot.Name, preview); } else { material.SetTexture(slot.Name, current); } } }
public void Paint(P3dGroup group, P3dCommand command) { var commandMaterial = command.Material; //if (bounds.Intersects(lastBounds) == true) { for (var i = PaintableTextures.Count - 1; i >= 0; i--) { var paintableTexture = PaintableTextures[i]; var renderTexture = paintableTexture.PreparePaint(); // Prepare the paint regardless, to sync undo states if (paintableTexture.Group == group) { var oldActive = RenderTexture.active; var swap = default(RenderTexture); RenderTexture.active = renderTexture; if (command.RequireSwap == true) { swap = P3dHelper.GetRenderTexture(renderTexture.width, renderTexture.height, renderTexture.depth, renderTexture.format); P3dHelper.Blit(swap, renderTexture); commandMaterial.SetTexture(P3dShader._Buffer, swap); } command.Apply(); if (command.RequireMesh == true) { switch (paintableTexture.Channel) { case P3dChannel.UV: commandMaterial.SetVector(P3dShader._Channel, new Vector4(1.0f, 0.0f, 0.0f, 0.0f)); break; case P3dChannel.UV2: commandMaterial.SetVector(P3dShader._Channel, new Vector4(0.0f, 1.0f, 0.0f, 0.0f)); break; case P3dChannel.UV3: commandMaterial.SetVector(P3dShader._Channel, new Vector4(0.0f, 0.0f, 1.0f, 0.0f)); break; case P3dChannel.UV4: commandMaterial.SetVector(P3dShader._Channel, new Vector4(0.0f, 0.0f, 0.0f, 1.0f)); break; } commandMaterial.SetPass(0); Graphics.DrawMeshNow(lastMesh, lastMatrix, paintableTexture.MaterialIndex); } else { Graphics.Blit(default(Texture), renderTexture, commandMaterial); } RenderTexture.active = oldActive; if (swap != null) { P3dHelper.ReleaseRenderTexture(swap); } } } } }
private void UpdatePaintedMats() { // Mark foreach (var mat in scene.Mats) { foreach (var slot in mat.Slots) { slot.Dirty = true; } } /* * if (mat.Template != null) * { * foreach (var slot in mat.Template.Slots) * { * if (paintedGroups.Contains(slot.WriteR.SourceGroup) == true || * paintedGroups.Contains(slot.WriteG.SourceGroup) == true || * paintedGroups.Contains(slot.WriteB.SourceGroup) == true || * paintedGroups.Contains(slot.WriteA.SourceGroup) == true) * { * var matSlot = mat.Slots.Find(s => s.Name == slot.Name); * * if (matSlot != null) * { * matSlot.Dirty = true; * } * } * } * } * } */ scene.UpdateMergedLayers(currentLayer); foreach (var mat in scene.Mats) { if (mat.Template != null) { foreach (var templateSlot in mat.Template.Slots) { var sceneSlot = mat.GetSlot(templateSlot.Name); if (sceneSlot.Texture == null) { sceneSlot.Texture = P3dHelper.GetRenderTexture(mat.Desc); } var textureR = mat.GetFinalTexture(templateSlot.WriteR.SourceGroup); var textureG = mat.GetFinalTexture(templateSlot.WriteG.SourceGroup); var textureB = mat.GetFinalTexture(templateSlot.WriteB.SourceGroup); var textureA = mat.GetFinalTexture(templateSlot.WriteA.SourceGroup); var channelR = P3dHelper.IndexToVector((int)templateSlot.WriteR.SourceChannel); var channelG = P3dHelper.IndexToVector((int)templateSlot.WriteG.SourceChannel); var channelB = P3dHelper.IndexToVector((int)templateSlot.WriteB.SourceChannel); var channelA = P3dHelper.IndexToVector((int)templateSlot.WriteA.SourceChannel); P3dPaintReplaceChannels.Blit(sceneSlot.Texture, textureR, textureG, textureB, textureA, channelR, channelG, channelB, channelA); } } } // Sweep foreach (var mat in scene.Mats) { for (var i = 0; i < mat.Slots.Count; i++) { var slot = mat.Slots[i]; if (slot.Dirty == true) { P3dHelper.ReleaseRenderTexture(slot.Texture); mat.Slots.RemoveAt(i); } } } }
private void Render(P3dCommand command, P3dScene.Mat mat, P3dScene.Image image, P3dScene.Obj obj, int subMesh) { var oldActive = RenderTexture.active; if (image.Current == null) { if (image.Width > 0 && image.Height > 0 && image.Pixels != null && image.Pixels.Length > 0) { var texture = new Texture2D(1, 1); if (texture.LoadImage(image.Pixels) == true) { var desc = mat.Desc; desc.width = image.Width; desc.height = image.Height; image.Current = P3dHelper.GetRenderTexture(mat.Desc); P3dPaintReplace.BlitFast(image.Current, texture, Color.white); } else { image.Current = P3dHelper.GetRenderTexture(mat.Desc); P3dPaintReplace.BlitFast(image.Current, default(Texture), default(Color)); } DestroyImmediate(texture); } else { image.Current = P3dHelper.GetRenderTexture(mat.Desc); P3dPaintReplace.BlitFast(image.Current, default(Texture), default(Color)); } } var swap = P3dHelper.GetRenderTexture(image.Current.descriptor); if (command.Preview == true) { if (image.Preview == null) { image.Preview = P3dHelper.GetRenderTexture(image.Current.descriptor); P3dPaintReplace.BlitFast(image.Preview, image.Current, Color.white); } P3dPaintReplace.BlitFast(swap, image.Preview, Color.white); command.Apply(image.Preview); } else { P3dPaintReplace.BlitFast(swap, image.Current, Color.white); command.Apply(image.Current); } RenderTexture.active = swap; if (command.RequireMesh == true) { P3dHelper.Draw(command.Material, obj.Mesh, obj.Matrix, subMesh, obj.Coord); } else { P3dHelper.Draw(command.Material); } RenderTexture.active = oldActive; if (command.Preview == true) { P3dHelper.ReleaseRenderTexture(image.Preview); image.Preview = swap; previewDrawn = true; } else { P3dHelper.ReleaseRenderTexture(image.Current); image.Current = swap; } paintedGroups.Add(command.Priority); // Group is stored in priority }
public void Activate() { if (activated == false) { UpdateMaterial(); if (material != null) { var finalWidth = width; var finalHeight = height; var finalTexture = material.GetTexture(slot.Name); CachedPaintable.ScaleSize(ref finalWidth, ref finalHeight); if (texture != null) { finalTexture = texture; } if (string.IsNullOrEmpty(shaderKeyword) == false) { material.EnableKeyword(shaderKeyword); } var desc = new RenderTextureDescriptor(width, height, format, 0); desc.autoGenerateMips = false; if (mipMaps == MipType.ForceOn) { desc.useMipMap = true; } else if (mipMaps == MipType.Auto && P3dHelper.HasMipMaps(finalTexture) == true) { desc.useMipMap = true; } current = P3dHelper.GetRenderTexture(desc); current.wrapMode = TextureWrapMode.Repeat; P3dCommandReplace.Blit(current, finalTexture, color); if (current.useMipMap == true) { current.GenerateMips(); } material.SetTexture(slot.Name, current); activated = true; if (string.IsNullOrEmpty(saveName) == false) { Load(); } NotifyOnModified(false); } } }
private void Bake(RenderTexture temporary, int width, int height, int depth, RenderTextureFormat format, int scale) { if (bakedPixels == null) { bakedPixels = new List <bool>(); } else { bakedPixels.Clear(); } baked = true; bakedMesh = mesh; bakedSize = new Vector2Int(width, height); if (cachedMaterial == null) { cachedMaterial = P3dPaintableManager.BuildMaterial("Hidden/Paint in 3D/White"); } switch (PaintableTexture.Channel) { case P3dChannel.UV: cachedMaterial.SetVector(P3dShader._Channel, new Vector4(1.0f, 0.0f, 0.0f, 0.0f)); break; case P3dChannel.UV2: cachedMaterial.SetVector(P3dShader._Channel, new Vector4(0.0f, 1.0f, 0.0f, 0.0f)); break; case P3dChannel.UV3: cachedMaterial.SetVector(P3dShader._Channel, new Vector4(0.0f, 0.0f, 1.0f, 0.0f)); break; case P3dChannel.UV4: cachedMaterial.SetVector(P3dShader._Channel, new Vector4(0.0f, 0.0f, 0.0f, 1.0f)); break; } // Write to temp RenderTexture var oldActive = RenderTexture.active; var renderTexture = temporary; if (temporary == null) { renderTexture = P3dHelper.GetRenderTexture(width, height, depth, format); } RenderTexture.active = renderTexture; GL.Clear(true, true, Color.black); cachedMaterial.SetPass(0); Graphics.DrawMeshNow(mesh, Matrix4x4.identity, PaintableTexture.Slot.Index); RenderTexture.active = oldActive; // Get readable copy var readable = P3dHelper.GetReadableCopy(renderTexture); if (temporary == null) { P3dHelper.ReleaseRenderTexture(renderTexture); } // Run through pixels to count total and build binary mask bakedPixels.Capacity = width * height; total = 0; for (var y = 0; y < height; y++) { for (var x = 0; x < width; x++) { if (readable.GetPixel(x, y).r > 0.5f) { bakedPixels.Add(true); total += scale; } else { bakedPixels.Add(false); } } } // Clean up P3dHelper.Destroy(readable); }
/// <summary>This allows you to manually execute all commands in the paint stack. /// This is useful if you need to modify the state of your object before the end of the frame.</summary> public void ExecuteCommands(bool sendNotifications) { if (activated == true) { var hidePreview = true; if (CommandsPending == true) { var oldActive = RenderTexture.active; var swap = P3dHelper.GetRenderTexture(current.descriptor); var preparedMesh = default(Mesh); var preparedMatrix = default(Matrix4x4); // Blit so we don't lose non-UVd areas P3dPaintReplace.BlitFast(swap, current, Color.white); // Paint if (paintCommands.Count > 0) { ExecuteCommands(paintCommands, sendNotifications, ref current, ref swap, ref preparedMesh, ref preparedMatrix); } // Preview if (previewCommands.Count > 0) { if (previewSet == false) { preview = P3dHelper.GetRenderTexture(current.descriptor); previewSet = true; } hidePreview = false; preview.DiscardContents(); Graphics.Blit(current, preview); previewCommands.Sort(P3dCommand.Compare); ExecuteCommands(previewCommands, sendNotifications, ref preview, ref swap, ref preparedMesh, ref preparedMatrix); } P3dHelper.ReleaseRenderTexture(swap); RenderTexture.active = oldActive; } if (hidePreview == true && previewSet == true) { P3dHelper.ReleaseRenderTexture(preview); preview = null; previewSet = false; } if (materialSet == false) { UpdateMaterial(); } material.SetTexture(slot.Name, previewSet == true ? preview : current); } }
public void ExecuteCommands(P3dPaintable paintable) { if (activated == true) { var commandCount = commands.Count; var swap = default(RenderTexture); var swapSet = false; // Revert snapshot if (previewSet == true) { P3dHelper.ReleaseRenderTexture(preview); previewSet = false; } if (commandCount > 0) { var oldActive = RenderTexture.active; var prepared = false; var preparedMesh = default(Mesh); var preparedMatrix = default(Matrix4x4); RenderTexture.active = current; for (var i = 0; i < commandCount; i++) { var command = commands[i]; var commandMaterial = command.Material; if (command.Preview != previewSet) { NotifyOnModified(previewSet); if (previewSet == true) { P3dHelper.ReleaseRenderTexture(preview); previewSet = false; RenderTexture.active = current; } else { preview = P3dHelper.GetRenderTexture(current.width, current.height, current.depth, current.format); previewSet = true; P3dHelper.Blit(preview, current); RenderTexture.active = preview; } } if (command.RequireSwap == true) { if (swapSet == false) { swap = P3dHelper.GetRenderTexture(current.width, current.height, current.depth, current.format); swapSet = true; } RenderTexture.active = swap; if (previewSet == true) { swap = preview; preview = RenderTexture.active; } else { swap = current; current = RenderTexture.active; } command.Material.SetTexture(P3dShader._Buffer, swap); } command.Apply(); if (command.RequireMesh == true) { if (prepared == false) { prepared = true; paintable.GetPrepared(ref preparedMesh, ref preparedMatrix); } switch (channel) { case P3dChannel.UV: commandMaterial.SetVector(P3dShader._Channel, new Vector4(1.0f, 0.0f, 0.0f, 0.0f)); break; case P3dChannel.UV2: commandMaterial.SetVector(P3dShader._Channel, new Vector4(0.0f, 1.0f, 0.0f, 0.0f)); break; case P3dChannel.UV3: commandMaterial.SetVector(P3dShader._Channel, new Vector4(0.0f, 0.0f, 1.0f, 0.0f)); break; case P3dChannel.UV4: commandMaterial.SetVector(P3dShader._Channel, new Vector4(0.0f, 0.0f, 0.0f, 1.0f)); break; } commandMaterial.SetPass(0); Graphics.DrawMeshNow(preparedMesh, preparedMatrix, slot.Index); } else { Graphics.Blit(default(Texture), current, commandMaterial); } command.Pool(); } RenderTexture.active = oldActive; commands.Clear(); } if (swapSet == true) { P3dHelper.ReleaseRenderTexture(swap); swapSet = false; } if (commandCount > 0) { NotifyOnModified(previewSet); } if (materialSet == false) { UpdateMaterial(); } if (previewSet == true) { material.SetTexture(slot.Name, preview); } else { material.SetTexture(slot.Name, current); } } }
public void UpdateMergedLayers(Layer currentLayer) { foreach (var mat in Mats) { foreach (var mergedLayer in mat.MergedLayers.Values) { mergedLayer.Dirty = true; if (mergedLayer.Layer != currentLayer) { mergedLayer.Clear(); mergedLayer.Layer = currentLayer; } } if (mat.Template != null) { foreach (var slot in mat.Template.Slots) { mat.UpdateMergedLayers(slot.WriteR.SourceGroup); mat.UpdateMergedLayers(slot.WriteG.SourceGroup); mat.UpdateMergedLayers(slot.WriteB.SourceGroup); mat.UpdateMergedLayers(slot.WriteA.SourceGroup); } } foreach (var pair in mat.MergedLayers) { var group = pair.Key; var mergedLayer = pair.Value; if (mergedLayer.Dirty == true) { mergedLayer.Clear(); } else { var currentLayerIndex = Layers.IndexOf(currentLayer); if (mergedLayer.Under == null) { mergedLayer.Under = P3dHelper.GetRenderTexture(mat.Desc); var groupData = P3dGroupData.GetGroupData(group); if (groupData != null) { P3dPaintReplace.Blit(mergedLayer.Under, groupData.DefaultTexture, groupData.DefaultColor); } else { P3dPaintReplace.Blit(mergedLayer.Under, default(Texture), default(Color)); } for (var i = 0; i < currentLayerIndex; i++) { TryBlendInto(ref mergedLayer.Under, Layers[i], mat.Id, group); } } // Last layer? if (currentLayerIndex == Layers.Count - 1) { if (mergedLayer.Above != null) { mergedLayer.Above = P3dHelper.ReleaseRenderTexture(mergedLayer.Above); } } else { if (mergedLayer.Above == null) { mergedLayer.Above = P3dHelper.GetRenderTexture(mat.Desc); P3dPaintReplace.Blit(mergedLayer.Above, default(Texture), default(Color)); for (var i = currentLayerIndex + 1; i < Layers.Count; i++) { TryBlendInto(ref mergedLayer.Above, Layers[i], mat.Id, group); } } } if (mergedLayer.Final == null) { mergedLayer.Final = P3dHelper.GetRenderTexture(mat.Desc); } P3dPaintReplace.Blit(mergedLayer.Final, mergedLayer.Under, Color.white); TryBlendInto(ref mergedLayer.Final, currentLayer, mat.Id, group); if (mergedLayer.Above != null) { mergedLayer.Final = P3dPaintFill.Blit(mergedLayer.Final, P3dBlendMode.AlphaBlend, mergedLayer.Above, Color.white, 1.0f, 0.0f); } } } } }
private void DrawNextPaint() { if (P3dPaintMaterial.CachedInstances.Count > 0) { if (paintIndex >= P3dPaintMaterial.CachedInstances.Count) { paintIndex = 0; } var paint = P3dPaintMaterial.CachedInstances[paintIndex++]; DestroyImmediate(paint.Thumbnail); paint.Thumbnail = null; if (paint != null && paint.Thumbnail == null && paint.Material != null) { var tempTextures = new List <RenderTexture>(); if (paintProperties == null) { paintProperties = new MaterialPropertyBlock(); } else { paintProperties.Clear(); } if (paint.Template != null) { foreach (var slot in paint.Template.Slots) { var slotR = paint.GetSlot(slot.WriteR.SourceGroup); var slotG = paint.GetSlot(slot.WriteG.SourceGroup); var slotB = paint.GetSlot(slot.WriteB.SourceGroup); var slotA = paint.GetSlot(slot.WriteA.SourceGroup); if (slotR != null || slotG != null || slotB != null || slotA != null) { var tempTexture = P3dHelper.GetRenderTexture(new RenderTextureDescriptor(1024, 1024, RenderTextureFormat.ARGB32, 0)); tempTextures.Add(tempTexture); var textureR = P3dHelper.GetRenderTexture(tempTexture.descriptor); var textureG = P3dHelper.GetRenderTexture(tempTexture.descriptor); var textureB = P3dHelper.GetRenderTexture(tempTexture.descriptor); var textureA = P3dHelper.GetRenderTexture(tempTexture.descriptor); WriteThumbnailTex(textureR, slotR, slot.WriteR); WriteThumbnailTex(textureG, slotG, slot.WriteG); WriteThumbnailTex(textureB, slotB, slot.WriteB); WriteThumbnailTex(textureA, slotA, slot.WriteA); var channelR = P3dHelper.IndexToVector((int)slot.WriteR.SourceChannel); var channelG = P3dHelper.IndexToVector((int)slot.WriteG.SourceChannel); var channelB = P3dHelper.IndexToVector((int)slot.WriteB.SourceChannel); var channelA = P3dHelper.IndexToVector((int)slot.WriteA.SourceChannel); P3dPaintReplaceChannels.Blit(tempTexture, textureR, textureG, textureB, textureA, channelR, channelG, channelB, channelA); P3dHelper.ReleaseRenderTexture(textureR); P3dHelper.ReleaseRenderTexture(textureG); P3dHelper.ReleaseRenderTexture(textureB); P3dHelper.ReleaseRenderTexture(textureA); paintProperties.SetTexture(slot.Name, tempTexture); } } } BeginPreview(thumbnailUtil, new Rect(0, 0, settings.ThumbnailSize, settings.ThumbnailSize)); var probeAnchor = default(Transform); var probeExists = false; if (settings.Environment != null) { probeAnchor = settings.Environment.transform; probeExists = true; } switch (paint.Style) { case P3dPaintMaterial.StyleType.Seamless: { thumbnailUtil.DrawMesh(P3dHelper.GetSphereMesh(), Matrix4x4.identity, paint.Material, 0, paintProperties, probeAnchor, probeExists); } break; case P3dPaintMaterial.StyleType.Decal: { thumbnailUtil.DrawMesh(P3dHelper.GetQuadMesh(), Matrix4x4.identity, paint.Material, 0, paintProperties, probeAnchor, probeExists); } break; } paint.Thumbnail = P3dHelper.GetReadableCopy(EndPreview(thumbnailUtil)); foreach (var tempTexture in tempTextures) { P3dHelper.ReleaseRenderTexture(tempTexture); } } } }