Evgenii Golubev 8 年前
当前提交
62d91392
共有 6 个文件被更改,包括 218 次插入39 次删除
  1. 24
      Assets/ScriptableRenderLoop/common/ShaderBase.h
  2. 137
      Assets/ScriptableRenderLoop/common/TextureCache.cs
  3. 4
      Assets/ScriptableRenderLoop/fptl/LightingTemplate.hlsl
  4. 10
      Assets/ScriptableRenderLoop/fptl/ReflectionTemplate.hlsl
  5. 2
      README.md
  6. 80
      Assets/ScriptableRenderLoop/common/CubeToSpherical.shader

24
Assets/ScriptableRenderLoop/common/ShaderBase.h


#ifndef __SHADERBASE_H__
#define __SHADERBASE_H__
//#define CUBE_ARRAY_NOT_SUPPORTED
half2 DirectionToSphericalTexCoordinate(half3 dir)
{
// coordinate frame is (-Z,X) meaning negative Z is primary axis and X is secondary axis.
float recipPi = 1.0/3.1415926535897932384626433832795;
return half2( 1.0-0.5*recipPi*atan2(dir.x, -dir.z), asin(dir.y)*recipPi+0.5 );
}
#ifdef CUBE_ARRAY_NOT_SUPPORTED
#define UNITY_DECLARE_ABSTRACT_CUBE_ARRAY UNITY_DECLARE_TEX2DARRAY
#define UNITY_PASS_ABSTRACT_CUBE_ARRAY UNITY_PASS_TEX2DARRAY
#define UNITY_ARGS_ABSTRACT_CUBE_ARRAY UNITY_ARGS_TEX2DARRAY
#define UNITY_SAMPLE_ABSTRACT_CUBE_ARRAY_LOD(tex,coord,lod) UNITY_SAMPLE_TEX2DARRAY_LOD(tex, float3(DirectionToSphericalTexCoordinate((coord).xyz), (coord).w), lod)
#else
#define UNITY_DECLARE_ABSTRACT_CUBE_ARRAY UNITY_DECLARE_TEXCUBEARRAY
#define UNITY_PASS_ABSTRACT_CUBE_ARRAY UNITY_PASS_TEXCUBEARRAY
#define UNITY_ARGS_ABSTRACT_CUBE_ARRAY UNITY_ARGS_TEXCUBEARRAY
#define UNITY_SAMPLE_ABSTRACT_CUBE_ARRAY_LOD(tex,coord,lod) UNITY_SAMPLE_TEXCUBEARRAY_LOD(tex,coord,lod)
#endif
// can't use UNITY_REVERSED_Z since it's not enabled in compute shaders
#if !defined(SHADER_API_GLES3) && !defined(SHADER_API_GLCORE)
#define REVERSE_ZBUF

137
Assets/ScriptableRenderLoop/common/TextureCache.cs


