Skip to content

Instantly share code, notes, and snippets.

@aras-p
Created November 25, 2011 06:43
Show Gist options
  • Save aras-p/1392951 to your computer and use it in GitHub Desktop.
Save aras-p/1392951 to your computer and use it in GitHub Desktop.
Directional Lightmap optimization try
Shader "Bumped Specular" {
Properties {
_Color ("Main Color", Color) = (1,1,1,1)
_SpecColor ("Specular Color", Color) = (0.5, 0.5, 0.5, 1)
_Shininess ("Shininess", Range (0.03, 1)) = 0.078125
_MainTex ("Base (RGB) Gloss (A)", 2D) = "white" {}
_BumpMap ("Normalmap", 2D) = "bump" {}
}
SubShader {
Tags { "RenderType"="Opaque" }
LOD 400
Pass {
Name "FORWARD"
Tags { "LightMode" = "ForwardBase" }
CGPROGRAM
#pragma vertex vert_surf
#pragma fragment frag_surf
#pragma fragmentoption ARB_precision_hint_fastest
#define DIRECTIONAL 1
#define LIGHTMAP_ON
#define DIRLIGHTMAP_ON
#define SHADOWS_SCREEN
#include "HLSLSupport.cginc"
#define UNITY_PASS_FORWARDBASE
#include "UnityCG.cginc"
#include "Lighting.cginc"
#include "AutoLight.cginc"
// 57 d3d9, 48/6 gl, nogo flash (9 regs) - Initial
// 50 d3d9, 48/6 gl, nogo flash (9 regs) - DIRBASIS to float, fudge numbers to make Cg not collapse regs
sampler2D _MainTex;
sampler2D _BumpMap;
fixed4 _Color;
half _Shininess;
struct Input {
float2 uv_MainTex;
float2 uv_BumpMap;
};
void surf (Input IN, inout SurfaceOutput o) {
fixed4 tex = tex2D(_MainTex, IN.uv_MainTex);
o.Albedo = tex.rgb * _Color.rgb;
o.Gloss = tex.a;
o.Alpha = tex.a * _Color.a;
o.Specular = _Shininess;
o.Normal = UnpackNormal(tex2D(_BumpMap, IN.uv_BumpMap));
}
struct v2f_surf {
float4 pos : SV_POSITION;
float4 pack0 : TEXCOORD0;
float2 lmap : TEXCOORD1;
float3 viewDir : TEXCOORD2;
LIGHTING_COORDS(3,4)
};
float4 unity_LightmapST;
float4 unity_ShadowFadeCenterAndType;
float4 _MainTex_ST;
float4 _BumpMap_ST;
v2f_surf vert_surf (appdata_full v) {
v2f_surf o;
o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
o.pack0.xy = TRANSFORM_TEX(v.texcoord, _MainTex);
o.pack0.zw = TRANSFORM_TEX(v.texcoord, _BumpMap);
o.lmap.xy = v.texcoord1.xy * unity_LightmapST.xy + unity_LightmapST.zw;
float3 worldN = mul((float3x3)_Object2World, SCALED_NORMAL);
TANGENT_SPACE_ROTATION;
float3 lightDir = mul (rotation, ObjSpaceLightDir(v.vertex));
float3 viewDirForLight = mul (rotation, ObjSpaceViewDir(v.vertex));
o.viewDir = viewDirForLight;
TRANSFER_VERTEX_TO_FRAGMENT(o);
return o;
}
sampler2D unity_Lightmap;
sampler2D unity_LightmapInd;
#define MYUNITY_DIRBASIS \
const float3x3 unity_DirBasis = float3x3( \
float3( 0.81649658, 0.0, 0.57735028), \
float3(-0.40824830, 0.70710679, 0.57735027), \
float3(-0.40824829, -0.70710678, 0.57735026) \
);
//#define MYUNITY_DIRBASIS \
//const half3x3 unity_DirBasis = half3x3( \
// half3(0.816496580927726, 0.0, 0.5773502691896258), \
// half3(-0.408248290463863, 0.7071067811865475, 0.5773502691896258), \
// half3(-0.408248290463863, -0.7071067811865475, 0.5773502691896258) \
//);
inline half3 MyDirLightmapDiffuse(in half3x3 dirBasis, fixed4 color, fixed4 scale, half3 normal, bool surfFuncWritesNormal, out half3 scalePerBasisVector)
{
half3 lm = DecodeLightmap (color);
// will be compiled out (and so will the texture sample providing the value)
// if it's not used in the lighting function, like in LightingLambert
scalePerBasisVector = DecodeLightmap (scale);
// will be compiled out when surface function does not write into o.Normal
if (surfFuncWritesNormal)
{
half3 normalInRnmBasis = saturate (mul (dirBasis, normal));
lm *= dot (normalInRnmBasis, scalePerBasisVector);
}
return lm;
}
inline half4 MyLightingBlinnPhong_DirLightmap (SurfaceOutput s, fixed4 color, fixed4 scale, half3 viewDir, bool surfFuncWritesNormal, out half3 specColor)
{
MYUNITY_DIRBASIS
half3 scalePerBasisVector;
half3 lm = MyDirLightmapDiffuse (unity_DirBasis, color, scale, s.Normal, surfFuncWritesNormal, scalePerBasisVector);
half3 lightDir = normalize (scalePerBasisVector.x * unity_DirBasis[0] + scalePerBasisVector.y * unity_DirBasis[1] + scalePerBasisVector.z * unity_DirBasis[2]);
half3 h = normalize (lightDir + viewDir);
float nh = max (0, dot (s.Normal, h));
float spec = pow (nh, s.Specular * 128.0);
// specColor used outside in the forward path, compiled out in prepass
specColor = lm * _SpecColor.rgb * s.Gloss * spec;
// spec from the alpha component is used to calculate specular
// in the Lighting*_Prepass function, it's not used in forward
return half4(lm, spec);
}
fixed4 frag_surf (v2f_surf IN) : COLOR {
Input surfIN;
surfIN.uv_MainTex = IN.pack0.xy;
surfIN.uv_BumpMap = IN.pack0.zw;
SurfaceOutput o;
o.Albedo = 0.0;
o.Emission = 0.0;
o.Specular = 0.0;
o.Alpha = 0.0;
o.Gloss = 0.0;
surf (surfIN, o);
fixed atten = LIGHT_ATTENUATION(IN);
fixed4 c = 0;
half3 specColor;
fixed4 lmtex = tex2D(unity_Lightmap, IN.lmap.xy);
fixed4 lmIndTex = tex2D(unity_LightmapInd, IN.lmap.xy);
half3 lm = MyLightingBlinnPhong_DirLightmap(o, lmtex, lmIndTex, normalize(half3(IN.viewDir)), 1, specColor).rgb;
c.rgb += specColor;
#if defined(SHADER_API_GLES) && defined(SHADER_API_MOBILE)
c.rgb += o.Albedo * min(lm, atten*2);
#else
c.rgb += o.Albedo * max(min(lm,(atten*2)*lmtex.rgb), lm*atten);
#endif
c.a = o.Alpha;
return c;
}
ENDCG
}
}
FallBack "Specular"
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment