重新导入obi

This commit is contained in:
2026-04-06 11:35:18 +08:00
parent 05fa2d6e5e
commit ae3002a0e2
1643 changed files with 232496 additions and 13 deletions

View File

@@ -0,0 +1,166 @@
using System;
using UnityEngine;
namespace Obi
{
[AddComponentMenu("Physics/Obi/Obi Distance Field Renderer", 1003)]
[ExecuteInEditMode]
[RequireComponent(typeof(ObiCollider))]
public class ObiDistanceFieldRenderer : MonoBehaviour
{
public enum Axis
{
X = 0,
Y = 1,
Z = 2,
}
public Axis axis;
[Range(0, 1)]
public float slice = 0.25f;
public float maxDistance = 0.5f;
private ObiCollider unityCollider;
private Material material;
private Mesh planeMesh;
private Texture2D cutawayTexture;
private float sampleSize;
private int sampleCount;
private Color boundsColor = new Color(1, 1, 1, 0.5f);
public void Awake()
{
unityCollider = GetComponent<ObiCollider>();
}
public void OnEnable()
{
material = GameObject.Instantiate(Resources.Load<Material>("ObiMaterials/DistanceFieldRendering"));
material.hideFlags = HideFlags.HideAndDontSave;
}
public void OnDisable()
{
Cleanup();
}
private void Cleanup()
{
GameObject.DestroyImmediate(cutawayTexture);
GameObject.DestroyImmediate(planeMesh);
GameObject.DestroyImmediate(material);
}
private void ResizeTexture()
{
if (cutawayTexture == null)
{
cutawayTexture = new Texture2D(sampleCount, sampleCount, TextureFormat.RHalf, false);
cutawayTexture.wrapMode = TextureWrapMode.Clamp;
cutawayTexture.hideFlags = HideFlags.HideAndDontSave;
}
else
cutawayTexture.Reinitialize(sampleCount, sampleCount);
}
private void CreatePlaneMesh(ObiDistanceField field)
{
if (field != null && planeMesh == null)
{
float uvBorder = (1 - field.FieldBounds.size[0] / (sampleSize * sampleCount)) * 0.5f;
planeMesh = new Mesh();
planeMesh.vertices = new Vector3[]{new Vector3(-0.5f,-0.5f,0),
new Vector3(0.5f,-0.5f,0),
new Vector3(-0.5f,0.5f,0),
new Vector3(0.5f,0.5f,0)};
planeMesh.uv = new Vector2[]{new Vector2(uvBorder,uvBorder),
new Vector2(1-uvBorder,uvBorder),
new Vector2(uvBorder,1-uvBorder),
new Vector2(1-uvBorder,1-uvBorder)};
planeMesh.normals = new Vector3[] { -Vector3.forward, -Vector3.forward, -Vector3.forward, -Vector3.forward };
planeMesh.triangles = new int[] { 0, 2, 1, 2, 3, 1 };
}
}
private void RefreshCutawayTexture(ObiDistanceField field)
{
if (field == null)
return;
Bounds b = field.FieldBounds;
sampleSize = field.EffectiveSampleSize;
sampleCount = (int)(b.size[0] / sampleSize) + 1;
CreatePlaneMesh(field);
ResizeTexture();
float sweep = (sampleCount * slice) * sampleSize;
Vector3 origin = b.center - b.extents;
for (int x = 0; x < sampleCount; ++x)
for (int y = 0; y < sampleCount; ++y)
{
Vector3 offset = Vector3.zero;
switch (axis)
{
case Axis.X: offset = new Vector3(sweep, y * sampleSize, x * sampleSize); break;
case Axis.Y: offset = new Vector3(x * sampleSize, sweep, y * sampleSize); break;
case Axis.Z: offset = new Vector3(x * sampleSize, y * sampleSize, sweep); break;
}
float distance = ASDF.Sample(field.nodes, origin + offset);
float value = ObiUtils.Remap(distance, -maxDistance, maxDistance, 0, 1);
cutawayTexture.SetPixel(x, y, new Color(value, 0, 0));
}
cutawayTexture.Apply();
}
private void DrawCutawayPlane(ObiDistanceField field, Matrix4x4 matrix)
{
if (field == null)
return;
RefreshCutawayTexture(field);
material.mainTexture = cutawayTexture;
material.SetPass(0);
Quaternion rotation = Quaternion.identity;
Vector3 offset = Vector3.zero;
offset[(int)axis] = field.FieldBounds.size[0];
if (axis == Axis.Y)
rotation = Quaternion.Euler(90, 0, 0);
else if (axis == Axis.X)
rotation = Quaternion.Euler(0, -90, 0);
Matrix4x4 sc = Matrix4x4.TRS(field.FieldBounds.center + offset * (slice - 0.5f), rotation, Vector3.one * field.FieldBounds.size[0]);
Graphics.DrawMeshNow(planeMesh, matrix * sc);
}
public void OnDrawGizmos()
{
if (unityCollider != null && unityCollider.distanceField != null && unityCollider.distanceField.Initialized && material != null)
{
DrawCutawayPlane(unityCollider.distanceField, transform.localToWorldMatrix);
Gizmos.color = boundsColor;
Gizmos.DrawWireCube(unityCollider.distanceField.FieldBounds.center, unityCollider.distanceField.FieldBounds.size);
}
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 382f1f06ad1a84a9f8fb3a60b50dd9b7
timeCreated: 1516041863
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {fileID: 2800000, guid: 41cb9d55de5b24458b45e5465606249a, type: 3}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,92 @@
using UnityEngine;
using Unity.Profiling;
using System;
using System.Threading;
using System.Collections;
using System.Collections.Generic;
namespace Obi
{
[AddComponentMenu("Physics/Obi/Obi Instanced Particle Renderer", 1001)]
[ExecuteInEditMode]
[RequireComponent(typeof(ObiActor))]
public class ObiInstancedParticleRenderer : MonoBehaviour
{
static ProfilerMarker m_DrawParticlesPerfMarker = new ProfilerMarker("DrawParticles");
public bool render = true;
public Mesh mesh;
public Material material;
public Vector3 instanceScale = Vector3.one;
private List<Matrix4x4> matrices = new List<Matrix4x4>();
private List<Vector4> colors = new List<Vector4>();
private MaterialPropertyBlock mpb;
int meshesPerBatch = 0;
int batchCount;
public void OnEnable()
{
GetComponent<ObiActor>().OnInterpolate += DrawParticles;
}
public void OnDisable()
{
GetComponent<ObiActor>().OnInterpolate -= DrawParticles;
}
void DrawParticles(ObiActor actor)
{
using (m_DrawParticlesPerfMarker.Auto())
{
if (mesh == null || material == null || !render || !isActiveAndEnabled || !actor.isActiveAndEnabled || actor.solver == null)
{
return;
}
ObiSolver solver = actor.solver;
// figure out the size of our instance batches:
meshesPerBatch = Constants.maxInstancesPerBatch;
batchCount = actor.particleCount / meshesPerBatch + 1;
meshesPerBatch = Mathf.Min(meshesPerBatch, actor.particleCount);
Vector4 basis1 = new Vector4(1, 0, 0, 0);
Vector4 basis2 = new Vector4(0, 1, 0, 0);
Vector4 basis3 = new Vector4(0, 0, 1, 0);
//Convert particle data to mesh instances:
for (int i = 0; i < batchCount; i++)
{
matrices.Clear();
colors.Clear();
mpb = new MaterialPropertyBlock();
int limit = Mathf.Min((i + 1) * meshesPerBatch, actor.activeParticleCount);
for (int j = i * meshesPerBatch; j < limit; ++j)
{
int solverIndex = actor.solverIndices[j];
actor.GetParticleAnisotropy(solverIndex, ref basis1, ref basis2, ref basis3);
matrices.Add(Matrix4x4.TRS(actor.GetParticlePosition(solverIndex),
actor.GetParticleOrientation(solverIndex),
Vector3.Scale(new Vector3(basis1[3], basis2[3], basis3[3]), instanceScale)));
colors.Add(actor.GetParticleColor(solverIndex));
}
if (colors.Count > 0)
mpb.SetVectorArray("_Color", colors);
// Send the meshes to be drawn:
Graphics.DrawMeshInstanced(mesh, 0, material, matrices, mpb);
}
}
}
}
}

View File

@@ -0,0 +1,13 @@
fileFormatVersion: 2
guid: 356b834afda224f73a26e39580b330f1
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences:
- mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0}
- material: {fileID: 2100000, guid: 2b7dfa8ebb76247318ce5b7df4b97484, type: 2}
executionOrder: 0
icon: {fileID: 2800000, guid: f424a87c9f03240c2870a664731ac9aa, type: 3}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,110 @@
using UnityEngine;
using Unity.Profiling;
using System;
using System.Threading;
using System.Collections;
using System.Collections.Generic;
namespace Obi
{
[AddComponentMenu("Physics/Obi/Obi Particle Renderer", 1000)]
[ExecuteInEditMode]
[RequireComponent(typeof(ObiActor))]
public class ObiParticleRenderer : MonoBehaviour
{
static ProfilerMarker m_DrawParticlesPerfMarker = new ProfilerMarker("DrawParticles");
public bool render = true;
public Shader shader;
public Color particleColor = Color.white;
public float radiusScale = 1;
private ParticleImpostorRendering m_Impostors;
public IEnumerable<Mesh> ParticleMeshes
{
get { return impostors.Meshes; }
}
public ParticleImpostorRendering impostors
{
get {
if (m_Impostors == null)
m_Impostors = new ParticleImpostorRendering();
return m_Impostors;
}
}
public Material ParticleMaterial { get; private set; }
public void OnEnable()
{
GetComponent<ObiActor>().OnInterpolate += DrawParticles;
}
public void OnDisable()
{
GetComponent<ObiActor>().OnInterpolate -= DrawParticles;
if (m_Impostors != null)
m_Impostors.ClearMeshes();
DestroyImmediate(ParticleMaterial);
}
void CreateMaterialIfNeeded()
{
if (shader != null)
{
if (!shader.isSupported)
Debug.LogWarning("Particle rendering shader not suported.");
if (ParticleMaterial == null || ParticleMaterial.shader != shader)
{
DestroyImmediate(ParticleMaterial);
ParticleMaterial = new Material(shader);
ParticleMaterial.hideFlags = HideFlags.HideAndDontSave;
}
}
}
void DrawParticles(ObiActor actor)
{
using (m_DrawParticlesPerfMarker.Auto())
{
if (!isActiveAndEnabled || !actor.isActiveAndEnabled || actor.solver == null)
{
impostors.ClearMeshes();
return;
}
CreateMaterialIfNeeded();
impostors.UpdateMeshes(actor);
DrawParticles();
}
}
private void DrawParticles()
{
if (ParticleMaterial != null)
{
ParticleMaterial.SetFloat("_RadiusScale", radiusScale);
ParticleMaterial.SetColor("_Color", particleColor);
// Send the meshes to be drawn:
if (render)
{
var meshes = ParticleMeshes;
foreach (Mesh mesh in meshes)
Graphics.DrawMesh(mesh, Matrix4x4.identity, ParticleMaterial, gameObject.layer);
}
}
}
}
}

View File

@@ -0,0 +1,13 @@
fileFormatVersion: 2
guid: c8b45ebbf86be4df6b0e6cd933812af2
timeCreated: 1521054123
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences:
- shader: {fileID: 4800000, guid: 801733041f66b49e1b3c2101471db877, type: 3}
executionOrder: 0
icon: {fileID: 2800000, guid: f424a87c9f03240c2870a664731ac9aa, type: 3}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,164 @@
using UnityEngine;
using Unity.Profiling;
using System.Collections;
using System.Collections.Generic;
namespace Obi
{
public class ParticleImpostorRendering
{
static ProfilerMarker m_ParticlesToMeshPerfMarker = new ProfilerMarker("ParticlesToMesh");
private List<Mesh> meshes = new List<Mesh>();
private List<Vector3> vertices = new List<Vector3>(4000);
private List<Vector3> normals = new List<Vector3>(4000);
private List<Color> colors = new List<Color>(4000);
private List<int> triangles = new List<int>(6000);
private List<Vector4> anisotropy1 = new List<Vector4>(4000);
private List<Vector4> anisotropy2 = new List<Vector4>(4000);
private List<Vector4> anisotropy3 = new List<Vector4>(4000);
int particlesPerDrawcall = 0;
int drawcallCount;
private Vector3 particleOffset0 = new Vector3(1, 1, 0);
private Vector3 particleOffset1 = new Vector3(-1, 1, 0);
private Vector3 particleOffset2 = new Vector3(-1, -1, 0);
private Vector3 particleOffset3 = new Vector3(1, -1, 0);
public IEnumerable<Mesh> Meshes
{
get { return meshes.AsReadOnly(); }
}
private void Apply(Mesh mesh)
{
mesh.Clear();
mesh.SetVertices(vertices);
mesh.SetNormals(normals);
mesh.SetColors(colors);
mesh.SetUVs(0, anisotropy1);
mesh.SetUVs(1, anisotropy2);
mesh.SetUVs(2, anisotropy3);
mesh.SetTriangles(triangles, 0, true);
}
public void ClearMeshes()
{
foreach (Mesh mesh in meshes)
GameObject.DestroyImmediate(mesh);
meshes.Clear();
}
public void UpdateMeshes(IObiParticleCollection collection, bool[] visible = null, Color[] tint = null)
{
using (m_ParticlesToMeshPerfMarker.Auto())
{
// figure out the size of our drawcall arrays:
particlesPerDrawcall = Constants.maxVertsPerMesh / 4;
drawcallCount = collection.activeParticleCount / particlesPerDrawcall + 1;
particlesPerDrawcall = Mathf.Min(particlesPerDrawcall, collection.activeParticleCount);
// If the amount of meshes we need to draw the particles has changed:
if (drawcallCount != meshes.Count)
{
// Re-generate meshes:
ClearMeshes();
for (int i = 0; i < drawcallCount; i++)
{
Mesh mesh = new Mesh();
mesh.name = "Particle impostors";
mesh.hideFlags = HideFlags.HideAndDontSave;
meshes.Add(mesh);
}
}
Vector3 position;
Vector4 basis1 = new Vector4(1, 0, 0, 0);
Vector4 basis2 = new Vector4(0, 1, 0, 0);
Vector4 basis3 = new Vector4(0, 0, 1, 0);
Color color;
int visibleLength = visible != null ? visible.Length : 0;
int tintLength = tint != null ? tint.Length : 0;
//Convert particle data to mesh geometry:
for (int i = 0; i < drawcallCount; i++)
{
// Clear all arrays
vertices.Clear();
normals.Clear();
colors.Clear();
triangles.Clear();
anisotropy1.Clear();
anisotropy2.Clear();
anisotropy3.Clear();
int index = 0;
int limit = Mathf.Min((i + 1) * particlesPerDrawcall, collection.activeParticleCount);
for (int j = i * particlesPerDrawcall; j < limit; ++j)
{
if (j < visibleLength && !visible[j])
continue;
int runtimeIndex = collection.GetParticleRuntimeIndex(j);
position = collection.GetParticlePosition(runtimeIndex);
collection.GetParticleAnisotropy(runtimeIndex, ref basis1, ref basis2, ref basis3);
color = collection.GetParticleColor(runtimeIndex);
if (j < tintLength)
color *= tint[j];
vertices.Add(position);
vertices.Add(position);
vertices.Add(position);
vertices.Add(position);
normals.Add(particleOffset0);
normals.Add(particleOffset1);
normals.Add(particleOffset2);
normals.Add(particleOffset3);
colors.Add(color);
colors.Add(color);
colors.Add(color);
colors.Add(color);
anisotropy1.Add(basis1);
anisotropy1.Add(basis1);
anisotropy1.Add(basis1);
anisotropy1.Add(basis1);
anisotropy2.Add(basis2);
anisotropy2.Add(basis2);
anisotropy2.Add(basis2);
anisotropy2.Add(basis2);
anisotropy3.Add(basis3);
anisotropy3.Add(basis3);
anisotropy3.Add(basis3);
anisotropy3.Add(basis3);
triangles.Add(index + 2);
triangles.Add(index + 1);
triangles.Add(index);
triangles.Add(index + 3);
triangles.Add(index + 2);
triangles.Add(index);
index += 4;
}
Apply(meshes[i]);
}
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: bf17f48345c0f42a9a419ec65398dcd8
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,70 @@
using System;
using UnityEngine;
using UnityEngine.Rendering;
namespace Obi{
public class ShadowmapExposer : MonoBehaviour
{
Light unityLight;
CommandBuffer afterShadow = null;
public ObiParticleRenderer[] particleRenderers;
public void Awake(){
unityLight = GetComponent<Light>();
}
public void OnEnable(){
Cleanup();
afterShadow = new CommandBuffer();
afterShadow.name = "FluidShadows";
unityLight.AddCommandBuffer (LightEvent.AfterShadowMapPass, afterShadow);
}
public void OnDisable(){
Cleanup();
}
private void Cleanup(){
if (afterShadow != null){
unityLight.RemoveCommandBuffer (LightEvent.AfterShadowMapPass,afterShadow);
afterShadow = null;
}
}
public void SetupFluidShadowsCommandBuffer()
{
afterShadow.Clear();
if (particleRenderers == null)
return;
foreach(ObiParticleRenderer renderer in particleRenderers){
if (renderer != null){
foreach(Mesh mesh in renderer.ParticleMeshes)
afterShadow.DrawMesh(mesh,Matrix4x4.identity,renderer.ParticleMaterial,0,1);
}
}
afterShadow.SetGlobalTexture ("_MyShadowMap", new RenderTargetIdentifier(BuiltinRenderTextureType.CurrentActive));
}
// Use this for initialization
void Update()
{
bool act = gameObject.activeInHierarchy && enabled;
if (!act || particleRenderers == null || particleRenderers.Length == 0)
{
Cleanup();
return;
}
if (afterShadow != null)
{
SetupFluidShadowsCommandBuffer();
}
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: dbf7247281ef14860853fa0ee2cb4829
timeCreated: 1463174681
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: