浏览代码

Added support to Evaluate SH pervertex/pixel. Added support to disable LIGHTMAP and ADDITIONAL lights with shader define. Useful for ShaderGraph

/Add-support-for-light-specular-color-tint
Felipe Lira 7 年前
当前提交
9982097c
共有 3 个文件被更改,包括 88 次插入50 次删除
  1. 29
      ScriptableRenderPipeline/LightweightPipeline/Shaders/LightweightCore.cginc
  2. 58
      ScriptableRenderPipeline/LightweightPipeline/Shaders/LightweightLighting.cginc
  3. 51
      ScriptableRenderPipeline/LightweightPipeline/Shaders/LightweightPassLit.cginc

29
ScriptableRenderPipeline/LightweightPipeline/Shaders/LightweightCore.cginc


#include "UnityCG.cginc"
#define MAX_VISIBLE_LIGHTS 16
#if defined(UNITY_COLORSPACE_GAMMA)
#define LIGHTWEIGHT_GAMMA_TO_LINEAR(gammaColor) gammaColor * gammaColor
#define LIGHTWEIGHT_LINEAR_TO_GAMMA(linColor) sqrt(color)

#endif
half Pow4(half x)
half _Pow4(half x)
half LerpOneTo(half b, half t)
half _LerpOneTo(half b, half t)
{
half oneMinusT = 1 - t;
return oneMinusT + b * t;

{
half dp3 = max(1.e-4h, dot(inVec, inVec));
return inVec * rsqrt(dp3);
}
half3 EvaluateSHPerVertex(half3 normalWS)
{
#if defined(EVALUATE_SH_FULLY_VERTEX)
return max(half3(0, 0, 0), ShadeSH9(half4(normalWS, 1.0)));
#elif defined(EVALUATE_SH_MIXED)
// no max since this is only L2 contribution
return SHEvalLinearL2(half4(normalWS, 1.0));
#else
// Fully per-pixel. Nothing to compute.
return half3(0.0, 0.0, 0.0);
#endif
}
half3 EvaluateSHPerPixel(half3 normalWS, half3 L2Term)
{
#ifdef EVALUATE_SH_MIXED
return = max(half3(0, 0, 0), L2Term + SHEvalLinearL0L1(half4(normalWS, 1.0)));
#else
// Default: Evaluate SH fully per-pixel
return max(half3(0, 0, 0), ShadeSH9(half4(normalWS, 1.0)));
#endif
}
void OutputTangentToWorld(half4 vertexTangent, half3 vertexNormal, out half3 tangentWS, out half3 binormalWS, out half3 normalWS)

58
ScriptableRenderPipeline/LightweightPipeline/Shaders/LightweightLighting.cginc


#define PI 3.14159265359f
#define kDieletricSpec half4(0.04, 0.04, 0.04, 1.0 - 0.04) // standard dielectric reflectivity coef at incident angle (= 4%)
#define MAX_VISIBLE_LIGHTS 16
#endif
#if SHADER_TARGET < 30
#define EVALUATE_SH_FULLY_VERTEX
#else
#define EVALUATE_SH_MIXED
#endif
#ifdef NO_LIGHTMAP
#undef LIGHTMAP_ON
#endif
#ifdef NO_ADDITIONAL_LIGHTS
#undef _ADDITIONAL_LIGHTS
#endif
// Main light initialized without indexing

half4 spotDir;
};
struct SurfaceData
{
half3 albedo;
half3 specular;
half metallic;
half smoothness;
half3 normal;
half3 emission;
half occlusion;
half alpha;
};
struct SurfaceInput
{
float4 lightmapUV;
half3 normalWS;
half3 tangentWS;
half3 bitangentWS;
float3 positionWS;
half3 viewDirectionWS;
half fogFactor;
};
struct BRDFData
{
half3 diffuse;

return c;
}
void LightweightGI(float4 lightmapUV, half3 normalWorld, half3 reflectVec, half occlusion, half perceptualRoughness, out half3 indirectDiffuse, out half3 indirectSpecular)
void LightweightGI(float4 lightmapUV, half4 ambient, half3 normalWS, half3 reflectVec, half occlusion, half perceptualRoughness, out half3 indirectDiffuse, out half3 indirectSpecular)
indirectDiffuse = ShadeSH9(half4(normalWorld, 1.0)) * occlusion;
indirectDiffuse = EvaluateSHPerPixel(normalWS, ambient) * occlusion;
#endif
#ifndef _GLOSSYREFLECTIONS_OFF

return (diffuse + specular) * atten;
}
half4 LightweightFragmentPBR(half4 lightmapUV, float3 positionWS, half3 normalWS, half3 tangentWS, half3 bitangentWS,
half3 viewDirectionWS, half fogFactor, half3 albedo, half metallic, half3 specular, half smoothness,
half3 normalTS, half ambientOcclusion, half3 emission, half alpha)
half4 LightweightFragmentPBR(half4 lightmapUV, float3 positionWS, half3 normalWS, half3 viewDirectionWS, half fogFactor, half4 ambient, half3 albedo, half metallic, half3 specular, half smoothness, half ambientOcclusion, half3 emission, half alpha)
// TODO: When refactoring shadows remove dependency from vertex normal
#if _NORMALMAP
normalWS = TangentToWorldNormal(normalTS, tangentWS, bitangentWS, normalWS);
#else
normalWS = normalize(normalWS);
#endif
LightweightGI(lightmapUV, normalWS, reflectVec, ambientOcclusion, brdfData.perceptualRoughness, indirectDiffuse, indirectSpecular);
LightweightGI(lightmapUV, ambient, normalWS, reflectVec, ambientOcclusion, brdfData.perceptualRoughness, indirectDiffuse, indirectSpecular);
half fresnelTerm = Pow4(1.0 - saturate(dot(normalWS, viewDirectionWS)));
half fresnelTerm = _Pow4(1.0 - saturate(dot(normalWS, viewDirectionWS)));
half3 color = LightweightBRDFIndirect(brdfData, indirectDiffuse, indirectSpecular, roughness2, fresnelTerm);
half3 lightDirectionWS;