{
private CubemapArray m_Cache;
// alternative panorama path intended for mobile
// the member variables below are only in use when m_IsNoCubeArray is true.
private bool m_IsNoCubeArray = false;
private Texture2DArray m_CacheNoCubeArray;
private RenderTexture[] m_StagingRTs;
private int m_NumPanoMipLevels;
private Material m_CubeBlitMaterial;
private int m_CubeMipLevelPropName;
private int m_cubeSrcTexPropName;
// alternative panorama path intended for mobile
// the member variables below are only in use when m_IsNoCubeArray is true.
var mismatch = (m_Cache.width != texture.width) || (m_Cache.height != texture.height);
if (texture is Cubemap)
if(m_IsNoCubeArray)
TransferToPanoCache(sliceIndex, texture);
else
mismatch |= (m_Cache.format != (texture as Cubemap).format);
}
var mismatch = (m_Cache.width != texture.width) || (m_Cache.height != texture.height);
if (mismatch)
{
bool failed = false;
if (texture is Cubemap)
{
mismatch |= (m_Cache.format != (texture as Cubemap).format);
}
for (int f = 0; f < 6; f++)
if (mismatch)
if (!Graphics.ConvertTexture(texture, f, m_Cache, 6 * sliceIndex + f))
bool failed = false;
for (int f = 0; f < 6; f++)
{
if (!Graphics.ConvertTexture(texture, f, m_Cache, 6 * sliceIndex + f))
{
failed = true;
break;
}
}
if (failed)
failed = true;
break;
Debug.LogErrorFormat(texture, "Unable to convert texture \"{0}\" to match renderloop settings ({1}x{2} {3})",
texture.name, m_Cache.width, m_Cache.height, m_Cache.format);
if (failed)
else
Debug.LogErrorFormat(texture, "Unable to convert texture \"{0}\" to match renderloop settings ({1}x{2} {3})",
texture.name, m_Cache.width, m_Cache.height, m_Cache.format);
for (int f = 0; f < 6; f++)
Graphics.CopyTexture(texture, f, m_Cache, 6 * sliceIndex + f);
else
{
for (int f = 0; f < 6; f++)
Graphics.CopyTexture(texture, f, m_Cache, 6 * sliceIndex + f);
}
return m_Cache;
return m_IsNoCubeArray ? (Texture) m_CacheNoCubeArray : m_Cache;
var res = AllocTextureArray(6 * numCubeMaps);
m_NumMipLevels = GetNumMips(width, width);
var res = AllocTextureArray(numCubeMaps);
m_NumMipLevels = GetNumMips(width, width); // will calculate same way whether we have cube array or not
if(m_IsNoCubeArray)
{
if(!m_CubeBlitMaterial) m_CubeBlitMaterial = new Material(Shader.Find("Hidden/CubeToPano"));
int panoWidthTop = 4*width;
int panoHeightTop = 2*width;
// create panorama 2D array. Hardcoding the render target for now when m_IsNoCubeArray is true. No convenient way atm. to
// map from TextureFormat to RenderTextureFormat and don't want to deal with sRGB issues for now.
m_CacheNoCubeArray = new Texture2DArray(panoWidthTop, panoHeightTop, numCubeMaps, TextureFormat.RGBAHalf, isMipMapped)
{
hideFlags = HideFlags.HideAndDontSave,
wrapMode = TextureWrapMode.Repeat,
filterMode = FilterMode.Trilinear,
anisoLevel = 0
};
m_Cache = new CubemapArray(width, numCubeMaps, format, isMipMapped)
m_NumPanoMipLevels = isMipMapped ? GetNumMips(panoWidthTop, panoHeightTop) : 1;
m_StagingRTs = new RenderTexture[m_NumPanoMipLevels];
for(int m=0; m<m_NumPanoMipLevels; m++)
{
m_StagingRTs[m] = new RenderTexture(Mathf.Max(1,panoWidthTop>>m), Mathf.Max(1,panoHeightTop>>m), 0, RenderTextureFormat.ARGBHalf);
}
if(m_CubeBlitMaterial)
{
m_CubeMipLevelPropName = Shader.PropertyToID("_cubeMipLvl");
m_cubeSrcTexPropName = Shader.PropertyToID("_srcCubeTexture");
}
}
else
hideFlags = HideFlags.HideAndDontSave,
wrapMode = TextureWrapMode.Clamp,
filterMode = FilterMode.Trilinear,
anisoLevel = 0 // It is important to set 0 here, else unity force anisotropy filtering
};
m_Cache = new CubemapArray(width, numCubeMaps, format, isMipMapped)
{
hideFlags = HideFlags.HideAndDontSave,
wrapMode = TextureWrapMode.Clamp,
filterMode = FilterMode.Trilinear,
anisoLevel = 0 // It is important to set 0 here, else unity force anisotropy filtering
};
}
return res;
}

