浏览代码
Merge remote-tracking branch 'origin/master' into scriptablerenderloop-materialgraph
/scriptablerenderloop-materialgraph
Merge remote-tracking branch 'origin/master' into scriptablerenderloop-materialgraph
/scriptablerenderloop-materialgraph
Paul Demeulenaere
8 年前
当前提交
ab48557b
共有 71 个文件被更改,包括 2708 次插入 和 816 次删除
-
2Assets/ScriptableRenderLoop/HDRenderLoop/Debug.meta
-
28Assets/ScriptableRenderLoop/HDRenderLoop/Editor/HDRenderLoopInspector.cs
-
5Assets/ScriptableRenderLoop/HDRenderLoop/HDRenderLoop.asset
-
2Assets/ScriptableRenderLoop/HDRenderLoop/HDRenderLoop.asset.meta
-
53Assets/ScriptableRenderLoop/HDRenderLoop/HDRenderLoop.cs
-
2Assets/ScriptableRenderLoop/HDRenderLoop/Lighting.meta
-
2Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/Forward.hlsl
-
5Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/LightDefinition.cs.hlsl
-
4Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/Lighting.hlsl
-
9Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/Resources/Deferred.shader
-
2Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/SinglePass.meta
-
7Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/SinglePass/SinglePass.cs
-
10Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/SinglePass/SinglePass.hlsl
-
2Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/SinglePass/SinglePassLoop.hlsl
-
2Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/TilePass/ClusteredUtils.hlsl
-
9Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/TilePass/Resources/lightlistbuild-bigtile.compute
-
4Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/TilePass/Resources/lightlistbuild-clustered.compute
-
17Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/TilePass/Resources/lightlistbuild.compute
-
130Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/TilePass/TilePass.cs
-
6Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/TilePass/TilePass.cs.hlsl
-
3Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/TilePass/TilePass.hlsl
-
17Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/TilePass/TilePassLoop.hlsl
-
2Assets/ScriptableRenderLoop/HDRenderLoop/Material/Builtin.meta
-
2Assets/ScriptableRenderLoop/HDRenderLoop/Material/LayeredLit.meta
-
2Assets/ScriptableRenderLoop/HDRenderLoop/Material/LayeredLit/Editor/LayeredLitUI.cs
-
2Assets/ScriptableRenderLoop/HDRenderLoop/Material/LayeredLit/LayeredLit.shader
-
331Assets/ScriptableRenderLoop/HDRenderLoop/Material/Lit/Editor/LitUI.cs
-
3Assets/ScriptableRenderLoop/HDRenderLoop/Material/Lit/Lit.shader
-
2Assets/ScriptableRenderLoop/HDRenderLoop/Material/Unlit.meta
-
278Assets/ScriptableRenderLoop/HDRenderLoop/Material/Unlit/Editor/UnlitUI.cs
-
2Assets/ScriptableRenderLoop/HDRenderLoop/Material/Unlit/Unlit.shader
-
2Assets/ScriptableRenderLoop/HDRenderLoop/PostProcess.meta
-
2Assets/ScriptableRenderLoop/HDRenderLoop/ShaderPass.meta
-
2Assets/ScriptableRenderLoop/HDRenderLoop/Shadow.meta
-
2Assets/ScriptableRenderLoop/HDRenderLoop/Shadow/FixedSizePCF.meta
-
53Assets/ScriptableRenderLoop/HDRenderLoop/Sky/Resources/SkyHDRI.shader
-
1Assets/ScriptableRenderLoop/HDRenderLoop/Sky/SkyRenderer.cs
-
8Assets/ScriptableRenderLoop/HDRenderLoop/Utilities.cs
-
9Assets/ScriptableRenderLoop/ScriptableRenderLoopPicker.cs
-
12Assets/ScriptableRenderLoop/ShaderLibrary/API/D3D11.hlsl
-
23Assets/ScriptableRenderLoop/ShaderLibrary/Common.hlsl
-
6Assets/ScriptableRenderLoop/ShaderLibrary/CommonMaterial.hlsl
-
39Assets/ScriptableRenderLoop/ShaderLibrary/Debug.hlsl
-
6Assets/ScriptableRenderLoop/fptl/FptlLighting.cs
-
152Assets/ScriptableRenderLoop/fptl/LightingUtils.hlsl
-
147Assets/TestScenes/HDTest/HDRenderLoopTest.unity
-
9Assets/ScriptableRenderLoop/Editor.meta
-
130Assets/ScriptableRenderLoop/HDRenderLoop/Debug/Resources/DebugViewTiles.shader
-
9Assets/ScriptableRenderLoop/HDRenderLoop/Debug/Resources/DebugViewTiles.shader.meta
-
42Assets/ScriptableRenderLoop/HDRenderLoop/Editor/UpgradeStandardShaderMaterials.cs
-
12Assets/ScriptableRenderLoop/HDRenderLoop/Editor/UpgradeStandardShaderMaterials.cs.meta
-
334Assets/ScriptableRenderLoop/HDRenderLoop/Material/Lit/Editor/BaseLitUI.cs
-
12Assets/ScriptableRenderLoop/HDRenderLoop/Material/Lit/Editor/BaseLitUI.cs.meta
-
63Assets/ScriptableRenderLoop/HDRenderLoop/Material/Lit/Editor/StandardSpecularToHDLitMaterialUpgrader.cs
-
12Assets/ScriptableRenderLoop/HDRenderLoop/Material/Lit/Editor/StandardSpecularToHDLitMaterialUpgrader.cs.meta
-
69Assets/ScriptableRenderLoop/HDRenderLoop/Material/Lit/Editor/StandardToHDLitMaterialUpgrader.cs
-
12Assets/ScriptableRenderLoop/HDRenderLoop/Material/Lit/Editor/StandardToHDLitMaterialUpgrader.cs.meta
-
20Assets/ScriptableRenderLoop/HDRenderLoop/Material/Lit/PatchStandardShaderToNewNamingConvention.cginc
-
9Assets/ScriptableRenderLoop/HDRenderLoop/Material/Lit/PatchStandardShaderToNewNamingConvention.cginc.meta
-
279Assets/ScriptableRenderLoop/HDRenderLoop/Material/Unlit/Editor/BaseUnlitUI.cs
-
12Assets/ScriptableRenderLoop/HDRenderLoop/Material/Unlit/Editor/BaseUnlitUI.cs.meta
-
390Assets/ScriptableRenderLoop/HDRenderLoop/Sky/AtmosphericParameters.cs
-
12Assets/ScriptableRenderLoop/HDRenderLoop/Sky/AtmosphericParameters.cs.meta
-
113Assets/ScriptableRenderLoop/HDRenderLoop/Sky/README.txt
-
354Assets/ScriptableRenderLoop/HDRenderLoop/Sky/Resources/AtmosphericScattering.hlsl
-
9Assets/ScriptableRenderLoop/HDRenderLoop/Sky/Resources/AtmosphericScattering.hlsl.meta
-
12Assets/ScriptableRenderLoop/Editor/MaterialUpgrader.cs.meta
-
173Assets/ScriptableRenderLoop/Editor/MaterialUpgrader.cs
-
20Assets/forwardrenderloop.asset
-
8Assets/forwardrenderloop.asset.meta
|
|||
fileFormatVersion: 2 |
|||
guid: 2400b74f5ce370c4481e5dc417d03703 |
|||
timeCreated: 1479691644 |
|||
timeCreated: 1480265826 |
|||
licenseType: Pro |
|||
NativeFormatImporter: |
|||
userData: |
|
|||
fileFormatVersion: 2 |
|||
guid: 74ae8146f4a01491ba1306f3db78139d |
|||
folderAsset: yes |
|||
timeCreated: 1479851675 |
|||
licenseType: Pro |
|||
DefaultImporter: |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
Shader "Hidden/HDRenderLoop/DebugViewTiles" |
|||
{ |
|||
SubShader |
|||
{ |
|||
|
|||
Pass |
|||
{ |
|||
ZWrite Off |
|||
Blend SrcAlpha OneMinusSrcAlpha |
|||
|
|||
HLSLPROGRAM |
|||
#pragma target 5.0 |
|||
#pragma only_renderers d3d11 // TEMP: unitl we go futher in dev |
|||
|
|||
#pragma vertex VertViewTiles |
|||
#pragma fragment FragViewTiles |
|||
|
|||
#define LIGHTLOOP_TILE_PASS 1 |
|||
#define USE_FPTL_LIGHTLIST 1 //TODO: make it also work with clustered |
|||
#define LIGHTLOOP_TILE_ALL 1 |
|||
|
|||
|
|||
//------------------------------------------------------------------------------------- |
|||
// Include |
|||
//------------------------------------------------------------------------------------- |
|||
|
|||
#include "Common.hlsl" |
|||
|
|||
// Note: We have fix as guidelines that we have only one deferred material (with control of GBuffer enabled). Mean a users that add a new |
|||
// deferred material must replace the old one here. If in the future we want to support multiple layout (cause a lot of consistency problem), |
|||
// the deferred shader will require to use multicompile. |
|||
#define UNITY_MATERIAL_LIT // Need to be define before including Material.hlsl |
|||
#include "Assets/ScriptableRenderLoop/HDRenderLoop/ShaderConfig.cs.hlsl" |
|||
#include "Assets/ScriptableRenderLoop/HDRenderLoop/ShaderVariables.hlsl" |
|||
#include "Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/Lighting.hlsl" // This include Material.hlsl |
|||
|
|||
//------------------------------------------------------------------------------------- |
|||
// variable declaration |
|||
//------------------------------------------------------------------------------------- |
|||
|
|||
uint _ViewTilesFlags; |
|||
|
|||
TEXTURE2D(_CameraDepthTexture); |
|||
SAMPLER2D(sampler_CameraDepthTexture); |
|||
|
|||
float4 VertViewTiles(float3 positionOS : POSITION): SV_POSITION |
|||
{ |
|||
return TransformWorldToHClip(TransformObjectToWorld(positionOS)); |
|||
} |
|||
|
|||
float4 OverlayHeatMap(uint2 pixCoord, uint numLights) |
|||
{ |
|||
const float4 kRadarColors[12] = |
|||
{ |
|||
float4(0.0, 0.0, 0.0, 0.0), // black |
|||
float4(0.0, 0.0, 0.6, 0.5), // dark blue |
|||
float4(0.0, 0.0, 0.9, 0.5), // blue |
|||
float4(0.0, 0.6, 0.9, 0.5), // light blue |
|||
float4(0.0, 0.9, 0.9, 0.5), // cyan |
|||
float4(0.0, 0.9, 0.6, 0.5), // blueish green |
|||
float4(0.0, 0.9, 0.0, 0.5), // green |
|||
float4(0.6, 0.9, 0.0, 0.5), // yellowish green |
|||
float4(0.9, 0.9, 0.0, 0.5), // yellow |
|||
float4(0.9, 0.6, 0.0, 0.5), // orange |
|||
float4(0.9, 0.0, 0.0, 0.5), // red |
|||
float4(1.0, 0.0, 0.0, 0.9) // strong red |
|||
}; |
|||
|
|||
float maxNrLightsPerTile = 31; |
|||
|
|||
int nColorIndex = numLights == 0 ? 0 : (1 + (int)floor(10 * (log2((float)numLights) / log2(maxNrLightsPerTile)))); |
|||
nColorIndex = nColorIndex<0 ? 0 : nColorIndex; |
|||
float4 col = nColorIndex>11 ? float4(1.0, 1.0, 1.0, 1.0) : kRadarColors[nColorIndex]; |
|||
|
|||
int2 coord = pixCoord - int2(1, 1); |
|||
|
|||
float4 color = float4(pow(col.xyz, 2.2), 0.3*col.w); |
|||
if (numLights > 0) |
|||
{ |
|||
if (SampleDebugFontNumber(coord, numLights)) // Shadow |
|||
color = float4(0, 0, 0, 1); |
|||
if (SampleDebugFontNumber(coord + 1, numLights)) // Text |
|||
color = float4(1, 1, 1, 1); |
|||
} |
|||
return color; |
|||
} |
|||
|
|||
float4 FragViewTiles(float4 positionCS : SV_POSITION) : SV_Target |
|||
{ |
|||
Coordinate coord = GetCoordinate(positionCS.xy, _ScreenSize.zw); |
|||
|
|||
#if USE_FPTL_LIGHTLIST |
|||
float linearDepth = 0.0; |
|||
#else |
|||
float depth = LOAD_TEXTURE2D(_CameraDepthTexture, coord.unPositionSS).x; |
|||
float linearDepth = GetLinearDepth(depth); |
|||
#endif |
|||
|
|||
int n = 0; |
|||
if (_ViewTilesFlags & DEBUGVIEWTILESFLAGS_DIRECT_LIGHTING) |
|||
{ |
|||
uint punctualLightStart; |
|||
uint punctualLightCount; |
|||
GetCountAndStart(coord, DIRECT_LIGHT, linearDepth, punctualLightStart, punctualLightCount); |
|||
n += punctualLightCount; |
|||
} |
|||
|
|||
if (_ViewTilesFlags & DEBUGVIEWTILESFLAGS_REFLECTION) |
|||
{ |
|||
uint envLightStart; |
|||
uint envLightCount; |
|||
GetCountAndStart(coord, REFLECTION_LIGHT, linearDepth, envLightStart, envLightCount); |
|||
n += envLightCount; |
|||
} |
|||
|
|||
if (n > 0) |
|||
{ |
|||
return OverlayHeatMap(int2(coord.unPositionSS.xy) & 15, n); |
|||
} |
|||
else |
|||
{ |
|||
return 0.0; |
|||
} |
|||
} |
|||
|
|||
ENDHLSL |
|||
} |
|||
} |
|||
Fallback Off |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: c7c2bd17b06ceb4468e14081aaf1b96f |
|||
timeCreated: 1480329456 |
|||
licenseType: Pro |
|||
ShaderImporter: |
|||
defaultTextures: [] |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
using System.Collections; |
|||
using System.Collections.Generic; |
|||
using UnityEngine; |
|||
using UnityEditor; |
|||
using System; |
|||
using NUnit.Framework; |
|||
|
|||
namespace UnityEditor.Experimental.ScriptableRenderLoop |
|||
{ |
|||
public class UpgradeStandardShaderMaterials |
|||
{ |
|||
static List<MaterialUpgrader> GetHDUpgraders() |
|||
{ |
|||
var upgraders = new List<MaterialUpgrader>(); |
|||
upgraders.Add(new StandardToHDLitMaterialUpgrader()); |
|||
upgraders.Add(new StandardSpecularToHDLitMaterialUpgrader()); |
|||
return upgraders; |
|||
} |
|||
|
|||
[MenuItem("HDRenderLoop/Upgrade Materials - Project")] |
|||
static void UpgradeMaterialsProject() |
|||
{ |
|||
MaterialUpgrader.UpgradeProjectFolder(GetHDUpgraders(), "Upgrade to HD Material"); |
|||
} |
|||
|
|||
[MenuItem("HDRenderLoop/Upgrade Materials - Selection")] |
|||
static void UpgradeMaterialsSelection() |
|||
{ |
|||
MaterialUpgrader.UpgradeSelection(GetHDUpgraders(), "Upgrade to HD Material"); |
|||
} |
|||
|
|||
[MenuItem("HDRenderLoop/Modify Light Intensity for Upgrade - Scene Only")] |
|||
static void UpgradeLights() |
|||
{ |
|||
Light[] lights = Light.GetLights(LightType.Directional, 0); |
|||
foreach (var l in lights) |
|||
{ |
|||
l.intensity *= Mathf.PI; |
|||
} |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: 9384735d0665f47539990919bf72504e |
|||
timeCreated: 1479839793 |
|||
licenseType: Pro |
|||
MonoImporter: |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
using System; |
|||
using UnityEngine; |
|||
using UnityEngine.Rendering; |
|||
|
|||
namespace UnityEditor.Experimental.ScriptableRenderLoop |
|||
{ |
|||
public abstract class BaseLitGUI : ShaderGUI |
|||
{ |
|||
protected static class Styles |
|||
{ |
|||
public static string OptionText = "Options"; |
|||
public static string SurfaceTypeText = "Surface Type"; |
|||
public static string BlendModeText = "Blend Mode"; |
|||
public static string detailText = "Inputs Detail"; |
|||
public static string lightingText = "Inputs Lighting"; |
|||
|
|||
public static GUIContent alphaCutoffEnableText = new GUIContent("Alpha Cutoff Enable", "Threshold for alpha cutoff"); |
|||
public static GUIContent alphaCutoffText = new GUIContent("Alpha Cutoff", "Threshold for alpha cutoff"); |
|||
public static GUIContent doubleSidedModeText = new GUIContent("Double Sided", "This will render the two face of the objects (disable backface culling)"); |
|||
|
|||
public static readonly string[] surfaceTypeNames = Enum.GetNames(typeof(SurfaceType)); |
|||
public static readonly string[] blendModeNames = Enum.GetNames(typeof(BlendMode)); |
|||
|
|||
public static string InputsOptionsText = "Inputs options"; |
|||
|
|||
public static GUIContent smoothnessMapChannelText = new GUIContent("Smoothness Source", "Smoothness texture and channel"); |
|||
public static GUIContent UVBaseMappingText = new GUIContent("UV set for Base", ""); |
|||
public static GUIContent texWorldScaleText = new GUIContent("Scale to apply on world coordinate in case of Planar/Triplanar", ""); |
|||
public static GUIContent UVBaseDetailMappingText = new GUIContent("UV set for Base and Detail", ""); |
|||
public static GUIContent normalMapSpaceText = new GUIContent("Normal/Tangent Map space", ""); |
|||
public static GUIContent heightMapModeText = new GUIContent("Height Map Mode", ""); |
|||
public static GUIContent detailMapModeText = new GUIContent("Detail Map with Normal", "Detail Map with AO / Height"); |
|||
public static GUIContent UVDetailMappingText = new GUIContent("UV set for Detail", ""); |
|||
public static GUIContent emissiveColorModeText = new GUIContent("Emissive Color Usage", "Use emissive color or emissive mask"); |
|||
|
|||
public static string InputsText = "Inputs"; |
|||
|
|||
public static string InputsMapText = ""; |
|||
|
|||
public static GUIContent baseColorText = new GUIContent("Base Color + Opacity", "Albedo (RGB) and Opacity (A)"); |
|||
public static GUIContent baseColorSmoothnessText = new GUIContent("Base Color + Smoothness", "Albedo (RGB) and Smoothness (A)"); |
|||
|
|||
public static GUIContent metallicText = new GUIContent("Metallic", "Metallic scale factor"); |
|||
public static GUIContent smoothnessText = new GUIContent("Smoothness", "Smoothness scale factor"); |
|||
public static GUIContent maskMapESText = new GUIContent("Mask Map - M(R), AO(G), E(B), S(A)", "Mask map"); |
|||
public static GUIContent maskMapEText = new GUIContent("Mask Map - M(R), AO(G), E(B)", "Mask map"); |
|||
public static GUIContent maskMapText = new GUIContent("Mask Map - M(R), AO(G)", "Mask map"); |
|||
public static GUIContent maskMapSText = new GUIContent("Mask Map - M(R), AO(G), S(A)", "Mask map"); |
|||
|
|||
public static GUIContent specularOcclusionMapText = new GUIContent("Specular Occlusion Map (RGBA)", "Specular Occlusion Map"); |
|||
|
|||
public static GUIContent normalMapText = new GUIContent("Normal Map", "Normal Map (DXT5) - Need to implement BC5"); |
|||
|
|||
public static GUIContent heightMapText = new GUIContent("Height Map (R)", "Height Map"); |
|||
|
|||
public static GUIContent tangentMapText = new GUIContent("Tangent Map", "Tangent Map (BC5) - DXT5 for test"); |
|||
public static GUIContent anisotropyText = new GUIContent("Anisotropy", "Anisotropy scale factor"); |
|||
public static GUIContent anisotropyMapText = new GUIContent("Anisotropy Map (G)", "Anisotropy"); |
|||
|
|||
public static GUIContent detailMapNormalText = new GUIContent("Detail Map A(R) Ny(G) S(B) Nx(A)", "Detail Map"); |
|||
public static GUIContent detailMapAOHeightText = new GUIContent("Detail Map A(R) AO(G) S(B) H(A)", "Detail Map"); |
|||
public static GUIContent detailMaskText = new GUIContent("Detail Mask (B)", "Mask for detailMap"); |
|||
public static GUIContent detailAlbedoScaleText = new GUIContent("Detail AlbedoScale", "Detail Albedo Scale factor"); |
|||
public static GUIContent detailNormalScaleText = new GUIContent("Detail NormalScale", "Normal Scale factor"); |
|||
public static GUIContent detailSmoothnessScaleText = new GUIContent("Detail SmoothnessScale", "Smoothness Scale factor"); |
|||
public static GUIContent detailHeightScaleText = new GUIContent("Detail HeightScale", "Height Scale factor"); |
|||
public static GUIContent detailAOScaleText = new GUIContent("Detail AOScale", "AO Scale factor"); |
|||
|
|||
public static GUIContent emissiveText = new GUIContent("Emissive Color", "Emissive"); |
|||
public static GUIContent emissiveIntensityText = new GUIContent("Emissive Intensity", "Emissive"); |
|||
|
|||
public static GUIContent emissiveWarning = new GUIContent("Emissive value is animated but the material has not been configured to support emissive. Please make sure the material itself has some amount of emissive."); |
|||
public static GUIContent emissiveColorWarning = new GUIContent("Ensure emissive color is non-black for emission to have effect."); |
|||
} |
|||
|
|||
public enum SurfaceType |
|||
{ |
|||
Opaque, |
|||
Transparent |
|||
} |
|||
public enum BlendMode |
|||
{ |
|||
Lerp, |
|||
Add, |
|||
SoftAdd, |
|||
Multiply, |
|||
Premultiply |
|||
} |
|||
public enum DoubleSidedMode |
|||
{ |
|||
None, |
|||
DoubleSided, |
|||
DoubleSidedLightingFlip, |
|||
DoubleSidedLightingMirror, |
|||
} |
|||
|
|||
void SurfaceTypePopup() |
|||
{ |
|||
EditorGUI.showMixedValue = surfaceType.hasMixedValue; |
|||
var mode = (SurfaceType)surfaceType.floatValue; |
|||
|
|||
EditorGUI.BeginChangeCheck(); |
|||
mode = (SurfaceType)EditorGUILayout.Popup(Styles.SurfaceTypeText, (int)mode, Styles.surfaceTypeNames); |
|||
if (EditorGUI.EndChangeCheck()) |
|||
{ |
|||
m_MaterialEditor.RegisterPropertyChangeUndo("Surface Type"); |
|||
surfaceType.floatValue = (float)mode; |
|||
} |
|||
|
|||
EditorGUI.showMixedValue = false; |
|||
} |
|||
|
|||
protected void ShaderOptionsGUI() |
|||
{ |
|||
EditorGUI.indentLevel++; |
|||
GUILayout.Label(Styles.OptionText, EditorStyles.boldLabel); |
|||
SurfaceTypePopup(); |
|||
if ((SurfaceType)surfaceType.floatValue == SurfaceType.Transparent) |
|||
{ |
|||
BlendModePopup(); |
|||
} |
|||
m_MaterialEditor.ShaderProperty(alphaCutoffEnable, Styles.alphaCutoffEnableText.text); |
|||
if (alphaCutoffEnable.floatValue == 1.0) |
|||
{ |
|||
m_MaterialEditor.ShaderProperty(alphaCutoff, Styles.alphaCutoffText.text); |
|||
} |
|||
m_MaterialEditor.ShaderProperty(doubleSidedMode, Styles.doubleSidedModeText.text); |
|||
|
|||
EditorGUI.indentLevel--; |
|||
} |
|||
|
|||
private void BlendModePopup() |
|||
{ |
|||
EditorGUI.showMixedValue = blendMode.hasMixedValue; |
|||
var mode = (BlendMode)blendMode.floatValue; |
|||
|
|||
EditorGUI.BeginChangeCheck(); |
|||
mode = (BlendMode)EditorGUILayout.Popup(Styles.BlendModeText, (int)mode, Styles.blendModeNames); |
|||
if (EditorGUI.EndChangeCheck()) |
|||
{ |
|||
m_MaterialEditor.RegisterPropertyChangeUndo("Blend Mode"); |
|||
blendMode.floatValue = (float)mode; |
|||
} |
|||
|
|||
EditorGUI.showMixedValue = false; |
|||
} |
|||
|
|||
protected void FindOptionProperties(MaterialProperty[] props) |
|||
{ |
|||
surfaceType = FindProperty(kSurfaceType, props); |
|||
blendMode = FindProperty(kBlendMode, props); |
|||
alphaCutoff = FindProperty(kAlphaCutoff, props); |
|||
alphaCutoffEnable = FindProperty(kAlphaCutoffEnabled, props); |
|||
doubleSidedMode = FindProperty(kDoubleSidedMode, props); |
|||
FindInputOptionProperties(props); |
|||
} |
|||
|
|||
protected void SetupMaterial(Material material) |
|||
{ |
|||
bool alphaTestEnable = material.GetFloat(kAlphaCutoffEnabled) == 1.0; |
|||
SurfaceType surfaceType = (SurfaceType)material.GetFloat(kSurfaceType); |
|||
BlendMode blendMode = (BlendMode)material.GetFloat(kBlendMode); |
|||
DoubleSidedMode doubleSidedMode = (DoubleSidedMode)material.GetFloat(kDoubleSidedMode); |
|||
|
|||
if (surfaceType == SurfaceType.Opaque) |
|||
{ |
|||
material.SetOverrideTag("RenderType", alphaTestEnable ? "TransparentCutout" : ""); |
|||
material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One); |
|||
material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero); |
|||
material.SetInt("_ZWrite", 1); |
|||
material.renderQueue = alphaTestEnable ? (int)UnityEngine.Rendering.RenderQueue.AlphaTest : -1; |
|||
} |
|||
else |
|||
{ |
|||
material.SetOverrideTag("RenderType", "Transparent"); |
|||
material.SetInt("_ZWrite", 0); |
|||
material.renderQueue = (int)UnityEngine.Rendering.RenderQueue.Transparent; |
|||
|
|||
switch (blendMode) |
|||
{ |
|||
case BlendMode.Lerp: |
|||
material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.SrcAlpha); |
|||
material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha); |
|||
break; |
|||
|
|||
case BlendMode.Add: |
|||
material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One); |
|||
material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.One); |
|||
break; |
|||
|
|||
case BlendMode.SoftAdd: |
|||
material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusDstColor); |
|||
material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.One); |
|||
break; |
|||
|
|||
case BlendMode.Multiply: |
|||
material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.DstColor); |
|||
material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero); |
|||
break; |
|||
|
|||
case BlendMode.Premultiply: |
|||
material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One); |
|||
material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha); |
|||
break; |
|||
} |
|||
} |
|||
|
|||
if (doubleSidedMode == DoubleSidedMode.None) |
|||
{ |
|||
material.SetInt("_CullMode", (int)UnityEngine.Rendering.CullMode.Back); |
|||
} |
|||
else |
|||
{ |
|||
material.SetInt("_CullMode", (int)UnityEngine.Rendering.CullMode.Off); |
|||
} |
|||
|
|||
if (doubleSidedMode == DoubleSidedMode.DoubleSidedLightingFlip) |
|||
{ |
|||
material.EnableKeyword("_DOUBLESIDED_LIGHTING_FLIP"); |
|||
material.DisableKeyword("_DOUBLESIDED_LIGHTING_MIRROR"); |
|||
} |
|||
else if (doubleSidedMode == DoubleSidedMode.DoubleSidedLightingMirror) |
|||
{ |
|||
material.DisableKeyword("_DOUBLESIDED_LIGHTING_FLIP"); |
|||
material.EnableKeyword("_DOUBLESIDED_LIGHTING_MIRROR"); |
|||
} |
|||
else |
|||
{ |
|||
material.DisableKeyword("_DOUBLESIDED_LIGHTING_FLIP"); |
|||
material.DisableKeyword("_DOUBLESIDED_LIGHTING_MIRROR"); |
|||
} |
|||
|
|||
SetKeyword(material, "_ALPHATEST_ON", alphaTestEnable); |
|||
SetupInputMaterial(material); |
|||
SetupEmissionGIFlags(material); |
|||
} |
|||
|
|||
protected void SetKeyword(Material m, string keyword, bool state) |
|||
{ |
|||
if (state) |
|||
m.EnableKeyword(keyword); |
|||
else |
|||
m.DisableKeyword(keyword); |
|||
} |
|||
|
|||
public void ShaderPropertiesGUI(Material material) |
|||
{ |
|||
// Use default labelWidth
|
|||
EditorGUIUtility.labelWidth = 0f; |
|||
|
|||
// Detect any changes to the material
|
|||
EditorGUI.BeginChangeCheck(); |
|||
{ |
|||
ShaderOptionsGUI(); |
|||
EditorGUILayout.Space(); |
|||
|
|||
ShaderInputOptionsGUI(); |
|||
|
|||
EditorGUILayout.Space(); |
|||
ShaderInputGUI(); |
|||
} |
|||
|
|||
if (EditorGUI.EndChangeCheck()) |
|||
{ |
|||
foreach (var obj in m_MaterialEditor.targets) |
|||
SetupMaterial((Material)obj); |
|||
} |
|||
} |
|||
|
|||
public override void OnGUI(MaterialEditor materialEditor, MaterialProperty[] props) |
|||
{ |
|||
FindOptionProperties(props); // MaterialProperties can be animated so we do not cache them but fetch them every event to ensure animated values are updated correctly
|
|||
FindInputProperties(props); |
|||
|
|||
m_MaterialEditor = materialEditor; |
|||
Material material = materialEditor.target as Material; |
|||
ShaderPropertiesGUI(material); |
|||
} |
|||
|
|||
// TODO: ? or remove
|
|||
bool HasValidEmissiveKeyword(Material material) |
|||
{ |
|||
/* |
|||
// Material animation might be out of sync with the material keyword.
|
|||
// So if the emission support is disabled on the material, but the property blocks have a value that requires it, then we need to show a warning.
|
|||
// (note: (Renderer MaterialPropertyBlock applies its values to emissionColorForRendering))
|
|||
bool hasEmissionKeyword = material.IsKeywordEnabled ("_EMISSION"); |
|||
if (!hasEmissionKeyword && ShouldEmissionBeEnabled (material, emissionColorForRendering.colorValue)) |
|||
return false; |
|||
else |
|||
return true; |
|||
*/ |
|||
|
|||
return true; |
|||
} |
|||
|
|||
protected virtual void SetupEmissionGIFlags(Material material) |
|||
{ |
|||
// Setup lightmap emissive flags
|
|||
MaterialGlobalIlluminationFlags flags = material.globalIlluminationFlags; |
|||
if ((flags & (MaterialGlobalIlluminationFlags.BakedEmissive | MaterialGlobalIlluminationFlags.RealtimeEmissive)) != 0) |
|||
{ |
|||
if (ShouldEmissionBeEnabled(material)) |
|||
flags &= ~MaterialGlobalIlluminationFlags.EmissiveIsBlack; |
|||
else |
|||
flags |= MaterialGlobalIlluminationFlags.EmissiveIsBlack; |
|||
|
|||
material.globalIlluminationFlags = flags; |
|||
} |
|||
} |
|||
|
|||
protected MaterialEditor m_MaterialEditor; |
|||
|
|||
MaterialProperty surfaceType = null; |
|||
MaterialProperty alphaCutoffEnable = null; |
|||
MaterialProperty blendMode = null; |
|||
MaterialProperty alphaCutoff = null; |
|||
MaterialProperty doubleSidedMode = null; |
|||
|
|||
const string kSurfaceType = "_SurfaceType"; |
|||
const string kBlendMode = "_BlendMode"; |
|||
const string kAlphaCutoff = "_AlphaCutoff"; |
|||
const string kAlphaCutoffEnabled = "_AlphaCutoffEnable"; |
|||
const string kDoubleSidedMode = "_DoubleSidedMode"; |
|||
protected static string[] reservedProperties = new string[] { kSurfaceType, kBlendMode, kAlphaCutoff, kAlphaCutoffEnabled, kDoubleSidedMode }; |
|||
|
|||
protected abstract void FindInputProperties(MaterialProperty[] props); |
|||
protected abstract void ShaderInputGUI(); |
|||
protected abstract void ShaderInputOptionsGUI(); |
|||
protected abstract void FindInputOptionProperties(MaterialProperty[] props); |
|||
protected abstract void SetupInputMaterial(Material material); |
|||
protected abstract bool ShouldEmissionBeEnabled(Material material); |
|||
} |
|||
} // namespace UnityEditor
|
|
|||
fileFormatVersion: 2 |
|||
guid: d35c4b8ec5d49e4438d0b0ba2655c495 |
|||
timeCreated: 1480349253 |
|||
licenseType: Pro |
|||
MonoImporter: |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
using System; |
|||
using NUnit.Framework; |
|||
using UnityEngine; |
|||
|
|||
namespace UnityEditor.Experimental.ScriptableRenderLoop |
|||
{ |
|||
class StandardSpecularToHDLitMaterialUpgrader : MaterialUpgrader |
|||
{ |
|||
public StandardSpecularToHDLitMaterialUpgrader() |
|||
{ |
|||
RenameShader("Standard (Specular setup)", "HDRenderLoop/LitLegacySupport"); |
|||
|
|||
RenameTexture("_MainTex", "_BaseColorMap"); |
|||
RenameColor("_Color", "_BaseColor"); |
|||
RenameFloat("_Glossiness", "_Smoothness"); |
|||
RenameTexture("_BumpMap", "_NormalMap"); |
|||
RenameColor("_EmissionColor", "_EmissiveColor"); |
|||
RenameFloat("_DetailNormalMapScale", "_DetailNormalScale"); |
|||
RenameTexture("_DetailNormalMap", "_DetailMap"); |
|||
|
|||
//@Seb: Bumpmap scale doesn't exist in new shader
|
|||
//_BumpScale("Scale", Float) = 1.0
|
|||
|
|||
// Anything reasonable that can be done here?
|
|||
//RenameFloat("_SpecColor", ...);
|
|||
|
|||
//@TODO: Seb. Why do we multiply color by intensity
|
|||
// in shader when we can just store a color?
|
|||
// builtinData.emissiveColor * builtinData.emissiveIntensity
|
|||
} |
|||
|
|||
public override void Convert(Material srcMaterial, Material dstMaterial) |
|||
{ |
|||
base.Convert(srcMaterial, dstMaterial); |
|||
//@TODO: Find a good way of setting up keywords etc from properties.
|
|||
// Code should be shared with material UI code.
|
|||
} |
|||
|
|||
[Test] |
|||
public void UpgradeMaterial() |
|||
{ |
|||
var newShader = Shader.Find("HDRenderLoop/LitLegacySupport"); |
|||
var mat = new Material(Shader.Find("Standard (Specular setup)")); |
|||
var albedo = new Texture2D(1, 1); |
|||
var normals = new Texture2D(1, 1); |
|||
var baseScale = new Vector2(1, 1); |
|||
var color = Color.red; |
|||
mat.mainTexture = albedo; |
|||
mat.SetTexture("_BumpMap", normals); |
|||
mat.color = color; |
|||
mat.SetTextureScale("_MainTex", baseScale); |
|||
|
|||
MaterialUpgrader.Upgrade(mat, new StandardSpecularToHDLitMaterialUpgrader(), MaterialUpgrader.UpgradeFlags.CleanupNonUpgradedProperties); |
|||
|
|||
Assert.AreEqual(newShader, mat.shader); |
|||
Assert.AreEqual(albedo, mat.GetTexture("_BaseColorMap")); |
|||
Assert.AreEqual(color, mat.GetColor("_BaseColor")); |
|||
Assert.AreEqual(baseScale, mat.GetTextureScale("_BaseColorMap")); |
|||
Assert.AreEqual(normals, mat.GetTexture("_NormalMap")); |
|||
} |
|||
} |
|||
} |
|||
|
|
|||
fileFormatVersion: 2 |
|||
guid: 775bef174b1e2ed47972a143845e1191 |
|||
timeCreated: 1479911618 |
|||
licenseType: Pro |
|||
MonoImporter: |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
using System; |
|||
using NUnit.Framework; |
|||
using UnityEngine; |
|||
|
|||
namespace UnityEditor.Experimental.ScriptableRenderLoop |
|||
{ |
|||
class StandardToHDLitMaterialUpgrader : MaterialUpgrader |
|||
{ |
|||
public StandardToHDLitMaterialUpgrader() |
|||
{ |
|||
RenameShader("Standard", "HDRenderLoop/LitLegacySupport"); |
|||
|
|||
RenameTexture("_MainTex", "_BaseColorMap"); |
|||
RenameColor("_Color", "_BaseColor"); |
|||
RenameFloat("_Glossiness", "_Smoothness"); |
|||
RenameTexture("_BumpMap", "_NormalMap"); |
|||
RenameColor("_EmissionColor", "_EmissiveColor"); |
|||
RenameFloat("_DetailNormalMapScale", "_DetailNormalScale"); |
|||
|
|||
// the HD renderloop packs detail albedo and detail normals into a single texture.
|
|||
// mapping the detail normal map, if any, to the detail map, should do the right thing if
|
|||
// there is no detail albedo.
|
|||
RenameTexture("_DetailNormalMap", "_DetailMap"); |
|||
|
|||
//@Seb: Bumpmap scale doesn't exist in new shader
|
|||
//_BumpScale("Scale", Float) = 1.0
|
|||
|
|||
// Metallic uses [Gamma] attribute in standard shader but not in Lit.
|
|||
// @Seb: Should we convert?
|
|||
RenameFloat("_Metallic", "_Metallic"); |
|||
|
|||
//@TODO: Seb. Why do we multiply color by intensity
|
|||
// in shader when we can just store a color?
|
|||
// builtinData.emissiveColor * builtinData.emissiveIntensity
|
|||
} |
|||
|
|||
public override void Convert(Material srcMaterial, Material dstMaterial) |
|||
{ |
|||
base.Convert(srcMaterial, dstMaterial); |
|||
//@TODO: Find a good way of setting up keywords etc from properties.
|
|||
// Code should be shared with material UI code.
|
|||
} |
|||
|
|||
[Test] |
|||
public void UpgradeMaterial() |
|||
{ |
|||
var newShader = Shader.Find("HDRenderLoop/LitLegacySupport"); |
|||
var mat = new Material(Shader.Find("Standard")); |
|||
var albedo = new Texture2D(1, 1); |
|||
var normals = new Texture2D(1, 1); |
|||
var baseScale = new Vector2(1, 1); |
|||
var color = Color.red; |
|||
mat.mainTexture = albedo; |
|||
mat.SetTexture("_BumpMap", normals); |
|||
mat.color = color; |
|||
mat.SetTextureScale("_MainTex", baseScale); |
|||
|
|||
|
|||
MaterialUpgrader.Upgrade(mat, new StandardToHDLitMaterialUpgrader(), MaterialUpgrader.UpgradeFlags.CleanupNonUpgradedProperties); |
|||
|
|||
Assert.AreEqual(newShader, mat.shader); |
|||
Assert.AreEqual(albedo, mat.GetTexture("_BaseColorMap")); |
|||
Assert.AreEqual(color, mat.GetColor("_BaseColor")); |
|||
Assert.AreEqual(baseScale, mat.GetTextureScale("_BaseColorMap")); |
|||
Assert.AreEqual(normals, mat.GetTexture("_NormalMap")); |
|||
} |
|||
} |
|||
} |
|||
|
|
|||
fileFormatVersion: 2 |
|||
guid: fedbd6bc5d95f4d768cb8077e8454b4e |
|||
timeCreated: 1479851295 |
|||
licenseType: Pro |
|||
MonoImporter: |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
// NOTE: For performing a project upgrade where you temporarily support both old and new renderloops |
|||
// in the same sahder |
|||
// |
|||
// The basic approach is: |
|||
// Upgrade all your shaders to the new naming convention, using a SubShader that also contains the legacy // renderloop code. |
|||
// |
|||
// 1. Copy HDRenderloop Lit.shader into your project |
|||
// 2. Add a SubShader and copy old Standard shader passes into it. |
|||
// 2. Set LOD on subshader to make Unity pick at runtime to use new renderloop shaders or |
|||
// legacy standard shaders based on if SRL is enabled or not. |
|||
// In the legacy standard shader section add |
|||
// #include "PatchStandardShaderToNewNamingConvention.cginc" |
|||
|
|||
// List of name remaps |
|||
#define _MainTex _BaseColorMap |
|||
#define _MainTex_ST _BaseColorMap_ST |
|||
#define _BumpMap _NormalMap |
|||
#define _ParallaxMap _HeightMap |
|||
#define _Parallax _HeightScale |
|||
#define _Glossiness _Smoothness |
|
|||
fileFormatVersion: 2 |
|||
guid: a9b4e2b7ef9a45f49834b052e7722acb |
|||
timeCreated: 1480085057 |
|||
licenseType: Pro |
|||
ShaderImporter: |
|||
defaultTextures: [] |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
using System; |
|||
using UnityEngine; |
|||
using UnityEngine.Rendering; |
|||
|
|||
namespace UnityEditor.Experimental.ScriptableRenderLoop |
|||
{ |
|||
public abstract class BaseUnlitGUI : ShaderGUI |
|||
{ |
|||
public enum SurfaceType |
|||
{ |
|||
Opaque, |
|||
Transparent |
|||
} |
|||
public enum BlendMode |
|||
{ |
|||
Lerp, |
|||
Add, |
|||
SoftAdd, |
|||
Multiply, |
|||
Premultiply |
|||
} |
|||
|
|||
public enum DoubleSidedMode |
|||
{ |
|||
None, |
|||
DoubleSided |
|||
} |
|||
|
|||
protected static class Styles |
|||
{ |
|||
public static string OptionText = "Options"; |
|||
public static string SurfaceTypeText = "Surface Type"; |
|||
public static string BlendModeText = "Blend Mode"; |
|||
|
|||
public static GUIContent alphaCutoffEnableText = new GUIContent("Alpha Cutoff Enable", "Threshold for alpha cutoff"); |
|||
public static GUIContent alphaCutoffText = new GUIContent("Alpha Cutoff", "Threshold for alpha cutoff"); |
|||
public static GUIContent doubleSidedModeText = new GUIContent("Double Sided", "This will render the two face of the objects (disable backface culling)"); |
|||
|
|||
public static readonly string[] surfaceTypeNames = Enum.GetNames(typeof(SurfaceType)); |
|||
public static readonly string[] blendModeNames = Enum.GetNames(typeof(BlendMode)); |
|||
|
|||
public static string InputsOptionsText = "Inputs options"; |
|||
|
|||
public static string InputsText = "Inputs"; |
|||
|
|||
public static string InputsMapText = ""; |
|||
|
|||
public static GUIContent colorText = new GUIContent("Color + Opacity", "Albedo (RGB) and Opacity (A)"); |
|||
|
|||
public static GUIContent emissiveText = new GUIContent("Emissive Color", "Emissive"); |
|||
public static GUIContent emissiveIntensityText = new GUIContent("Emissive Intensity", "Emissive"); |
|||
} |
|||
|
|||
MaterialProperty surfaceType = null; |
|||
MaterialProperty blendMode = null; |
|||
MaterialProperty alphaCutoff = null; |
|||
MaterialProperty alphaCutoffEnable = null; |
|||
MaterialProperty doubleSidedMode = null; |
|||
|
|||
protected const string kSurfaceType = "_SurfaceType"; |
|||
protected const string kBlendMode = "_BlendMode"; |
|||
protected const string kAlphaCutoff = "_AlphaCutoff"; |
|||
protected const string kAlphaCutoffEnabled = "_AlphaCutoffEnable"; |
|||
protected const string kDoubleSidedMode = "_DoubleSidedMode"; |
|||
|
|||
protected MaterialEditor m_MaterialEditor; |
|||
|
|||
public void FindOptionProperties(MaterialProperty[] props) |
|||
{ |
|||
surfaceType = FindProperty(kSurfaceType, props); |
|||
blendMode = FindProperty(kBlendMode, props); |
|||
alphaCutoff = FindProperty(kAlphaCutoff, props); |
|||
alphaCutoffEnable = FindProperty(kAlphaCutoffEnabled, props); |
|||
doubleSidedMode = FindProperty(kDoubleSidedMode, props); |
|||
FindInputOptionProperties(props); |
|||
} |
|||
|
|||
public override void OnGUI(MaterialEditor materialEditor, MaterialProperty[] props) |
|||
{ |
|||
FindOptionProperties(props); // MaterialProperties can be animated so we do not cache them but fetch them every event to ensure animated values are updated correctly
|
|||
FindInputProperties(props); |
|||
|
|||
m_MaterialEditor = materialEditor; |
|||
Material material = materialEditor.target as Material; |
|||
ShaderPropertiesGUI(material); |
|||
} |
|||
|
|||
protected void ShaderOptionsGUI() |
|||
{ |
|||
EditorGUI.indentLevel++; |
|||
GUILayout.Label(Styles.OptionText, EditorStyles.boldLabel); |
|||
SurfaceTypePopup(); |
|||
if ((SurfaceType)surfaceType.floatValue == SurfaceType.Transparent) |
|||
{ |
|||
BlendModePopup(); |
|||
} |
|||
m_MaterialEditor.ShaderProperty(alphaCutoffEnable, Styles.alphaCutoffEnableText.text); |
|||
if (alphaCutoffEnable.floatValue == 1.0) |
|||
{ |
|||
m_MaterialEditor.ShaderProperty(alphaCutoff, Styles.alphaCutoffText.text); |
|||
} |
|||
m_MaterialEditor.ShaderProperty(doubleSidedMode, Styles.doubleSidedModeText.text); |
|||
|
|||
EditorGUI.indentLevel--; |
|||
} |
|||
|
|||
public void ShaderPropertiesGUI(Material material) |
|||
{ |
|||
// Use default labelWidth
|
|||
EditorGUIUtility.labelWidth = 0f; |
|||
|
|||
// Detect any changes to the material
|
|||
EditorGUI.BeginChangeCheck(); |
|||
{ |
|||
ShaderOptionsGUI(); |
|||
EditorGUILayout.Space(); |
|||
|
|||
ShaderInputOptionsGUI(); |
|||
|
|||
EditorGUILayout.Space(); |
|||
ShaderInputGUI(); |
|||
} |
|||
|
|||
if (EditorGUI.EndChangeCheck()) |
|||
{ |
|||
foreach (var obj in m_MaterialEditor.targets) |
|||
SetupMaterial((Material)obj); |
|||
} |
|||
} |
|||
|
|||
// TODO: try to setup minimun value to fall back to standard shaders and reverse
|
|||
public override void AssignNewShaderToMaterial(Material material, Shader oldShader, Shader newShader) |
|||
{ |
|||
base.AssignNewShaderToMaterial(material, oldShader, newShader); |
|||
} |
|||
|
|||
void SurfaceTypePopup() |
|||
{ |
|||
EditorGUI.showMixedValue = surfaceType.hasMixedValue; |
|||
var mode = (SurfaceType)surfaceType.floatValue; |
|||
|
|||
EditorGUI.BeginChangeCheck(); |
|||
mode = (SurfaceType)EditorGUILayout.Popup(Styles.SurfaceTypeText, (int)mode, Styles.surfaceTypeNames); |
|||
if (EditorGUI.EndChangeCheck()) |
|||
{ |
|||
m_MaterialEditor.RegisterPropertyChangeUndo("Surface Type"); |
|||
surfaceType.floatValue = (float)mode; |
|||
} |
|||
|
|||
EditorGUI.showMixedValue = false; |
|||
} |
|||
|
|||
void BlendModePopup() |
|||
{ |
|||
EditorGUI.showMixedValue = blendMode.hasMixedValue; |
|||
var mode = (BlendMode)blendMode.floatValue; |
|||
|
|||
EditorGUI.BeginChangeCheck(); |
|||
mode = (BlendMode)EditorGUILayout.Popup(Styles.BlendModeText, (int)mode, Styles.blendModeNames); |
|||
if (EditorGUI.EndChangeCheck()) |
|||
{ |
|||
m_MaterialEditor.RegisterPropertyChangeUndo("Blend Mode"); |
|||
blendMode.floatValue = (float)mode; |
|||
} |
|||
|
|||
EditorGUI.showMixedValue = false; |
|||
} |
|||
|
|||
protected void SetupMaterial(Material material) |
|||
{ |
|||
// Note: keywords must be based on Material value not on MaterialProperty due to multi-edit & material animation
|
|||
// (MaterialProperty value might come from renderer material property block)
|
|||
|
|||
bool alphaTestEnable = material.GetFloat(kAlphaCutoffEnabled) == 1.0; |
|||
SurfaceType surfaceType = (SurfaceType)material.GetFloat(kSurfaceType); |
|||
BlendMode blendMode = (BlendMode)material.GetFloat(kBlendMode); |
|||
DoubleSidedMode doubleSidedMode = (DoubleSidedMode)material.GetFloat(kDoubleSidedMode); |
|||
|
|||
if (surfaceType == SurfaceType.Opaque) |
|||
{ |
|||
material.SetOverrideTag("RenderType", alphaTestEnable ? "TransparentCutout" : ""); |
|||
material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One); |
|||
material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero); |
|||
material.SetInt("_ZWrite", 1); |
|||
material.renderQueue = alphaTestEnable ? (int)UnityEngine.Rendering.RenderQueue.AlphaTest : -1; |
|||
} |
|||
else |
|||
{ |
|||
material.SetOverrideTag("RenderType", "Transparent"); |
|||
material.SetInt("_ZWrite", 0); |
|||
material.renderQueue = (int)UnityEngine.Rendering.RenderQueue.Transparent; |
|||
|
|||
switch (blendMode) |
|||
{ |
|||
case BlendMode.Lerp: |
|||
material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.SrcAlpha); |
|||
material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha); |
|||
break; |
|||
|
|||
case BlendMode.Add: |
|||
material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One); |
|||
material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.One); |
|||
break; |
|||
|
|||
case BlendMode.SoftAdd: |
|||
material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusDstColor); |
|||
material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.One); |
|||
break; |
|||
|
|||
case BlendMode.Multiply: |
|||
material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.DstColor); |
|||
material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero); |
|||
break; |
|||
|
|||
case BlendMode.Premultiply: |
|||
material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One); |
|||
material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha); |
|||
break; |
|||
} |
|||
} |
|||
|
|||
if (doubleSidedMode == DoubleSidedMode.None) |
|||
{ |
|||
material.SetInt("_CullMode", (int)UnityEngine.Rendering.CullMode.Back); |
|||
} |
|||
else |
|||
{ |
|||
material.SetInt("_CullMode", (int)UnityEngine.Rendering.CullMode.Off); |
|||
} |
|||
|
|||
SetKeyword(material, "_ALPHATEST_ON", alphaTestEnable); |
|||
SetupInputMaterial(material); |
|||
|
|||
// Setup lightmap emissive flags
|
|||
MaterialGlobalIlluminationFlags flags = material.globalIlluminationFlags; |
|||
if ((flags & (MaterialGlobalIlluminationFlags.BakedEmissive | MaterialGlobalIlluminationFlags.RealtimeEmissive)) != 0) |
|||
{ |
|||
if (ShouldEmissionBeEnabled(material)) |
|||
flags &= ~MaterialGlobalIlluminationFlags.EmissiveIsBlack; |
|||
else |
|||
flags |= MaterialGlobalIlluminationFlags.EmissiveIsBlack; |
|||
|
|||
material.globalIlluminationFlags = flags; |
|||
} |
|||
} |
|||
|
|||
bool HasValidEmissiveKeyword(Material material) |
|||
{ |
|||
/* |
|||
// Material animation might be out of sync with the material keyword.
|
|||
// So if the emission support is disabled on the material, but the property blocks have a value that requires it, then we need to show a warning.
|
|||
// (note: (Renderer MaterialPropertyBlock applies its values to emissionColorForRendering))
|
|||
bool hasEmissionKeyword = material.IsKeywordEnabled ("_EMISSION"); |
|||
if (!hasEmissionKeyword && ShouldEmissionBeEnabled (material, emissionColorForRendering.colorValue)) |
|||
return false; |
|||
else |
|||
return true; |
|||
*/ |
|||
|
|||
return true; |
|||
} |
|||
|
|||
protected void SetKeyword(Material m, string keyword, bool state) |
|||
{ |
|||
if (state) |
|||
m.EnableKeyword(keyword); |
|||
else |
|||
m.DisableKeyword(keyword); |
|||
} |
|||
|
|||
protected abstract void FindInputProperties(MaterialProperty[] props); |
|||
protected abstract void ShaderInputGUI(); |
|||
protected abstract void ShaderInputOptionsGUI(); |
|||
protected abstract void FindInputOptionProperties(MaterialProperty[] props); |
|||
protected abstract void SetupInputMaterial(Material material); |
|||
protected abstract bool ShouldEmissionBeEnabled(Material material); |
|||
} |
|||
|
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: 11fd029bb88b2c04092b1e4d71b919c6 |
|||
timeCreated: 1480351138 |
|||
licenseType: Pro |
|||
MonoImporter: |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
using UnityEngine; |
|||
|
|||
[ExecuteInEditMode] |
|||
public class AtmosphericParameters : MonoBehaviour |
|||
{ |
|||
public enum OcclusionDownscale { x1 = 1, x2 = 2, x4 = 4 } |
|||
public enum OcclusionSamples { x64 = 0, x164 = 1, x244 = 2 } |
|||
public enum DepthTexture { Enable, Disable/*, Ignore*/ } // 'Ignore' appears to be currently unused.
|
|||
public enum ScatterDebugMode { None, Scattering, Occlusion, OccludedScattering, Rayleigh, Mie, Height } |
|||
|
|||
[Header("Global Settings")] |
|||
public Gradient worldRayleighColorRamp = null; |
|||
public float worldRayleighColorIntensity = 1f; |
|||
public float worldRayleighDensity = 10f; |
|||
public float worldRayleighExtinctionFactor = 1.1f; |
|||
public float worldRayleighIndirectScatter = 0.33f; |
|||
public Gradient worldMieColorRamp = null; |
|||
public float worldMieColorIntensity = 1f; |
|||
public float worldMieDensity = 15f; |
|||
public float worldMieExtinctionFactor = 0f; |
|||
public float worldMiePhaseAnisotropy = 0.9f; |
|||
public float worldNearScatterPush = 0f; |
|||
public float worldNormalDistance = 1000f; |
|||
|
|||
[Header("Height Settings")] |
|||
public Color heightRayleighColor = Color.white; |
|||
public float heightRayleighIntensity = 1f; |
|||
public float heightRayleighDensity = 10f; |
|||
public float heightMieDensity = 0f; |
|||
public float heightExtinctionFactor = 1.1f; |
|||
public float heightSeaLevel = 0f; |
|||
public float heightDistance = 50f; |
|||
public Vector3 heightPlaneShift = Vector3.zero; |
|||
public float heightNearScatterPush = 0f; |
|||
public float heightNormalDistance = 1000f; |
|||
|
|||
[Header("Sky Dome")] |
|||
/*public*/ Vector3 skyDomeScale = new Vector3(1f, 1f, 1f); |
|||
/*public*/ Vector3 skyDomeRotation = Vector3.zero; |
|||
/*public*/ Transform skyDomeTrackedYawRotation = null; |
|||
/*public*/ bool skyDomeVerticalFlip = false; |
|||
/*public*/ Cubemap skyDomeCube = null; |
|||
/*public*/ float skyDomeExposure = 1f; |
|||
/*public*/ Color skyDomeTint = Color.white; |
|||
/*public*/ Vector3 skyDomeOffset = Vector3.zero; |
|||
|
|||
/* |
|||
[Header("Scatter Occlusion")] |
|||
public bool useOcclusion = false; |
|||
public float occlusionBias = 0f; |
|||
public float occlusionBiasIndirect = 0.6f; |
|||
public float occlusionBiasClouds = 0.3f; |
|||
public OcclusionDownscale occlusionDownscale = OcclusionDownscale.x2; |
|||
public OcclusionSamples occlusionSamples = OcclusionSamples.x64; |
|||
public bool occlusionDepthFixup = true; |
|||
public float occlusionDepthThreshold = 25f; |
|||
public bool occlusionFullSky = false; |
|||
public float occlusionBiasSkyRayleigh = 0.2f; |
|||
public float occlusionBiasSkyMie = 0.4f; |
|||
*/ |
|||
|
|||
[Header("Other")] |
|||
public Shader atmosphericShaderOverride = null; |
|||
// public Shader occlusionShaderOverride = null;
|
|||
public float worldScaleExponent = 1.0f; |
|||
// public bool forcePerPixel = true;
|
|||
// public bool forcePostEffect = true;
|
|||
[Tooltip("Soft clouds need depth values. Ignore means externally controlled.")] |
|||
public DepthTexture depthTexture = DepthTexture.Enable; |
|||
public ScatterDebugMode debugMode = ScatterDebugMode.None; |
|||
|
|||
// [HideInInspector] public Shader occlusionShaderOverride;
|
|||
|
|||
// Camera m_currentCamera;
|
|||
|
|||
// UnityEngine.Rendering.CommandBuffer m_occlusionCmdAfterShadows, m_occlusionCmdBeforeScreen;
|
|||
|
|||
Material m_atmosphericMaterial = null; |
|||
// Material m_occlusionMaterial = null;
|
|||
bool m_isAwake = false; |
|||
|
|||
public static AtmosphericParameters instance { get; private set; } |
|||
|
|||
void Awake() |
|||
{ |
|||
if (worldRayleighColorRamp == null) |
|||
{ |
|||
worldRayleighColorRamp = new Gradient(); |
|||
worldRayleighColorRamp.SetKeys( |
|||
new[] { new GradientColorKey(new Color(0.3f, 0.4f, 0.6f), 0f), |
|||
new GradientColorKey(new Color(0.5f, 0.6f, 0.8f), 1f) }, |
|||
new[] { new GradientAlphaKey(1f, 0f), |
|||
new GradientAlphaKey(1f, 1f) } |
|||
); |
|||
} |
|||
|
|||
if (worldMieColorRamp == null) |
|||
{ |
|||
worldMieColorRamp = new Gradient(); |
|||
worldMieColorRamp.SetKeys( |
|||
new[] { new GradientColorKey(new Color(0.95f, 0.75f, 0.5f), 0f), |
|||
new GradientColorKey(new Color(1f, 0.9f, 8.0f), 1f) }, |
|||
new[] { new GradientAlphaKey(1f, 0f), |
|||
new GradientAlphaKey(1f, 1f) } |
|||
); |
|||
} |
|||
|
|||
if (atmosphericShaderOverride != null) |
|||
{ |
|||
// Override the default shader.
|
|||
m_atmosphericMaterial = new Material(atmosphericShaderOverride); |
|||
m_atmosphericMaterial.hideFlags = HideFlags.HideAndDontSave; |
|||
} |
|||
|
|||
/* |
|||
if (occlusionShaderOverride != null) |
|||
{ |
|||
// Override the default shader.
|
|||
m_occlusionMaterial = new Material(occlusionShaderOverride); |
|||
m_occlusionMaterial.hideFlags = HideFlags.HideAndDontSave; |
|||
} |
|||
*/ |
|||
|
|||
m_isAwake = true; |
|||
} |
|||
|
|||
public void OnValidate() |
|||
{ |
|||
if (!m_isAwake) return; |
|||
|
|||
Light light = gameObject.GetComponentInParent<Light>(); |
|||
|
|||
if (light == null || light.type != LightType.Directional) |
|||
{ |
|||
Debug.LogErrorFormat("Unexpected: AtmosphericParameters is not attached to a directional light."); |
|||
return; |
|||
} |
|||
|
|||
worldScaleExponent = Mathf.Clamp(worldScaleExponent, 1f, 2f); |
|||
worldNormalDistance = Mathf.Clamp(worldNormalDistance, 1f, 10000f); |
|||
worldNearScatterPush = Mathf.Clamp(worldNearScatterPush, -200f, 300f); |
|||
worldRayleighDensity = Mathf.Clamp(worldRayleighDensity, 0, 1000f); |
|||
worldMieDensity = Mathf.Clamp(worldMieDensity, 0f, 1000f); |
|||
worldRayleighIndirectScatter = Mathf.Clamp(worldRayleighIndirectScatter, 0f, 1f); |
|||
worldMiePhaseAnisotropy = Mathf.Clamp01(worldMiePhaseAnisotropy); |
|||
|
|||
heightNormalDistance = Mathf.Clamp(heightNormalDistance, 1f, 10000f); |
|||
heightNearScatterPush = Mathf.Clamp(heightNearScatterPush, -200f, 300f); |
|||
heightRayleighDensity = Mathf.Clamp(heightRayleighDensity, 0, 1000f); |
|||
heightMieDensity = Mathf.Clamp(heightMieDensity, 0, 1000f); |
|||
|
|||
/* |
|||
occlusionBias = Mathf.Clamp01(occlusionBias); |
|||
occlusionBiasIndirect = Mathf.Clamp01(occlusionBiasIndirect); |
|||
occlusionBiasClouds = Mathf.Clamp01(occlusionBiasClouds); |
|||
occlusionBiasSkyRayleigh = Mathf.Clamp01(occlusionBiasSkyRayleigh); |
|||
occlusionBiasSkyMie = Mathf.Clamp01(occlusionBiasSkyMie); |
|||
*/ |
|||
|
|||
skyDomeExposure = Mathf.Clamp(skyDomeExposure, 0f, 8f); |
|||
|
|||
if (instance == this) |
|||
{ |
|||
// TODO: what's the point of doing this?
|
|||
OnDisable(); |
|||
OnEnable(); |
|||
} |
|||
|
|||
// TODO: why would I want to do that here?
|
|||
// #if UNITY_EDITOR
|
|||
// UnityEditor.SceneView.RepaintAll();
|
|||
// #endif
|
|||
} |
|||
|
|||
void OnEnable() |
|||
{ |
|||
if (!m_isAwake) return; |
|||
|
|||
// Define select preprocessor symbols.
|
|||
UpdateKeywords(true); |
|||
|
|||
if (depthTexture == DepthTexture.Disable) |
|||
{ |
|||
// Disable depth texture rendering.
|
|||
Camera.current.depthTextureMode = DepthTextureMode.None; |
|||
} |
|||
|
|||
// Set shader constants.
|
|||
UpdateStaticUniforms(); |
|||
UpdateDynamicUniforms(); |
|||
|
|||
if (instance && instance != this) |
|||
{ |
|||
Debug.LogErrorFormat("Unexpected: AtmosphericParameters.instance already set (to: {0}). Still overriding with: {1}.", instance.name, name); |
|||
} |
|||
|
|||
instance = this; |
|||
} |
|||
|
|||
void OnDisable() |
|||
{ |
|||
// Undefine all preprocessor symbols.
|
|||
UpdateKeywords(false); |
|||
|
|||
if (instance && instance != this) |
|||
{ |
|||
Debug.LogErrorFormat("Unexpected: AtmosphericParameters.instance set to: {0}, not to: {1}. Leaving alone.", instance.name, name); |
|||
} |
|||
else |
|||
{ |
|||
instance = null; |
|||
} |
|||
} |
|||
|
|||
void UpdateKeywords(bool enable) |
|||
{ |
|||
Shader.DisableKeyword("ATMOSPHERICS_OCCLUSION"); |
|||
Shader.DisableKeyword("ATMOSPHERICS_OCCLUSION_FULLSKY"); |
|||
Shader.DisableKeyword("ATMOSPHERICS_OCCLUSION_EDGE_FIXUP"); |
|||
Shader.DisableKeyword("ATMOSPHERICS_SUNRAYS"); |
|||
Shader.DisableKeyword("ATMOSPHERICS_DEBUG"); |
|||
|
|||
if (enable) |
|||
{ |
|||
/* |
|||
if (useOcclusion) |
|||
{ |
|||
Shader.EnableKeyword("ATMOSPHERICS_OCCLUSION"); |
|||
|
|||
if(occlusionDepthFixup && occlusionDownscale != OcclusionDownscale.x1) |
|||
Shader.EnableKeyword("ATMOSPHERICS_OCCLUSION_EDGE_FIXUP"); |
|||
|
|||
if(occlusionFullSky) |
|||
Shader.EnableKeyword("ATMOSPHERICS_OCCLUSION_FULLSKY"); |
|||
} |
|||
*/ |
|||
|
|||
if (debugMode != ScatterDebugMode.None) |
|||
{ |
|||
Shader.EnableKeyword("ATMOSPHERICS_DEBUG"); |
|||
} |
|||
} |
|||
} |
|||
|
|||
void UpdateStaticUniforms() |
|||
{ |
|||
Shader.SetGlobalVector("_SkyDomeOffset", skyDomeOffset); |
|||
Shader.SetGlobalVector("_SkyDomeScale", skyDomeScale); |
|||
Shader.SetGlobalTexture("_SkyDomeCube", skyDomeCube); |
|||
Shader.SetGlobalFloat("_SkyDomeExposure", skyDomeExposure); |
|||
Shader.SetGlobalColor("_SkyDomeTint", skyDomeTint); |
|||
|
|||
/* |
|||
Shader.SetGlobalFloat("_ShadowBias", useOcclusion ? occlusionBias : 1f); |
|||
Shader.SetGlobalFloat("_ShadowBiasIndirect", useOcclusion ? occlusionBiasIndirect : 1f); |
|||
Shader.SetGlobalFloat("_ShadowBiasClouds", useOcclusion ? occlusionBiasClouds : 1f); |
|||
Shader.SetGlobalVector("_ShadowBiasSkyRayleighMie", useOcclusion ? new Vector4(occlusionBiasSkyRayleigh, occlusionBiasSkyMie, 0f, 0f) : Vector4.zero); |
|||
Shader.SetGlobalFloat("_OcclusionDepthThreshold", occlusionDepthThreshold); |
|||
*/ |
|||
|
|||
Shader.SetGlobalFloat("_WorldScaleExponent", worldScaleExponent); |
|||
|
|||
Shader.SetGlobalFloat("_WorldNormalDistanceRcp", 1f/worldNormalDistance); |
|||
Shader.SetGlobalFloat("_WorldNearScatterPush", -Mathf.Pow(Mathf.Abs(worldNearScatterPush), worldScaleExponent) * Mathf.Sign(worldNearScatterPush)); |
|||
|
|||
Shader.SetGlobalFloat("_WorldRayleighDensity", -worldRayleighDensity / 100000f); |
|||
Shader.SetGlobalFloat("_MiePhaseAnisotropy", worldMiePhaseAnisotropy); |
|||
Shader.SetGlobalVector("_RayleighInScatterPct", new Vector4(1f - worldRayleighIndirectScatter, worldRayleighIndirectScatter, 0f, 0f)); |
|||
|
|||
Shader.SetGlobalFloat("_HeightNormalDistanceRcp", 1f/heightNormalDistance); |
|||
Shader.SetGlobalFloat("_HeightNearScatterPush", -Mathf.Pow(Mathf.Abs(heightNearScatterPush), worldScaleExponent) * Mathf.Sign(heightNearScatterPush)); |
|||
Shader.SetGlobalFloat("_HeightRayleighDensity", -heightRayleighDensity / 100000f); |
|||
|
|||
Shader.SetGlobalFloat("_HeightSeaLevel", heightSeaLevel); |
|||
Shader.SetGlobalFloat("_HeightDistanceRcp", 1f/heightDistance); |
|||
Shader.SetGlobalVector("_HeightPlaneShift", heightPlaneShift); |
|||
Shader.SetGlobalVector("_HeightRayleighColor", (Vector4)heightRayleighColor * heightRayleighIntensity); |
|||
Shader.SetGlobalFloat("_HeightExtinctionFactor", heightExtinctionFactor); |
|||
Shader.SetGlobalFloat("_RayleighExtinctionFactor", worldRayleighExtinctionFactor); |
|||
Shader.SetGlobalFloat("_MieExtinctionFactor", worldMieExtinctionFactor); |
|||
|
|||
var rayleighColorM20 = worldRayleighColorRamp.Evaluate(0.00f); |
|||
var rayleighColorM10 = worldRayleighColorRamp.Evaluate(0.25f); |
|||
var rayleighColorO00 = worldRayleighColorRamp.Evaluate(0.50f); |
|||
var rayleighColorP10 = worldRayleighColorRamp.Evaluate(0.75f); |
|||
var rayleighColorP20 = worldRayleighColorRamp.Evaluate(1.00f); |
|||
|
|||
var mieColorM20 = worldMieColorRamp.Evaluate(0.00f); |
|||
var mieColorO00 = worldMieColorRamp.Evaluate(0.50f); |
|||
var mieColorP20 = worldMieColorRamp.Evaluate(1.00f); |
|||
|
|||
Shader.SetGlobalVector("_RayleighColorM20", (Vector4)rayleighColorM20 * worldRayleighColorIntensity); |
|||
Shader.SetGlobalVector("_RayleighColorM10", (Vector4)rayleighColorM10 * worldRayleighColorIntensity); |
|||
Shader.SetGlobalVector("_RayleighColorO00", (Vector4)rayleighColorO00 * worldRayleighColorIntensity); |
|||
Shader.SetGlobalVector("_RayleighColorP10", (Vector4)rayleighColorP10 * worldRayleighColorIntensity); |
|||
Shader.SetGlobalVector("_RayleighColorP20", (Vector4)rayleighColorP20 * worldRayleighColorIntensity); |
|||
|
|||
Shader.SetGlobalVector("_MieColorM20", (Vector4)mieColorM20 * worldMieColorIntensity); |
|||
Shader.SetGlobalVector("_MieColorO00", (Vector4)mieColorO00 * worldMieColorIntensity); |
|||
Shader.SetGlobalVector("_MieColorP20", (Vector4)mieColorP20 * worldMieColorIntensity); |
|||
|
|||
Shader.SetGlobalInt("_AtmosphericsDebugMode", (int)debugMode); |
|||
} |
|||
|
|||
void OnWillRenderObject() |
|||
{ |
|||
/* |
|||
if (!m_isAwake) return; |
|||
|
|||
// For now, we only use the directional light we are attached to, and the current camera.
|
|||
|
|||
if (depthTexture == DepthTexture.Disable) |
|||
{ |
|||
// Disable depth texture rendering.
|
|||
Camera.current.depthTextureMode = DepthTextureMode.None; |
|||
} |
|||
|
|||
// Set shader constants.
|
|||
UpdateDynamicUniforms(); |
|||
|
|||
|
|||
if (useOcclusion) { |
|||
var camRgt = m_currentCamera.transform.right; |
|||
var camUp = m_currentCamera.transform.up; |
|||
var camFwd = m_currentCamera.transform.forward; |
|||
|
|||
var dy = Mathf.Tan(m_currentCamera.fieldOfView * 0.5f * Mathf.Deg2Rad); |
|||
var dx = dy * m_currentCamera.aspect; |
|||
|
|||
var vpCenter = camFwd * m_currentCamera.farClipPlane; |
|||
var vpRight = camRgt * dx * m_currentCamera.farClipPlane; |
|||
var vpUp = camUp * dy * m_currentCamera.farClipPlane; |
|||
|
|||
m_occlusionMaterial.SetVector("_CameraPosition", m_currentCamera.transform.position); |
|||
m_occlusionMaterial.SetVector("_ViewportCorner", vpCenter - vpRight - vpUp); |
|||
m_occlusionMaterial.SetVector("_ViewportRight", vpRight * 2f); |
|||
m_occlusionMaterial.SetVector("_ViewportUp", vpUp * 2f); |
|||
var farDist = m_currentCamera ? m_currentCamera.farClipPlane : 1000f; |
|||
var refDist = (Mathf.Min(farDist, QualitySettings.shadowDistance) - 1f) / farDist; |
|||
m_occlusionMaterial.SetFloat("_OcclusionSkyRefDistance", refDist); |
|||
|
|||
var srcRect = m_currentCamera.pixelRect; |
|||
var downscale = 1f / (float)(int)occlusionDownscale; |
|||
var occWidth = Mathf.RoundToInt(srcRect.width * downscale); |
|||
var occHeight = Mathf.RoundToInt(srcRect.height * downscale); |
|||
var occlusionId = Shader.PropertyToID("_OcclusionTexture"); |
|||
|
|||
m_occlusionCmdBeforeScreen.Clear(); |
|||
m_occlusionCmdBeforeScreen.GetTemporaryRT(occlusionId, occWidth, occHeight, 0, FilterMode.Bilinear, RenderTextureFormat.R8, RenderTextureReadWrite.sRGB); |
|||
m_occlusionCmdBeforeScreen.Blit( |
|||
null, |
|||
occlusionId, |
|||
m_occlusionMaterial, |
|||
(int)occlusionSamples |
|||
); |
|||
m_occlusionCmdBeforeScreen.SetGlobalTexture(occlusionId, occlusionId); |
|||
} |
|||
*/ |
|||
} |
|||
|
|||
void UpdateDynamicUniforms() |
|||
{ |
|||
/* For now, we only use the directional light we are attached to, and the current camera. */ |
|||
|
|||
var trackedYaw = skyDomeTrackedYawRotation ? skyDomeTrackedYawRotation.eulerAngles.y : 0f; |
|||
Shader.SetGlobalMatrix("_SkyDomeRotation", |
|||
Matrix4x4.TRS(Vector3.zero, Quaternion.Euler(skyDomeRotation.x, 0f, 0f), Vector3.one) |
|||
* Matrix4x4.TRS(Vector3.zero, Quaternion.Euler(0f, skyDomeRotation.y - trackedYaw, 0f), Vector3.one) |
|||
* Matrix4x4.TRS(Vector3.zero, Quaternion.identity, new Vector3(1f, skyDomeVerticalFlip ? -1f : 1f, 1f)) |
|||
); |
|||
|
|||
Shader.SetGlobalVector("_SunDirection", -transform.forward); |
|||
Shader.SetGlobalFloat("_WorldMieDensity", -worldMieDensity / 100000f); |
|||
Shader.SetGlobalFloat("_HeightMieDensity", -heightMieDensity / 100000f); |
|||
|
|||
var pixelRect = Camera.current ? Camera.current.pixelRect |
|||
: new Rect(0f, 0f, Screen.width, Screen.height); |
|||
var scale = 1.0f; //(float)(int)occlusionDownscale;
|
|||
var depthTextureScaledTexelSize = new Vector4(scale / pixelRect.width, |
|||
scale / pixelRect.height, |
|||
-scale / pixelRect.width, |
|||
-scale / pixelRect.height); |
|||
Shader.SetGlobalVector("_DepthTextureScaledTexelSize", depthTextureScaledTexelSize); |
|||
} |
|||
|
|||
void OnRenderObject() |
|||
{ |
|||
/* This component is not rendered directly. */ |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: 97f65a78ace4fbf4187144e9fe724009 |
|||
timeCreated: 1479992550 |
|||
licenseType: Pro |
|||
MonoImporter: |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
# Atmospheric Scattering |
|||
|
|||
Atmospheric scattering is a solution developed for nicer aerial perspective in The Blacksmith. It provides a model emulating atmospheric Rayleigh, Mie and height scattering (and also takes a lot of shortcuts in the name of performance and artistic control). Take a look at the blog post at this address http://blogs.unity3d.com/?p=27218 to get a high-level overview of the components making up the final composition. |
|||
|
|||
|
|||
### Options description |
|||
|
|||
This component comes with quite a lot of options - but you normally don't have to tweak more than a handful of them to get good results - start with the densities and colors and that will get you started nicely. |
|||
|
|||
|
|||
#### World Components |
|||
|
|||
**World Rayleigh Color Ramp**: The color or colors used for rayleigh scattering. It's a ramp instead of a single color because you can have different scattering colors depending on the angle to the unit being shaded. Values to the left in the ramp are mapped to angles below horizon, whereas values to the right are mapped to angles above the horizon. |
|||
|
|||
**World Rayleigh Color Intensity**: An HDR color scale for the rayleigh color ramp. |
|||
|
|||
**World Rayleigh Density**: The density of the rayleigh component. |
|||
|
|||
**World Rayleigh Extinction Factor**: How much light is out-scattered or absorbed on its way to the eye. Basically how much to darken the shaded pixel. |
|||
|
|||
**World Rayleigh Indirect Scatter**: Which percentage of the rayleigh scattering should be considered 'indirect' scattering. (relevant for occlusion only) |
|||
|
|||
**World Mie Color Ramp**: The color or colors used for mie scattering. It's a ramp instead of a single color because you can have different scattering colors depending on the angle to the unit being shaded. Values to the left in the ramp are mapped to angles below horizon, whereas values to the right are mapped to angles above the horizon. |
|||
|
|||
**World Mie Color Intensity**: An HDR color scale for the mie color ramp. |
|||
|
|||
**World Mie Density**: The density of the mie component. |
|||
|
|||
**World Mie Extinction Factor**: How much light is out-scattered or absorbed on its way to the eye. Basically how much to darken the shaded pixel. |
|||
|
|||
**World Mie Phase Anisotropy**: How focused the forward directionality of the mie scattering is. Values close to 1 produce a small, very sharp mie component, whereas values below 0.5 creates a very large and unfocused mie component. |
|||
|
|||
**World Near Scatter Push**: Allows the scattering to be pushed out to have no scattering directly in front of the camera, or pulled in to have more scattering close to the camera. |
|||
|
|||
**World Normal Distance**: A measure of the scale of the scene. Essentially this desaturates the scattering near the camera, and interpolates into full color ramp at the edge of the specified distance. |
|||
|
|||
|
|||
#### Height Components |
|||
|
|||
**Height Rayleigh Color**: The general global scattering color for height fog. |
|||
|
|||
**Height Rayleigh Intensity**: An HDR color scale for the height global fog color. |
|||
|
|||
**Height Rayleigh Density**: The density of the global height fog. |
|||
|
|||
**Height Mie Density**: The density of the mie scattering being added to the global height fog. |
|||
|
|||
**Height Extinction Factor**: How much light is out-scattered or absorbed on its way to the eye. Basically how much to darken the shaded pixel. |
|||
|
|||
**Height Sea Level**: Sea level height offset from origin. |
|||
|
|||
**Height Distance**: Falloff distance from sea level |
|||
|
|||
**Height Plane Shift**: An optional plane vector for a tilted sea level. |
|||
|
|||
**Height Near Scatter Push**: Allows the scattering to be pushed out to have no scattering directly in front of the camera, or pulled in to have more scattering close to the camera. |
|||
|
|||
**Height Normal Distance**: A measure of the scale of the scene. Essentially this desaturates the scattering near the camera, and interpolates into full color at the edge of the specified distance. |
|||
|
|||
|
|||
#### Sky Dome |
|||
|
|||
**Sky Dome Scale**: The scale of the skydome. We use this to virtually squash the sky sphere into behaving like a dome. The xz-dimensions affect how much scattering the horizon picks up, whereas the y-dimension dictates how far up on the sky the scattering is blended. |
|||
|
|||
**Sky Dome Rotation**: An optional rotation of the skydome. Usually, only Y-rotation makes sense. |
|||
|
|||
**Sky Dome Tracked Yaw Rotation**: Optionally have the skydome rotate to track a transform, typically a light source. Use in combination with rotation to perfectly align and track the sun to the skydome. |
|||
|
|||
**Sky Dome Vertical Flip**: We have the option of putting two skybox textures into the same cubemap. This flags flips the UV projection to show the bottom half instead of the top half. |
|||
|
|||
**Sky Dome Cube**: An HDR cubemap to use as sky dome. |
|||
|
|||
**Sky Dome Exposure**: The exposure of the sky cubemap. |
|||
|
|||
**Sky Dome Tint**: Tint color for the cubemap. |
|||
|
|||
|
|||
#### Scatter Occlusion |
|||
|
|||
**Use Occlusion**: This flag enables scatter occlusion. |
|||
|
|||
**Occlusion Bias**: Controls how strongly occlusion affects direct scattering. |
|||
|
|||
**Occlusion BiasIndirect**: Controls how strongly occlusion affects indirect scattering. |
|||
|
|||
**Occlusion BiasClouds**: Controls how strongly occlusion affects placed clouds. |
|||
|
|||
**Occlusion Downscale**: Controls the downscale factor for occlusion gathering. |
|||
|
|||
**Occlusion Samples**: The number of samples to use in gathering. |
|||
|
|||
**Occlusion DepthFixup**: Whether to attempt to fix upsampling across depth discontinuities (currently d3d11 only). |
|||
|
|||
**Occlusion DepthThreshold**: The threshold defining discontinuous depth. |
|||
|
|||
**Occlusion FullSky**: Whether to gather occlusion even for skydome pixels. |
|||
|
|||
**Occlusion BiasSkyRayleigh **: Controls how strongly occlusion affects rayleigh scattering on the skydome. |
|||
|
|||
**Occlusion BiasSkyMie **: Controls how strongly occlusion affects mie scattering on the skydome. |
|||
|
|||
|
|||
#### Other |
|||
|
|||
**World ScaleExponent**: An option to exponentially scale the world for scattering calculations (fake aerial perspective in small scenes). |
|||
|
|||
**Force Per Pixel**: Force all scatter calculations to run at per-pixel frequency. |
|||
|
|||
**Force Post Effect**: Force all scatter calculations to run in a post-process (requires the AtmosphericScatteringDeferred component on the camera, and doesn't apply to transparent object) |
|||
|
|||
**Depth Texture**: Whether to enable, disable or leave alone the camera depth texture settings. (required for depth fixup and soft cloud planes) |
|||
|
|||
**Debug Mode**: Various debug visualizations of the different rendering components. |
|
|||
#ifndef FILE_ATMOSPHERICSCATTERING |
|||
#define FILE_ATMOSPHERICSCATTERING |
|||
|
|||
#define ATMOSPHERICS_DBG_NONE 0 |
|||
#define ATMOSPHERICS_DBG_SCATTERING 1 |
|||
#define ATMOSPHERICS_DBG_OCCLUSION 2 |
|||
#define ATMOSPHERICS_DBG_OCCLUDEDSCATTERING 3 |
|||
#define ATMOSPHERICS_DBG_RAYLEIGH 4 |
|||
#define ATMOSPHERICS_DBG_MIE 5 |
|||
#define ATMOSPHERICS_DBG_HEIGHT 6 |
|||
|
|||
uniform int _AtmosphericsDebugMode; |
|||
|
|||
uniform float3 _SunDirection; |
|||
|
|||
uniform float _ShadowBias; |
|||
uniform float _ShadowBiasIndirect; |
|||
uniform float _ShadowBiasClouds; |
|||
uniform float _OcclusionDepthThreshold; |
|||
uniform float4 _OcclusionTexture_TexelSize; |
|||
|
|||
uniform float4 _DepthTextureScaledTexelSize; |
|||
|
|||
uniform float _WorldScaleExponent; |
|||
uniform float _WorldNormalDistanceRcp; |
|||
uniform float _WorldNearScatterPush; |
|||
uniform float _WorldRayleighDensity; |
|||
uniform float _WorldMieDensity; |
|||
|
|||
uniform float3 _RayleighColorM20; |
|||
uniform float3 _RayleighColorM10; |
|||
uniform float3 _RayleighColorO00; |
|||
uniform float3 _RayleighColorP10; |
|||
uniform float3 _RayleighColorP20; |
|||
uniform float3 _RayleighColorP45; |
|||
|
|||
uniform float3 _MieColorM20; |
|||
uniform float3 _MieColorO00; |
|||
uniform float3 _MieColorP20; |
|||
uniform float3 _MieColorP45; |
|||
|
|||
uniform float _HeightNormalDistanceRcp; |
|||
uniform float _HeightNearScatterPush; |
|||
uniform float _HeightRayleighDensity; |
|||
uniform float _HeightMieDensity; |
|||
uniform float _HeightSeaLevel; |
|||
uniform float3 _HeightPlaneShift; |
|||
uniform float _HeightDistanceRcp; |
|||
|
|||
uniform float _RayleighCoeffScale; |
|||
uniform float3 _RayleighSunTintIntensity; |
|||
uniform float2 _RayleighInScatterPct; |
|||
|
|||
uniform float _MieCoeffScale; |
|||
uniform float3 _MieSunTintIntensity; |
|||
uniform float _MiePhaseAnisotropy; |
|||
|
|||
uniform float _HeightExtinctionFactor; |
|||
uniform float _RayleighExtinctionFactor; |
|||
uniform float _MieExtinctionFactor; |
|||
|
|||
uniform float4 _HeightRayleighColor; |
|||
|
|||
SAMPLER2D(sampler_CameraDepthTexture) |
|||
#define SRL_BilinearSampler sampler_CameraDepthTexture // Used for all textures |
|||
|
|||
TEXTURE2D(_CameraDepthTexture); |
|||
TEXTURE2D(_OcclusionTexture); |
|||
|
|||
float HenyeyGreensteinPhase(float g, float cosTheta) { |
|||
float gSqr = g * g; |
|||
float a1 = (1.f - gSqr); |
|||
float a2 = (2.f + gSqr); |
|||
float b1 = 1.f + cosTheta * cosTheta; |
|||
float b2 = pow(abs(1.f + gSqr - 2.f * g * cosTheta), 1.5f); |
|||
return (a1 / a2) * (b1 / b2); |
|||
} |
|||
|
|||
float RayleighPhase(float cosTheta) { |
|||
const float f = 3.f / (16.f * PI); |
|||
return f + f * cosTheta * cosTheta; |
|||
} |
|||
|
|||
float MiePhase(float cosTheta, float anisotropy) { |
|||
const float f = 3.f / (8.f * PI); |
|||
return f * HenyeyGreensteinPhase(anisotropy, cosTheta); |
|||
} |
|||
|
|||
float HeightDensity(float h, float H) { |
|||
return exp(-h/H); |
|||
} |
|||
|
|||
float3 WorldScale(float3 p) { |
|||
p.xz = sign(p.xz) * pow(abs(p.xz), _WorldScaleExponent); |
|||
return p; |
|||
} |
|||
|
|||
void VolundTransferScatter(float3 worldPos, out float4 coords1, out float4 coords2, out float4 coords3) { |
|||
const float3 scaledWorldPos = WorldScale(worldPos); |
|||
const float3 worldCamPos = WorldScale(_WorldSpaceCameraPos.xyz); |
|||
|
|||
const float c_MieScaleHeight = 1200.f; |
|||
const float worldRayleighDensity = 1.f; |
|||
const float worldMieDensity = HeightDensity(scaledWorldPos.y, c_MieScaleHeight); |
|||
|
|||
const float3 worldVec = scaledWorldPos.xyz - worldCamPos.xyz; |
|||
const float worldVecLen = length(worldVec); |
|||
const float3 worldDir = worldVec / worldVecLen; |
|||
|
|||
const float3 worldDirUnscaled = normalize(worldPos - _WorldSpaceCameraPos.xyz); |
|||
|
|||
const float viewSunCos = dot(worldDirUnscaled, _SunDirection); |
|||
const float rayleighPh = min(1.f, RayleighPhase(viewSunCos) * 12.f); |
|||
const float miePh = MiePhase(viewSunCos, _MiePhaseAnisotropy); |
|||
|
|||
const float angle20 = 0.324f / 1.5f; |
|||
const float angle10 = 0.174f / 1.5f; |
|||
const float angleY = worldDir.y * saturate(worldVecLen / 250.0); |
|||
|
|||
float3 rayleighColor; |
|||
if(angleY >= angle10) rayleighColor = lerp(_RayleighColorP10, _RayleighColorP20, saturate((angleY - angle10) / (angle20 - angle10))); |
|||
else if(angleY >= 0.f) rayleighColor = lerp(_RayleighColorO00, _RayleighColorP10, angleY / angle10); |
|||
else if(angleY >= -angle10) rayleighColor = lerp(_RayleighColorM10, _RayleighColorO00, (angleY + angle10) / angle10); |
|||
else rayleighColor = lerp(_RayleighColorM20, _RayleighColorM10, saturate((angleY + angle20) / (angle20 - angle10))); |
|||
|
|||
float3 mieColor; |
|||
if(angleY >= 0.f) mieColor = lerp(_MieColorO00, _MieColorP20, saturate(angleY / angle20)); |
|||
else mieColor = lerp(_MieColorM20, _MieColorO00, saturate((angleY + angle20) / angle20)); |
|||
|
|||
const float pushedDistance = max(0.f, worldVecLen + _WorldNearScatterPush); |
|||
const float pushedDensity = /*HeightDensity **/ pushedDistance /** exp(-scaledWorldPos.y / 8000.f)*/; |
|||
const float rayleighScatter = (1.f - exp(_WorldRayleighDensity * pushedDensity)) * rayleighPh; |
|||
#ifdef IS_RENDERING_SKY |
|||
const float mieScatter = (1.f - exp(_WorldMieDensity * pushedDensity)); |
|||
#else |
|||
const float mieScatter = (1.f - exp(_WorldMieDensity * pushedDensity)) * miePh; |
|||
#endif |
|||
|
|||
const float heightShift = dot(worldVec, _HeightPlaneShift); |
|||
const float heightScaledOffset = (scaledWorldPos.y - heightShift - _HeightSeaLevel) * _HeightDistanceRcp; |
|||
const float HeightDensity = exp(-heightScaledOffset); |
|||
const float pushedHeightDistance = max(0.f, worldVecLen + _HeightNearScatterPush); |
|||
const float heightScatter = (1.f - exp(_HeightRayleighDensity * pushedHeightDistance)) * HeightDensity; |
|||
#ifdef IS_RENDERING_SKY |
|||
const float heightMieScatter = (1.f - exp(_HeightMieDensity * pushedHeightDistance)) * HeightDensity; |
|||
#else |
|||
const float heightMieScatter = (1.f - exp(_HeightMieDensity * pushedHeightDistance)) * HeightDensity * miePh; |
|||
#endif |
|||
|
|||
rayleighColor = lerp(Luminance(rayleighColor).rrr, rayleighColor, saturate(pushedDistance * _WorldNormalDistanceRcp)); |
|||
float3 heightRayleighColor = lerp(Luminance(_HeightRayleighColor.xyz).rrr, _HeightRayleighColor.xyz, saturate(pushedHeightDistance * _HeightNormalDistanceRcp)); |
|||
|
|||
coords1.rgb = rayleighScatter * rayleighColor; |
|||
coords1.a = rayleighScatter; |
|||
|
|||
coords3.rgb = saturate(heightScatter) * heightRayleighColor; |
|||
coords3.a = heightScatter; |
|||
|
|||
coords2.rgb = mieScatter * mieColor + saturate(heightMieScatter) * mieColor; |
|||
coords2.a = mieScatter; |
|||
} |
|||
|
|||
void VolundTransferScatter(float3 scaledWorldPos, out float4 coords1) { |
|||
float4 c1, c2, c3; |
|||
VolundTransferScatter(scaledWorldPos, c1, c2, c3); |
|||
|
|||
#ifdef IS_RENDERING_SKY |
|||
coords1.rgb = c3.rgb; |
|||
coords1.a = max(0.f, 1.f - c3.a * _HeightExtinctionFactor); |
|||
#else |
|||
coords1.rgb = c1.rgb; |
|||
coords1.rgb += c3.rgb; |
|||
coords1.a = max(0.f, 1.f - c1.a * _RayleighExtinctionFactor - c3.a * _HeightExtinctionFactor); |
|||
#endif |
|||
|
|||
coords1.rgb += c2.rgb; |
|||
coords1.a *= max(0.f, 1.f - c2.a * _MieExtinctionFactor); |
|||
|
|||
#ifdef ATMOSPHERICS_DEBUG |
|||
if(_AtmosphericsDebugMode == ATMOSPHERICS_DBG_RAYLEIGH) |
|||
coords1.rgb = c1.rgb; |
|||
else if(_AtmosphericsDebugMode == ATMOSPHERICS_DBG_MIE) |
|||
coords1.rgb = c2.rgb; |
|||
else if(_AtmosphericsDebugMode == ATMOSPHERICS_DBG_HEIGHT) |
|||
coords1.rgb = c3.rgb; |
|||
#endif |
|||
} |
|||
|
|||
float2 UVFromPos(float2 pos) { |
|||
return pos / _ScreenParams.xy; |
|||
} |
|||
|
|||
float3 VolundApplyScatter(float4 coords1, float2 pos, float3 color) { |
|||
#ifdef ATMOSPHERICS_DEBUG |
|||
if(_AtmosphericsDebugMode == ATMOSPHERICS_DBG_OCCLUSION) |
|||
return 1; |
|||
else if(_AtmosphericsDebugMode == ATMOSPHERICS_DBG_SCATTERING || _AtmosphericsDebugMode == ATMOSPHERICS_DBG_OCCLUDEDSCATTERING) |
|||
return coords1.rgb; |
|||
else if(_AtmosphericsDebugMode == ATMOSPHERICS_DBG_RAYLEIGH || _AtmosphericsDebugMode == ATMOSPHERICS_DBG_MIE || _AtmosphericsDebugMode == ATMOSPHERICS_DBG_HEIGHT) |
|||
return coords1.rgb; |
|||
#endif |
|||
|
|||
return color * coords1.a + coords1.rgb; |
|||
} |
|||
|
|||
float3 VolundApplyScatterAdd(float coords1, float3 color) { |
|||
return color * coords1; |
|||
} |
|||
|
|||
void VolundTransferScatterOcclusion(float3 scaledWorldPos, out float4 coords1, out float3 coords2) { |
|||
float4 c1, c2, c3; |
|||
VolundTransferScatter(scaledWorldPos, c1, c2, c3); |
|||
|
|||
coords1.rgb = c1.rgb * _RayleighInScatterPct.x; |
|||
coords1.a = max(0.f, 1.f - c1.a * _RayleighExtinctionFactor - c3.a * _HeightExtinctionFactor); |
|||
|
|||
coords1.rgb += c2.rgb; |
|||
coords1.a *= max(0.f, 1.f - c2.a * _MieExtinctionFactor); |
|||
|
|||
coords2.rgb = c3.rgb + c1.rgb * _RayleighInScatterPct.y; |
|||
|
|||
#ifdef ATMOSPHERICS_DEBUG |
|||
if(_AtmosphericsDebugMode == ATMOSPHERICS_DBG_RAYLEIGH) |
|||
coords1.rgb = c1.rgb; |
|||
else if(_AtmosphericsDebugMode == ATMOSPHERICS_DBG_MIE) |
|||
coords1.rgb = c2.rgb; |
|||
else if(_AtmosphericsDebugMode == ATMOSPHERICS_DBG_HEIGHT) |
|||
coords1.rgb = c3.rgb; |
|||
#endif |
|||
} |
|||
|
|||
float VolundSampleScatterOcclusion(float2 pos) { |
|||
#if defined(ATMOSPHERICS_OCCLUSION) |
|||
float2 uv = UVFromPos(pos); |
|||
#if defined(ATMOSPHERICS_OCCLUSION_EDGE_FIXUP) |
|||
float4 baseUV = float4(uv.x, uv.y, 0.f, 0.f); |
|||
|
|||
float cDepth = SAMPLE_TEXTURE2D_LOD(_CameraDepthTexture, SRL_BilinearSampler, baseUV, 0.f).r; |
|||
cDepth = LinearEyeDepth(cDepth); |
|||
|
|||
float4 xDepth; |
|||
baseUV.xy = uv + _DepthTextureScaledTexelSize.zy; xDepth.x = SAMPLE_TEXTURE2D_LOD(_CameraDepthTexture, SRL_BilinearSampler, baseUV); |
|||
baseUV.xy = uv + _DepthTextureScaledTexelSize.xy; xDepth.y = SAMPLE_TEXTURE2D_LOD(_CameraDepthTexture, SRL_BilinearSampler, baseUV); |
|||
baseUV.xy = uv + _DepthTextureScaledTexelSize.xw; xDepth.z = SAMPLE_TEXTURE2D_LOD(_CameraDepthTexture, SRL_BilinearSampler, baseUV); |
|||
baseUV.xy = uv + _DepthTextureScaledTexelSize.zw; xDepth.w = SAMPLE_TEXTURE2D_LOD(_CameraDepthTexture, SRL_BilinearSampler, baseUV); |
|||
|
|||
xDepth.x = LinearEyeDepth4(xDepth.x); |
|||
xDepth.y = LinearEyeDepth4(xDepth.y); |
|||
xDepth.z = LinearEyeDepth4(xDepth.z); |
|||
xDepth.w = LinearEyeDepth4(xDepth.w); |
|||
|
|||
float4 diffDepth = xDepth - cDepth.rrrr; |
|||
float4 maskDepth = abs(diffDepth) < _OcclusionDepthThreshold; |
|||
float maskWeight = dot(maskDepth, maskDepth); |
|||
|
|||
UNITY_BRANCH |
|||
if(maskWeight == 4.f || maskWeight == 0.f) { |
|||
return SAMPLE_TEXTURE2D_LOD(_OcclusionTexture, SRL_BilinearSampler, uv, 0.f).r; |
|||
} else { |
|||
float4 occ = GATHER_TEXTURE2D(_OcclusionTexture, SRL_BilinearSampler, uv); |
|||
|
|||
float4 fWeights; |
|||
fWeights.xy = frac(uv * _OcclusionTexture_TexelSize.zw - 0.5f); |
|||
fWeights.zw = float2(1.f, 1.f) - fWeights.xy; |
|||
|
|||
float4 mfWeights = float4(fWeights.z * fWeights.y, fWeights.x * fWeights.y, fWeights.x * fWeights.w, fWeights.z * fWeights.w); |
|||
return dot(occ, mfWeights * maskDepth) / dot(mfWeights, maskDepth); |
|||
} |
|||
#endif //defined(ATMOSPHERICS_OCCLUSION_EDGE_FIXUP) |
|||
#else //defined(ATMOSPHERICS_OCCLUSION) |
|||
return 1.f; |
|||
#endif //defined(ATMOSPHERICS_OCCLUSION) |
|||
} |
|||
|
|||
float3 VolundApplyScatterOcclusion(float4 coords1, float3 coords2, float2 pos, float3 color) { |
|||
float occlusion = VolundSampleScatterOcclusion(pos); |
|||
|
|||
#ifdef ATMOSPHERICS_DEBUG |
|||
if(_AtmosphericsDebugMode == ATMOSPHERICS_DBG_SCATTERING) |
|||
return coords1.rgb + coords2.rgb; |
|||
else if(_AtmosphericsDebugMode == ATMOSPHERICS_DBG_OCCLUSION) |
|||
return occlusion; |
|||
else if(_AtmosphericsDebugMode == ATMOSPHERICS_DBG_OCCLUDEDSCATTERING) |
|||
return coords1.rgb * min(1.f, occlusion + _ShadowBias) + coords2.rgb * min(1.f, occlusion + _ShadowBiasIndirect); |
|||
else if(_AtmosphericsDebugMode == ATMOSPHERICS_DBG_RAYLEIGH || _AtmosphericsDebugMode == ATMOSPHERICS_DBG_MIE || _AtmosphericsDebugMode == ATMOSPHERICS_DBG_HEIGHT) |
|||
return coords1.rgb; |
|||
#endif |
|||
|
|||
return |
|||
color * coords1.a |
|||
+ coords1.rgb * min(1.f, occlusion + _ShadowBias) + coords2.rgb * min(1.f, occlusion + _ShadowBiasIndirect); |
|||
; |
|||
} |
|||
|
|||
float VolundCloudOcclusion(float2 pos) { |
|||
#if defined(ATMOSPHERICS_OCCLUSION) |
|||
return min(1.f, VolundSampleScatterOcclusion(pos) + _ShadowBiasClouds); |
|||
#else |
|||
return 1.f; |
|||
#endif |
|||
} |
|||
|
|||
|
|||
float4 VolundApplyCloudScatter(float4 coords1, float4 color) { |
|||
#if defined(DBG_ATMOSPHERICS_SCATTERING) || defined(DBG_ATMOSPHERICS_OCCLUDEDSCATTERING) |
|||
return float4(coords1.rgb, color.a); |
|||
#elif defined(DBG_ATMOSPHERICS_OCCLUSION) |
|||
return 1; |
|||
#endif |
|||
|
|||
color.rgb = color.rgb * coords1.a + coords1.rgb; |
|||
return color; |
|||
} |
|||
|
|||
float4 VolundApplyCloudScatterOcclusion(float4 coords1, float3 coords2, float2 pos, float4 color) { |
|||
float occlusion = VolundSampleScatterOcclusion(pos); |
|||
#ifdef ATMOSPHERICS_OCCLUSION_DEBUG2 |
|||
color.rgb = coords1.rgb * min(1.f, occlusion + _ShadowBias) + coords2.rgb * min(1.f, occlusion + _ShadowBiasIndirect); |
|||
return color; |
|||
#endif |
|||
#ifdef ATMOSPHERICS_OCCLUSION_DEBUG |
|||
return occlusion; |
|||
#endif |
|||
|
|||
color.rgb = color.rgb * coords1.a + coords1.rgb * min(1.f, occlusion + _ShadowBias) + coords2.rgb * min(1.f, occlusion + _ShadowBiasIndirect); |
|||
|
|||
float cloudOcclusion = min(1.f, occlusion + _ShadowBiasClouds); |
|||
color.a *= cloudOcclusion; |
|||
|
|||
return color; |
|||
} |
|||
|
|||
// Original vert/frag macros |
|||
#if defined(ATMOSPHERICS_OCCLUSION) |
|||
#define VOLUND_SCATTER_COORDS(idx1, idx2) float4 scatterCoords1 : TEXCOORD##idx1; float3 scatterCoords2 : TEXCOORD##idx2; |
|||
#define VOLUND_TRANSFER_SCATTER(pos, o) o.scatterCoords1 = pos.xyzz; o.scatterCoords2 = pos.xyz; |
|||
#define VOLUND_APPLY_SCATTER(i, color) VolundTransferScatterOcclusion(i.scatterCoords1.xyz, i.scatterCoords1, i.scatterCoords2); color = VolundApplyScatterOcclusion(i.scatterCoords1, i.scatterCoords2, i.pos.xy, color) |
|||
#define VOLUND_CLOUD_SCATTER(i, color) VolundTransferScatterOcclusion(i.scatterCoords1.xyz, i.scatterCoords1, i.scatterCoords2); color = VolundApplyCloudScatterOcclusion(i.scatterCoords1, i.scatterCoords2, i.pos.xy, color) |
|||
#else |
|||
#define VOLUND_SCATTER_COORDS(idx1, idx2) float4 scatterCoords1 : TEXCOORD##idx1; |
|||
#define VOLUND_TRANSFER_SCATTER(pos, o) o.scatterCoords1 = pos.xyzz; |
|||
#define VOLUND_APPLY_SCATTER(i, color) VolundTransferScatter(i.scatterCoords1.xyz, i.scatterCoords1); color = VolundApplyScatter(i.scatterCoords1, i.pos.xy, color); |
|||
#define VOLUND_CLOUD_SCATTER(i, color) VolundTransferScatter(i.scatterCoords1.xyz, i.scatterCoords1); color = VolundApplyCloudScatter(i.scatterCoords1, color); |
|||
#endif |
|||
|
|||
#if !defined(SURFACE_SCATTER_COORDS) |
|||
/* surface shader analysis currently forces us to include stuff even when unused */ |
|||
/* we also have to convince the analyzer to not optimize out stuff we need */ |
|||
#define SURFACE_SCATTER_COORDS float3 scaledWorldPos; float4 scatterCoords1; float3 scatterCoords2; |
|||
#define SURFACE_SCATTER_TRANSFER(pos, o) o.scatterCoords1.r = o.scatterCoords2.r = pos.x; |
|||
#define SURFACE_SCATTER_APPLY(i, color) color += (i.scaledWorldPos + i.scatterCoords1.xyz + i.scatterCoords2.xyz) * 0.000001f |
|||
#endif |
|||
|
|||
#endif //FILE_ATMOSPHERICSCATTERING |
|
|||
fileFormatVersion: 2 |
|||
guid: b0be9dce952dbb9479a5eb30e49c07a3 |
|||
timeCreated: 1480068393 |
|||
licenseType: Pro |
|||
ShaderImporter: |
|||
defaultTextures: [] |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
fileFormatVersion: 2 |
|||
guid: 67b996d0727a74b029aff1545143be17 |
|||
timeCreated: 1479851694 |
|||
licenseType: Pro |
|||
MonoImporter: |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
using System.Collections; |
|||
using System.Collections.Generic; |
|||
using UnityEngine; |
|||
using System; |
|||
|
|||
namespace UnityEditor.Experimental.ScriptableRenderLoop |
|||
{ |
|||
public class MaterialUpgrader |
|||
{ |
|||
string m_OldShader; |
|||
string m_NewShader; |
|||
|
|||
Dictionary<string, string> m_TextureRename = new Dictionary<string, string>(); |
|||
Dictionary<string, string> m_FloatRename = new Dictionary<string, string>(); |
|||
Dictionary<string, string> m_ColorRename = new Dictionary<string, string>(); |
|||
|
|||
[Flags] |
|||
public enum UpgradeFlags |
|||
{ |
|||
None = 0, |
|||
LogErrorOnNonExistingProperty = 1, |
|||
CleanupNonUpgradedProperties = 2, |
|||
} |
|||
|
|||
public void Upgrade(Material material, UpgradeFlags flags) |
|||
{ |
|||
Material newMaterial; |
|||
if ((flags & UpgradeFlags.CleanupNonUpgradedProperties) != 0) |
|||
{ |
|||
newMaterial = new Material(Shader.Find(m_NewShader)); |
|||
} |
|||
else |
|||
{ |
|||
newMaterial = UnityEngine.Object.Instantiate(material) as Material; |
|||
newMaterial.shader = Shader.Find(m_NewShader); |
|||
} |
|||
|
|||
Convert(material, newMaterial); |
|||
|
|||
material.shader = Shader.Find(m_NewShader); |
|||
material.CopyPropertiesFromMaterial(newMaterial); |
|||
UnityEngine.Object.DestroyImmediate(newMaterial); |
|||
} |
|||
|
|||
// Overridable function to implement custom material upgrading functionality
|
|||
public virtual void Convert(Material srcMaterial, Material dstMaterial) |
|||
{ |
|||
foreach (var t in m_TextureRename) |
|||
{ |
|||
dstMaterial.SetTextureScale(t.Value, srcMaterial.GetTextureScale(t.Key)); |
|||
dstMaterial.SetTextureOffset(t.Value, srcMaterial.GetTextureOffset(t.Key)); |
|||
dstMaterial.SetTexture(t.Value, srcMaterial.GetTexture(t.Key)); |
|||
} |
|||
|
|||
foreach (var t in m_FloatRename) |
|||
dstMaterial.SetFloat(t.Value, srcMaterial.GetFloat(t.Key)); |
|||
|
|||
foreach (var t in m_ColorRename) |
|||
dstMaterial.SetColor(t.Value, srcMaterial.GetColor(t.Key)); |
|||
} |
|||
|
|||
public void RenameShader(string oldName, string newName) |
|||
{ |
|||
m_OldShader = oldName; |
|||
m_NewShader = newName; |
|||
} |
|||
|
|||
public void RenameTexture(string oldName, string newName) |
|||
{ |
|||
m_TextureRename[oldName] = newName; |
|||
} |
|||
|
|||
public void RenameFloat(string oldName, string newName) |
|||
{ |
|||
m_FloatRename[oldName] = newName; |
|||
} |
|||
|
|||
public void RenameColor(string oldName, string newName) |
|||
{ |
|||
m_ColorRename[oldName] = newName; |
|||
} |
|||
|
|||
static bool IsMaterialPath(string path) |
|||
{ |
|||
return path.EndsWith(".mat", StringComparison.OrdinalIgnoreCase); |
|||
} |
|||
|
|||
static MaterialUpgrader GetUpgrader(List<MaterialUpgrader> upgraders, Material material) |
|||
{ |
|||
if (material == null || material.shader == null) |
|||
return null; |
|||
|
|||
string shaderName = material.shader.name; |
|||
for (int i = 0; i != upgraders.Count; i++) |
|||
{ |
|||
if (upgraders[i].m_OldShader == shaderName) |
|||
return upgraders[i]; |
|||
} |
|||
|
|||
return null; |
|||
} |
|||
|
|||
//@TODO: Only do this when it exceeds memory consumption...
|
|||
static void SaveAssetsAndFreeMemory() |
|||
{ |
|||
AssetDatabase.SaveAssets(); |
|||
GC.Collect(); |
|||
EditorUtility.UnloadUnusedAssetsImmediate(); |
|||
AssetDatabase.Refresh(); |
|||
} |
|||
|
|||
public static void UpgradeProjectFolder(List<MaterialUpgrader> upgraders, string progressBarName) |
|||
{ |
|||
int totalMaterialCount = 0; |
|||
foreach (string s in UnityEditor.AssetDatabase.GetAllAssetPaths()) |
|||
{ |
|||
if (IsMaterialPath(s)) |
|||
totalMaterialCount++; |
|||
} |
|||
|
|||
int materialIndex = 0; |
|||
foreach (string path in UnityEditor.AssetDatabase.GetAllAssetPaths()) |
|||
{ |
|||
if (IsMaterialPath(path)) |
|||
{ |
|||
materialIndex++; |
|||
if (UnityEditor.EditorUtility.DisplayCancelableProgressBar(progressBarName, string.Format("({0} of {1}) {2}", materialIndex, totalMaterialCount, path), (float)materialIndex / (float)totalMaterialCount)) |
|||
break; |
|||
|
|||
Material m = UnityEditor.AssetDatabase.LoadMainAssetAtPath(path) as Material; |
|||
Upgrade(m, upgraders, UpgradeFlags.None); |
|||
|
|||
//SaveAssetsAndFreeMemory();
|
|||
} |
|||
} |
|||
|
|||
UnityEditor.EditorUtility.ClearProgressBar(); |
|||
} |
|||
|
|||
public static void Upgrade(Material material, MaterialUpgrader upgrader, UpgradeFlags flags) |
|||
{ |
|||
var upgraders = new List<MaterialUpgrader>(); |
|||
upgraders.Add(upgrader); |
|||
Upgrade(material, upgraders, flags); |
|||
} |
|||
|
|||
public static void Upgrade(Material material, List<MaterialUpgrader> upgraders, UpgradeFlags flags) |
|||
{ |
|||
var upgrader = GetUpgrader(upgraders, material); |
|||
if (upgrader != null) |
|||
upgrader.Upgrade(material, flags); |
|||
} |
|||
|
|||
public static void UpgradeSelection(List<MaterialUpgrader> upgraders, string progressBarName) |
|||
{ |
|||
string lastMaterialName = ""; |
|||
var selection = Selection.objects; |
|||
for (int i = 0; i < selection.Length; i++) |
|||
{ |
|||
|
|||
if (UnityEditor.EditorUtility.DisplayCancelableProgressBar(progressBarName, string.Format("({0} of {1}) {2}", i, selection.Length, lastMaterialName), (float)i / (float)selection.Length)) |
|||
break; |
|||
|
|||
var material = selection[i] as Material; |
|||
Upgrade(material, upgraders, UpgradeFlags.None); |
|||
if (material != null) |
|||
lastMaterialName = material.name; |
|||
} |
|||
|
|||
UnityEditor.EditorUtility.ClearProgressBar(); |
|||
} |
|||
} |
|||
} |
|
|||
%YAML 1.1 |
|||
%TAG !u! tag:unity3d.com,2011: |
|||
--- !u!114 &11400000 |
|||
MonoBehaviour: |
|||
m_ObjectHideFlags: 0 |
|||
m_PrefabParentObject: {fileID: 0} |
|||
m_PrefabInternal: {fileID: 0} |
|||
m_GameObject: {fileID: 0} |
|||
m_Enabled: 1 |
|||
m_EditorHideFlags: 0 |
|||
m_Script: {fileID: 11500000, guid: 98fe12104b04e43dd9a963f3f7b26e8e, type: 3} |
|||
m_Name: forwardrenderloop |
|||
m_EditorClassIdentifier: |
|||
m_ShadowSettings: |
|||
enabled: 1 |
|||
shadowAtlasWidth: 4096 |
|||
shadowAtlasHeight: 4096 |
|||
maxShadowDistance: 1000 |
|||
directionalLightCascadeCount: 4 |
|||
directionalLightCascades: {x: 0.05, y: 0.2, z: 0.3} |
|
|||
fileFormatVersion: 2 |
|||
guid: bfc231f294556ca4799e7f7feddee50d |
|||
timeCreated: 1475076344 |
|||
licenseType: Pro |
|||
NativeFormatImporter: |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
撰写
预览
正在加载...
取消
保存
Reference in new issue