浏览代码
Merge pull request #7 from Unity-Technologies/ShadowMapSupport
Merge pull request #7 from Unity-Technologies/ShadowMapSupport
First draft design of shadowmap/main
GitHub
8 年前
当前提交
89924c46
共有 42 个文件被更改,包括 1116 次插入 和 405 次删除
-
30Assets/ScriptableRenderLoop/AdditionalLightData.cs
-
90Assets/ScriptableRenderLoop/HDRenderLoop/HDRenderLoop.cs
-
2Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/Debug/DebugViewMaterialGBuffer.shader
-
37Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/Lighting/LightDefinition.cs
-
96Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/Lighting/LightDefinition.cs.hlsl
-
21Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/Lighting/Lighting.hlsl
-
332Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/Material/Lit/Lit.hlsl
-
2Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/Material/Lit/LitData.hlsl
-
7Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/Material/Lit/LitDefault.shader
-
2Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/Material/Lit/LitShare.hlsl
-
38Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/Material/Material.hlsl
-
5Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/Material/Unlit/Unlit.hlsl
-
2Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/Material/Unlit/UnlitData.hlsl
-
2Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/Material/Unlit/UnlitShare.hlsl
-
5Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/ShaderPass/ShaderPassForward.hlsl
-
45Assets/ScriptableRenderLoop/ShaderLibrary/API/D3D11.hlsl
-
32Assets/ScriptableRenderLoop/ShaderLibrary/Common.hlsl
-
19Assets/ScriptableRenderLoop/ShaderLibrary/CommonLighting.hlsl
-
90Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/Lighting/Deferred.shader
-
9Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/Lighting/Deferred.shader.meta
-
16Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/Lighting/Forward.hlsl
-
9Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/Lighting/Forward.hlsl.meta
-
25Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/Lighting/Shadow.hlsl
-
9Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/Lighting/Shadow.hlsl.meta
-
28Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/Lighting/ShadowDefinition.cs
-
37Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/Lighting/ShadowDefinition.cs.hlsl
-
9Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/Lighting/ShadowDefinition.cs.hlsl.meta
-
12Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/Lighting/ShadowDefinition.cs.meta
-
9Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/Lighting/SinglePass.meta
-
17Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/Lighting/SinglePass/SinglePass.cs
-
12Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/Lighting/SinglePass/SinglePass.cs.meta
-
9Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/Lighting/SinglePass/SinglePass.hlsl.meta
-
69Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/Lighting/SinglePass/SinglePassLoop.hlsl
-
9Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/Lighting/SinglePass/SinglePassLoop.hlsl.meta
-
120Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/Lighting/SinglePass/SinglePass.hlsl
-
9Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/Lighting/LightingDeferred.meta
-
9Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/Lighting/LightingForward.meta
-
238Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/Material/Lit/LitEnvTemplate.hlsl
-
9Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/Material/Lit/LitEnvTemplate.hlsl.meta
|
|||
#ifndef UNITY_LIGHTING_INCLUDED |
|||
#define UNITY_LIGHTING_INCLUDED |
|||
|
|||
// We need to define the macro used for env map evaluation based on the different architecture. |
|||
// Like for material we have one define by architecture. |
|||
// TODO: who setup the define for a given architecture ? |
|||
// The lighting architecture is in charge to define the light loop |
|||
// It is also in charge to define the sampling function for shadowmap, ies, cookie and reflection |
|||
// as only the lighting architecture is aware of the usage of texture atlas, array and format (latlong, 2D, cube) |
|||
|
|||
#define LIGHTING // This define is used to know that we have include lighting when compiling material, else it will generate "default" function that are neutral to use Material.hlsl alone. |
|||
|
|||
#include "Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/Lighting/ShadowDefinition.cs.hlsl" |
|||
|
|||
#ifdef SINGLE_PASS |
|||
#include "Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/Lighting/SinglePass/SinglePass.hlsl" |
|||
//#elif ... |
|||
#endif |
|||
#include "Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/Lighting/LightingForward/LightingForward.hlsl" |
|||
#ifdef SINGLE_PASS |
|||
#include "Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/Lighting/SinglePass/SinglePassLoop.hlsl" |
|||
//#elif ... |
|||
#endif |
|||
|
|||
|
|||
#endif // UNITY_LIGHTING_INCLUDED |
|
|||
Shader "Hidden/Unity/Deferred" |
|||
{ |
|||
Properties |
|||
{ |
|||
_SrcBlend("", Float) = 1 |
|||
_DstBlend("", Float) = 1 |
|||
} |
|||
|
|||
SubShader |
|||
{ |
|||
|
|||
Pass |
|||
{ |
|||
ZWrite Off |
|||
Blend[_SrcBlend][_DstBlend] |
|||
|
|||
HLSLPROGRAM |
|||
#pragma target 5.0 |
|||
#pragma only_renderers d3d11 // TEMP: unitl we go futher in dev |
|||
|
|||
#pragma vertex VertDeferred |
|||
#pragma fragment FragDeferred |
|||
|
|||
#include "Common.hlsl" |
|||
// Chose supported lighting architecture in case of deferred rendering |
|||
#pragma multi_compile SINGLE_PASS |
|||
|
|||
// CAUTION: In case deferred lighting need to support various lighting model statically, we will require to do multicompile with different define like UNITY_MATERIAL_DISNEYGXX |
|||
// TODO: Currently a users that add a new deferred material must also add it manually here... Need to think about it. Maybe add a multicompile inside a file in Material directory to include here ? |
|||
#define UNITY_MATERIAL_LIT // Need to be define before including Material.hlsl |
|||
#include "Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/Lighting/Lighting.hlsl" // This include Material.hlsl |
|||
#include "Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/ShaderVariables.hlsl" |
|||
|
|||
DECLARE_GBUFFER_TEXTURE(_CameraGBufferTexture); |
|||
DECLARE_GBUFFER_BAKE_LIGHTING(_CameraGBufferTexture); |
|||
|
|||
UNITY_DECLARE_TEX2D(_CameraDepthTexture); |
|||
|
|||
float4x4 _InvViewProjMatrix; |
|||
|
|||
struct Attributes |
|||
{ |
|||
float3 positionOS : POSITION; |
|||
}; |
|||
|
|||
struct Varyings |
|||
{ |
|||
float4 positionHS : SV_POSITION; |
|||
}; |
|||
|
|||
Varyings VertDeferred(Attributes input) |
|||
{ |
|||
// TODO: implement SV_vertexID full screen quad |
|||
// Lights are draw as one fullscreen quad |
|||
Varyings output; |
|||
float3 positionWS = TransformObjectToWorld(input.positionOS); |
|||
output.positionHS = TransformWorldToHClip(positionWS); |
|||
|
|||
return output; |
|||
} |
|||
|
|||
float4 FragDeferred(Varyings input) : SV_Target |
|||
{ |
|||
Coordinate coord = GetCoordinate(input.positionHS.xy, _ScreenSize.zw); |
|||
|
|||
// No need to manage inverse depth, this is handled by the projection matrix |
|||
float depth = _CameraDepthTexture.Load(uint3(coord.unPositionSS, 0)).x; |
|||
float3 positionWS = UnprojectToWorld(depth, coord.positionSS, _InvViewProjMatrix); |
|||
float3 V = GetWorldSpaceNormalizeViewDir(positionWS); |
|||
|
|||
FETCH_GBUFFER(gbuffer, _CameraGBufferTexture, coord.unPositionSS); |
|||
BSDFData bsdfData = DECODE_FROM_GBUFFER(gbuffer); |
|||
|
|||
PreLightData preLightData = GetPreLightData(V, positionWS, coord, bsdfData); |
|||
|
|||
float4 diffuseLighting; |
|||
float4 specularLighting; |
|||
FETCH_BAKE_LIGHTING_GBUFFER(gbuffer, _CameraGBufferTexture, coord.unPositionSS); |
|||
float3 bakeDiffuseLighting = DECODE_BAKE_LIGHTING_FROM_GBUFFER(gbuffer); |
|||
LightingLoop(V, positionWS, preLightData, bsdfData, bakeDiffuseLighting, diffuseLighting, specularLighting); |
|||
|
|||
return float4(diffuseLighting.rgb + specularLighting.rgb, 1.0); |
|||
} |
|||
|
|||
ENDHLSL |
|||
} |
|||
|
|||
} |
|||
Fallback Off |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: 00dd221e34a6ab349a1196b0f2fab693 |
|||
timeCreated: 1477266585 |
|||
licenseType: Pro |
|||
ShaderImporter: |
|||
defaultTextures: [] |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
// There is two kind of lighting architectures. |
|||
// Those that are control from inside the "Material".shader with "Pass" concept like forward lighting. Call later forward lighting architecture. |
|||
// Those that are control outside the "Material".shader in a "Lighting".shader like deferred lighting. Call later deferred lighting architecture. |
|||
|
|||
// When dealing with deferred lighting architecture, the renderloop is in charge to call the correct .shader. |
|||
// RenderLoop can do multiple call of various deferred lighting architecture. |
|||
// (Note: enabled variant for deferred lighting architecture are in deferred.shader) |
|||
// When dealing with forward lighting architecture, the renderloop must specify a shader pass (like "forward") but it also need |
|||
// to specify which variant of the forward lighting architecture he want (with cmd.EnableShaderKeyword()). |
|||
// Renderloop can suppose dynamically switching from regular forward to tile forward for example within the same "Forward" pass. |
|||
|
|||
// The purpose of the following pragma is to define the variant available for "Forward" Pass in "Material".shader. |
|||
// If only one keyword is present it mean that only one type of forward lighting architecture is supported. |
|||
|
|||
// Must match name in GetKeyword() method of forward lighting architecture .cs file |
|||
// #pragma multi_compile SINGLE_PASS -> can't use a pragma from include... (for now) |
|
|||
fileFormatVersion: 2 |
|||
guid: c4e4a82a4f02d5946848b918b72488fd |
|||
timeCreated: 1477269249 |
|||
licenseType: Pro |
|||
ShaderImporter: |
|||
defaultTextures: [] |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
//----------------------------------------------------------------------------- |
|||
// Shadow |
|||
// Ref: https://mynameismjp.wordpress.com/2015/02/18/shadow-sample-update/ |
|||
// ---------------------------------------------------------------------------- |
|||
|
|||
//------------------------------------------------------------------------------------------------- |
|||
// Calculates the offset to use for sampling the shadow map, based on the surface normal |
|||
//------------------------------------------------------------------------------------------------- |
|||
float3 GetShadowPosOffset(float NdotL, float3 normalWS, float2 invShadowMapSize) |
|||
{ |
|||
float texelSize = 2.0 * invShadowMapSize.x; |
|||
float offsetScaleNormalize = saturate(1.0 - NdotL); |
|||
// return texelSize * OffsetScale * offsetScaleNormalize * normalWS; |
|||
return texelSize * offsetScaleNormalize * normalWS; |
|||
} |
|||
|
|||
// TODO: implement various algorithm |
|||
|
|||
// GetShadowAttenuation is the "default" algorithm use, material can code explicitely a particular algorithm if required. |
|||
// TODO: how this work related to shadow format ? |
|||
float GetShadowAttenuation(LightLoopContext lightLoopContext, int index, float3 shadowCoord, float3 shadowPosDX, float3 shadowPosDY, float2 unPositionSS) |
|||
{ |
|||
// TODO: How to support a Gather sampling with such abstraction... |
|||
return SampleShadowCompare(lightLoopContext, index, shadowCoord); |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: 272a43c3c23646a4e8bc73faebaf0ee5 |
|||
timeCreated: 1477313383 |
|||
licenseType: Pro |
|||
ShaderImporter: |
|||
defaultTextures: [] |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
using UnityEngine; |
|||
|
|||
//-----------------------------------------------------------------------------
|
|||
// structure definition
|
|||
//-----------------------------------------------------------------------------
|
|||
namespace UnityEngine.Experimental.ScriptableRenderLoop |
|||
{ |
|||
[GenerateHLSL] |
|||
public enum ShadowType |
|||
{ |
|||
Spot, |
|||
Directional, |
|||
Point |
|||
}; |
|||
|
|||
// A point light is 6x PunctualShadowData
|
|||
[GenerateHLSL] |
|||
public struct PunctualShadowData |
|||
{ |
|||
// World to ShadowMap matrix
|
|||
// Include scale and bias for shadow atlas if any
|
|||
public Matrix4x4 worldToShadow; |
|||
|
|||
public ShadowType shadowType; |
|||
public float bias; |
|||
public Vector2 unused; |
|||
}; |
|||
} // namespace UnityEngine.Experimental.ScriptableRenderLoop
|
|
|||
// |
|||
// This file was automatically generated from Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/Lighting/ShadowDefinition.cs. Please don't edit by hand. |
|||
// |
|||
|
|||
// |
|||
// UnityEngine.Experimental.ScriptableRenderLoop.ShadowType: static fields |
|||
// |
|||
#define SHADOWTYPE_SPOT (0) |
|||
#define SHADOWTYPE_DIRECTIONAL (1) |
|||
#define SHADOWTYPE_POINT (2) |
|||
|
|||
// Generated from UnityEngine.Experimental.ScriptableRenderLoop.PunctualShadowData |
|||
// PackingRules = Exact |
|||
struct PunctualShadowData |
|||
{ |
|||
float4x4 worldToShadow; |
|||
int shadowType; |
|||
float3 unused; |
|||
}; |
|||
|
|||
// |
|||
// Accessors for UnityEngine.Experimental.ScriptableRenderLoop.PunctualShadowData |
|||
// |
|||
float4x4 GetWorldToShadow(PunctualShadowData value) |
|||
{ |
|||
return value.worldToShadow; |
|||
} |
|||
int GetShadowType(PunctualShadowData value) |
|||
{ |
|||
return value.shadowType; |
|||
} |
|||
float3 GetUnused(PunctualShadowData value) |
|||
{ |
|||
return value.unused; |
|||
} |
|||
|
|||
|
|
|||
fileFormatVersion: 2 |
|||
guid: f22956c3631d5f64388bdb93e12ec747 |
|||
timeCreated: 1477268655 |
|||
licenseType: Pro |
|||
ShaderImporter: |
|||
defaultTextures: [] |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
fileFormatVersion: 2 |
|||
guid: 548c943bc73a18d4998420073b25d44b |
|||
timeCreated: 1477263464 |
|||
licenseType: Pro |
|||
MonoImporter: |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
fileFormatVersion: 2 |
|||
guid: 16efe1cc514ae594993f6705dacbf97d |
|||
folderAsset: yes |
|||
timeCreated: 1477266406 |
|||
licenseType: Pro |
|||
DefaultImporter: |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
using UnityEngine; |
|||
using UnityEngine.Experimental.Rendering; |
|||
using System; |
|||
|
|||
//-----------------------------------------------------------------------------
|
|||
// structure definition
|
|||
//-----------------------------------------------------------------------------
|
|||
namespace UnityEngine.Experimental.ScriptableRenderLoop |
|||
{ |
|||
public class SinglePass |
|||
{ |
|||
string GetKeyword() |
|||
{ |
|||
return "SINGLE_PASS"; |
|||
} |
|||
}; |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: cb651810696af0d4789441b1f469aa2f |
|||
timeCreated: 1477266406 |
|||
licenseType: Pro |
|||
MonoImporter: |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
fileFormatVersion: 2 |
|||
guid: 16878a2c634119a4ab27e2c83a09b20e |
|||
timeCreated: 1477266410 |
|||
licenseType: Pro |
|||
ShaderImporter: |
|||
defaultTextures: [] |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
StructuredBuffer<PunctualLightData> _PunctualLightList; |
|||
int _PunctualLightCount; |
|||
|
|||
StructuredBuffer<EnvLightData> _EnvLightList; |
|||
int _EnvLightCount; |
|||
|
|||
EnvLightData _EnvLightSky; |
|||
|
|||
// bakeDiffuseLighting is part of the prototype so a user is able to implement a "base pass" with GI and multipass direct light (aka old unity rendering path) |
|||
void LightingLoop( float3 V, float3 positionWS, PreLightData prelightData, BSDFData bsdfData, float3 bakeDiffuseLighting, |
|||
out float4 diffuseLighting, |
|||
out float4 specularLighting) |
|||
{ |
|||
LightLoopContext context; |
|||
ZERO_INITIALIZE(LightLoopContext, context); |
|||
|
|||
diffuseLighting = float4(0.0, 0.0, 0.0, 0.0); |
|||
specularLighting = float4(0.0, 0.0, 0.0, 0.0); |
|||
|
|||
for (int i = 0; i < _PunctualLightCount; ++i) |
|||
{ |
|||
float4 localDiffuseLighting; |
|||
float4 localSpecularLighting; |
|||
EvaluateBSDF_Punctual(context, V, positionWS, prelightData, _PunctualLightList[i], bsdfData, localDiffuseLighting, localSpecularLighting); |
|||
diffuseLighting += localDiffuseLighting; |
|||
specularLighting += localSpecularLighting; |
|||
} |
|||
|
|||
/* |
|||
for (int i = 0; i < 4; ++i) |
|||
{ |
|||
float4 localDiffuseLighting; |
|||
float4 localSpecularLighting; |
|||
EvaluateBSDF_Area(0, V, positionWS, areaLightData[i], bsdfData, localDiffuseLighting, localSpecularLighting); |
|||
diffuseLighting += localDiffuseLighting; |
|||
specularLighting += localSpecularLighting; |
|||
} |
|||
*/ |
|||
|
|||
float4 iblDiffuseLighting = float4(0.0, 0.0, 0.0, 0.0); |
|||
float4 iblSpecularLighting = float4(0.0, 0.0, 0.0, 0.0); |
|||
|
|||
for (int j = 0; j < _EnvLightCount; ++j) |
|||
{ |
|||
float4 localDiffuseLighting; |
|||
float4 localSpecularLighting; |
|||
context.sampleReflection = SINGLE_PASS_CONTEXT_SAMPLE_REFLECTION_PROBES; |
|||
EvaluateBSDF_Env(context, V, positionWS, prelightData, _EnvLightList[j], bsdfData, localDiffuseLighting, localSpecularLighting); |
|||
iblDiffuseLighting.rgb = lerp(iblDiffuseLighting.rgb, localDiffuseLighting.rgb, localDiffuseLighting.a); // Should be remove by the compiler if it is smart as all is constant 0 |
|||
iblSpecularLighting.rgb = lerp(iblSpecularLighting.rgb, localSpecularLighting.rgb, localSpecularLighting.a); |
|||
} |
|||
|
|||
/* |
|||
// Sky Ibl |
|||
{ |
|||
float4 localDiffuseLighting; |
|||
float4 localSpecularLighting; |
|||
context.sampleReflection = SINGLE_PASS_CONTEXT_SAMPLE_SKY; |
|||
EvaluateBSDF_Env(context, V, positionWS, prelightData, _EnvLightSky, bsdfData, localDiffuseLighting, localSpecularLighting); |
|||
iblDiffuseLighting.rgb = lerp(iblDiffuseLighting.rgb, localDiffuseLighting.rgb, localDiffuseLighting.a); // Should be remove by the compiler if it is smart as all is constant 0 |
|||
iblSpecularLighting.rgb = lerp(iblSpecularLighting.rgb, localSpecularLighting.rgb, localSpecularLighting.a); |
|||
} |
|||
*/ |
|||
|
|||
diffuseLighting += iblDiffuseLighting; |
|||
specularLighting += iblSpecularLighting; |
|||
|
|||
diffuseLighting.rgb += bakeDiffuseLighting; |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: beb12ac3f2147dd499eee23eab1aea89 |
|||
timeCreated: 1477266410 |
|||
licenseType: Pro |
|||
ShaderImporter: |
|||
defaultTextures: [] |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
//----------------------------------------------------------------------------- |
|||
// Single pass forward loop architecture |
|||
// It use maxed list of lights of the scene - use just as proof of concept - do not used in regular game |
|||
//----------------------------------------------------------------------------- |
|||
|
|||
struct LightLoopContext |
|||
{ |
|||
int sampleShadow; |
|||
int sampleReflection; |
|||
}; |
|||
|
|||
//----------------------------------------------------------------------------- |
|||
// Shadow |
|||
// ---------------------------------------------------------------------------- |
|||
|
|||
#define SINGLE_PASS_CONTEXT_SAMPLE_SHADOWATLAS 0 |
|||
#define SINGLE_PASS_CONTEXT_SAMPLE_SHADOWARRAY 1 |
|||
|
|||
//TEXTURE2D_ARRAY(_ShadowArray); |
|||
//SAMPLER2D_SHADOW(sampler_ShadowArray); |
|||
//SAMPLER2D(sampler_ManualShadowArray); // TODO: settings sampler individually is not supported in shader yet... |
|||
|
|||
//TEXTURE2D(_ShadowAtlas); |
|||
//SAMPLER2D_SHADOW(sampler_ShadowAtlas); |
|||
//SAMPLER2D(sampler_ManualShadowAtlas); // TODO: settings sampler individually is not supported in shader yet... |
|||
|
|||
TEXTURE2D(g_tShadowBuffer) // TODO: No choice, the name is hardcoded in ShadowrenderPass.cs for now. Need to change this! |
|||
SAMPLER2D_SHADOW(samplerg_tShadowBuffer); |
|||
|
|||
// Use texture atlas for shadow map |
|||
StructuredBuffer<PunctualShadowData> _PunctualShadowList; |
|||
|
|||
float3 GetShadowTextureCoordinate(LightLoopContext lightLoopContext, int index, float3 positionWS, float3 L) |
|||
{ |
|||
int faceIndex; |
|||
if (_PunctualShadowList[index].shadowType == SHADOWTYPE_POINT) |
|||
{ |
|||
GetCubeFaceID(L, faceIndex); |
|||
} |
|||
|
|||
// Note: scale and bias of shadow atlas are included in ShadowTransform |
|||
float4x4 shadowTransform = _PunctualShadowList[index + faceIndex].worldToShadow; |
|||
|
|||
float4 positionTXS = mul(float4(positionWS, 1.0), shadowTransform); |
|||
return positionTXS.xyz / positionTXS.w; |
|||
} |
|||
|
|||
float SampleShadowCompare(LightLoopContext lightLoopContext, int index, float3 texCoord) |
|||
{ |
|||
// if (lightLoopContext.sampleShadow == SINGLE_PASS_CONTEXT_SAMPLE_SHADOWATLAS) |
|||
{ |
|||
// Index could be use to get scale bias for uv but this is already merged into the shadow matrix |
|||
return SAMPLE_TEXTURE2D_SHADOW(g_tShadowBuffer, samplerg_tShadowBuffer, texCoord); |
|||
} |
|||
/* |
|||
else // SINGLE_PASS_CONTEXT_SAMPLE_SHADOWARRAY |
|||
{ |
|||
return SAMPLE_TEXTURE2D_ARRAY_SHADOW(_ShadowArray, sampler_ShadowArray, texCoord, index); |
|||
} |
|||
*/ |
|||
} |
|||
|
|||
/* |
|||
float SampleShadow(LightLoopContext lightLoopContext, int index, float2 texCoord) |
|||
{ |
|||
if (lightLoopContext.sampleShadow == SINGLE_PASS_CONTEXT_SAMPLE_SHADOWATLAS) |
|||
{ |
|||
// Index could be use to get scale bias for uv but this is already merged into the shadow matrix |
|||
return SAMPLE_TEXTURE2D(_ShadowAtlas, sampler_ManualShadowArray, texCoord); |
|||
} |
|||
else // SINGLE_PASS_CONTEXT_SAMPLE_SHADOWARRAY |
|||
{ |
|||
return SAMPLE_TEXTURE2D_ARRAY(_ShadowArray, sampler_ManualShadowAtlas, texCoord, index); |
|||
} |
|||
} |
|||
*/ |
|||
|
|||
//----------------------------------------------------------------------------- |
|||
// IES |
|||
// ---------------------------------------------------------------------------- |
|||
|
|||
#define SINGLE_PASS_CONTEXT_SAMPLE_IESARRAY 0 |
|||
|
|||
TEXTURE2D_ARRAY(_IESArray); |
|||
SAMPLER2D(sampler_IESArray); |
|||
|
|||
// sphericalTexCoord is theta and phi spherical coordinate |
|||
float4 SampleIES(LightLoopContext lightLoopContext, int index, float2 sphericalTexCoord, float lod) |
|||
{ |
|||
return SAMPLE_TEXTURE2D_ARRAY_LOD(_IESArray, sampler_IESArray, sphericalTexCoord, index, 0); |
|||
} |
|||
|
|||
//----------------------------------------------------------------------------- |
|||
// Reflection proble / Sky |
|||
// ---------------------------------------------------------------------------- |
|||
|
|||
// Use texture array for reflection |
|||
TEXTURECUBE_ARRAY(_EnvTextures); |
|||
SAMPLERCUBE(sampler_EnvTextures); |
|||
|
|||
TEXTURECUBE(_SkyTexture); |
|||
SAMPLERCUBE(sampler_SkyTexture); // NOTE: Sampler could be share here with _EnvTextures. Don't know if the shader compiler will complain... |
|||
|
|||
#define SINGLE_PASS_CONTEXT_SAMPLE_REFLECTION_PROBES 0 |
|||
#define SINGLE_PASS_CONTEXT_SAMPLE_SKY 1 |
|||
|
|||
// Note: index is whatever the lighting architecture want, it can contain information like in which texture to sample (in case we have a compressed BC6H texture and an uncompressed for real time reflection ?) |
|||
// EnvIndex can also be use to fetch in another array of struct (to atlas information etc...). |
|||
float4 SampleEnv(LightLoopContext lightLoopContext, int index, float3 texCoord, float lod) |
|||
{ |
|||
// This code will be inlined as lightLoopContext is hardcoded in the light loop |
|||
if (lightLoopContext.sampleReflection == SINGLE_PASS_CONTEXT_SAMPLE_REFLECTION_PROBES) |
|||
{ |
|||
return UNITY_SAMPLE_TEXCUBEARRAY_LOD(_EnvTextures, float4(texCoord, index), lod); |
|||
} |
|||
else // SINGLE_PASS_SAMPLE_SKY |
|||
{ |
|||
return UNITY_SAMPLE_TEXCUBE_LOD(_SkyTexture, texCoord, lod); |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: df85c88f855185249aad13cf37a4952a |
|||
folderAsset: yes |
|||
timeCreated: 1476653183 |
|||
licenseType: Pro |
|||
DefaultImporter: |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
fileFormatVersion: 2 |
|||
guid: 8f27521401d2efc4fb35f246e296940e |
|||
folderAsset: yes |
|||
timeCreated: 1476653182 |
|||
licenseType: Pro |
|||
DefaultImporter: |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
// No guard header! |
|||
|
|||
//----------------------------------------------------------------------------- |
|||
// EvaluateBSDF_Env - Reference |
|||
// ---------------------------------------------------------------------------- |
|||
|
|||
// Ref: Moving Frostbite to PBR (Appendix A) |
|||
float3 IntegrateLambertIBLRef( EnvLightData lightData, BSDFData bsdfData, |
|||
UNITY_ARGS_ENV(_EnvTextures), |
|||
uint sampleCount = 2048) |
|||
{ |
|||
float3 N = bsdfData.normalWS; |
|||
float3 acc = float3(0.0, 0.0, 0.0); |
|||
// Add some jittering on Hammersley2d |
|||
float2 randNum = InitRandom(N.xy * 0.5 + 0.5); |
|||
|
|||
float3 tangentX, tangentY; |
|||
GetLocalFrame(N, tangentX, tangentY); |
|||
|
|||
for (uint i = 0; i < sampleCount; ++i) |
|||
{ |
|||
float2 u = Hammersley2d(i, sampleCount); |
|||
u = frac(u + randNum + 0.5); |
|||
|
|||
float3 L; |
|||
float NdotL; |
|||
float weightOverPdf; |
|||
ImportanceSampleLambert(u, N, tangentX, tangentY, L, NdotL, weightOverPdf); |
|||
|
|||
if (NdotL > 0.0) |
|||
{ |
|||
float4 val = UNITY_SAMPLE_ENV_LOD(_EnvTextures, L, lightData, 0); |
|||
|
|||
// diffuse Albedo is apply here as describe in ImportanceSampleLambert function |
|||
acc += bsdfData.diffuseColor * Lambert() * weightOverPdf * val.rgb; |
|||
} |
|||
} |
|||
|
|||
return acc / sampleCount; |
|||
} |
|||
|
|||
float3 IntegrateDisneyDiffuseIBLRef(float3 V, EnvLightData lightData, BSDFData bsdfData, |
|||
UNITY_ARGS_ENV(_EnvTextures), |
|||
uint sampleCount = 2048) |
|||
{ |
|||
float3 N = bsdfData.normalWS; |
|||
float NdotV = dot(N, V); |
|||
float3 acc = float3(0.0, 0.0, 0.0); |
|||
// Add some jittering on Hammersley2d |
|||
float2 randNum = InitRandom(N.xy * 0.5 + 0.5); |
|||
|
|||
float3 tangentX, tangentY; |
|||
GetLocalFrame(N, tangentX, tangentY); |
|||
|
|||
for (uint i = 0; i < sampleCount; ++i) |
|||
{ |
|||
float2 u = Hammersley2d(i, sampleCount); |
|||
u = frac(u + randNum + 0.5); |
|||
|
|||
float3 L; |
|||
float NdotL; |
|||
float weightOverPdf; |
|||
// for Disney we still use a Cosine importance sampling, true Disney importance sampling imply a look up table |
|||
ImportanceSampleLambert(u, N, tangentX, tangentY, L, NdotL, weightOverPdf); |
|||
|
|||
if (NdotL > 0.0) |
|||
{ |
|||
float3 H = normalize(L + V); |
|||
float LdotH = dot(L, H); |
|||
// Note: we call DisneyDiffuse that require to multiply by Albedo / PI. Divide by PI is already taken into account |
|||
// in weightOverPdf of ImportanceSampleLambert call. |
|||
float disneyDiffuse = DisneyDiffuse(NdotV, NdotL, LdotH, bsdfData.perceptualRoughness); |
|||
|
|||
// diffuse Albedo is apply here as describe in ImportanceSampleLambert function |
|||
float4 val = UNITY_SAMPLE_ENV_LOD(_EnvTextures, L, lightData, 0); |
|||
acc += bsdfData.diffuseColor * disneyDiffuse * weightOverPdf * val.rgb; |
|||
} |
|||
} |
|||
|
|||
return acc / sampleCount; |
|||
} |
|||
|
|||
// Ref: Moving Frostbite to PBR (Appendix A) |
|||
float3 IntegrateSpecularGGXIBLRef( float3 V, EnvLightData lightData, BSDFData bsdfData, |
|||
UNITY_ARGS_ENV(_EnvTextures), |
|||
uint sampleCount = 2048) |
|||
{ |
|||
float3 N = bsdfData.normalWS; |
|||
float NdotV = saturate(dot(N, V)); |
|||
float3 acc = float3(0.0, 0.0, 0.0); |
|||
|
|||
// Add some jittering on Hammersley2d |
|||
float2 randNum = InitRandom(V.xy * 0.5 + 0.5); |
|||
|
|||
float3 tangentX, tangentY; |
|||
GetLocalFrame(N, tangentX, tangentY); |
|||
|
|||
for (uint i = 0; i < sampleCount; ++i) |
|||
{ |
|||
float2 u = Hammersley2d(i, sampleCount); |
|||
u = frac(u + randNum + 0.5); |
|||
|
|||
float VdotH; |
|||
float NdotL; |
|||
float3 L; |
|||
float weightOverPdf; |
|||
|
|||
// GGX BRDF |
|||
ImportanceSampleGGX(u, V, N, tangentX, tangentY, bsdfData.roughness, NdotV, |
|||
L, VdotH, NdotL, weightOverPdf); |
|||
|
|||
if (NdotL > 0.0) |
|||
{ |
|||
// Fresnel component is apply here as describe in ImportanceSampleGGX function |
|||
float3 FweightOverPdf = F_Schlick(bsdfData.fresnel0, VdotH) * weightOverPdf; |
|||
|
|||
float4 val = UNITY_SAMPLE_ENV_LOD(_EnvTextures, L, lightData, 0); |
|||
|
|||
acc += FweightOverPdf * val.rgb; |
|||
} |
|||
} |
|||
|
|||
return acc / sampleCount; |
|||
} |
|||
|
|||
//----------------------------------------------------------------------------- |
|||
// EvaluateBSDF_Env |
|||
// ---------------------------------------------------------------------------- |
|||
|
|||
// _preIntegratedFGD and _CubemapLD are unique for each BRDF |
|||
void EvaluateBSDF_Env( float3 V, float3 positionWS, PreLightData prelightData, EnvLightData lightData, BSDFData bsdfData, |
|||
UNITY_ARGS_ENV(_EnvTextures), |
|||
out float4 diffuseLighting, |
|||
out float4 specularLighting) |
|||
{ |
|||
#ifdef LIT_DISPLAY_REFERENCE |
|||
|
|||
specularLighting.rgb = IntegrateSpecularGGXIBLRef(V, lightData, bsdfData, UNITY_PASS_ENV(_EnvTextures)); |
|||
specularLighting.a = 1.0; |
|||
|
|||
/* |
|||
#ifdef DIFFUSE_LAMBERT_BRDF |
|||
diffuseLighting.rgb = IntegrateLambertIBLRef(lightData, bsdfData, UNITY_PASS_ENV(_EnvTextures)); |
|||
#else |
|||
diffuseLighting.rgb = IntegrateDisneyDiffuseIBLRef(V, lightData, bsdfData, UNITY_PASS_ENV(_EnvTextures)); |
|||
#endif |
|||
diffuseLighting.a = 1.0; |
|||
*/ |
|||
diffuseLighting = float4(0.0, 0.0, 0.0, 0.0); |
|||
|
|||
#else |
|||
// TODO: factor this code in common, so other material authoring don't require to rewrite everything, |
|||
// also think about how such a loop can handle 2 cubemap at the same time as old unity. Macro can allow to do that |
|||
// but we need to have UNITY_SAMPLE_ENV_LOD replace by a true function instead that is define by the lighting arcitecture. |
|||
// Also not sure how to deal with 2 intersection.... |
|||
// Box and sphere are related to light property (but we have also distance based roughness etc...) |
|||
|
|||
// TODO: test the strech from Tomasz |
|||
// float shrinkedRoughness = AnisotropicStrechAtGrazingAngle(bsdfData.roughness, bsdfData.perceptualRoughness, NdotV); |
|||
|
|||
// Note: As explain in GetPreLightData we use normalWS and not iblNormalWS here (in case of anisotropy) |
|||
float3 rayWS = GetSpecularDominantDir(bsdfData.normalWS, prelightData.iblR, bsdfData.roughness); |
|||
|
|||
float3 R = rayWS; |
|||
float weight = 1.0; |
|||
|
|||
// In this code we redefine a bit the behavior of the reflcetion proble. We separate the projection volume (the proxy of the scene) form the influence volume (what pixel on the screen is affected) |
|||
|
|||
// 1. First determine the projection volume |
|||
|
|||
// In Unity the cubemaps are capture with the localToWorld transform of the component. |
|||
// This mean that location and oritention matter. So after intersection of proxy volume we need to convert back to world. |
|||
|
|||
// CAUTION: localToWorld is the transform use to convert the cubemap capture point to world space (mean it include the offset) |
|||
// the center of the bounding box is thus in locals space: positionLS - offsetLS |
|||
// We use this formulation as it is the one of legacy unity that was using only AABB box. |
|||
|
|||
float3x3 worldToLocal = transpose(float3x3(lightData.right, lightData.up, lightData.forward)); // worldToLocal assume no scaling |
|||
float3 positionLS = positionWS - lightData.positionWS; |
|||
positionLS = mul(positionLS, worldToLocal).xyz - lightData.offsetLS; // We want to calculate the intersection from the center of the bounding box. |
|||
|
|||
if (lightData.envShapeType == ENVSHAPETYPE_BOX) |
|||
{ |
|||
float3 rayLS = mul(rayWS, worldToLocal); |
|||
float3 boxOuterDistance = lightData.innerDistance + float3(lightData.blendDistance, lightData.blendDistance, lightData.blendDistance); |
|||
float dist = BoxRayIntersectSimple(positionLS, rayLS, -boxOuterDistance, boxOuterDistance); |
|||
|
|||
// No need to normalize for fetching cubemap |
|||
// We can reuse dist calculate in LS directly in WS as there is no scaling. Also the offset is already include in lightData.positionWS |
|||
R = (positionWS + dist * rayWS) - lightData.positionWS; |
|||
|
|||
// TODO: add distance based roughness |
|||
} |
|||
else if (lightData.envShapeType == ENVSHAPETYPE_SPHERE) |
|||
{ |
|||
float3 rayLS = mul(rayWS, worldToLocal); |
|||
float sphereOuterDistance = lightData.innerDistance.x + lightData.blendDistance; |
|||
float dist = SphereRayIntersectSimple(positionLS, rayLS, sphereOuterDistance); |
|||
|
|||
R = (positionWS + dist * rayWS) - lightData.positionWS; |
|||
} |
|||
|
|||
// 2. Apply the influence volume (Box volume is used for culling whatever the influence shape) |
|||
// TODO: In the future we could have an influence volume inside the projection volume (so with a different transform, in this case we will need another transform) |
|||
if (lightData.envShapeType == ENVSHAPETYPE_SPHERE) |
|||
{ |
|||
float distFade = max(length(positionLS) - lightData.innerDistance.x, 0.0); |
|||
weight = saturate(1.0 - distFade / max(lightData.blendDistance, 0.0001)); // avoid divide by zero |
|||
} |
|||
else // ENVSHAPETYPE_BOX or ENVSHAPETYPE_NONE |
|||
{ |
|||
// Calculate falloff value, so reflections on the edges of the volume would gradually blend to previous reflection. |
|||
float distFade = DistancePointBox(positionLS, -lightData.innerDistance, lightData.innerDistance); |
|||
weight = saturate(1.0 - distFade / max(lightData.blendDistance, 0.0001)); // avoid divide by zero |
|||
} |
|||
|
|||
// Smooth weighting |
|||
weight = smoothstep01(weight); |
|||
|
|||
// TODO: we must always perform a weight calculation as due to tiled rendering we need to smooth out cubemap at boundaries. |
|||
// So goal is to split into two category and have an option to say if we parallax correct or not. |
|||
|
|||
// TODO: compare current Morten version: offline cubemap with a particular remap + the bias in perceptualRoughnessToMipmapLevel |
|||
// to classic remap like unreal/Frobiste. The function GetSpecularDominantDir can result in a better matching in this case |
|||
// We let GetSpecularDominantDir currently as it still an improvement but not as good as it could be |
|||
float mip = perceptualRoughnessToMipmapLevel(bsdfData.perceptualRoughness); |
|||
float4 preLD = UNITY_SAMPLE_ENV_LOD(_EnvTextures, R, lightData, mip); |
|||
specularLighting.rgb = preLD.rgb * prelightData.specularFGD; |
|||
|
|||
// Apply specular occlusion on it |
|||
specularLighting.rgb *= bsdfData.specularOcclusion; |
|||
specularLighting.a = weight; |
|||
|
|||
diffuseLighting = float4(0.0, 0.0, 0.0, 0.0); |
|||
|
|||
#endif |
|||
} |
|||
|
|
|||
fileFormatVersion: 2 |
|||
guid: 22c20a34a48ade04daa95ffdc51ac052 |
|||
timeCreated: 1476997917 |
|||
licenseType: Pro |
|||
ShaderImporter: |
|||
defaultTextures: [] |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
撰写
预览
正在加载...
取消
保存
Reference in new issue