欢迎光临散文网 会员登陆 & 注册

使用脚本放置探针

2020-06-12 10:00 作者:unity_某某师_高锦锦  | 我要投稿

手动大量放置光照探针可能十分耗时。您可以通过编写自己的编辑器脚本来自动放置光照探针。您的脚本可创建具有 LightProbeGroup 组件的新游戏对象,然后您可以根据您选择编程的任何规则单独添加探针位置。

例如,以下脚本可将光照探针放置在圆形或圆环中。

using UnityEngine; 

using System.Collections.Generic; 

[RequireComponent (typeof (LightProbeGroup))] 

public class LightProbesTetrahedralGrid : MonoBehaviour { 

 // 公用 

public float m_Side = 1.0f; 

public float m_Radius = 5.0f; 

public float m_InnerRadius = 0.1f;

public float m_Height = 2.0f;

public uint m_Levels = 3; 

const float kMinSide = 0.05f; 

const float kMinHeight = 0.05f; 

const float kMinInnerRadius = 0.1f; 

const uint kMinIterations = 4; 

 public void OnValidate () {  

m_Side = Mathf.Max (kMinSide, m_Side);  

m_Height = Mathf.Max (kMinHeight, m_Height);  

if (m_InnerRadius < kMinInnerRadius)  {

TriangleProps props = new TriangleProps (m_Side);   

m_Radius = Mathf.Max (props.circumscribedCircleRadius + 0.01f, m_Radius);  

}  

else  {   

m_Radius = Mathf.Max (0.1f, m_Radius);   

m_InnerRadius = Mathf.Min (m_Radius, m_InnerRadius);  

} } 

struct TriangleProps {  

public TriangleProps (float triangleSide)  {   

side = triangleSide;   

halfSide = side / 2.0f;   

height = Mathf.Sqrt (3.0f) * side / 2.0f;   

inscribedCircleRadius = Mathf.Sqrt (3.0f) * side / 6.0f;   

circumscribedCircleRadius = 2.0f * height / 3.0f;  

}  

public float side;  

public float halfSide;  

public float height;  

public float inscribedCircleRadius;  

public float circumscribedCircleRadius; 

}; 

private TriangleProps m_TriangleProps; 

public void Generate () {  

LightProbeGroup lightProbeGroup = GetComponent<LightProbeGroup> ();  

List<Vector3> positions = new List<Vector3> ();  

m_TriangleProps = new TriangleProps (m_Side);  

if (m_InnerRadius < kMinInnerRadius)   

GenerateCylinder (m_TriangleProps, m_Radius, m_Height, m_Levels, positions);  

else   

GenerateRing (m_TriangleProps, m_Radius, m_InnerRadius, m_Height, m_Levels, positions);  

lightProbeGroup.probePositions = positions.ToArray (); 

static void AttemptAdding (Vector3 position, Vector3 center, float distanceCutoffSquared, List<Vector3> outPositions) {  

if ((position - center).sqrMagnitude < distanceCutoffSquared)   

outPositions.Add (position); 

 } 

 uint CalculateCylinderIterations (TriangleProps props, float radius) {  

int iterations = Mathf.CeilToInt ((radius + props.height - props.inscribedCircleRadius) / props.height);  

if (iterations > 0)   

return (uint)iterations;  return 0; 

void GenerateCylinder (TriangleProps props, float radius, float height, uint levels, List<Vector3> outPositions) {  

uint iterations = CalculateCylinderIterations (props, radius);  

float distanceCutoff = radius; 

 float distanceCutoffSquared = distanceCutoff * distanceCutoff;  

Vector3 up = new Vector3 (props.circumscribedCircleRadius, 0.0f, 0.0f);  

Vector3 leftDown = new Vector3 (-props.inscribedCircleRadius, 0.0f, -props.halfSide);

 Vector3 rightDown = new Vector3 (-props.inscribedCircleRadius, 0.0f, props.halfSide); 

 for (uint l = 0; l < levels; l++)  {   

float tLevel = levels == 1 ? 0 : (float)l / (float)(levels - 1);  

 Vector3 center = new Vector3 (0.0f, tLevel * height, 0.0f);   

if (l % 2 == 0)   {    for (uint i = 0; i < iterations; i++)    {     

Vector3 upCorner = center + up + (float)i * up * 2.0f * 3.0f / 2.0f;     

Vector3 leftDownCorner = center + leftDown + (float)i * leftDown * 2.0f * 3.0f / 2.0f;     

Vector3 rightDownCorner = center + rightDown + (float)i * rightDown * 2.0f * 3.0f / 2.0f;     

AttemptAdding (upCorner, center, distanceCutoffSquared, outPositions);     

AttemptAdding (leftDownCorner, center, distanceCutoffSquared, outPositions);     

AttemptAdding (rightDownCorner, center, distanceCutoffSquared, outPositions);     

Vector3 leftDownUp = upCorner - leftDownCorner;     

Vector3 upRightDown = rightDownCorner - upCorner;     

Vector3 rightDownLeftDown = leftDownCorner - rightDownCorner;     

uint subdiv = 3 * i + 1;     

for (uint s = 1; s < subdiv; s++)     {      

Vector3 leftDownUpSubdiv = leftDownCorner + leftDownUp * (float)s / (float)subdiv;

 AttemptAdding (leftDownUpSubdiv, center, distanceCutoffSquared, outPositions); 

Vector3 upRightDownSubdiv = upCorner + upRightDown * (float)s / (float)subdiv;

AttemptAdding (upRightDownSubdiv, center, distanceCutoffSquared, outPositions);

Vector3 rightDownLeftDownSubdiv = rightDownCorner + rightDownLeftDown * (float)s / (float)subdiv;

AttemptAdding (rightDownLeftDownSubdiv, center, distanceCutoffSquared, outPositions);

}}}

else{    

for (uint i = 0; i < iterations; i++) {     

Vector3 upCorner = center + (float)i * (2.0f * up * 3.0f / 2.0f);     

Vector3 leftDownCorner = center + (float)i * (2.0f * leftDown * 3.0f / 2.0f);     

Vector3 rightDownCorner = center + (float)i * (2.0f * rightDown * 3.0f / 2.0f);     

AttemptAdding (upCorner, center, distanceCutoffSquared, outPositions);     

AttemptAdding (leftDownCorner, center, distanceCutoffSquared, outPositions); 

AttemptAdding (rightDownCorner, center, distanceCutoffSquared, outPositions);     

Vector3 leftDownUp = upCorner - leftDownCorner;     

Vector3 upRightDown = rightDownCorner - upCorner;     

Vector3 rightDownLeftDown = leftDownCorner - rightDownCorner;     

uint subdiv = 3 * i;     for (uint s = 1; s < subdiv; s++){      

Vector3 leftDownUpSubdiv = leftDownCorner + leftDownUp * (float)s / (float)subdiv;

 AttemptAdding (leftDownUpSubdiv, center, distanceCutoffSquared, outPositions); 

 Vector3 upRightDownSubdiv = upCorner + upRightDown * (float)s / (float)subdiv;

 AttemptAdding (upRightDownSubdiv, center, distanceCutoffSquared, outPositions);

 Vector3 rightDownLeftDownSubdiv = rightDownCorner + rightDownLeftDown * (float)s / (float)subdiv;     

 AttemptAdding (rightDownLeftDownSubdiv, center, distanceCutoffSquared, outPositions);

}}}}} 

void GenerateRing (TriangleProps props, float radius, float innerRadius, float height, uint levels, List<Vector3> outPositions) {  

float chordLength = props.side;  

float angle = Mathf.Clamp (2.0f * Mathf.Asin (chordLength / (2.0f * radius)), 0.01f, 2.0f * Mathf.PI);  

uint slicesAtRadius = (uint)Mathf.FloorToInt (2.0f * Mathf.PI / angle);  

uint layers = (uint)Mathf.Max (Mathf.Ceil ((radius - innerRadius) / props.height), 0.0f);  

for (uint level = 0; level < levels; level++)  {   

float tLevel = levels == 1 ? 0 : (float)level / (float)(levels - 1);   

float y = height * tLevel;   

float iterationOffset0 = level % 2 == 0 ? 0.0f : 0.5f;   

for (uint layer = 0; layer < layers; layer++)   {

float tLayer = layers == 1 ? 1.0f : (float)layer / (float)(layers - 1); 

float tIterations = (tLayer * (radius - innerRadius) + innerRadius - kMinInnerRadius) / (radius - kMinInnerRadius);    

uint slices = (uint)Mathf.CeilToInt (Mathf.Lerp (kMinIterations, slicesAtRadius, tIterations));

 float x = innerRadius + (radius - innerRadius) * tLayer;    

Vector3 position = new Vector3 (x, y, 0.0f);    

float layerSliceOffset = layer % 2 == 0 ? 0.0f : 0.5f;    

for (uint slice = 0; slice < slices; slice++)    {     

Quaternion rotation = Quaternion.Euler (0.0f, (slice + iterationOffset0 + layerSliceOffset) * 360.0f / (float)slices, 0.0f);     

outPositions.Add (rotation * position);    

}   }  } } }

使用脚本放置探针的评论 (共 条)

分享到微博请遵守国家法律