Texture.DestroyImmediate(m_Cache); // do I need this?
if(m_IsNoCubeArray)
{
Texture.DestroyImmediate(m_CacheNoCubeArray);
for(int m=0; m<m_NumPanoMipLevels; m++)
{
m_StagingRTs[m].Release();
}
m_StagingRTs=null;
if(m_CubeBlitMaterial) Material.DestroyImmediate(m_CubeBlitMaterial);
}
else Texture.DestroyImmediate(m_Cache);
}
private void TransferToPanoCache(int sliceIndex, Texture texture)
{
m_CubeBlitMaterial.SetTexture(m_cubeSrcTexPropName, texture);
for(int m=0; m<m_NumPanoMipLevels; m++)
{
m_CubeBlitMaterial.SetInt(m_CubeMipLevelPropName, Mathf.Min(m_NumMipLevels-1,m) );
Graphics.SetRenderTarget(m_StagingRTs[m]);
Graphics.Blit(null, m_CubeBlitMaterial, 0);
}
for(int m=0; m<m_NumPanoMipLevels; m++)
Graphics.CopyTexture(m_StagingRTs[m], 0, 0, m_CacheNoCubeArray, sliceIndex, m);
}
}

4
Assets/ScriptableRenderLoop/fptl/LightingTemplate.hlsl


//UNITY_DECLARE_TEX2D(_LightTextureB0);
sampler2D _LightTextureB0;
UNITY_DECLARE_TEX2DARRAY(_spotCookieTextures);
UNITY_DECLARE_TEXCUBEARRAY(_pointCookieTextures);
UNITY_DECLARE_ABSTRACT_CUBE_ARRAY(_pointCookieTextures);
StructuredBuffer<DirectionalLight> g_dirLightData;

[branch]if(bHasCookie)
{
float3 cookieCoord = -float3(dot(vL, lgtDat.lightAxisX.xyz), dot(vL, lgtDat.lightAxisY.xyz), dot(vL, lgtDat.lightAxisZ.xyz)); // negate to make vL a fromLight vector
cookieColor = UNITY_SAMPLE_TEXCUBEARRAY_LOD(_pointCookieTextures, float4(cookieCoord, lgtDat.sliceIndex), 0.0);
cookieColor = UNITY_SAMPLE_ABSTRACT_CUBE_ARRAY_LOD(_pointCookieTextures, float4(cookieCoord, lgtDat.sliceIndex), 0.0);
atten *= cookieColor.w;
}

10
Assets/ScriptableRenderLoop/fptl/ReflectionTemplate.hlsl


#include "UnityPBSLighting.cginc"
UNITY_DECLARE_TEXCUBEARRAY(_reflCubeTextures);
UNITY_DECLARE_ABSTRACT_CUBE_ARRAY(_reflCubeTextures);
UNITY_DECLARE_TEXCUBE(_reflRootCubeTexture);
//uniform int _reflRootSliceIndex;
uniform float _reflRootHdrDecodeMult;

half3 Unity_GlossyEnvironment (UNITY_ARGS_TEXCUBEARRAY(tex), int sliceIndex, half4 hdr, Unity_GlossyEnvironmentData glossIn);
half3 Unity_GlossyEnvironment (UNITY_ARGS_ABSTRACT_CUBE_ARRAY(tex), int sliceIndex, half4 hdr, Unity_GlossyEnvironmentData glossIn);
half3 distanceFromAABB(half3 p, half3 aabbMin, half3 aabbMax)
{

g.roughness = percRoughness;
g.reflUVW = sampleDir;
half3 env0 = Unity_GlossyEnvironment(UNITY_PASS_TEXCUBEARRAY(_reflCubeTextures), lgtDat.sliceIndex, float4(lgtDat.lightIntensity, lgtDat.decodeExp, 0.0, 0.0), g);
half3 env0 = Unity_GlossyEnvironment(UNITY_PASS_ABSTRACT_CUBE_ARRAY(_reflCubeTextures), lgtDat.sliceIndex, float4(lgtDat.lightIntensity, lgtDat.decodeExp, 0.0, 0.0), g);
UnityIndirect ind;

}
half3 Unity_GlossyEnvironment (UNITY_ARGS_TEXCUBEARRAY(tex), int sliceIndex, half4 hdr, Unity_GlossyEnvironmentData glossIn)
half3 Unity_GlossyEnvironment (UNITY_ARGS_ABSTRACT_CUBE_ARRAY(tex), int sliceIndex, half4 hdr, Unity_GlossyEnvironmentData glossIn)
{
#if UNITY_GLOSS_MATCHES_MARMOSET_TOOLBAG2 && (SHADER_TARGET >= 30)
// TODO: remove pow, store cubemap mips differently

half mip = perceptualRoughness * UNITY_SPECCUBE_LOD_STEPS;
half4 rgbm = UNITY_SAMPLE_TEXCUBEARRAY_LOD(tex, float4(glossIn.reflUVW.xyz, sliceIndex), mip);
half4 rgbm = UNITY_SAMPLE_ABSTRACT_CUBE_ARRAY_LOD(tex, float4(glossIn.reflUVW.xyz, sliceIndex), mip);
return DecodeHDR(rgbm, hdr);
}

