GreasePencilRendererTrashed.cs
1 using System; 2 using System.Collections.Generic; 3 using System.Runtime.InteropServices; 4 using Unity.Mathematics; 5 using UnityEngine; 6 7 [RequireComponent(typeof(MeshFilter), typeof(MeshRenderer))] 8 public class GreasePencilRendererTrashed : MonoBehaviour 9 { 10 public GreasePencilSO greasePencil; 11 public int frameidx = 0; 12 13 // ComputeBuffers 14 ComputeBuffer posBuffer; 15 ComputeBuffer strokesBuffer; 16 ComputeBuffer uvOpacityBuffer; 17 ComputeBuffer vcolBuffer; 18 ComputeBuffer fcolBuffer; 19 ComputeBuffer materialBuffer; 20 21 // Keep references so we can dispose 22 bool buffersCreated = false; 23 24 Mesh mesh; 25 26 // static void grease_pencil_geom_batch_ensure(Object &object, 27 // const GreasePencil &grease_pencil, 28 // const Scene &scene) 29 [StructLayout(LayoutKind.Sequential)] 30 public struct GreasePencilStrokeVert 31 { 32 // float3 pos; 33 public Vector3 pos; 34 35 // float radius; 36 public float radius; 37 38 // int4 mat, stroke_id, point_id, packed_asp_hard_rot; 39 public int mat; 40 public int stroke_id; 41 public int point_id; 42 public int packed_asp_hard_rot; 43 44 // float2 uv_fill; 45 public Vector2 uv_fill; 46 47 // float u_stroke, opacity; 48 public float u_stroke; 49 public float opacity; 50 }; 51 52 struct GreasePencilColorVert { 53 public float4 vcol; /* Vertex color */ 54 public float4 fcol; /* Fill color */ 55 }; 56 57 [ContextMenu("Build Stroke Mesh")] 58 void CreateMesh() 59 { 60 var vertsStartOffsetsPerLayer = CalculateOffsets(out var totalNumPoints, out var totalVertexOffset); 61 // struct GreasePencilStrokeVert { 62 // /** Position and radius packed in the same attribute. */ 63 // float pos[3], radius; 64 // /** Material Index, Stroke Index, Point Index, Packed aspect + hardness + rotation. */ 65 // int32_t mat, stroke_id, point_id, packed_asp_hard_rot; 66 // /** UV and opacity packed in the same attribute. */ 67 // float uv_fill[2], u_stroke, opacity; 68 // }; 69 70 // Add extra space at the end of the buffer because of quad load. 71 GreasePencilStrokeVert[] verts = new GreasePencilStrokeVert[totalVertexOffset+2]; 72 GreasePencilColorVert[] cols = new GreasePencilColorVert[totalVertexOffset+2]; 73 74 // a quad for every strokePoint 75 int[] triangleIbo = new int[totalNumPoints*2*3]; 76 var triVbo = new Vector3[totalVertexOffset*4]; 77 int triangleIboIndex = 0; 78 79 for (int layerIdx = 0; layerIdx < greasePencil.data.layers.Count; layerIdx++) 80 { 81 var layer = greasePencil.data.layers[layerIdx]; 82 var strokes = layer.frames[frameidx].strokes; 83 if (strokes.Count == 0) 84 { 85 continue; 86 } 87 88 var vertsStartOffSets = vertsStartOffsetsPerLayer[layerIdx]; 89 for (int strokeIdx = 0; strokeIdx < strokes.Count; strokeIdx++) 90 { 91 var stroke = strokes[strokeIdx]; 92 var pointsCount = stroke.points.Count; 93 bool isCyclic = stroke.cyclic && pointsCount >= 3; 94 var vertsStartOffset = vertsStartOffSets[strokeIdx]; 95 var numVerts = 1 + pointsCount + (isCyclic ? 1 : 0) + 1; 96 97 // First vertex is not drawn 98 verts[vertsStartOffset].mat = -1; 99 // The first vertex will have the index of the last vertex. 100 verts[vertsStartOffset].stroke_id = vertsStartOffset + numVerts - 1; 101 // 102 // // If the stroke has more than 2 points, add the triangle indices to the index buffer. 103 // if (pointsCount >= 3) 104 // { 105 // var trisSlice = new Span<int3>(triangles.ToArray(), trisStartOffset, numVerts); 106 // foreach (var tri in trisSlice) 107 // { 108 // triangleIbo[triangleIboIndex + 0] = (vertsStartOffset + 1 + tri.x) << 2; 109 // triangleIbo[triangleIboIndex + 1] = (vertsStartOffset + 1 + tri.y) << 2; 110 // triangleIbo[triangleIboIndex + 2] = (vertsStartOffset + 1 + tri.z) << 2; 111 // triangleIboIndex += 3; 112 // } 113 // } 114 115 // Write all the point attributes to the vertex buffers. Create a quad for each point. 116 for (int pointIdx = 0; pointIdx < pointsCount; pointIdx++) 117 { 118 var strokePoint = stroke.points[pointIdx]; 119 var idx = vertsStartOffset + pointIdx + 1; 120 PopulatePoint(strokePoint, out verts[idx], out cols[idx], idx, isCyclic); 121 } 122 123 void PopulatePoint(PointData strokePoint, out GreasePencilStrokeVert sVert, out GreasePencilColorVert cVert, int idx, bool cyclic) 124 { 125 sVert.pos = strokePoint.Position; 126 // sVert.pos = new float3(idx, 0, 0); 127 var posNext = stroke.points[(idx) % pointsCount].Position; 128 sVert.radius = strokePoint.radius; 129 sVert.opacity = strokePoint.opacity; 130 var offset = vertsStartOffset + idx + 1; 131 // Store if the curve is cyclic in the sign of the point index. 132 sVert.point_id = cyclic ? -offset : offset; 133 sVert.stroke_id = vertsStartOffset; 134 135 /* The material index is allowed to be negative as it's stored as a generic attribute. To 136 * ensure the material used by the shader is valid this needs to be clamped to zero. */ 137 sVert.mat = Math.Max(stroke.material_index, 0) % 256; 138 139 sVert.packed_asp_hard_rot = 0; //todo 140 sVert.u_stroke = 0; //todo 141 sVert.uv_fill = float2.zero; //todo 142 143 cVert.vcol = strokePoint.VertexColor; 144 cVert.fcol = Vector4.one; 145 146 // quad 147 triangleIbo[triangleIboIndex + 0] = ((vertsStartOffset + idx) << 2) + 0; 148 triangleIbo[triangleIboIndex + 1] = ((vertsStartOffset + idx) << 2) + 1; 149 triangleIbo[triangleIboIndex + 2] = ((vertsStartOffset + idx) << 2) + 2; 150 triangleIboIndex += 3; 151 triangleIbo[triangleIboIndex + 0] = ((vertsStartOffset + idx) << 2) + 2; 152 triangleIbo[triangleIboIndex + 1] = ((vertsStartOffset + idx) << 2) + 1; 153 triangleIbo[triangleIboIndex + 2] = ((vertsStartOffset + idx) << 2) + 3; 154 triangleIboIndex += 3; 155 triVbo[((vertsStartOffset + idx) << 2) + 0] = strokePoint.Position + Vector3.up; 156 triVbo[((vertsStartOffset + idx) << 2) + 1] = strokePoint.Position - Vector3.up; 157 triVbo[((vertsStartOffset + idx) << 2) + 2] = posNext + Vector3.up; 158 triVbo[((vertsStartOffset + idx) << 2) + 3] = posNext - Vector3.up; 159 } 160 } 161 } 162 163 ReleaseBuffers(); 164 165 if (mesh == null) 166 { 167 mesh = new Mesh(); 168 mesh.name = "GreasePencilMesh"; 169 GetComponent<MeshFilter>().sharedMesh = mesh; 170 } 171 else 172 { 173 mesh.Clear(); 174 } 175 mesh.indexFormat = UnityEngine.Rendering.IndexFormat.UInt32; 176 mesh.vertices = triVbo; 177 mesh.SetIndices(triangleIbo, MeshTopology.Triangles, 0); 178 posBuffer = new ComputeBuffer(verts.Length, sizeof(float) * 4 * 3); 179 // var posArray = new Vector4[verts.Length]; 180 // for (int i = 0; i < verts.Length; i++) 181 // { 182 // posArray[i] = new Vector4(verts[i].pos.x, verts[i].pos.y, verts[i].pos.z, verts[i].radius); 183 // } 184 // posBuffer.SetData(posArray); 185 posBuffer.SetData(verts); 186 vcolBuffer = new ComputeBuffer(cols.Length, sizeof(float) * 4 * 2); 187 vcolBuffer.SetData(cols); 188 CreateMaterialBuffer(); 189 buffersCreated = true; 190 191 var targetMaterial = GetComponent<MeshRenderer>().sharedMaterial; 192 // 4) Bind to material 193 if (targetMaterial != null) 194 { 195 targetMaterial.SetBuffer("_Pos", posBuffer); 196 targetMaterial.SetBuffer("_Color", vcolBuffer); 197 targetMaterial.SetBuffer("gp_materials", materialBuffer); 198 } 199 else 200 { 201 Debug.LogWarning("targetMaterial not assigned; buffers created but not bound."); 202 } 203 204 } 205 206 private List<int[]> CalculateOffsets(out int totalNumPoints, out int totalVertexOffset) 207 { 208 totalNumPoints = 0; 209 totalVertexOffset = 0; 210 var vertsStartOffsetsPerLayer = new List<int[]>(); 211 212 foreach (var layer in greasePencil.data.layers) 213 { 214 var strokes = layer.frames[frameidx].strokes; 215 int numStrokes = strokes.Count; 216 int[] vertsStartOffsets = new int[numStrokes]; 217 218 // Calculate the triangle and vertex offsets for all the strokes 219 int numCyclic = 0; 220 int numPoints = 0; 221 for (int strokeIdx = 0; strokeIdx < numStrokes; strokeIdx++) 222 { 223 var stroke = strokes[strokeIdx]; 224 var pointsCount = stroke.points.Count; 225 bool isCyclic = stroke.cyclic && pointsCount >= 3; 226 if (isCyclic) numCyclic++; 227 vertsStartOffsets[strokeIdx] = totalVertexOffset; 228 // One vertex is stored before and after as padding. Cyclic strokes have one extra vertex. 229 totalVertexOffset += 1 + pointsCount + (isCyclic ? 1 : 0) + 1; 230 numPoints += pointsCount; 231 } 232 233 // the strokes 234 totalNumPoints += (numPoints + numCyclic); 235 236 vertsStartOffsetsPerLayer.Add(vertsStartOffsets); 237 } 238 239 return vertsStartOffsetsPerLayer; 240 } 241 242 // BLI_INLINE int32_t pack_rotation_aspect_hardness(float rot, float asp, float softness) 243 // { 244 // int32_t packed = 0; 245 // /* Aspect uses 9 bits */ 246 // float asp_normalized = (asp > 1.0f) ? (1.0f / asp) : asp; 247 // packed |= int32_t(unit_float_to_uchar_clamp(asp_normalized)); 248 // /* Store if inverted in the 9th bit. */ 249 // if (asp > 1.0f) { 250 // packed |= 1 << 8; 251 // } 252 // /* Rotation uses 9 bits */ 253 // /* Rotation are in [-90..90] degree range, so we can encode the sign of the angle + the cosine 254 // * because the cosine will always be positive. */ 255 // packed |= int32_t(unit_float_to_uchar_clamp(cosf(rot))) << 9; 256 // /* Store sine sign in 9th bit. */ 257 // if (rot < 0.0f) { 258 // packed |= 1 << 17; 259 // } 260 // /* Hardness uses 8 bits */ 261 // packed |= int32_t(unit_float_to_uchar_clamp(1.0f - softness)) << 18; 262 // return packed; 263 // } 264 265 void BuildMesh() 266 { 267 // This method remains largely the same as the mesh structure is separate from the buffer packing. 268 if (greasePencil == null) 269 { 270 Debug.LogError("No GreasePencil asset assigned."); 271 return; 272 } 273 274 var vertices = new List<Vector3>(); 275 var uvs = new List<Vector2>(); // stroke index, point index 276 var uvs2 = new List<Vector2>(); // could hold vertex ID for buffer lookup 277 var colors = new List<Color>(); 278 var indices = new List<int>(); 279 280 int vertBase = 0; 281 282 int strokeIndex = 0; 283 foreach (var layer in greasePencil.data.layers) 284 { 285 foreach (var stroke in layer.frames[frameidx].strokes) 286 { 287 if (stroke.points == null || stroke.points.Count < 2) 288 continue; 289 290 for (int i = 0; i < stroke.points.Count - 1; i++) 291 { 292 PointData p0 = stroke.points[i]; 293 PointData p1 = stroke.points[i + 1]; 294 295 // build a quad segment between p0 and p1 296 Vector3 dir = (p1.Position - p0.Position).normalized; 297 Vector3 normal = Vector3.up; // assume Z-up camera; adjust later 298 Vector3 side = Vector3.Cross(dir, normal).normalized; 299 300 float r0 = p0.radius; 301 float r1 = p1.radius; 302 303 // 4 vertices for the quad 304 vertices.Add(p0.Position + side * r0); 305 vertices.Add(p0.Position - side * r0); 306 vertices.Add(p1.Position + side * r1); 307 vertices.Add(p1.Position - side * r1); 308 309 // UVs (store strokeIndex + pointIndex) 310 uvs.Add(new Vector2(strokeIndex, i)); 311 uvs.Add(new Vector2(strokeIndex, i)); 312 uvs.Add(new Vector2(strokeIndex, i + 1)); 313 uvs.Add(new Vector2(strokeIndex, i + 1)); 314 315 // UV2 (for vertex id if you later map to buffers) 316 uvs2.Add(new Vector2(vertices.Count - 4, 0)); 317 uvs2.Add(new Vector2(vertices.Count - 3, 0)); 318 uvs2.Add(new Vector2(vertices.Count - 2, 0)); 319 uvs2.Add(new Vector2(vertices.Count - 1, 0)); 320 321 // Color (pack opacity or stroke color if you have one) 322 Color c0 = new Color(1, 1, 1, p0.opacity); 323 Color c1 = new Color(1, 1, 1, p1.opacity); 324 colors.Add(c0); 325 colors.Add(c0); 326 colors.Add(c1); 327 colors.Add(c1); 328 329 // Indices (two triangles) 330 indices.Add(vertBase + 0); 331 indices.Add(vertBase + 2); 332 indices.Add(vertBase + 1); 333 indices.Add(vertBase + 2); 334 indices.Add(vertBase + 3); 335 indices.Add(vertBase + 1); 336 337 vertBase += 4; 338 } 339 strokeIndex++; 340 } 341 } 342 343 if (mesh == null) 344 { 345 mesh = new Mesh(); 346 mesh.name = "GreasePencilMesh"; 347 GetComponent<MeshFilter>().sharedMesh = mesh; 348 } 349 else 350 { 351 mesh.Clear(); 352 } 353 354 mesh.SetVertices(vertices); 355 mesh.SetUVs(0, uvs); 356 mesh.SetUVs(1, uvs2); 357 mesh.SetColors(colors); 358 mesh.SetTriangles(indices, 0); 359 mesh.RecalculateBounds(); 360 } 361 // Define the C# struct that matches the GPU struct layout. 362 // The GPU struct is packed, so we must be careful with alignment. 363 // The C# struct must have a size of 88 bytes to match the GPU side (22 floats * 4 bytes/float). 364 // Unity's GPU struct packing might differ slightly, but this is a close approximation. 365 struct GpMaterialData 366 { 367 public Vector4 stroke_color; 368 public Vector4 fill_color; 369 public Vector4 fill_mix_color; 370 public Vector4 fill_uv_rot_scale; 371 public Vector4 fill_uv_offset_alignment_rot; // Combined for packing 372 public float stroke_texture_mix; 373 public float stroke_u_scale; 374 public float fill_texture_mix; 375 public int flag; 376 } 377 [ContextMenu("pack Attributes")] 378 void ApplyIndices() 379 { 380 if (greasePencil == null) 381 { 382 Debug.LogError("GreasePencil asset not assigned."); 383 return; 384 } 385 386 MeshFilter mf = GetComponent<MeshFilter>(); 387 if (mf == null || mf.sharedMesh == null) 388 { 389 Debug.LogError("MeshFilter or sharedMesh missing."); 390 return; 391 } 392 393 var vertsStartOffsetsPerLayer = CalculateOffsets(out var totalNumPoints, out var totalVertexOffset); 394 395 // 1) write vertex ids into uv2.x (so shader can index) 396 var uvs2 = new List<Vector2>(totalVertexOffset); 397 for (int i = 0; i < totalVertexOffset; i++) 398 uvs2.Add(new Vector2(i, 0)); 399 mesh.SetUVs(1, uvs2); // TEXCOORD1 / uv2 400 401 // 2) Flatten grease pencil points and create stroke metadata 402 var posData = new Vector4[totalVertexOffset]; // (x,y,z,radius) 403 var strokeData = new Vector4[totalVertexOffset]; // (mat_idx, stroke_id, point_id, packed_data) 404 var uvOpacityData = new Vector4[totalVertexOffset]; // (uv_fill.x, uv_fill.y, u_stroke, opacity) 405 var vcolData = new Vector4[totalVertexOffset]; // (r, g, b, a) 406 var fcolData = new Vector4[totalVertexOffset]; // (r, g, b, a) 407 408 int runningPointIndex = 0; 409 int runningStrokeIndex = 0; 410 411 foreach (var layer in greasePencil.data.layers) 412 { 413 foreach (var stroke in layer.frames[frameidx].strokes) 414 { 415 bool is_cyclic = stroke.cyclic && (stroke.points.Count > 2); 416 // First point is not drawn 417 strokeData[runningPointIndex][0] = -1; 418 // The first vertex will have the index of the last vertex. 419 strokeData[runningPointIndex][1] = runningPointIndex + 1 + stroke.points.Count + (is_cyclic ? 1 : 0); 420 runningPointIndex++; 421 if (stroke.points != null) 422 { 423 int pointIndex = 0; 424 foreach (var p in stroke.points) 425 { 426 // Populating the new buffers 427 posData[runningPointIndex] = new Vector4(p.Position.x, p.Position.y, p.Position.z, p.radius); 428 429 // We need more data from the grease pencil asset to properly pack this, 430 // for now, use placeholders. Assuming mat_idx, stroke_id, and point_id. 431 int matIdx = stroke.material_index; 432 if (pointIndex == 0 || pointIndex == stroke.points.Count - 1) 433 { 434 matIdx = -1; 435 } 436 strokeData[runningPointIndex] = new Vector4(matIdx, runningStrokeIndex, pointIndex, 0f); 437 438 // Assuming you have uv_fill and u_stroke data in your PointData or you need to generate it 439 // Here's a placeholder, you'll need to adjust based on your data source. 440 uvOpacityData[runningPointIndex] = new Vector4(0f, 0f, (float)pointIndex / (stroke.points.Count - 1), p.opacity); 441 442 // Assuming you have vertex colors and fill colors 443 // For this example, we'll use placeholder colors. 444 vcolData[runningPointIndex] = new Vector4(1f, 1f, 1f, 1f); 445 fcolData[runningPointIndex] = new Vector4(1f, 1f, 1f, 1f); 446 447 runningPointIndex++; 448 pointIndex++; 449 } 450 } 451 runningStrokeIndex++; 452 runningPointIndex++; 453 } 454 } 455 456 // 3) Create / update ComputeBuffers 457 ReleaseBuffers(); 458 459 if (posData.Length == 0) 460 { 461 Debug.LogWarning("No points in grease pencil asset."); 462 return; 463 } 464 465 posBuffer = new ComputeBuffer(posData.Length, sizeof(float) * 4); 466 posBuffer.SetData(posData); 467 468 strokesBuffer = new ComputeBuffer(strokeData.Length, sizeof(int) * 4); 469 // Cast Vector4 to int4, as the shader expects ints 470 var strokeInts = new int[strokeData.Length * 4]; 471 for (int i = 0; i < strokeData.Length; i++) 472 { 473 strokeInts[i * 4 + 0] = (int)strokeData[i].x; 474 strokeInts[i * 4 + 1] = (int)strokeData[i].y; 475 strokeInts[i * 4 + 2] = (int)strokeData[i].z; 476 strokeInts[i * 4 + 3] = (int)strokeData[i].w; 477 } 478 strokesBuffer.SetData(strokeInts); 479 480 481 482 483 CreateMaterialBuffer(); 484 485 uvOpacityBuffer = new ComputeBuffer(uvOpacityData.Length, sizeof(float) * 4); 486 uvOpacityBuffer.SetData(uvOpacityData); 487 488 vcolBuffer = new ComputeBuffer(vcolData.Length, sizeof(float) * 4); 489 vcolBuffer.SetData(vcolData); 490 491 fcolBuffer = new ComputeBuffer(fcolData.Length, sizeof(float) * 4); 492 fcolBuffer.SetData(fcolData); 493 494 var targetMaterial = GetComponent<MeshRenderer>().sharedMaterial; 495 // 4) Bind to material 496 if (targetMaterial != null) 497 { 498 targetMaterial.SetBuffer("_Pos", posBuffer); 499 targetMaterial.SetBuffer("_Strokes", strokesBuffer); 500 targetMaterial.SetBuffer("_UvOpacity", uvOpacityBuffer); 501 targetMaterial.SetBuffer("_Vcol", vcolBuffer); 502 targetMaterial.SetBuffer("_Fcol", fcolBuffer); 503 targetMaterial.SetBuffer("gp_materials", materialBuffer); 504 } 505 else 506 { 507 Debug.LogWarning("targetMaterial not assigned; buffers created but not bound."); 508 } 509 510 buffersCreated = true; 511 512 Debug.Log($"GreasePencilRenderer: uploaded {posData.Length} points, {strokeData.Length} strokes."); 513 } 514 515 private void CreateMaterialBuffer() 516 { 517 var materialDataList = new List<GpMaterialData>(); 518 foreach (var mat in greasePencil.data.materials) 519 { 520 GpMaterialData gpuMat = new GpMaterialData(); 521 522 // Populate the C# struct from your GreasePencilSO data. 523 gpuMat.stroke_color = new Vector4(mat.stroke_color[0], mat.stroke_color[1], mat.stroke_color[2], 1.0f); 524 gpuMat.fill_color = new Vector4(mat.fill_color[0], mat.fill_color[1], mat.fill_color[2], 1.0f); 525 gpuMat.fill_mix_color = new Vector4(mat.fill_mix_color[0], mat.fill_mix_color[1], mat.fill_mix_color[2], 1.0f); 526 gpuMat.fill_uv_rot_scale = new Vector4(mat.fill_uv_rot_scale[0], mat.fill_uv_rot_scale[1], mat.fill_uv_rot_scale[2], mat.fill_uv_rot_scale[3]); 527 528 // Pack fill_uv_offset and alignment_rot into a single Vector4 529 gpuMat.fill_uv_offset_alignment_rot = new Vector4(mat.fill_uv_offset[0], mat.fill_uv_offset[1], mat.alignment_rot[0], mat.alignment_rot[1]); 530 531 gpuMat.stroke_texture_mix = mat.stroke_texture_mix; 532 gpuMat.stroke_u_scale = mat.stroke_u_scale; 533 gpuMat.fill_texture_mix = mat.fill_texture_mix; 534 gpuMat.flag = mat.flag; 535 536 materialDataList.Add(gpuMat); 537 } 538 539 // Create the ComputeBuffer and upload the data. 540 materialBuffer = new ComputeBuffer(materialDataList.Count, System.Runtime.InteropServices.Marshal.SizeOf(typeof(GpMaterialData))); 541 materialBuffer.SetData(materialDataList); 542 } 543 544 void ReleaseBuffers() 545 { 546 if (posBuffer != null) 547 { 548 posBuffer.Release(); 549 posBuffer = null; 550 } 551 if (strokesBuffer != null) 552 { 553 strokesBuffer.Release(); 554 strokesBuffer = null; 555 } 556 if (uvOpacityBuffer != null) 557 { 558 uvOpacityBuffer.Release(); 559 uvOpacityBuffer = null; 560 } 561 if (vcolBuffer != null) 562 { 563 vcolBuffer.Release(); 564 vcolBuffer = null; 565 } 566 if (fcolBuffer != null) 567 { 568 fcolBuffer.Release(); 569 fcolBuffer = null; 570 } 571 572 if (materialBuffer != null) 573 { 574 materialBuffer.Release(); 575 materialBuffer = null; 576 } 577 buffersCreated = false; 578 } 579 580 void OnDestroy() 581 { 582 ReleaseBuffers(); 583 } 584 585 void OnDisable() 586 { 587 var targetMaterial = GetComponent<MeshRenderer>().sharedMaterial; 588 589 // Unbind buffers from material to avoid dangling references 590 if (targetMaterial != null) 591 { 592 targetMaterial.SetBuffer("_Pos", (ComputeBuffer)null); 593 targetMaterial.SetBuffer("_Strokes", (ComputeBuffer)null); 594 targetMaterial.SetBuffer("_UvOpacity", (ComputeBuffer)null); 595 targetMaterial.SetBuffer("_Vcol", (ComputeBuffer)null); 596 targetMaterial.SetBuffer("_Fcol", (ComputeBuffer)null); 597 targetMaterial.SetBuffer("gp_materials", (ComputeBuffer)null); 598 } 599 ReleaseBuffers(); 600 } 601 }