Download

Trying to Implement Splatoon using vertex Color

I’m trying to create a Splaton effect on mobile. I’m trying to adapt the vertex paint technique used here
https://forum.unity.com/threads/how-do-they-do-the-painting-in-splatoon.460663/
because i need to count the painted area in real time as well in the less expensive way.

i created this code for the painting in c++


// Fill out your copyright notice in the Description page of Project Settings.

#include "ActorMeshPainter.h"
#include "DrawDebugHelpers.h"

// Sets default values for this component's properties
UActorMeshPainter::UActorMeshPainter()
{
    // Set this component to be initialized when the game starts, and to be ticked every frame.  You can turn these features
    // off to improve performance if you don't need them.
    PrimaryComponentTick.bCanEverTick = false;

    // ...
}


// Called when the game starts
void UActorMeshPainter::BeginPlay()
{
    Super::BeginPlay();


        SMComp = GetOwner()->FindComponentByClass< UStaticMeshComponent>();
        UStaticMesh* SM = SMComp->GetStaticMesh();
        if (SM)
        {
            //Get the vertex buffer from the 1st lod
            //FPositionVertexBuffer* PositionVertexBuffer = &SM->RenderData->LODResources[0].VertexBuffers.PositionVertexBuffer;
            //Make sure that we have at least 1 LOD
            SMComp->SetLODDataCount(1, SMComp->LODData.Num());
            FStaticMeshComponentLODInfo* LODInfo = &SMComp->LODData[0]; //We're going to modify the 1st LOD only

            //Empty the painted vertices and assign a new color vertex buffer which will contain the new colors for each vertex
            LODInfo->PaintedVertices.Empty();
            LODInfo->OverrideVertexColors = new FColorVertexBuffer();

            //We're going to use the LODResources to get the total number of vertices that the provided mesh has
            FStaticMeshLODResources& LodResources = SM->RenderData->LODResources[0];

            FColor fillColor = FColor::Black;
            fillColor.A = 255;

            //Since we know beforehand the number of elements we might as well reserve the memory now
            if (colorArray.Num() == 0)
            {
                colorArray.Reserve(LodResources.GetNumVertices() - 1);

                for (int32 i = 0; i < LodResources.GetNumVertices(); i++)
                {
                    colorArray.Add(fillColor);

                }

            }
            playerColorIndex.Init(-1, LodResources.GetNumVertices());




            //Initialize the new vertex colros with the array we created above
            LODInfo->OverrideVertexColors->InitFromColorArray(colorArray);
            //Initialize resource and mark render state of object as dirty in order for the engine to re-render it
            BeginInitResource(LODInfo->OverrideVertexColors);
            SMComp->MarkRenderStateDirty();
        }

}


// Called every frame
void UActorMeshPainter::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)
{
    Super::TickComponent(DeltaTime, TickType, ThisTickFunction);

    // ...
}

void UActorMeshPainter::PaintSMVertices(FVector _hitLocation,int32 _playerColorIndex,  FColor _paintColor,float _innerRadius,float _outerRadius)
{ 

    if (!SMComp) return;

    if (colorArray.Num() == 0)return;

    //Get the static mesh that we're going to paint
    UStaticMesh* SM = SMComp->GetStaticMesh();
    if (SM)
    {
        //Get the vertex buffer from the 1st lod
        //FPositionVertexBuffer* PositionVertexBuffer = &SM->RenderData->LODResources[0].VertexBuffers.PositionVertexBuffer;
        //Make sure that we have at least 1 LOD
        SMComp->SetLODDataCount(1, SMComp->LODData.Num());
        FStaticMeshComponentLODInfo* LODInfo = &SMComp->LODData[0]; //We're going to modify the 1st LOD only

        //Empty the painted vertices and assign a new color vertex buffer which will contain the new colors for each vertex
         LODInfo->PaintedVertices.Empty();
 LODInfo->OverrideVertexColors = new FColorVertexBuffer();

        //We're going to use the LODResources to get the total number of vertices that the provided mesh has
        FStaticMeshLODResources& LodResources = SM->RenderData->LODResources[0];


        FVector tmPos, vexPos;

        float tFactor = 1.0 / (_outerRadius - _innerRadius);

        //UE_LOG(LogTemp, Warning, TEXT(" dist %f > %f color %s "), dist,diff, *colorArray*.ToString());
        bool bSameColor = false;

        for (int32 i = 0; i < LodResources.GetNumVertices(); i++)
        {
            tmPos = GetOwner()->GetTransform().InverseTransformPosition(_hitLocation);
            vexPos = LodResources.VertexBuffers.PositionVertexBuffer.VertexPosition(i);


            float dist = FVector::Dist(tmPos, vexPos);
            if(dist>_outerRadius)continue;
            int a = colorArray*.A;
            colorArray* = _paintColor;

            bSameColor = _playerColorIndex == playerColorIndex*;
            playerColorIndex* = _playerColorIndex;

                    if (dist < _innerRadius)
                    {
                        colorArray*.A = 255;

                    }else
                    {

                        uint8 blobA = (uint8)(255 - 255 * (dist - _innerRadius)*tFactor);
                         if (blobA >= a) colorArray*.A = blobA;

                        // colorArray*.A = 0;

                    }
            //    RandomColorArray* = dist < 500? FColor::Red:FColor::White;

        }

        //Initialize the new vertex colros with the array we created above
        LODInfo->OverrideVertexColors->InitFromColorArray(colorArray);
        //Initialize resource and mark render state of object as dirty in order for the engine to re-render it
        BeginInitResource(LODInfo->OverrideVertexColors);
        SMComp->MarkRenderStateDirty();
    }

}



but im an unable to achieve the shader code to avoid the blocky side