51
ScriptableRenderPipeline/LightweightPipeline/Shaders/LightweightPassLit.cginc


UNITY_VERTEX_OUTPUT_STEREO
};
struct SurfaceData
{
half3 albedo;
half3 specular;
half metallic;
half smoothness;
half3 normal;
half3 emission;
half occlusion;
half alpha;
};
struct SurfaceInput
{
float4 lightmapUV;
half4 ambient;
half3 normalWS;
half3 tangentWS;
half3 bitangentWS;
float3 positionWS;
half3 viewDirectionWS;
half fogFactor;
};
inline half Alpha(half albedoAlpha)
{
#if defined(_SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A)

return tex2D(_OcclusionMap, uv).g;
#else
half occ = tex2D(_OcclusionMap, uv).g;
return LerpOneTo(occ, _OcclusionStrength);
return _LerpOneTo(occ, _OcclusionStrength);
#endif
#else
return 1.0;

{
#if LIGHTMAP_ON
outSurfaceInput.lightmapUV = float4(IN.ambientOrLightmapUV.xy, 0.0, 0.0);
outSurfaceInput.ambient = half4(0.0, 0.0, 0.0, 0.0);
outSurfaceInput.ambient = half4(IN.ambientOrLightmapUV);
#endif
#if _NORMALMAP

o.ambientOrLightmapUV.xy = v.lightmapUV * unity_LightmapST.xy + unity_LightmapST.zw;
// TODO: Dynamic Lightmap
o.ambientOrLightmapUV.zw = float2(0.0, 0.0);
// TODO: Currently there's no way to pass in ambient contribution to fragmentPBR.
// We should allow to create custom ambient computation for things like SH evaluation, lightmap, ambient color etc.
//#else
// o.ambientOrLightmapUV = half4(SHEvalLinearL2(half4(normal, 1.0)), 0.0h);
#else
o.ambientOrLightmapUV = half4(EvaluateSHPerVertex(o.normal), 0.0);
#endif
o.fogFactorAndVertexLight.yzw = half3(0.0h, 0.0h, 0.0h);

INITIALIZE_LIGHT(lightData, lightIter);
half3 lightDirection;
half atten = ComputeVertexLightAttenuation(lightData, normal, worldPos, lightDirection);
o.fogFactorAndVertexLight.yzw += LightingLambert(diffuse, lightDirection, normal, atten) * lightData.color;
half atten = ComputeVertexLightAttenuation(lightData, o.normal, worldPos, lightDirection);
o.fogFactorAndVertexLight.yzw += LightingLambert(diffuse, lightDirection, o.normal, atten) * lightData.color;
}
#endif

return o;
}

SurfaceInput surfaceInput;
InitializeSurfaceInput(IN, surfaceInput);
return LightweightFragmentPBR(surfaceInput.lightmapUV, surfaceInput.positionWS, surfaceInput.normalWS, surfaceInput.tangentWS, surfaceInput.bitangentWS, surfaceInput.viewDirectionWS, surfaceInput.fogFactor, surfaceData.albedo, surfaceData.metallic, surfaceData.specular, surfaceData.smoothness, surfaceData.normal, surfaceData.occlusion, surfaceData.emission, surfaceData.alpha);
#if _NORMALMAP
half3 normalWS = TangentToWorldNormal(surfaceData.normal, IN.tangent, IN.binormal, IN.normal);
#else
half3 normalWS = normalize(IN.normal);
#endif
return LightweightFragmentPBR(surfaceInput.lightmapUV, surfaceInput.positionWS, normalWS, surfaceInput.viewDirectionWS, surfaceInput.fogFactor, surfaceInput.ambient, surfaceData.albedo, surfaceData.metallic, surfaceData.specular, surfaceData.smoothness, surfaceData.occlusion, surfaceData.emission, surfaceData.alpha);
}
half4 LitPassFragmentSimple(LightweightVertexOutput IN) : SV_Target

#if defined(LIGHTMAP_ON)
half3 color = DecodeLightmap(UNITY_SAMPLE_TEX2D(unity_Lightmap, IN.ambientOrLightmapUV.xy)) * diffuse;
#else
half3 color = (ShadeSH9(half4(normalWorld, 1.0)) + IN.ambientOrLightmapUV.xyz) * diffuse;
half3 ambient = IN.ambientOrLightmapUV.xyz;
half3 color = EvaluateSHPerPixel(normalWorld, ambient) * diffuse;
#endif
half shininess = _Shininess * 128.0h;

正在加载...
取消
保存