// 0 : Fetch Position from Sun // 1 : Fetch Position from X/Y/Z or Bone, but you need to set your follow bone #define FOLLOW_POSITION 1 // 0 : None // 1 : You can use an image (bmp, png, jpg, tga, dds) by enter a relative and absolutely path to LENSFLARE_MAP_FILE. // 2 : You can use an animation image (gif, apng) by enter a relative and absolutely path to LENSFLARE_MAP_FILE. #define LENSFLARE_MAP_FROM 1 // 0 : Normal // 1 : Chromatic Aberration // 2 : Auto Rotation // The Image (Y axis) will always be face the light position // 3 : Chromatic Aberration & Auto Rotation #define LENSFLARE_MAP_TYPE 3 #define LENSFLARE_MAP_INDEX 1 // 0 ~ 15 #define LENSFLARE_MAP_FILE "textures by 2gou/lensflare.png" // R = Fixed scale // G = Fixed scale by camera // B = Fixed Brightness float3 GhostFlareParams = float3(10, 0.0, 2.0); #define GHOST_MAP_FROM 1 // see LENSFLARE_MAP_FROM #define GHOST_MAP_TYPE 3 // see LENSFLARE_MAP_TYPE #define GHOST_MAP_FILE "textures by 2gou/ghost.png" // R = Fixed Scale // G = Fixed Scale by camera // B = Increase Scale by ID float3 GhostAllScale = float3(0.125, 0.1, 0.025); // R = Fixed offset // G = Increase offset by ID // B = Decrease offset by ID float3 GhostAllOffset = float3(0.0, 0.25, 0.04); // R = Fixed Brightness // G = Increase Brightness by ID float2 GhostAllBrightness = float2(10.0, 0.0); // R = Fixed Flare shift // G = Fixed Ghost shift // B = Begin Increase shift by ID // A = End Increase shift by ID float4 GhostAllColorShift = float4(0.005, 0.05, 0.1, 0.8); // Control of single ghost image params // R = Fixed scale // G = Fixed scale by camera // B = Fixed Offset // A = Fixed Brightness float4 GhostParams[16] = { float4(1.0, 1.0, 1.0, 1.0), float4(3.0, 0.0, 1.0, 1.0), float4(1.0, 1.0, 1.0, 0.25), float4(1.0, 1.0, 1.0, 0.5), float4(1.0, 1.0, 1.0, 1.0), float4(1.0, 1.0, 1.0, 1.0), float4(1.0, 1.0, 1.0, 1.0), float4(1.0, 1.0, 1.0, 1.0), float4(1.0, 1.0, 1.0, 1.0), float4(1.0, 1.0, 1.0, 1.0), float4(1.0, 1.0, 1.0, 1.0), float4(1.0, 1.0, 1.0, 1.0), float4(1.0, 1.0, 1.0, 1.0), float4(1.0, 1.0, 1.0, 1.0), float4(1.0, 1.0, 1.0, 1.0), float4(1.0, 1.0, 1.0, 1.0) }; // Control of single chromatic aberration params float GhostShiftParams[16] = { 9.0, 1.0, 3.0, 3.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.4, 0.5 }; // 0 : None // 1 : Calculate occlusion by create depth map tab // 2 : Calculate occlusion by fetch depth from ray // this will be much faster than option at 1 #define OCCLUSION_MAP_FROM 1 // R = FadeIn Speed // G = FadeOut Speed // B = Max occlusion distance static float3 OcclusionParams = float3(10, 20, 1000); #define PI 3.1415926535f float luminance(float3 rgb) { return dot(rgb, float3(0.2126f, 0.7152f, 0.0722f)); } float3 srgb2linear(float3 rgb) { return pow(max(0, rgb), 2.2); } float4 srgb2linear(float4 c) { return float4(srgb2linear(c.rgb), c.a); } float3 linear2srgb(float3 srgb) { return pow(max(0, srgb), 1.0 / 2.2); } float4 linear2srgb(float4 c) { return float4(linear2srgb(c.rgb), c.a); } float3 hsv2rgb(float3 hsv) { float3 rgb = smoothstep(2.0,1.0, abs(fmod(hsv.x*6.0+float3(0,4,2), 6.0) - 3.0)); return hsv.z * (1.0 - hsv.y * rgb); } float2 PosToCoord(float2 position) { position = position * 0.5 + 0.5; return float2(position.x, 1 - position.y); } float2 CoordToPos(float2 coord) { coord.y = 1 - coord.y; return coord * 2 - 1; } float3x3 CreateRotationX(float theta) { float c, s; sincos(s, c, theta); return float3x3(1, 0, 0, 0, c, -s, 0, s, c); } float3x3 CreateRotationY(float theta) { float c, s; sincos(s, c, theta); return float3x3(c, 0, s, 0, 1, 0, -s, 0, c); } float3x3 CreateRotationZ(float theta) { float c = cos(theta); float s = sin(theta); return float3x3(c, -s, 0, s, c, 0, 0, 0, 1); } float3x3 CreateRotate(float3 euler) { float sj, cj, si, ci, sh, ch; sincos(euler.x, si, ci); sincos(euler.y, sj, cj); sincos(euler.z, sh, ch); float cc = ci * ch; float cs = ci * sh; float sc = si * ch; float ss = si * sh; float a1 = cj * ch; float a2 = sj * sc - cs; float a3 = sj * cc + ss; float b1 = cj * sh; float b2 = sj * ss + cc; float b3 = sj * cs - sc; float c1 = -sj; float c2 = cj * si; float c3 = cj * ci; float3x3 rotate; rotate[0] = float3(a1, a2, a3); rotate[1] = float3(b1, b2, b3); rotate[2] = float3(c1, c2, c3); return rotate; } float2 CreateBillboard(float2 position, float2 transalte, float2 center = 0.0, float2 up = float2(0, 1)) { float2 view = normalize(center - transalte); float angle = acos(dot(up, view)); if (transalte.x > 0) angle = PI - angle; else angle += PI; float c = cos(angle); float s = sin(angle); float2x2 m = float2x2(c, -s, s, c); return mul(position, m); } float2 CreateBillboardInverse(float2 position, float2 transalte, float2 center = 0.0, float2 up = float2(0, 1)) { float2 view = normalize(center - transalte); float angle = acos(dot(up, view)); if (transalte.x > 0) angle = PI - angle; else angle += PI; float c = cos(-angle); float s = sin(-angle); float2x2 m = float2x2(c, -s, s, c); return mul(position, m); } float time : TIME; float elapsed : ELAPSEDTIME; float2 MousePosition : MOUSEPOSITION; float4x4 matWorld : WORLD; float4x4 matWorldInverse : WORLDINVERSE; float4x4 matWorldView : WORLDVIEW; float4x4 matWorldViewProject : WORLDVIEWPROJECTION; float4x4 matView : VIEW; float4x4 matViewInverse : VIEWINVERSE; float4x4 matProject : PROJECTION; float4x4 matProjectInverse : PROJECTIONINVERSE; float4x4 matViewProject : VIEWPROJECTION; float4x4 matViewProjectInverse : VIEWPROJECTIONINVERSE; float3 CameraPosition : POSITION; float3 CameraDirection : DIRECTION; float3 LightSpecular : SPECULAR< string Object = "Light";>; float3 LightDirection : DIRECTION< string Object = "Light";>; float AcsScale : CONTROLOBJECT; float AcsTr : CONTROLOBJECT < string name = "(self)"; string item = "Tr"; >; float AcsRx : CONTROLOBJECT; float AcsRy : CONTROLOBJECT; float AcsRz : CONTROLOBJECT; float3 AcsPosition : CONTROLOBJECT; float2 ViewportSize : VIEWPORTPIXELSIZE; static const float2 ViewportOffset = 0.5 / ViewportSize; static const float2 ViewportOffset2 = 1.0 / ViewportSize; static const float ViewportAspect = ViewportSize.x / ViewportSize.y; #if OCCLUSION_MAP_FROM == 1 texture EyeLumMap : OFFSCREENRENDERTARGET< string Description = "Eye Adaptation For Occlusion Culling"; // int2 Dimensions = {256, 256}; int Width = 256; int Height = 256; string Format = "R16F"; float4 ClearColor = 0.0; float ClearDepth = 1.0; string DefaultEffect = "self = hide;" /* "*fog.pmx=hide;" "*controller.pmx=hide;" "*editor*.pmx=hide;" "*.pmx=Shader/Eye.fx;" "*.pmd=Shader/Eye.fx;" "*.x=hide;";*/ "* = hide"; >; sampler EyeLumMapSamp = sampler_state { texture = ; MinFilter = POINT; MagFilter = POINT; MipFilter = NONE; AddressU = CLAMP; AddressV = CLAMP; }; #elif OCCLUSION_MAP_FROM == 2 shared texture Gbuffer8RT: RENDERCOLORTARGET< float2 ViewportRatio = {1.0, 1.0}; string Format = "A16B16G16R16F"; int Miplevels = 0; >; sampler EyeLumMapSamp = sampler_state { texture = ; MinFilter = POINT; MagFilter = POINT; MipFilter = NONE; AddressU = CLAMP; AddressV = CLAMP; }; #endif texture EyeLumAveMap : RENDERCOLORTARGET< int Width = 1; int Height = 1; string Format = "R16F"; >; sampler EyeLumAveMapSamp = sampler_state { texture = ; MinFilter = POINT; MagFilter = POINT; MipFilter = NONE; AddressU = CLAMP; AddressV = CLAMP; }; float CalcAdaptedLum(float adaptedLum, float lum, float speed, float delta) { return max(0, adaptedLum + (lum - adaptedLum) * (1.0f - exp2(-speed * delta))); } float4 EyeAdaptationVS( in float4 Position : POSITION, in float4 Texcoord : TEXCOORD, out float4 oTexcoord0 : TEXCOORD0) : POSITION { oTexcoord0 = Texcoord; oTexcoord0.xy += ViewportOffset; oTexcoord0.zw = oTexcoord0.xy * ViewportSize; return Position; } float4 EyeAdaptationPS( in float2 coord: TEXCOORD0, uniform float3 lightPosition, uniform float3 cameraPosition, uniform float3 fadeSpeed) : COLOR { float4 proj = mul(float4(lightPosition, 1), matViewProject); proj.xy = PosToCoord(proj.xy / proj.w); float mask = tex2Dlod(EyeLumMapSamp, float4(proj.xy, 0, 0)).r; float maskDistance = min(fadeSpeed.z, distance(cameraPosition, lightPosition)); float lum = (mask < maskDistance && mask > 0.0) ? 0 : 1; float adaptedLum = tex2Dlod(EyeLumAveMapSamp, float4(float2(0.5, 0.5), 0, 0)).r; if (!all(isfinite(lum))) lum = 1.0f; if (!all(isfinite(adaptedLum))) adaptedLum = 1.0f; float speed = lum > adaptedLum ? fadeSpeed.x : fadeSpeed.y; return CalcAdaptedLum(adaptedLum, lum, speed, elapsed); } #if FOLLOW_POSITION == 0 static const float3 LightPosition = -LightDirection * 80000; #elif FOLLOW_POSITION == 1 static const float3 LightPosition = AcsPosition; #endif texture ScnMap : RENDERCOLORTARGET< float2 ViewportRatio = {1.0,1.0}; string Format = "A8B8G8R8"; >; sampler ScnSamp = sampler_state { texture = ; MAGFILTER = POINT; MINFILTER = POINT; MIPFILTER = NONE; ADDRESSU = CLAMP; ADDRESSV = CLAMP; }; #if LENSFLARE_MAP_FROM #if LENSFLARE_MAP_FROM == 1 texture LensFlareMap; #else texture LensFlareMap : ANIMATEDTEXTURE; #endif sampler LensFlareMapSamp = sampler_state { Texture = LensFlareMap; MAGFILTER = LINEAR; MINFILTER = LINEAR; MIPFILTER = NONE; ADDRESSU = CLAMP; ADDRESSV = CLAMP; }; #endif #if GHOST_MAP_FROM #if GHOST_MAP_FROM == 1 texture GhostMap; #else texture GhostMap : ANIMATEDTEXTURE; #endif sampler GhostMapSamp = sampler_state { Texture = GhostMap; MAGFILTER = POINT; MINFILTER = POINT; MIPFILTER = NONE; ADDRESSU = CLAMP; ADDRESSV = CLAMP; }; #endif float3 SampleSpectrum(float x) { float t = 3.0 * x - 1.5; return saturate(float3(-t, 1 - abs(t), t)); } float3 ChromaticAberration(sampler source, float2 coord, float2 offset, int samples, float4 limits = float4(0,0,1,1)) { float3 color = 0.0; float3 weight = 0.0; float2 delta = offset / samples; [unroll] for (int i = 0; i < samples; i++, coord += delta) { coord = clamp(coord, limits.xy, limits.zw); float3 w = SampleSpectrum(float(i) / samples); weight += w; color += w * srgb2linear(tex2Dlod(source, float4(coord, 0, 0)).rgb); } return color / weight; } float2 GetGhostImagePos(float2 position, float scale, float scale2, float offset, float index) { float4 screenPosition = mul(float4(LightPosition, 1), matViewProject); screenPosition.xyz /= screenPosition.w; if (screenPosition.w < 1e-5) return 0; float2 deltaScreenPos = -normalize(screenPosition.xyz).xy; float2 posScale = float2(1, ViewportAspect); posScale *= (GhostAllScale.x + GhostAllScale.z * index) * scale; posScale *= lerp(0.5, dot(deltaScreenPos, deltaScreenPos) + 0.5, GhostAllScale.y * scale2); float2 pos = 0; pos = position * posScale; pos += screenPosition.xy + deltaScreenPos * (GhostAllOffset.x + (index - LENSFLARE_MAP_INDEX) * GhostAllOffset.y) * offset; pos -= deltaScreenPos * index * GhostAllOffset.z; return pos; } float2 GetGhostImageBillboard(float2 position, float scale, float scale2, float offset, float index) { float4 screenPosition = mul(float4(LightPosition, 1), matViewProject); screenPosition.xyz /= screenPosition.w; if (screenPosition.w < 1e-5) return 0; float2 deltaScreenPos = -normalize(screenPosition.xyz).xy; float2 posScale = float2(1, ViewportAspect); posScale *= (GhostAllScale.x + GhostAllScale.z * index) * scale; posScale *= lerp(0.5, dot(deltaScreenPos, deltaScreenPos) + 0.5, GhostAllScale.y * scale2); float2 pos = 0; pos = CreateBillboard(position, screenPosition.xy) * posScale; pos += screenPosition.xy + deltaScreenPos * (GhostAllOffset.x + (index - LENSFLARE_MAP_INDEX) * GhostAllOffset.y) * offset; pos -= deltaScreenPos * index * GhostAllOffset.z; return pos; } #if LENSFLARE_MAP_FROM float4 LensflareVS( in float4 position : POSITION, in float2 texcoord : TEXCOORD0, out float4 oTexcoord0 : TEXCOORD0, out float3 oTexcoord1 : TEXCOORD1) : POSITION { float4 screenPosition = mul(float4(LightPosition, 1), matViewProject); screenPosition.x = 1 - screenPosition.x; screenPosition.xyz /= screenPosition.w; float2 deltaScreenPos = -normalize(screenPosition.xy).xy * float2(ViewportAspect, 1); deltaScreenPos *= GhostAllColorShift.x; #if LENSFLARE_MAP_TYPE == 2 || LENSFLARE_MAP_TYPE == 3 deltaScreenPos = CreateBillboardInverse(deltaScreenPos, screenPosition.xy); #endif oTexcoord0.xy = texcoord; oTexcoord0.zw = deltaScreenPos; oTexcoord1 = GhostFlareParams.z * AcsScale / 10.0; #if OCCLUSION_MAP_FROM oTexcoord1 *= tex2Dlod(EyeLumAveMapSamp, float4(0.5, 0.5, 0, 0)).r; #endif #if LENSFLARE_MAP_TYPE == 2 || LENSFLARE_MAP_TYPE == 3 return float4(GetGhostImageBillboard(position.xy, GhostFlareParams.x, GhostFlareParams.y, 0, 1), 0, 1); #else return float4(GetGhostImagePos(position.xy, GhostFlareParams.x, GhostFlareParams.y, 0, 1), 0, 1); #endif } float4 LensflarePS( in float4 coord0 : TEXCOORD0, in float3 coord1 : TEXCOORD1) : COLOR { #if LENSFLARE_MAP_TYPE == 1 || LENSFLARE_MAP_TYPE == 3 float3 color = ChromaticAberration(LensFlareMapSamp, coord0.xy, coord0.zw, 8).rgb * coord1; #else float3 color = srgb2linear(tex2Dlod(LensFlareMapSamp, float4(coord0.xy, 0, 0)).rgb) * coord1; #endif #if FOLLOW_POSITION == 0 color *= saturate(normalize(LightPosition).y); #endif color = linear2srgb(color); return float4(color, luminance(color) * 0.5); } #endif #if GHOST_MAP_FROM float4 GhostImageVS( in float4 position : POSITION, in float2 texcoord : TEXCOORD0, out float4 oTexcoord0 : TEXCOORD0, out float4 oTexcoord1 : TEXCOORD1, out float3 oTexcoord2 : TEXCOORD2, uniform int index) : POSITION { float4 screenPosition = mul(float4(LightPosition, 1), matViewProject); screenPosition.x = 1 - screenPosition.x; screenPosition.xyz /= screenPosition.w; float2 deltaScreenPos = -normalize(screenPosition.xy).xy * float2(ViewportAspect, 1); deltaScreenPos *= GhostAllColorShift.y; deltaScreenPos *= lerp(GhostAllColorShift.z, GhostAllColorShift.w, saturate(index / 16.0)); deltaScreenPos *= GhostShiftParams[index]; #if GHOST_MAP_TYPE == 2 || GHOST_MAP_TYPE == 3 deltaScreenPos = CreateBillboardInverse(deltaScreenPos, screenPosition.xy); #endif oTexcoord0.xy = float2(index % 4, index / 4) * 0.25 + texcoord * 0.25; oTexcoord0.zw = deltaScreenPos; oTexcoord1 = float4(float2(index % 4, index / 4) * 0.25, float2(index % 4, index / 4) * 0.25 + 0.25); oTexcoord2 = GhostParams[index].w * GhostAllBrightness.x; oTexcoord2 += (index - LENSFLARE_MAP_INDEX) * GhostAllBrightness.y; oTexcoord2 *= AcsScale / 10.0; #if OCCLUSION_MAP_FROM oTexcoord2 *= tex2Dlod(EyeLumAveMapSamp, float4(0.5,0.5,0,0)).r; #endif #if GHOST_MAP_TYPE == 2 || GHOST_MAP_TYPE == 3 return float4(GetGhostImageBillboard(position.xy, GhostParams[index].x, GhostParams[index].y, GhostParams[index].z, index), 0, 1); #else return float4(GetGhostImagePos(position.xy, GhostParams[index].x, GhostParams[index].y, GhostParams[index].z, index), 0, 1); #endif } float4 GhostImagePS( in float4 coord0 : TEXCOORD0, in float4 coord1 : TEXCOORD1, in float3 coord2 : TEXCOORD2) : COLOR { #if GHOST_MAP_TYPE == 1 || GHOST_MAP_TYPE == 3 float3 color = ChromaticAberration(GhostMapSamp, coord0.xy, coord0.zw, 24, coord1) * coord2; #else float3 color = srgb2linear(tex2Dlod(GhostMapSamp, float4(coord0.xy, 0, 0)).rgb) * coord2; #endif #if FOLLOW_POSITION == 0 color *= saturate(normalize(LightPosition).y); #endif color = linear2srgb(color); return float4(color, luminance(color) * 0.5); } #endif float4 ShowScreenVS( in float4 position : POSITION, in float4 texcoord : TEXCOORD, out float4 oTexcoord : TEXCOORD0) : POSITION { oTexcoord = texcoord.xyxy + ViewportOffset.xyxy; return position; } float4 ShowScreenPS(in float2 coord: TEXCOORD0) : COLOR { return tex2Dlod(ScnSamp, float4(coord, 0, 0)); } int GhostCount = 16; int GhostIndex = 0; float4 ClearColor = 0.0; float ClearDepth = 1.0; float Script : STANDARDSGLOBAL < string ScriptOutput = "color"; string ScriptClass = "scene"; string ScriptOrder = "postprocess"; > = 0.8; technique OpticalLight< string Script = "RenderColorTarget=ScnMap;" "RenderDepthStencilTarget=;" "ClearSetColor=ClearColor;" "ClearSetDepth=ClearDepth;" "Clear=Color;" "Clear=Depth;" "ScriptExternal=Color;" #if OCCLUSION_MAP_FROM "RenderColorTarget=EyeLumAveMap;" "Pass=EyeAdaptation;" #endif "RenderColorTarget=ScnMap;" #if LENSFLARE_MAP_FROM "Pass=GenLensflare;" #endif #if GHOST_MAP_FROM "LoopByCount=GhostCount;" "LoopGetIndex=GhostIndex;" "Pass=GenGhostImage;" "LoopEnd=;" #endif "RenderColorTarget=;" "Clear=Color;" "Clear=Depth;" "Pass=ShowScreen;" ;>{ pass ShowScreen{ AlphaBlendEnable = false; AlphaTestEnable = false; ZEnable = false; ZWriteEnable = false; CULLMODE = NONE; VertexShader = compile vs_3_0 ShowScreenVS(); PixelShader = compile ps_3_0 ShowScreenPS(); } #if OCCLUSION_MAP_FROM pass EyeAdaptation{ AlphaBlendEnable = false; AlphaTestEnable = false; ZEnable = false; ZWriteEnable = false; CULLMODE = NONE; VertexShader = compile vs_3_0 EyeAdaptationVS(); PixelShader = compile ps_3_0 EyeAdaptationPS(LightPosition, CameraPosition, OcclusionParams); } #endif #if LENSFLARE_MAP_FROM pass GenLensflare { AlphaBlendEnable = true; AlphaTestEnable = false; ZEnable = false; ZWriteEnable = false; SrcBlend = ONE; DestBlend = INVSRCALPHA; CULLMODE = NONE; VertexShader = compile vs_3_0 LensflareVS(); PixelShader = compile ps_3_0 LensflarePS(); } #endif #if GHOST_MAP_FROM pass GenGhostImage { AlphaBlendEnable = true; AlphaTestEnable = false; ZEnable = false; ZWriteEnable = false; SrcBlend = ONE; DestBlend = INVSRCALPHA; CULLMODE = NONE; VertexShader = compile vs_3_0 GhostImageVS(GhostIndex); PixelShader = compile ps_3_0 GhostImagePS(); } #endif } //0