2
README.md


## For Unity 5.6 beta users
* Unity 5.6 beta 1 should use an older revision of this project, [tagged unity-5.6.0b1](../../releases/tag/unity-5.6.0b1) (commit `acc230b` on 2016 Nov 23). "BasicRenderLoopScene" scene is the basic example, with the scriptable render loop defaulting to off; enable it by enabling the component on the camera. All the other scenes may or might not work. Use of Windows/DX11 is preferred.
* Unity 5.6 beta 1 and beta 2 should use an older revision of this project, [tagged unity-5.6.0b1](../../releases/tag/unity-5.6.0b1) (commit `acc230b` on 2016 Nov 23). "BasicRenderLoopScene" scene is the basic example, with the scriptable render loop defaulting to off; enable it by enabling the component on the camera. All the other scenes may or might not work. Use of Windows/DX11 is preferred.

80
Assets/ScriptableRenderLoop/common/CubeToSpherical.shader


Shader "Hidden/CubeToPano" {
Properties {
_SrcBlend ("", Float) = 1
_DstBlend ("", Float) = 1
}
SubShader {
Pass
{
ZWrite Off
ZTest Always
Cull Off
Blend Off
CGPROGRAM
#pragma target 4.5
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
UNITY_DECLARE_TEXCUBE(_srcCubeTexture);
uniform int _cubeMipLvl;
struct v2f {
float4 vertex : SV_POSITION;
float2 texcoord : TEXCOORD0;
};
v2f vert (float4 vertex : POSITION, float2 texcoord : TEXCOORD0)
{
v2f o;
o.vertex = UnityObjectToClipPos(vertex);
o.texcoord = texcoord.xy;
return o;
}
half2 DirectionToSphericalTexCoordinate(half3 dir) // use this for the lookup
{
// coordinate frame is (-Z,X) meaning negative Z is primary axis and X is secondary axis.
float recipPi = 1.0/3.1415926535897932384626433832795;
return half2( 1.0-0.5*recipPi*atan2(dir.x, -dir.z), asin(dir.y)*recipPi+0.5 );
}
half3 SphericalTexCoordinateToDirection(half2 sphTexCoord)
{
float pi = 3.1415926535897932384626433832795;
float theta = (1-sphTexCoord.x) * (pi*2);
float phi = (sphTexCoord.y-0.5) * pi;
float csTh, siTh, csPh, siPh;
sincos(theta, siTh, csTh);
sincos(phi, siPh, csPh);
// theta is 0 at negative Z (backwards). Coordinate frame is (-Z,X) meaning negative Z is primary axis and X is secondary axis.
return float3(siTh*csPh, siPh, -csTh*csPh);
}
half4 frag (v2f i) : SV_Target
{
uint2 pixCoord = ((uint2) i.vertex.xy);
half3 dir = SphericalTexCoordinateToDirection(i.texcoord.xy);
half3 res = UNITY_SAMPLE_TEXCUBE_LOD(_srcCubeTexture, dir, (float) _cubeMipLvl).xyz;
return half4(res,1.0);
}
ENDCG
}
}
Fallback Off
}
正在加载...
取消
保存