浏览代码

Merge pull request #1247 from Unity-Technologies/lw/api-review-v1

Lw/api review v1
/main
GitHub 7 年前
当前提交
a346a121
共有 12 个文件被更改,包括 169 次插入195 次删除
  1. 2
      ScriptableRenderPipeline/LightweightPipeline/LWRP/Data/LightweightPipelineEditorResources.cs
  2. 6
      ScriptableRenderPipeline/LightweightPipeline/LWRP/Editor/ShaderGUI/LightweightStandardSimpleLightingGUI.cs
  3. 2
      ScriptableRenderPipeline/LightweightPipeline/LWRP/Editor/ShaderGraph/LightWeightPBRSubShader.cs
  4. 2
      ScriptableRenderPipeline/LightweightPipeline/LWRP/Editor/ShaderGraph/LightWeightUnlitSubShader.cs
  5. 3
      ScriptableRenderPipeline/LightweightPipeline/LWRP/Editor/ShaderPreprocessor.cs
  6. 46
      ScriptableRenderPipeline/LightweightPipeline/LWRP/LightweightPipeline.cs
  7. 134
      ScriptableRenderPipeline/LightweightPipeline/LWRP/LightweightPipelineCore.cs
  8. 4
      ScriptableRenderPipeline/LightweightPipeline/LWRP/LightweightShadowPass.cs
  9. 4
      ScriptableRenderPipeline/LightweightPipeline/LWRP/SceneViewDrawMode.cs
  10. 1
      ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/Terrain/LightweightPassLitTerrain.hlsl
  11. 13
      ScriptableRenderPipeline/LightweightPipeline/LWRP/LightweightPipelineUtils.cs.meta
  12. 147
      ScriptableRenderPipeline/LightweightPipeline/LWRP/LightweightPipelineUtils.cs

2
ScriptableRenderPipeline/LightweightPipeline/LWRP/Data/LightweightPipelineEditorResources.cs


public Material DefaultMaterial;
public Material DefaultParticleMaterial;
public Material DefaultTerrainMaterial;
}
}

6
ScriptableRenderPipeline/LightweightPipeline/LWRP/Editor/ShaderGUI/LightweightStandardSimpleLightingGUI.cs


private bool RequiresAlpha()
{
SurfaceType surfaceType = (SurfaceType) surfaceTypeProp.floatValue;
SurfaceType surfaceType = (SurfaceType)surfaceTypeProp.floatValue;
return alphaClipProp.floatValue > 0.0f || surfaceType == SurfaceType.Transparent;
}

if (RequiresAlpha())
{
GUI.enabled = false;
glossinessSourceProp.floatValue = (float)EditorGUILayout.Popup(Styles.glossinessSourceLabel, (int) GlossinessSource.SpecularAlpha, Styles.glossinessSourceNames);
glossinessSourceProp.floatValue = (float)EditorGUILayout.Popup(Styles.glossinessSourceLabel, (int)GlossinessSource.SpecularAlpha, Styles.glossinessSourceNames);
GUI.enabled = true;
}
else

EditorGUI.BeginChangeCheck();
float shininess = EditorGUILayout.Slider(Styles.shininessLabel, shininessProp.floatValue,
kMinShininessValue, 1.0f);
kMinShininessValue, 1.0f);
if (EditorGUI.EndChangeCheck())
shininessProp.floatValue = shininess;
EditorGUI.indentLevel -= 2;

2
ScriptableRenderPipeline/LightweightPipeline/LWRP/Editor/ShaderGraph/LightWeightPBRSubShader.cs


if (masterNode.IsSlotConnected(PBRMasterNode.AlphaThresholdSlotId))
defines.AddShaderChunk("#define _AlphaClip 1", true);
if(masterNode.surfaceType == SurfaceType.Transparent && masterNode.alphaMode == AlphaMode.Premultiply)
if (masterNode.surfaceType == SurfaceType.Transparent && masterNode.alphaMode == AlphaMode.Premultiply)
defines.AddShaderChunk("#define _ALPHAPREMULTIPLY_ON 1", true);
var templateLocation = GetTemplatePath(template);

