Я пытаюсь нарисовать куб с сеточным коллайдером, когда мой шарик с краской сталкивается с ним. я могу выплеснуть свою краску на куб, но она разбрызгивает все 6 сторон куба, а также на передние точки.
This script is attached to every object that can be drawn.
public class DrawableBehaviour : MonoBehaviour
{
[Tooltip("Number of pixels per 1 unit of size in world coordinates.")]
[Range(16, 8182)]
[SerializeField] private int _textureSize = 64;
private readonly Color _color = new Color(0, 0, 0, 0);
private Material _material;
private Texture2D _texture;
private bool _isEnabled = false;
private object _lockFlag = new object();
private void Start()
{
Renderer renderer = GetComponent<Renderer>();
if (null == renderer)
return;
foreach (Material material in renderer.materials)
{
if (material.shader.name.Contains("Custom/PaintShader"))
{
_material = material;
break;
}
}
if (_material)
{
_texture = new Texture2D(_textureSize, _textureSize);
for (int x = 0; x < _textureSize; ++x)
for (int y = 0; y < _textureSize; ++y)
_texture.SetPixel(x, y, _color);
_texture.Apply();
_material.SetTexture("_DrawingTex", _texture);
_isEnabled = true;
}
}
public void PaintOnColored(Vector2 textureCoord, float[,] splashTexture, Color color)
{
MyPaintOn(textureCoord, splashTexture, color);
}
private void MyPaintOn(Vector2 textureCoord, float[,] splashTexture, Color targetColor)
{
if (_isEnabled)
{
lock (_lockFlag)
{
Stopwatch sw = new Stopwatch();
sw.Start();
int reqnx = splashTexture.GetLength(0);
int reqny = splashTexture.GetLength(1);
int reqX = (int)(textureCoord.x * _textureSize) - (reqnx / 2);
int reqY = (int)(textureCoord.y * _textureSize) - (reqny / 2);
int right = _texture.width - 1;
int bottom = _texture.height - 1;
int x = IntMax(reqX, 0);
int y = IntMax(reqY, 0);
int nx = IntMin(x + reqnx, right) - x;
int ny = IntMin(y + reqny, bottom) - y;
Color[] pixels = _texture.GetPixels(x, y, nx, ny);
int counter = 0;
for (int i = 0; i < nx; ++i)
{
for (int j = 0; j < ny; ++j)
{
float currAlpha = splashTexture[i, j];
if (currAlpha == 1)
pixels[counter] = targetColor;
else
{
Color currColor = pixels[counter];
// resulting color is an addition of splash texture to the texture based on alpha
Color newColor = Color.Lerp(currColor, targetColor, currAlpha);
// but resulting alpha is a sum of alphas (adding transparent color should not make base color more transparent)
newColor.a = pixels[counter].a + currAlpha;
pixels[counter] = newColor;
}
counter++;
}
}
_texture.SetPixels(x, y, nx, ny, pixels);
_texture.Apply();
sw.Stop();
}
}
}
private int IntMax(int a, int b)
{
return a > b ? a : b;
}
private int IntMin(int a, int b)
{
return a < b ? a : b;
}
}
Это сценарий моего объекта шара
public class PaintBallBehaviour : MonoBehaviour
{
[SerializeField] private Texture2D _splashTexture;
private void OnTriggerEnter(Collider other)
{
PaintProjectileManager manager = GameManager.GetInstance().GetProjectileManager();
var position = transform.position;
Vector3 backPos = new Vector3(position.x, position.y, position.z-2);
for (int i = 0; i < 14; ++i)
{
RaycastHit hit;
if (Physics.Raycast(backPos, transform.forward /*GetSphereRay(i)*/, out hit /*, paintDiameter*/))
{
if (hit.collider is MeshCollider)
{
DrawableBehaviour drawable = hit.collider.gameObject.GetComponent<DrawableBehaviour>();
if (drawable)
{
Debug.Log(hit.textureCoord2);
drawable.PaintOnColored(hit.textureCoord2, manager.GetRandomProjectileSplash(),
new Color32(0, 47, 255, 255));
}
}
}
}
Debug.DrawRay(backPos, manager.GetRandomSphereRay(),Color.red);
LeanPool.Despawn(gameObject);
}
}
И этомой шейдер
Shader "Custom/PaintShader"
{
Properties
{
[HideInInspector]_DrawingTex("Drawing texture", 2D) = "" {}
_Color ("Color", Color) = (1,1,1,1)
_MainTex ("Albedo (RGB)", 2D) = "white" {}
_Glossiness ("Smoothness", Range(0,1)) = 0.5
_Metallic ("Metallic", Range(0,1)) = 0.0
}
SubShader
{
Tags { "RenderType"="Opaque" }
LOD 200
CGPROGRAM
// Physically based Standard lighting model, and enable shadows on all light types
#pragma surface surf Standard fullforwardshadows
// Use shader model 3.0 target, to get nicer looking lighting
#pragma target 3.0
sampler2D _DrawingTex;
sampler2D _MainTex;
struct Input
{
float2 uv_DrawingTex;
float2 uv_MainTex;
};
half _Glossiness;
half _Metallic;
fixed4 _Color;
// Add instancing support for this shader. You need to check 'Enable Instancing' on materials that use the shader.
// See https://docs.unity3d.com/Manual/GPUInstancing.html for more information about instancing.
// #pragma instancing_options assumeuniformscaling
UNITY_INSTANCING_BUFFER_START(Props)
// put more per-instance properties here
UNITY_INSTANCING_BUFFER_END(Props)
void surf (Input IN, inout SurfaceOutputStandard o)
{
float4 drawData = tex2D(_DrawingTex, IN.uv_DrawingTex);
float4 mainData = tex2D(_MainTex, IN.uv_MainTex) * _Color;
fixed4 c = lerp(mainData, drawData, drawData.a);
c.a = drawData.a + mainData.a;
o.Albedo = c.rgb;
// Metallic and smoothness come from slider variables
o.Metallic = _Metallic;
o.Smoothness = _Glossiness;
o.Alpha = c.a;
}
ENDCG
}
FallBack "Diffuse"
}
Я не очень разбираюсь в отображении сплатов и тому подобном, поэтому кто-нибудь может помочь мне понять, что не так и как с этим справиться?
Вот видеоссылка: ВИДЕО