浏览代码
tiled forward (transparencies too)
tiled forward (transparencies too)
tiled forward (transparencies too). Didn't hook up reflections or cookies yet./main
mmikk
8 年前
当前提交
60d4e47d
共有 8 个文件被更改,包括 804 次插入 和 25 次删除
-
74Assets/ScriptableRenderLoop/fptl/FptlLighting.cs
-
288Assets/ScriptableRenderLoop/fptl/LightingTemplate.hlsl
-
130Assets/ScriptableRenderLoop/fptl/StandardTest.shader
-
86Assets/ScriptableRenderLoop/fptl/TiledLightingTemplate.hlsl
-
115Assets/ScriptableRenderLoop/fptl/UnityStandardForwardNew.cginc
-
136Assets/TestScenes/fptl/Materials/FwdMat.mat
|
|||
#ifndef __LIGHTINGTEMPLATE_H__ |
|||
#define __LIGHTINGTEMPLATE_H__ |
|||
|
|||
|
|||
#include "UnityCG.cginc" |
|||
#include "UnityStandardBRDF.cginc" |
|||
#include "UnityStandardUtils.cginc" |
|||
#include "UnityPBSLighting.cginc" |
|||
|
|||
#include "..\common\ShaderBase.h" |
|||
#include "LightDefinitions.cs.hlsl" |
|||
|
|||
|
|||
uniform uint g_nNumDirLights; |
|||
|
|||
//--------------------------------------------------------------------------------------------------------------------------------------------------------- |
|||
// TODO: clean up.. -va |
|||
#define MAX_SHADOW_LIGHTS 10 |
|||
#define MAX_SHADOWMAP_PER_LIGHT 6 |
|||
#define MAX_DIRECTIONAL_SPLIT 4 |
|||
|
|||
#define CUBEMAPFACE_POSITIVE_X 0 |
|||
#define CUBEMAPFACE_NEGATIVE_X 1 |
|||
#define CUBEMAPFACE_POSITIVE_Y 2 |
|||
#define CUBEMAPFACE_NEGATIVE_Y 3 |
|||
#define CUBEMAPFACE_POSITIVE_Z 4 |
|||
#define CUBEMAPFACE_NEGATIVE_Z 5 |
|||
|
|||
CBUFFER_START(ShadowLightData) |
|||
|
|||
float4 g_vShadow3x3PCFTerms0; |
|||
float4 g_vShadow3x3PCFTerms1; |
|||
float4 g_vShadow3x3PCFTerms2; |
|||
float4 g_vShadow3x3PCFTerms3; |
|||
|
|||
float4 g_vDirShadowSplitSpheres[MAX_DIRECTIONAL_SPLIT]; |
|||
float4x4 g_matWorldToShadow[MAX_SHADOW_LIGHTS * MAX_SHADOWMAP_PER_LIGHT]; |
|||
|
|||
CBUFFER_END |
|||
//--------------------------------------------------------------------------------------------------------------------------------------------------------- |
|||
|
|||
|
|||
//UNITY_DECLARE_TEX2D(_LightTextureB0); |
|||
sampler2D _LightTextureB0; |
|||
UNITY_DECLARE_TEX2DARRAY(_spotCookieTextures); |
|||
UNITY_DECLARE_TEXCUBEARRAY(_pointCookieTextures); |
|||
|
|||
StructuredBuffer<SFiniteLightData> g_vLightData; |
|||
StructuredBuffer<DirectionalLight> g_dirLightData; |
|||
|
|||
|
|||
#define VALVE_DECLARE_SHADOWMAP( tex ) Texture2D tex; SamplerComparisonState sampler##tex |
|||
#define VALVE_SAMPLE_SHADOW( tex, coord ) tex.SampleCmpLevelZero( sampler##tex, (coord).xy, (coord).z ) |
|||
|
|||
VALVE_DECLARE_SHADOWMAP(g_tShadowBuffer); |
|||
|
|||
float ComputeShadow_PCF_3x3_Gaussian(float3 vPositionWs, float4x4 matWorldToShadow) |
|||
{ |
|||
float4 vPositionTextureSpace = mul(float4(vPositionWs.xyz, 1.0), matWorldToShadow); |
|||
vPositionTextureSpace.xyz /= vPositionTextureSpace.w; |
|||
|
|||
float2 shadowMapCenter = vPositionTextureSpace.xy; |
|||
|
|||
if ((shadowMapCenter.x < 0.0f) || (shadowMapCenter.x > 1.0f) || (shadowMapCenter.y < 0.0f) || (shadowMapCenter.y > 1.0f)) |
|||
return 1.0f; |
|||
|
|||
float objDepth = saturate(257.0 / 256.0 - vPositionTextureSpace.z); |
|||
|
|||
float4 v20Taps; |
|||
v20Taps.x = VALVE_SAMPLE_SHADOW(g_tShadowBuffer, float3(shadowMapCenter.xy + g_vShadow3x3PCFTerms1.xy, objDepth)).x; // 1 1 |
|||
v20Taps.y = VALVE_SAMPLE_SHADOW(g_tShadowBuffer, float3(shadowMapCenter.xy + g_vShadow3x3PCFTerms1.zy, objDepth)).x; // -1 1 |
|||
v20Taps.z = VALVE_SAMPLE_SHADOW(g_tShadowBuffer, float3(shadowMapCenter.xy + g_vShadow3x3PCFTerms1.xw, objDepth)).x; // 1 -1 |
|||
v20Taps.w = VALVE_SAMPLE_SHADOW(g_tShadowBuffer, float3(shadowMapCenter.xy + g_vShadow3x3PCFTerms1.zw, objDepth)).x; // -1 -1 |
|||
float flSum = dot(v20Taps.xyzw, float4(0.25, 0.25, 0.25, 0.25)); |
|||
if ((flSum == 0.0) || (flSum == 1.0)) |
|||
return flSum; |
|||
flSum *= g_vShadow3x3PCFTerms0.x * 4.0; |
|||
|
|||
float4 v33Taps; |
|||
v33Taps.x = VALVE_SAMPLE_SHADOW(g_tShadowBuffer, float3(shadowMapCenter.xy + g_vShadow3x3PCFTerms2.xz, objDepth)).x; // 1 0 |
|||
v33Taps.y = VALVE_SAMPLE_SHADOW(g_tShadowBuffer, float3(shadowMapCenter.xy + g_vShadow3x3PCFTerms3.xz, objDepth)).x; // -1 0 |
|||
v33Taps.z = VALVE_SAMPLE_SHADOW(g_tShadowBuffer, float3(shadowMapCenter.xy + g_vShadow3x3PCFTerms3.zy, objDepth)).x; // 0 -1 |
|||
v33Taps.w = VALVE_SAMPLE_SHADOW(g_tShadowBuffer, float3(shadowMapCenter.xy + g_vShadow3x3PCFTerms2.zy, objDepth)).x; // 0 1 |
|||
flSum += dot(v33Taps.xyzw, g_vShadow3x3PCFTerms0.yyyy); |
|||
|
|||
flSum += VALVE_SAMPLE_SHADOW(g_tShadowBuffer, float3(shadowMapCenter.xy, objDepth)).x * g_vShadow3x3PCFTerms0.z; |
|||
|
|||
return flSum; |
|||
} |
|||
|
|||
//--------------------------------------------------------------------------------------------------------------------------------------------------------- |
|||
/** |
|||
* Gets the cascade weights based on the world position of the fragment and the positions of the split spheres for each cascade. |
|||
* Returns an invalid split index if past shadowDistance (ie 4 is invalid for cascade) |
|||
*/ |
|||
float GetSplitSphereIndexForDirshadows(float3 wpos) |
|||
{ |
|||
float3 fromCenter0 = wpos.xyz - g_vDirShadowSplitSpheres[0].xyz; |
|||
float3 fromCenter1 = wpos.xyz - g_vDirShadowSplitSpheres[1].xyz; |
|||
float3 fromCenter2 = wpos.xyz - g_vDirShadowSplitSpheres[2].xyz; |
|||
float3 fromCenter3 = wpos.xyz - g_vDirShadowSplitSpheres[3].xyz; |
|||
float4 distances2 = float4(dot(fromCenter0, fromCenter0), dot(fromCenter1, fromCenter1), dot(fromCenter2, fromCenter2), dot(fromCenter3, fromCenter3)); |
|||
|
|||
float4 vDirShadowSplitSphereSqRadii; |
|||
vDirShadowSplitSphereSqRadii.x = g_vDirShadowSplitSpheres[0].w; |
|||
vDirShadowSplitSphereSqRadii.y = g_vDirShadowSplitSpheres[1].w; |
|||
vDirShadowSplitSphereSqRadii.z = g_vDirShadowSplitSpheres[2].w; |
|||
vDirShadowSplitSphereSqRadii.w = g_vDirShadowSplitSpheres[3].w; |
|||
fixed4 weights = float4(distances2 < vDirShadowSplitSphereSqRadii); |
|||
weights.yzw = saturate(weights.yzw - weights.xyz); |
|||
return 4 - dot(weights, float4(4, 3, 2, 1)); |
|||
} |
|||
|
|||
float SampleShadow(uint type, float3 vPositionWs, float3 vPositionToLightDirWs, uint lightIndex) |
|||
{ |
|||
float flShadowScalar = 1.0; |
|||
int shadowSplitIndex = 0; |
|||
|
|||
if (type == DIRECTIONAL_LIGHT) |
|||
{ |
|||
shadowSplitIndex = GetSplitSphereIndexForDirshadows(vPositionWs); |
|||
} |
|||
|
|||
else if (type == SPHERE_LIGHT) |
|||
{ |
|||
float3 absPos = abs(vPositionToLightDirWs); |
|||
shadowSplitIndex = (vPositionToLightDirWs.z > 0) ? CUBEMAPFACE_NEGATIVE_Z : CUBEMAPFACE_POSITIVE_Z; |
|||
if (absPos.x > absPos.y) |
|||
{ |
|||
if (absPos.x > absPos.z) |
|||
{ |
|||
shadowSplitIndex = (vPositionToLightDirWs.x > 0) ? CUBEMAPFACE_NEGATIVE_X : CUBEMAPFACE_POSITIVE_X; |
|||
} |
|||
} |
|||
else |
|||
{ |
|||
if (absPos.y > absPos.z) |
|||
{ |
|||
shadowSplitIndex = (vPositionToLightDirWs.y > 0) ? CUBEMAPFACE_NEGATIVE_Y : CUBEMAPFACE_POSITIVE_Y; |
|||
} |
|||
} |
|||
} |
|||
|
|||
flShadowScalar = ComputeShadow_PCF_3x3_Gaussian(vPositionWs.xyz, g_matWorldToShadow[lightIndex * MAX_SHADOWMAP_PER_LIGHT + shadowSplitIndex]); |
|||
return flShadowScalar; |
|||
} |
|||
|
|||
|
|||
float3 ExecuteLightList(uint start, uint numLights, float3 vP, float3 vPw, float3 Vworld) |
|||
{ |
|||
UnityIndirect ind; |
|||
UNITY_INITIALIZE_OUTPUT(UnityIndirect, ind); |
|||
ind.diffuse = 0; |
|||
ind.specular = 0; |
|||
|
|||
|
|||
float3 ints = 0; |
|||
|
|||
uint l=0; |
|||
|
|||
for (int i = 0; i < g_nNumDirLights; i++) |
|||
{ |
|||
DirectionalLight lightData = g_dirLightData[i]; |
|||
float atten = 1; |
|||
|
|||
[branch] |
|||
if (lightData.uShadowLightIndex != 0xffffffff) |
|||
{ |
|||
float shadowScalar = SampleShadow(DIRECTIONAL_LIGHT, vPw, 0, lightData.uShadowLightIndex); |
|||
atten *= shadowScalar; |
|||
} |
|||
|
|||
UnityLight light; |
|||
light.color.xyz = lightData.vCol.xyz * atten; |
|||
light.dir.xyz = mul((float3x3) g_mViewToWorld, -lightData.vLaxisZ).xyz; |
|||
|
|||
ints += EvalMaterial(light, ind); |
|||
} |
|||
|
|||
// we need this outer loop for when we cannot assume a wavefront is 64 wide |
|||
// since in this case we cannot assume the lights will remain sorted by type |
|||
// during processing in lightlist_cs.hlsl |
|||
#if !defined(XBONE) && !defined(PLAYSTATION4) |
|||
while(l<numLights) |
|||
#endif |
|||
{ |
|||
uint uIndex = l<numLights ? FetchIndex(start, l) : 0; |
|||
uint uLgtType = l<numLights ? g_vLightData[uIndex].uLightType : 0; |
|||
|
|||
// specialized loop for spot lights |
|||
while(l<numLights && uLgtType==SPOT_LIGHT) |
|||
{ |
|||
SFiniteLightData lgtDat = g_vLightData[uIndex]; |
|||
float3 vLp = lgtDat.vLpos.xyz; |
|||
|
|||
float3 toLight = vLp - vP; |
|||
float dist = length(toLight); |
|||
float3 vL = toLight / dist; |
|||
|
|||
float attLookUp = dist*lgtDat.fRecipRange; attLookUp *= attLookUp; |
|||
float atten = tex2Dlod(_LightTextureB0, float4(attLookUp.rr, 0.0, 0.0)).UNITY_ATTEN_CHANNEL; |
|||
|
|||
// spot attenuation |
|||
const float fProjVec = -dot(vL, lgtDat.vLaxisZ.xyz); // spotDir = lgtDat.vLaxisZ.xyz |
|||
float2 cookCoord = (-lgtDat.cotan)*float2( dot(vL, lgtDat.vLaxisX.xyz), dot(vL, lgtDat.vLaxisY.xyz) ) / fProjVec; |
|||
|
|||
const bool bHasCookie = (lgtDat.flags&IS_CIRCULAR_SPOT_SHAPE)==0; // all square spots have cookies |
|||
float d0 = 0.65; |
|||
float4 angularAtt = float4(1,1,1,smoothstep(0.0, 1.0-d0, 1.0-length(cookCoord))); |
|||
[branch]if(bHasCookie) |
|||
{ |
|||
cookCoord = cookCoord*0.5 + 0.5; |
|||
angularAtt = UNITY_SAMPLE_TEX2DARRAY_LOD(_spotCookieTextures, float3(cookCoord, lgtDat.iSliceIndex), 0.0); |
|||
} |
|||
atten *= angularAtt.w*(fProjVec>0.0); // finally apply this to the dist att. |
|||
|
|||
const bool bHasShadow = (lgtDat.flags&HAS_SHADOW)!=0; |
|||
[branch]if(bHasShadow) |
|||
{ |
|||
float shadowScalar = SampleShadow(SPOT_LIGHT, vPw, 0, lgtDat.uShadowLightIndex); |
|||
atten *= shadowScalar; |
|||
} |
|||
|
|||
UnityLight light; |
|||
light.color.xyz = lgtDat.vCol.xyz*atten*angularAtt.xyz; |
|||
light.dir.xyz = mul((float3x3) g_mViewToWorld, vL).xyz; //unity_CameraToWorld |
|||
|
|||
ints += EvalMaterial(light, ind); |
|||
|
|||
++l; uIndex = l<numLights ? FetchIndex(start, l) : 0; |
|||
uLgtType = l<numLights ? g_vLightData[uIndex].uLightType : 0; |
|||
} |
|||
|
|||
// specialized loop for sphere lights |
|||
while(l<numLights && uLgtType==SPHERE_LIGHT) |
|||
{ |
|||
SFiniteLightData lgtDat = g_vLightData[uIndex]; |
|||
float3 vLp = lgtDat.vLpos.xyz; |
|||
|
|||
float3 toLight = vLp - vP; |
|||
float dist = length(toLight); |
|||
float3 vL = toLight / dist; |
|||
float3 vLw = mul((float3x3) g_mViewToWorld, vL).xyz; //unity_CameraToWorld |
|||
|
|||
float attLookUp = dist*lgtDat.fRecipRange; attLookUp *= attLookUp; |
|||
float atten = tex2Dlod(_LightTextureB0, float4(attLookUp.rr, 0.0, 0.0)).UNITY_ATTEN_CHANNEL; |
|||
|
|||
float4 cookieColor = float4(1,1,1,1); |
|||
|
|||
const bool bHasCookie = (lgtDat.flags&HAS_COOKIE_TEXTURE)!=0; |
|||
[branch]if(bHasCookie) |
|||
{ |
|||
float3 cookieCoord = -float3(dot(vL, lgtDat.vLaxisX.xyz), dot(vL, lgtDat.vLaxisY.xyz), dot(vL, lgtDat.vLaxisZ.xyz)); // negate to make vL a fromLight vector |
|||
cookieColor = UNITY_SAMPLE_TEXCUBEARRAY_LOD(_pointCookieTextures, float4(cookieCoord, lgtDat.iSliceIndex), 0.0); |
|||
atten *= cookieColor.w; |
|||
} |
|||
|
|||
const bool bHasShadow = (lgtDat.flags&HAS_SHADOW)!=0; |
|||
[branch]if(bHasShadow) |
|||
{ |
|||
float shadowScalar = SampleShadow(SPHERE_LIGHT, vPw, vLw, lgtDat.uShadowLightIndex); |
|||
atten *= shadowScalar; |
|||
} |
|||
|
|||
UnityLight light; |
|||
light.color.xyz = lgtDat.vCol.xyz*atten*cookieColor.xyz; |
|||
light.dir.xyz = vLw; |
|||
|
|||
ints += EvalMaterial(light, ind); |
|||
|
|||
++l; uIndex = l<numLights ? FetchIndex(start, l) : 0; |
|||
uLgtType = l<numLights ? g_vLightData[uIndex].uLightType : 0; |
|||
} |
|||
|
|||
#if !defined(XBONE) && !defined(PLAYSTATION4) |
|||
//if(uLgtType>=MAX_TYPES) ++l; |
|||
if(uLgtType!=SPOT_LIGHT && uLgtType!=SPHERE_LIGHT) ++l; |
|||
#endif |
|||
} |
|||
|
|||
return ints; |
|||
} |
|||
|
|||
|
|||
|
|||
|
|||
|
|||
#endif |
|
|||
Shader "Experim/StdShader" |
|||
{ |
|||
Properties |
|||
{ |
|||
_Color("Color", Color) = (1,1,1,1) |
|||
_MainTex("Albedo", 2D) = "white" {} |
|||
|
|||
_Cutoff("Alpha Cutoff", Range(0.0, 1.0)) = 0.5 |
|||
|
|||
_Glossiness("Smoothness", Range(0.0, 1.0)) = 0.5 |
|||
_GlossMapScale("Smoothness Scale", Range(0.0, 1.0)) = 1.0 |
|||
[Enum(Metallic Alpha,0,Albedo Alpha,1)] _SmoothnessTextureChannel ("Smoothness texture channel", Float) = 0 |
|||
|
|||
[Gamma] _Metallic("Metallic", Range(0.0, 1.0)) = 0.0 |
|||
_MetallicGlossMap("Metallic", 2D) = "white" {} |
|||
|
|||
[ToggleOff] _SpecularHighlights("Specular Highlights", Float) = 1.0 |
|||
[ToggleOff] _GlossyReflections("Glossy Reflections", Float) = 1.0 |
|||
|
|||
_BumpScale("Scale", Float) = 1.0 |
|||
_BumpMap("Normal Map", 2D) = "bump" {} |
|||
|
|||
_Parallax ("Height Scale", Range (0.005, 0.08)) = 0.02 |
|||
_ParallaxMap ("Height Map", 2D) = "black" {} |
|||
|
|||
_OcclusionStrength("Strength", Range(0.0, 1.0)) = 1.0 |
|||
_OcclusionMap("Occlusion", 2D) = "white" {} |
|||
|
|||
_EmissionColor("Color", Color) = (0,0,0) |
|||
_EmissionMap("Emission", 2D) = "white" {} |
|||
|
|||
_DetailMask("Detail Mask", 2D) = "white" {} |
|||
|
|||
_DetailAlbedoMap("Detail Albedo x2", 2D) = "grey" {} |
|||
_DetailNormalMapScale("Scale", Float) = 1.0 |
|||
_DetailNormalMap("Normal Map", 2D) = "bump" {} |
|||
|
|||
[Enum(UV0,0,UV1,1)] _UVSec ("UV Set for secondary textures", Float) = 0 |
|||
|
|||
|
|||
// Blending state |
|||
[HideInInspector] _Mode ("__mode", Float) = 0.0 |
|||
[HideInInspector] _SrcBlend ("__src", Float) = 1.0 |
|||
[HideInInspector] _DstBlend ("__dst", Float) = 0.0 |
|||
[HideInInspector] _ZWrite ("__zw", Float) = 1.0 |
|||
} |
|||
|
|||
CGINCLUDE |
|||
#define UNITY_SETUP_BRDF_INPUT MetallicSetup |
|||
ENDCG |
|||
|
|||
SubShader |
|||
{ |
|||
Tags { "RenderType" = "Opaque" "PerformanceChecks" = "False" } |
|||
LOD 300 |
|||
|
|||
|
|||
// ------------------------------------------------------------------ |
|||
// Forward pass |
|||
Pass |
|||
{ |
|||
Name "FORWARD" |
|||
Tags { "LightMode" = "ForwardSinglePass" } |
|||
|
|||
Blend [_SrcBlend] [_DstBlend] |
|||
ZWrite [_ZWrite] |
|||
|
|||
CGPROGRAM |
|||
#pragma target 5.0 |
|||
|
|||
// ------------------------------------- |
|||
|
|||
#pragma shader_feature _NORMALMAP |
|||
#pragma shader_feature _ _ALPHATEST_ON _ALPHABLEND_ON _ALPHAPREMULTIPLY_ON |
|||
#pragma shader_feature _EMISSION |
|||
#pragma shader_feature _METALLICGLOSSMAP |
|||
#pragma shader_feature ___ _DETAIL_MULX2 |
|||
#pragma shader_feature _ _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A |
|||
#pragma shader_feature _ _SPECULARHIGHLIGHTS_OFF |
|||
#pragma shader_feature _ _GLOSSYREFLECTIONS_OFF |
|||
#pragma shader_feature _PARALLAXMAP |
|||
|
|||
#pragma multi_compile LIGHTMAP_OFF LIGHTMAP_ON |
|||
#pragma multi_compile DIRLIGHTMAP_OFF DIRLIGHTMAP_COMBINED DIRLIGHTMAP_SEPARATE |
|||
#pragma multi_compile DYNAMICLIGHTMAP_OFF DYNAMICLIGHTMAP_ON |
|||
#pragma multi_compile_fog |
|||
|
|||
#pragma vertex vertForward |
|||
#pragma fragment fragForward |
|||
|
|||
#include "UnityStandardForwardNew.cginc" |
|||
|
|||
|
|||
ENDCG |
|||
} |
|||
|
|||
// ------------------------------------------------------------------ |
|||
// Shadow rendering pass |
|||
Pass { |
|||
Name "ShadowCaster" |
|||
Tags { "LightMode" = "ShadowCaster" } |
|||
|
|||
ZWrite On ZTest LEqual |
|||
|
|||
CGPROGRAM |
|||
#pragma target 5.0 |
|||
|
|||
// ------------------------------------- |
|||
|
|||
|
|||
#pragma shader_feature _ _ALPHATEST_ON _ALPHABLEND_ON _ALPHAPREMULTIPLY_ON |
|||
#pragma shader_feature _METALLICGLOSSMAP |
|||
#pragma multi_compile_shadowcaster |
|||
|
|||
#pragma vertex vertShadowCaster |
|||
#pragma fragment fragShadowCaster |
|||
|
|||
#include "UnityStandardShadow.cginc" |
|||
|
|||
ENDCG |
|||
} |
|||
// ------------------------------------------------------------------ |
|||
// Deferred pass |
|||
|
|||
} |
|||
|
|||
|
|||
FallBack "VertexLit" |
|||
CustomEditor "StandardShaderGUI" |
|||
} |
|
|||
#ifndef __TILEDLIGHTINGTEMPLATE_H__ |
|||
#define __TILEDLIGHTINGTEMPLATE_H__ |
|||
|
|||
uint FetchIndex(const uint tileOffs, const uint l); |
|||
|
|||
uniform float4x4 g_mViewToWorld; |
|||
uniform float4x4 g_mScrProjection; |
|||
|
|||
#include "LightingTemplate.hlsl" |
|||
|
|||
|
|||
void GetLightCountAndStart(out uint uStart, out uint uNrLights, uint2 tileIDX, int nrTilesX, int nrTilesY, float linDepth); |
|||
|
|||
uniform uint g_widthRT; |
|||
uniform uint g_heightRT; |
|||
|
|||
float3 ExecuteLightListTiled(uint2 pixCoord, float3 vP, float3 vPw, float3 Vworld) |
|||
{ |
|||
uint nrTilesX = (g_widthRT+15)/16; uint nrTilesY = (g_heightRT+15)/16; |
|||
uint2 tileIDX = pixCoord / 16; |
|||
|
|||
uint start = 0, numLights = 0; |
|||
GetLightCountAndStart(start, numLights, tileIDX, nrTilesX, nrTilesY, vP.z); |
|||
|
|||
return ExecuteLightList(start, numLights, vP, vPw, Vworld); |
|||
} |
|||
|
|||
uniform float g_fClustScale; |
|||
uniform float g_fClustBase; |
|||
uniform float g_fNearPlane; |
|||
uniform float g_fFarPlane; |
|||
//uniform int g_iLog2NumClusters; // numClusters = (1<<g_iLog2NumClusters) |
|||
uniform float g_fLog2NumClusters; |
|||
static int g_iLog2NumClusters; |
|||
|
|||
#include "ClusteredUtils.h" |
|||
|
|||
StructuredBuffer<uint> g_vLightListGlobal; |
|||
Buffer<uint> g_vLayeredOffsetsBuffer; |
|||
#ifdef ENABLE_DEPTH_TEXTURE_BACKPLANE |
|||
Buffer<float> g_logBaseBuffer; |
|||
#endif |
|||
|
|||
|
|||
void GetLightCountAndStart(out uint uStart, out uint uNrLights, uint2 tileIDX, int nrTilesX, int nrTilesY, float linDepth) |
|||
{ |
|||
g_iLog2NumClusters = (int) g_fLog2NumClusters; |
|||
#ifdef ENABLE_DEPTH_TEXTURE_BACKPLANE |
|||
float logBase = g_logBaseBuffer[tileIDX.y*nrTilesX + tileIDX.x]; |
|||
#else |
|||
float logBase = g_fClustBase; |
|||
#endif |
|||
int clustIdx = SnapToClusterIdx(linDepth, logBase); |
|||
|
|||
int nrClusters = (1<<g_iLog2NumClusters); |
|||
const int idx = ((DIRECT_LIGHT*nrClusters + clustIdx)*nrTilesY + tileIDX.y)*nrTilesX + tileIDX.x; |
|||
uint dataPair = g_vLayeredOffsetsBuffer[idx]; |
|||
uStart = dataPair&0x7ffffff; |
|||
uNrLights = (dataPair>>27)&31; |
|||
} |
|||
|
|||
uint FetchIndex(const uint tileOffs, const uint l) |
|||
{ |
|||
return g_vLightListGlobal[ tileOffs+l ]; |
|||
} |
|||
|
|||
|
|||
float3 GetViewPosFromLinDepth(float2 v2ScrPos, float fLinDepth) |
|||
{ |
|||
float fSx = g_mScrProjection[0].x; |
|||
//float fCx = g_mScrProjection[2].x; |
|||
float fCx = g_mScrProjection[0].z; |
|||
float fSy = g_mScrProjection[1].y; |
|||
//float fCy = g_mScrProjection[2].y; |
|||
float fCy = g_mScrProjection[1].z; |
|||
|
|||
#ifdef LEFT_HAND_COORDINATES |
|||
return fLinDepth*float3( ((v2ScrPos.x-fCx)/fSx), ((v2ScrPos.y-fCy)/fSy), 1.0 ); |
|||
#else |
|||
return fLinDepth*float3( -((v2ScrPos.x+fCx)/fSx), -((v2ScrPos.y+fCy)/fSy), 1.0 ); |
|||
#endif |
|||
} |
|||
|
|||
|
|||
|
|||
#endif |
|
|||
#ifndef UNITY_STANDARD_FORWARDNEW_INCLUDED |
|||
#define UNITY_STANDARD_FORWARDNEW_INCLUDED |
|||
|
|||
|
|||
// NOTE: had to split shadow functions into separate file, |
|||
// otherwise compiler gives trouble with LIGHTING_COORDS macro (in UnityStandardCore.cginc) |
|||
|
|||
#include "UnityStandardConfig.cginc" |
|||
#include "UnityStandardCore.cginc" |
|||
|
|||
struct VertexOutputForwardNew |
|||
{ |
|||
float4 pos : SV_POSITION; |
|||
float4 tex : TEXCOORD0; |
|||
half4 ambientOrLightmapUV : TEXCOORD1; // SH or Lightmap UV |
|||
half4 tangentToWorldAndParallax[3] : TEXCOORD2; // [3x3:tangentToWorld | 1x3:empty] |
|||
|
|||
LIGHTING_COORDS(5,6) |
|||
UNITY_FOG_COORDS(7) |
|||
|
|||
UNITY_VERTEX_OUTPUT_STEREO |
|||
}; |
|||
|
|||
|
|||
|
|||
VertexOutputForwardNew vertForward(VertexInput v) |
|||
{ |
|||
UNITY_SETUP_INSTANCE_ID(v); |
|||
VertexOutputForwardNew o; |
|||
UNITY_INITIALIZE_OUTPUT(VertexOutputForwardNew, o); |
|||
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); |
|||
|
|||
float4 posWorld = mul(unity_ObjectToWorld, v.vertex); |
|||
o.pos = UnityObjectToClipPos(v.vertex); |
|||
|
|||
o.tex = TexCoords(v); |
|||
|
|||
float3 normalWorld = UnityObjectToWorldNormal(v.normal); |
|||
#ifdef _TANGENT_TO_WORLD |
|||
float4 tangentWorld = float4(UnityObjectToWorldDir(v.tangent.xyz), v.tangent.w); |
|||
|
|||
float3x3 tangentToWorld = CreateTangentToWorldPerVertex(normalWorld, tangentWorld.xyz, tangentWorld.w); |
|||
o.tangentToWorldAndParallax[0].xyz = tangentToWorld[0]; |
|||
o.tangentToWorldAndParallax[1].xyz = tangentToWorld[1]; |
|||
o.tangentToWorldAndParallax[2].xyz = tangentToWorld[2]; |
|||
#else |
|||
o.tangentToWorldAndParallax[0].xyz = 0; |
|||
o.tangentToWorldAndParallax[1].xyz = 0; |
|||
o.tangentToWorldAndParallax[2].xyz = normalWorld; |
|||
#endif |
|||
|
|||
o.ambientOrLightmapUV = VertexGIForward(v, posWorld, normalWorld); |
|||
|
|||
UNITY_TRANSFER_FOG(o,o.pos); |
|||
|
|||
return o; |
|||
} |
|||
|
|||
|
|||
static FragmentCommonData gdata; |
|||
|
|||
|
|||
float3 EvalMaterial(UnityLight light, UnityIndirect ind) |
|||
{ |
|||
return UNITY_BRDF_PBS(gdata.diffColor, gdata.specColor, gdata.oneMinusReflectivity, gdata.smoothness, gdata.normalWorld, -gdata.eyeVec, light, ind); |
|||
} |
|||
|
|||
#define ENABLE_DEPTH_TEXTURE_BACKPLANE |
|||
|
|||
#include "TiledLightingTemplate.hlsl" |
|||
|
|||
|
|||
|
|||
half4 fragForward(VertexOutputForwardNew i) : SV_Target |
|||
{ |
|||
#ifdef LEFT_HAND_COORDINATES |
|||
float linZ = i.pos.w; |
|||
#else |
|||
float linZ = -i.pos.w; |
|||
#endif |
|||
|
|||
float3 vP = GetViewPosFromLinDepth(i.pos.xy, linZ); |
|||
float3 vPw = mul(g_mViewToWorld, float4(vP,1.0)).xyz; |
|||
float3 Vworld = normalize(mul((float3x3) g_mViewToWorld, -vP).xyz); //unity_CameraToWorld |
|||
|
|||
#ifdef _PARALLAXMAP |
|||
half3 tangent = i.tangentToWorldAndParallax[0].xyz; |
|||
half3 bitangent = i.tangentToWorldAndParallax[1].xyz; |
|||
half3 normal = i.tangentToWorldAndParallax[2].xyz; |
|||
float3 vDirForParallax = float3( dot(tangent, Vworld), dot(bitangent, Vworld), dot(normal, Vworld)); |
|||
#else |
|||
float3 vDirForParallax = Vworld; |
|||
#endif |
|||
gdata = FragmentSetup(i.tex, -Vworld, vDirForParallax, i.tangentToWorldAndParallax, vPw); // eyeVec = -Vworld |
|||
|
|||
|
|||
uint2 pixCoord = ((uint2) i.pos.xy); |
|||
|
|||
//float atten = 0.0; |
|||
//half occlusion = Occlusion(i.tex.xy); |
|||
//UnityGI gi = FragmentGI (gdata, occlusion, i.ambientOrLightmapUV, atten, mainLight); |
|||
|
|||
float3 res = 0; |
|||
res += ExecuteLightListTiled(pixCoord, vP, vPw, Vworld); |
|||
|
|||
// don't really have a handle on this yet |
|||
//UnityLight mainLight = MainLight (); |
|||
//res += UNITY_BRDF_GI (gdata.diffColor, gdata.specColor, gdata.oneMinusReflectivity, gdata.smoothness, gdata.normalWorld, -gdata.eyeVec, occlusion, gi); |
|||
res += Emission(i.tex.xy); |
|||
|
|||
//UNITY_APPLY_FOG(i.fogCoord, res); |
|||
return OutputForward (float4(res,1.0), gdata.alpha); |
|||
} |
|||
|
|||
#endif // UNITY_STANDARD_SHADOW_INCLUDED |
|
|||
%YAML 1.1 |
|||
%TAG !u! tag:unity3d.com,2011: |
|||
--- !u!21 &2100000 |
|||
Material: |
|||
serializedVersion: 6 |
|||
m_ObjectHideFlags: 0 |
|||
m_PrefabParentObject: {fileID: 0} |
|||
m_PrefabInternal: {fileID: 0} |
|||
m_Name: FwdMat |
|||
m_Shader: {fileID: 4800000, guid: ccaa200b3477a2a4cbc0fecd9fc2dde8, type: 3} |
|||
m_ShaderKeywords: _EMISSION |
|||
m_LightmapFlags: 1 |
|||
m_CustomRenderQueue: -1 |
|||
stringTagMap: {} |
|||
m_SavedProperties: |
|||
serializedVersion: 2 |
|||
m_TexEnvs: |
|||
- first: |
|||
name: _BumpMap |
|||
second: |
|||
m_Texture: {fileID: 0} |
|||
m_Scale: {x: 1, y: 1} |
|||
m_Offset: {x: 0, y: 0} |
|||
- first: |
|||
name: _DetailAlbedoMap |
|||
second: |
|||
m_Texture: {fileID: 0} |
|||
m_Scale: {x: 1, y: 1} |
|||
m_Offset: {x: 0, y: 0} |
|||
- first: |
|||
name: _DetailMask |
|||
second: |
|||
m_Texture: {fileID: 0} |
|||
m_Scale: {x: 1, y: 1} |
|||
m_Offset: {x: 0, y: 0} |
|||
- first: |
|||
name: _DetailNormalMap |
|||
second: |
|||
m_Texture: {fileID: 0} |
|||
m_Scale: {x: 1, y: 1} |
|||
m_Offset: {x: 0, y: 0} |
|||
- first: |
|||
name: _EmissionMap |
|||
second: |
|||
m_Texture: {fileID: 0} |
|||
m_Scale: {x: 1, y: 1} |
|||
m_Offset: {x: 0, y: 0} |
|||
- first: |
|||
name: _MainTex |
|||
second: |
|||
m_Texture: {fileID: 0} |
|||
m_Scale: {x: 1, y: 1} |
|||
m_Offset: {x: 0, y: 0} |
|||
- first: |
|||
name: _MetallicGlossMap |
|||
second: |
|||
m_Texture: {fileID: 0} |
|||
m_Scale: {x: 1, y: 1} |
|||
m_Offset: {x: 0, y: 0} |
|||
- first: |
|||
name: _OcclusionMap |
|||
second: |
|||
m_Texture: {fileID: 0} |
|||
m_Scale: {x: 1, y: 1} |
|||
m_Offset: {x: 0, y: 0} |
|||
- first: |
|||
name: _ParallaxMap |
|||
second: |
|||
m_Texture: {fileID: 0} |
|||
m_Scale: {x: 1, y: 1} |
|||
m_Offset: {x: 0, y: 0} |
|||
- first: |
|||
name: _SpecGlossMap |
|||
second: |
|||
m_Texture: {fileID: 0} |
|||
m_Scale: {x: 1, y: 1} |
|||
m_Offset: {x: 0, y: 0} |
|||
m_Floats: |
|||
- first: |
|||
name: _BumpScale |
|||
second: 1 |
|||
- first: |
|||
name: _Cutoff |
|||
second: 0.5 |
|||
- first: |
|||
name: _DetailNormalMapScale |
|||
second: 1 |
|||
- first: |
|||
name: _DstBlend |
|||
second: 0 |
|||
- first: |
|||
name: _GlossMapScale |
|||
second: 1 |
|||
- first: |
|||
name: _Glossiness |
|||
second: 0.5 |
|||
- first: |
|||
name: _GlossyReflections |
|||
second: 1 |
|||
- first: |
|||
name: _Metallic |
|||
second: 0 |
|||
- first: |
|||
name: _Mode |
|||
second: 0 |
|||
- first: |
|||
name: _OcclusionStrength |
|||
second: 1 |
|||
- first: |
|||
name: _Parallax |
|||
second: 0.02 |
|||
- first: |
|||
name: _SmoothnessTextureChannel |
|||
second: 0 |
|||
- first: |
|||
name: _SpecularHighlights |
|||
second: 1 |
|||
- first: |
|||
name: _SrcBlend |
|||
second: 1 |
|||
- first: |
|||
name: _UVSec |
|||
second: 0 |
|||
- first: |
|||
name: _ZWrite |
|||
second: 1 |
|||
m_Colors: |
|||
- first: |
|||
name: _Color |
|||
second: {r: 1, g: 1, b: 1, a: 1} |
|||
- first: |
|||
name: _EmissionColor |
|||
second: {r: 0, g: 0, b: 0, a: 1} |
|||
- first: |
|||
name: _SpecColor |
|||
second: {r: 0.19999996, g: 0.19999996, b: 0.19999996, a: 1} |
撰写
预览
正在加载...
取消
保存
Reference in new issue