2
ScriptableRenderPipeline/LightweightPipeline/LWRP/Editor/ShaderGraph/LightWeightUnlitSubShader.cs


if (masterNode.IsSlotConnected(UnlitMasterNode.AlphaThresholdSlotId))
defines.AddShaderChunk("#define _AlphaClip 1", true);
if(masterNode.surfaceType == SurfaceType.Transparent && masterNode.alphaMode == AlphaMode.Premultiply)
if (masterNode.surfaceType == SurfaceType.Transparent && masterNode.alphaMode == AlphaMode.Premultiply)
defines.AddShaderChunk("#define _ALPHAPREMULTIPLY_ON 1", true);
var templateLocation = GetTemplatePath(template);

3
ScriptableRenderPipeline/LightweightPipeline/LWRP/Editor/ShaderPreprocessor.cs


using UnityEngine.Experimental.Rendering;
using UnityEngine.Experimental.Rendering.LightweightPipeline;
using UnityEngine.Rendering;
using LightweightRP = UnityEngine.Experimental.Rendering.LightweightPipeline.LightweightPipeline;
namespace UnityEditor.Experimental.Rendering.LightweightPipeline
{

public void OnProcessShader(Shader shader, ShaderSnippetData snippetData, IList<ShaderCompilerData> compilerDataList)
{
PipelineCapabilities capabilities = UnityEngine.Experimental.Rendering.LightweightPipeline.LightweightPipeline.GetPipelineCapabilities();
PipelineCapabilities capabilities = LightweightRP.GetPipelineCapabilities();
int prevVariantCount = compilerDataList.Count;
for (int i = 0; i < compilerDataList.Count; ++i)

46
ScriptableRenderPipeline/LightweightPipeline/LWRP/LightweightPipeline.cs


// Setup global time properties (_Time, _SinTime, _CosTime)
context.SetupCameraProperties(m_CurrCamera, stereoEnabled);
if (LightweightUtils.HasFlag(frameRenderingConfiguration, FrameRenderingConfiguration.DepthPrePass))
if (CoreUtils.HasFlag(frameRenderingConfiguration, FrameRenderingConfiguration.DepthPrePass))
DepthPass(ref context, frameRenderingConfiguration);
if (screenspaceShadows)

renderQueueRange = RenderQueueRange.opaque
};
LightweightUtils.StartStereoRendering(m_CurrCamera, ref context, frameRenderingConfiguration);
StartStereoRendering(m_CurrCamera, ref context, frameRenderingConfiguration);
LightweightUtils.StopStereoRendering(m_CurrCamera, ref context, frameRenderingConfiguration);
StopStereoRendering(m_CurrCamera, ref context, frameRenderingConfiguration);
}
private void OpaqueTexturePass(ref ScriptableRenderContext context, FrameRenderingConfiguration frameRenderingConfiguration)

