BumpMappedAndPointLightBasePass
Author: Ricardo A
Contents |
Description
These are a shader+script to render objects using Lightmaps and an extra point light, in Forward mode (mobile) all in the base pass.
Usage
Prerequisites:
- Create a material that uses the shader below (Mobile/Bumped Specular Point Light)
- Add the "SetPointLightData.cs" script to a GameObject. The script executes in Edit Mode.
ShaderLab - LightmapsAndPoint.shader
Invalid language.
You need to specify a language like this: <source lang="html4strict">...</source>
Supported languages for syntax highlighting:
4cs, 6502acme, 6502kickass, 6502tasm, 68000devpac, abap, actionscript, actionscript3, ada, algol68, apache, applescript, apt_sources, asm, asp, autoconf, autohotkey, autoit, avisynth, awk, bascomavr, bash, basic4gl, bf, bibtex, blitzbasic, bnf, boo, c, c_loadrunner, c_mac, caddcl, cadlisp, cfdg, cfm, chaiscript, cil, clojure, cmake, cobol, coffeescript, cpp, cpp-qt, csharp, css, cuesheet, d, dcs, delphi, diff, div, dos, dot, e, ecmascript, eiffel, email, epc, erlang, euphoria, f1, falcon, fo, fortran, freebasic, fsharp, gambas, gdb, genero, genie, gettext, glsl, gml, gnuplot, go, groovy, gwbasic, haskell, hicest, hq9plus, html4strict, html5, icon, idl, ini, inno, intercal, io, j, java, java5, javascript, jquery, kixtart, klonec, klonecpp, latex, lb, lisp, llvm, locobasic, logtalk, lolcode, lotusformulas, lotusscript, lscript, lsl2, lua, m68k, magiksf, make, mapbasic, matlab, mirc, mmix, modula2, modula3, mpasm, mxml, mysql, newlisp, nsis, oberon2, objc, objeck, ocaml, ocaml-brief, oobas, oracle11, oracle8, oxygene, oz, pascal, pcre, per, perl, perl6, pf, php, php-brief, pic16, pike, pixelbender, pli, plsql, postgresql, povray, powerbuilder, powershell, proftpd, progress, prolog, properties, providex, purebasic, pycon, python, q, qbasic, rails, rebol, reg, robots, rpmspec, rsplus, ruby, sas, scala, scheme, scilab, sdlbasic, smalltalk, smarty, sql, systemverilog, tcl, teraterm, text, thinbasic, tsql, typoscript, unicon, uscript, vala, vb, vbnet, verilog, vhdl, vim, visualfoxpro, visualprolog, whitespace, whois, winbatch, xbasic, xml, xorg_conf, xpp, yaml, z80, zxbasic
// Lightmaps and a single point light in forward base pass Shader "Mobile/Bumped Specular Point Light" { Properties { _Color ("Main Color", Color) = (1,1,1,1) _Specular ("Specular Color", Color) = (0.5, 0.5, 0.5, 1) _Shininess ("Shininess", Range (0.01, 1)) = 0.5 _MainTex ("Base (RGB)", 2D) = "white" {} _BumpMap ("Normalmap", 2D) = "bump" {} } SubShader { Tags { "RenderType"="Opaque" } LOD 300 Pass { Name "FORWARD" Tags { "LightMode" = "ForwardBase" } CGPROGRAM #pragma vertex vert #pragma fragment frag #pragma fragmentoption ARB_precision_hint_fastest #pragma multi_compile_fwdbase novertexlight #include "HLSLSupport.cginc" #define UNITY_PASS_FORWARDBASE #include "UnityCG.cginc" #include "Lighting.cginc" #include "AutoLight.cginc" #define INTERNAL_DATA // To debug //#pragma debug sampler2D _MainTex; sampler2D _BumpMap; fixed4 _MainTex_ST; fixed4 _BumpMap_ST; fixed4 _Color; fixed4 _Specular; fixed _Shininess; // Light & Camera uniform fixed4 _worldSpaceLightPosition; uniform fixed4 _worldSpaceViewPos; uniform fixed4 _lightColor; uniform fixed _lightRange; uniform fixed _lightIntensity; #ifdef LIGHTMAP_OFF struct v2f { float4 pos : SV_POSITION; fixed4 pack0 : TEXCOORD0; fixed4 lightDir : TEXCOORD1; fixed3 viewDir : TEXCOORD2; LIGHTING_COORDS(3,4) }; #endif #ifndef LIGHTMAP_OFF struct v2f { float4 pos : SV_POSITION; fixed4 pack0 : TEXCOORD0; fixed2 lmap : TEXCOORD1; fixed4 lightDir : TEXCOORD2; fixed3 viewDir : TEXCOORD3; LIGHTING_COORDS(4,5) }; sampler2D unity_Lightmap; fixed4 unity_LightmapST; #endif v2f vert (appdata_full v) { v2f 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); // Computes object space light direction TANGENT_SPACE_ROTATION; fixed3 objSpaceLightPos = mul(_World2Object, _worldSpaceLightPosition).xyz; objSpaceLightPos = objSpaceLightPos.xyz - v.vertex.xyz; fixed3 lightDir = mul (rotation, objSpaceLightPos); o.lightDir.rgb = lightDir; o.lightDir.a = dot(objSpaceLightPos, objSpaceLightPos); // Computes object space view direction fixed3 objSpaceCameraPos = mul(_World2Object, fixed4(_worldSpaceViewPos.xyz, 1)).xyz * unity_Scale.w; objSpaceCameraPos = objSpaceCameraPos - v.vertex.xyz; fixed3 viewDirForLight = mul (rotation, objSpaceCameraPos); o.viewDir = viewDirForLight; // Lightmap coordinates #ifndef LIGHTMAP_OFF o.lmap.xy = v.texcoord1.xy * unity_LightmapST.xy + unity_LightmapST.zw; #endif TRANSFER_VERTEX_TO_FRAGMENT(o); return o; } fixed4 frag (v2f IN) : COLOR { fixed2 uv_MainTex = IN.pack0.xy; fixed2 uv_BumpMap = IN.pack0.zw; // Texture & Normal fixed4 albedo_alpha = tex2D(_MainTex, uv_MainTex) * _Color; fixed3 Normal = normalize(UnpackNormal(tex2D(_BumpMap, uv_BumpMap))); // Blinn Phong fixed3 h = normalize (IN.lightDir.rgb + IN.viewDir); fixed diff = max (0, dot (Normal, IN.lightDir.rgb)); fixed nh = max (0, dot (Normal, h)); fixed spec = pow (nh, _Shininess*128.0f) * albedo_alpha.a; fixed atten = 1.0f / (1.0f + (25.0f * IN.lightDir.a / (_lightRange * _lightRange))); fixed4 c; c.rgb = (albedo_alpha.rgb * _lightColor.rgb * _lightIntensity * diff + _lightColor.rgb * _lightIntensity * _Specular.rgb * spec) * (atten * 2); c.a = albedo_alpha.a + _lightColor.a * _Specular.a * spec * atten; #ifndef LIGHTMAP_OFF fixed4 lmtex = tex2D(unity_Lightmap, IN.lmap.xy); fixed3 lm = DecodeLightmap (lmtex); c.rgb += albedo_alpha.rgb * lm; c.a += albedo_alpha.a; #endif // LIGHTMAP_OFF return c; } ENDCG } } Fallback "Mobile/Diffuse" }
C# - SetPointLightData.cs
using UnityEngine; // This sets the light's data to be used by the shader. It need to be done this way, because Unity doesn't provide the point light information for the base pass [ExecuteInEditMode] // Live update when not in Play mode public class SetPointLightData : MonoBehaviour { public new Light pointLight; Transform t; void Start() { t = pointLight.transform; } void OnPreRender() { Vector3 pos = t.position; if (pointLight.enabled && pointLight.gameObject.active) { Shader.SetGlobalVector("_worldSpaceLightPosition", new Vector4(pos.x, pos.y, pos.z, 0)); Shader.SetGlobalVector("_worldSpaceViewPos", Camera.mainCamera.transform.position); Shader.SetGlobalVector("_lightColor", pointLight.color); Shader.SetGlobalFloat("_lightRange", pointLight.range); Shader.SetGlobalFloat("_lightIntensity", pointLight.intensity); } else { Shader.SetGlobalFloat("_lightIntensity", 0); } } }