// TODO: There's currently an issue in the PostFX stack that has a one frame delay when an effect is enabled/disabled
// when an effect is disabled, HasOpaqueOnlyEffects returns true in the first frame, however inside render the effect
// state is update, causing RenderPostProcess here to not blit to FinalColorRT. Until the next frame the RT will have garbage.
if (LightweightUtils.HasFlag(config, FrameRenderingConfiguration.BeforeTransparentPostProcess))
if (CoreUtils.HasFlag(config, FrameRenderingConfiguration.BeforeTransparentPostProcess))
{
// When only have one effect in the stack we blit to a work RT then blit it back to active color RT.
// This seems like an extra blit but it saves us a depth copy/blit which has some corner cases like msaa depth resolve.

SetRenderTarget(cmd, m_CurrCameraColorRT, m_DepthRT);
}
if (LightweightUtils.HasFlag(config, FrameRenderingConfiguration.DepthCopy))
if (CoreUtils.HasFlag(config, FrameRenderingConfiguration.DepthCopy))
{
bool forceBlit = false;
if (m_MSAASamples > 1)

context.ExecuteCommandBuffer(cmd);
CommandBufferPool.Release(cmd);
}
if (m_Asset.RequireOpaqueTexture)
{
OpaqueTexturePass(ref context, config);

private void AfterTransparent(ref ScriptableRenderContext context, FrameRenderingConfiguration config)
{
if (!LightweightUtils.HasFlag(config, FrameRenderingConfiguration.PostProcess))
if (!CoreUtils.HasFlag(config, FrameRenderingConfiguration.PostProcess))
return;
CommandBuffer cmd = CommandBufferPool.Get("After Transparent");

if (msaaEnabled)
{
configuration |= FrameRenderingConfiguration.Msaa;
intermediateTexture = intermediateTexture || !LightweightUtils.PlatformSupportsMSAABackBuffer();
intermediateTexture = intermediateTexture || !PlatformSupportsMSAABackBuffer();
canSkipDepthCopy = false;
}

private RenderTextureDescriptor CreateRTDesc(FrameRenderingConfiguration renderingConfig, float scaler = 1.0f)
{
RenderTextureDescriptor desc;
if (LightweightUtils.HasFlag(renderingConfig, FrameRenderingConfiguration.Stereo))
if (CoreUtils.HasFlag(renderingConfig, FrameRenderingConfiguration.Stereo))
desc = XRSettings.eyeTextureDesc;
else
desc = new RenderTextureDescriptor(m_CurrCamera.pixelWidth, m_CurrCamera.pixelHeight);

CommandBuffer cmd = CommandBufferPool.Get("Setup Intermediate Resources");
int msaaSamples = (m_IsOffscreenCamera) ? Math.Min(m_CurrCamera.targetTexture.antiAliasing, m_Asset.MSAASampleCount) : m_Asset.MSAASampleCount;
msaaSamples = (LightweightUtils.HasFlag(renderingConfig, FrameRenderingConfiguration.Msaa)) ? msaaSamples : 1;
msaaSamples = (CoreUtils.HasFlag(renderingConfig, FrameRenderingConfiguration.Msaa)) ? msaaSamples : 1;
if (LightweightUtils.HasFlag(renderingConfig, FrameRenderingConfiguration.IntermediateTexture) || m_RequireDepthTexture)
if (CoreUtils.HasFlag(renderingConfig, FrameRenderingConfiguration.IntermediateTexture) || m_RequireDepthTexture)
SetupIntermediateRenderTextures(cmd, renderingConfig, shadows, msaaSamples);
context.ExecuteCommandBuffer(cmd);

depthRTDesc.depthBufferBits = kDepthStencilBufferBits;
// This also means we don't do a depth copy
bool doesDepthPrepass = LightweightUtils.HasFlag(renderingConfig, FrameRenderingConfiguration.DepthPrePass);
bool doesDepthPrepass = CoreUtils.HasFlag(renderingConfig, FrameRenderingConfiguration.DepthPrePass);
if (!doesDepthPrepass)
{
depthRTDesc.bindMS = msaaSamples > 1;

VisibleLight mainLight = lights[lightData.mainLightIndex];
Light mainLightRef = mainLight.light;
if (LightweightUtils.IsSupportedCookieType(mainLight.lightType) && mainLightRef.cookie != null)
if (IsSupportedCookieType(mainLight.lightType) && mainLightRef.cookie != null)
LightweightUtils.GetLightCookieMatrix(mainLight, out lightCookieMatrix);
GetLightCookieMatrix(mainLight, out lightCookieMatrix);
cmd.SetGlobalTexture(PerCameraBuffer._MainLightCookie, mainLightRef.cookie);
cmd.SetGlobalMatrix(PerCameraBuffer._WorldToLight, lightCookieMatrix);
}

RenderTargetIdentifier colorRT = BuiltinRenderTextureType.CameraTarget;
RenderTargetIdentifier depthRT = BuiltinRenderTextureType.None;
LightweightUtils.StartStereoRendering(m_CurrCamera, ref context, renderingConfig);
StartStereoRendering(m_CurrCamera, ref context, renderingConfig);
bool intermediateTexture = LightweightUtils.HasFlag(renderingConfig, FrameRenderingConfiguration.IntermediateTexture);
bool intermediateTexture = CoreUtils.HasFlag(renderingConfig, FrameRenderingConfiguration.IntermediateTexture);
if (intermediateTexture)
{
if (!m_IsOffscreenCamera)

// If rendering to an intermediate RT we resolve viewport on blit due to offset not being supported
// while rendering to a RT.
if (!intermediateTexture && !LightweightUtils.HasFlag(renderingConfig, FrameRenderingConfiguration.DefaultViewport))
if (!intermediateTexture && !CoreUtils.HasFlag(renderingConfig, FrameRenderingConfiguration.DefaultViewport))
cmd.SetViewport(m_CurrCamera.pixelRect);
context.ExecuteCommandBuffer(cmd);

{
cmd.Blit(m_CurrCameraColorRT, BuiltinRenderTextureType.CameraTarget);
}
else if (LightweightUtils.HasFlag(renderingConfig, FrameRenderingConfiguration.IntermediateTexture))
else if (CoreUtils.HasFlag(renderingConfig, FrameRenderingConfiguration.IntermediateTexture))
if (LightweightUtils.HasFlag(renderingConfig, FrameRenderingConfiguration.Stereo))
if (CoreUtils.HasFlag(renderingConfig, FrameRenderingConfiguration.Stereo))
if (!LightweightUtils.HasFlag(renderingConfig, FrameRenderingConfiguration.PostProcess))
if (!CoreUtils.HasFlag(renderingConfig, FrameRenderingConfiguration.PostProcess))
Blit(cmd, renderingConfig, m_CurrCameraColorRT, BuiltinRenderTextureType.CameraTarget, blitMaterial);
}

CommandBufferPool.Release(cmd);
if (LightweightUtils.HasFlag(renderingConfig, FrameRenderingConfiguration.Stereo))
if (CoreUtils.HasFlag(renderingConfig, FrameRenderingConfiguration.Stereo))
{
context.StopMultiEye(m_CurrCamera);
context.StereoEndRender(m_CurrCamera);

private void Blit(CommandBuffer cmd, FrameRenderingConfiguration renderingConfig, RenderTargetIdentifier sourceRT, RenderTargetIdentifier destRT, Material material = null)
{
cmd.SetGlobalTexture(m_BlitTexID, sourceRT);
if (LightweightUtils.HasFlag(renderingConfig, FrameRenderingConfiguration.DefaultViewport))
if (CoreUtils.HasFlag(renderingConfig, FrameRenderingConfiguration.DefaultViewport))
{
cmd.Blit(sourceRT, destRT, material);
}

SetRenderTarget(cmd, destRT);
cmd.SetViewProjectionMatrices(Matrix4x4.identity, Matrix4x4.identity);
cmd.SetViewport(m_CurrCamera.pixelRect);
LightweightUtils.DrawFullScreen(cmd, m_BlitMaterial);
DrawFullScreen(cmd, m_BlitMaterial);
}
}

134
ScriptableRenderPipeline/LightweightPipeline/LWRP/LightweightPipelineCore.cs


using System;
using System.Collections.Generic;
public enum FrameRenderingConfiguration
{
None = (0 << 0),
Stereo = (1 << 0),
Msaa = (1 << 1),
BeforeTransparentPostProcess = (1 << 2),
PostProcess = (1 << 3),
DepthPrePass = (1 << 4),
DepthCopy = (1 << 5),
DefaultViewport = (1 << 6),
IntermediateTexture = (1 << 7)
}
[Flags]
public enum PipelineCapabilities
{
AdditionalLights = (1 << 0),

SoftShadows = (1 << 4),
}
public class CameraComparer : IComparer<Camera>
{
public int Compare(Camera lhs, Camera rhs)
{
return (int)(lhs.depth - rhs.depth);
}
}
public class LightweightKeywords
{
public static readonly string AdditionalLightsText = "_ADDITIONAL_LIGHTS";

public partial class LightweightPipeline
{
static Mesh s_FullscreenMesh = null;
public static Mesh fullscreenMesh
{
get
{
if (s_FullscreenMesh != null)
return s_FullscreenMesh;
float topV = 1.0f;
float bottomV = 0.0f;
Mesh mesh = new Mesh { name = "Fullscreen Quad" };
mesh.SetVertices(new List<Vector3>
{
new Vector3(-1.0f, -1.0f, 0.0f),
new Vector3(-1.0f, 1.0f, 0.0f),
new Vector3(1.0f, -1.0f, 0.0f),
new Vector3(1.0f, 1.0f, 0.0f)
});
mesh.SetUVs(0, new List<Vector2>
{
new Vector2(0.0f, bottomV),
new Vector2(0.0f, topV),
new Vector2(1.0f, bottomV),
new Vector2(1.0f, topV)
});
mesh.SetIndices(new[] { 0, 1, 2, 2, 1, 3 }, MeshTopology.Triangles, 0, false);
mesh.UploadMeshData(true);
return mesh;
}
}
static PipelineCapabilities s_PipelineCapabilities;
public static PipelineCapabilities GetPipelineCapabilities()

bool anyShadows = pipelineAsset.SupportsDirectionalShadows || pipelineAsset.SupportsLocalShadows;
if (pipelineAsset.SupportsSoftShadows && anyShadows)
s_PipelineCapabilities |= PipelineCapabilities.SoftShadows;
}
public static void DrawFullScreen(CommandBuffer commandBuffer, Material material,
MaterialPropertyBlock properties = null, int shaderPassId = 0)
{
commandBuffer.DrawMesh(fullscreenMesh, Matrix4x4.identity, material, 0, shaderPassId, properties);
}
public static void StartStereoRendering(Camera camera, ref ScriptableRenderContext context, FrameRenderingConfiguration renderingConfiguration)
{
if (CoreUtils.HasFlag(renderingConfiguration, FrameRenderingConfiguration.Stereo))
context.StartMultiEye(camera);
}
public static void StopStereoRendering(Camera camera, ref ScriptableRenderContext context, FrameRenderingConfiguration renderingConfiguration)
{
if (CoreUtils.HasFlag(renderingConfiguration, FrameRenderingConfiguration.Stereo))
context.StopMultiEye(camera);
}
public static void GetLightCookieMatrix(VisibleLight light, out Matrix4x4 cookieMatrix)
{
cookieMatrix = Matrix4x4.Inverse(light.localToWorld);
if (light.lightType == LightType.Directional)
{
float scale = 1.0f / light.light.cookieSize;
// apply cookie scale and offset by 0.5 to convert from [-0.5, 0.5] to texture space [0, 1]
Vector4 row0 = cookieMatrix.GetRow(0);
Vector4 row1 = cookieMatrix.GetRow(1);
cookieMatrix.SetRow(0, new Vector4(row0.x * scale, row0.y * scale, row0.z * scale, row0.w * scale + 0.5f));
cookieMatrix.SetRow(1, new Vector4(row1.x * scale, row1.y * scale, row1.z * scale, row1.w * scale + 0.5f));
}
else if (light.lightType == LightType.Spot)
{
// we want out.w = 2.0 * in.z / m_CotanHalfSpotAngle
// c = cotHalfSpotAngle
// 1 0 0 0
// 0 1 0 0
// 0 0 1 0
// 0 0 2/c 0
// the "2" will be used to scale .xy for the cookie as in .xy/2 + 0.5
float scale = 1.0f / light.range;
float halfSpotAngleRad = Mathf.Deg2Rad * light.spotAngle * 0.5f;
float cs = Mathf.Cos(halfSpotAngleRad);
float ss = Mathf.Sin(halfSpotAngleRad);
float cotHalfSpotAngle = cs / ss;
Matrix4x4 scaleMatrix = Matrix4x4.identity;
scaleMatrix.m00 = scaleMatrix.m11 = scaleMatrix.m22 = scale;
scaleMatrix.m33 = 0.0f;
scaleMatrix.m32 = scale * (2.0f / cotHalfSpotAngle);
cookieMatrix = scaleMatrix * cookieMatrix;
}
// Remaining light types don't support cookies
}
public static bool IsSupportedShadowType(LightType lightType)
{
return lightType == LightType.Directional || lightType == LightType.Spot;
}
public static bool IsSupportedCookieType(LightType lightType)
{
return lightType == LightType.Directional || lightType == LightType.Spot;
}
public static bool PlatformSupportsMSAABackBuffer()
{
#if UNITY_ANDROID || UNITY_IPHONE || UNITY_TVOS || UNITY_SAMSUNGTV
return true;
#else
return false;
#endif
}
}
}

4
ScriptableRenderPipeline/LightweightPipeline/LWRP/LightweightShadowPass.cs


cmd.ClearRenderTarget(true, true, Color.white);
cmd.Blit(m_ScreenSpaceShadowmapTexture, m_ScreenSpaceShadowmapTexture, m_ScreenSpaceShadowsMaterial);
LightweightUtils.StartStereoRendering(camera, ref context, frameRenderingConfiguration);
LightweightPipeline.StartStereoRendering(camera, ref context, frameRenderingConfiguration);
LightweightUtils.StopStereoRendering(camera, ref context, frameRenderingConfiguration);
LightweightPipeline.StopStereoRendering(camera, ref context, frameRenderingConfiguration);
CommandBufferPool.Release(cmd);
}

4
ScriptableRenderPipeline/LightweightPipeline/LWRP/SceneViewDrawMode.cs


#if UNITY_EDITOR
#if UNITY_EDITOR
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

cameraMode.drawMode == DrawCameraMode.ValidateMetalSpecular ||
cameraMode.drawMode == DrawCameraMode.ShadowMasks ||
cameraMode.drawMode == DrawCameraMode.LightOverlap
)
)
return false;
return true;

1
ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/Terrain/LightweightPassLitTerrain.hlsl


}
#endif // LIGHTWEIGHT_PASS_LIT_TERRAIN_INCLUDED

13
ScriptableRenderPipeline/LightweightPipeline/LWRP/LightweightPipelineUtils.cs.meta


fileFormatVersion: 2
guid: 1556a6d19597541c8bed4b90c704fb06
timeCreated: 1505115136
licenseType: Free
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

147
ScriptableRenderPipeline/LightweightPipeline/LWRP/LightweightPipelineUtils.cs


using System;
using System.Collections.Generic;
using UnityEngine.Rendering;
namespace UnityEngine.Experimental.Rendering.LightweightPipeline
{
public class CameraComparer : IComparer<Camera>
{
public int Compare(Camera lhs, Camera rhs)
{
return (int)(lhs.depth - rhs.depth);
}
}
[Flags]
public enum FrameRenderingConfiguration
{
None = 0,
Stereo = (1 << 0),
Msaa = (1 << 1),
BeforeTransparentPostProcess = (1 << 2),
PostProcess = (1 << 3),
DepthPrePass = (1 << 4),
DepthCopy = (1 << 5),
DefaultViewport = (1 << 6),
IntermediateTexture = (1 << 7)
}
public static class LightweightUtils
{
static Mesh s_FullscreenMesh = null;
public static Mesh fullscreenMesh
{
get
{
if (s_FullscreenMesh != null)
return s_FullscreenMesh;
float topV = 1.0f;
float bottomV = 0.0f;
Mesh mesh = new Mesh {name = "Fullscreen Quad"};
mesh.SetVertices(new List<Vector3>
{
new Vector3(-1.0f, -1.0f, 0.0f),
new Vector3(-1.0f, 1.0f, 0.0f),
new Vector3( 1.0f, -1.0f, 0.0f),
new Vector3( 1.0f, 1.0f, 0.0f)
});
mesh.SetUVs(0, new List<Vector2>
{
new Vector2(0.0f, bottomV),
new Vector2(0.0f, topV),
new Vector2(1.0f, bottomV),
new Vector2(1.0f, topV)
});
mesh.SetIndices(new[] { 0, 1, 2, 2, 1, 3 }, MeshTopology.Triangles, 0, false);
mesh.UploadMeshData(true);
return mesh;
}
}
public static void DrawFullScreen(CommandBuffer commandBuffer, Material material,
MaterialPropertyBlock properties = null, int shaderPassId = 0)
{
commandBuffer.DrawMesh(fullscreenMesh, Matrix4x4.identity, material, 0, shaderPassId, properties);
}
public static void StartStereoRendering(Camera camera, ref ScriptableRenderContext context, FrameRenderingConfiguration renderingConfiguration)
{
if (HasFlag(renderingConfiguration, FrameRenderingConfiguration.Stereo))
context.StartMultiEye(camera);
}
public static void StopStereoRendering(Camera camera, ref ScriptableRenderContext context, FrameRenderingConfiguration renderingConfiguration)
{
if (HasFlag(renderingConfiguration, FrameRenderingConfiguration.Stereo))
context.StopMultiEye(camera);
}
public static void GetLightCookieMatrix(VisibleLight light, out Matrix4x4 cookieMatrix)
{
cookieMatrix = Matrix4x4.Inverse(light.localToWorld);
if (light.lightType == LightType.Directional)
{
float scale = 1.0f / light.light.cookieSize;
// apply cookie scale and offset by 0.5 to convert from [-0.5, 0.5] to texture space [0, 1]
Vector4 row0 = cookieMatrix.GetRow(0);
Vector4 row1 = cookieMatrix.GetRow(1);
cookieMatrix.SetRow(0, new Vector4(row0.x * scale, row0.y * scale, row0.z * scale, row0.w * scale + 0.5f));
cookieMatrix.SetRow(1, new Vector4(row1.x * scale, row1.y * scale, row1.z * scale, row1.w * scale + 0.5f));
}
else if (light.lightType == LightType.Spot)
{
// we want out.w = 2.0 * in.z / m_CotanHalfSpotAngle
// c = cotHalfSpotAngle
// 1 0 0 0
// 0 1 0 0
// 0 0 1 0
// 0 0 2/c 0
// the "2" will be used to scale .xy for the cookie as in .xy/2 + 0.5
float scale = 1.0f / light.range;
float halfSpotAngleRad = Mathf.Deg2Rad * light.spotAngle * 0.5f;
float cs = Mathf.Cos(halfSpotAngleRad);
float ss = Mathf.Sin(halfSpotAngleRad);
float cotHalfSpotAngle = cs / ss;
Matrix4x4 scaleMatrix = Matrix4x4.identity;
scaleMatrix.m00 = scaleMatrix.m11 = scaleMatrix.m22 = scale;
scaleMatrix.m33 = 0.0f;
scaleMatrix.m32 = scale * (2.0f / cotHalfSpotAngle);
cookieMatrix = scaleMatrix * cookieMatrix;
}
// Remaining light types don't support cookies
}
public static bool IsSupportedShadowType(LightType lightType)
{
return lightType == LightType.Directional || lightType == LightType.Spot;
}
public static bool IsSupportedCookieType(LightType lightType)
{
return lightType == LightType.Directional || lightType == LightType.Spot;
}
public static bool PlatformSupportsMSAABackBuffer()
{
#if UNITY_ANDROID || UNITY_IPHONE || UNITY_TVOS || UNITY_SAMSUNGTV
return true;
#else
return false;
#endif
}
public static bool HasFlag(FrameRenderingConfiguration mask, FrameRenderingConfiguration flag)
{
return (mask & flag) != 0;
}
}
}
正在加载...
取消
保存