From 3f6e4efd8b171a56086f6bf48de2149bf6181bc4 Mon Sep 17 00:00:00 2001 From: turanszkij Date: Thu, 3 Nov 2016 23:46:06 +0100 Subject: [PATCH] refactored lensflare geometry shader --- WickedEngine/lensFlareGS.hlsl | 75 ++++++++++++++++++++--------------- 1 file changed, 43 insertions(+), 32 deletions(-) diff --git a/WickedEngine/lensFlareGS.hlsl b/WickedEngine/lensFlareGS.hlsl index f93d9f5ac..4407bfeb4 100644 --- a/WickedEngine/lensFlareGS.hlsl +++ b/WickedEngine/lensFlareGS.hlsl @@ -1,27 +1,28 @@ #include "globals.hlsli" +// constant buffer CBUFFER(LensFlareCB, CBSLOT_OTHER_LENSFLARE) { - float4 xSunPos; - float4 xScreen; + float4 xSunPos; // light position + float4 xScreen; // screen dimensions }; -struct InVert{ - float4 pos : SV_POSITION; - nointerpolation uint vid : VERTEXID; +struct InVert +{ + float4 pos : SV_POSITION; + nointerpolation uint vid : VERTEXID; }; struct VertextoPixel{ - float4 pos : SV_POSITION; - float3 texPos : TEXCOORD0; - nointerpolation uint sel : TEXCOORD1; - nointerpolation float4 opa : TEXCOORD2; + float4 pos : SV_POSITION; + float3 texPos : TEXCOORD0; // texture coordinates (xy) + offset(z) + nointerpolation uint sel : TEXCOORD1; // texture selector + nointerpolation float4 opa : TEXCOORD2; // opacity + padding }; -//Texture2D depth:register(t0); -//Texture2D flare[7]:register(t1); - -inline void append(inout TriangleStream triStream, VertextoPixel p1, uint selector, float2 posMod, float2 size){ +// Append a screen space quad to the output stream: +inline void append(inout TriangleStream triStream, VertextoPixel p1, uint selector, float2 posMod, float2 size) +{ float2 pos = (xSunPos.xy-0.5)*float2(2,-2); float2 moddedPos = pos*posMod; float dis = distance(pos,moddedPos); @@ -43,20 +44,18 @@ inline void append(inout TriangleStream triStream, VertextoPixel p1.pos.xy=moddedPos+float2(size.x,size.y); p1.texPos.xy=float2(1,1); triStream.Append(p1); - - //triStream.RestartStrip(); } -#define VERTEXCOUNT 4 +// pre-baked offsets +// These values work well for me, but should be tweakable +static const float mods[] = { 1,0.55,0.4,0.1,-0.1,-0.3,-0.5 }; -static const float mods[] = {1,0.55,0.4,0.1,-0.1,-0.3,-0.5}; -//static const float size[] = {0.12,0.1,0.25,0.05,0.15,0.1,0.3}; - -[maxvertexcount(VERTEXCOUNT)] +[maxvertexcount(4)] void main(point InVert p[1], inout TriangleStream triStream) { VertextoPixel p1 = (VertextoPixel)0; + // Determine flare size from texture dimensions float2 flareSize=float2(256,256); [branch] switch(p[0].vid){ @@ -84,25 +83,37 @@ void main(point InVert p[1], inout TriangleStream triStream) default:break; }; - + // determine depthmap dimensions (could be screen dimensions from the constantbuffer) float2 depthMapSize; texture_depth.GetDimensions(depthMapSize.x,depthMapSize.y); - flareSize/=depthMapSize; + flareSize /= depthMapSize; - const float range = 10.5f; + // determine the flare opacity: + // These values work well for me, but should be tweakable + const float2 step = 1.0f / (depthMapSize*xSunPos.z); + const float2 range = 10.5f * step; float samples = 0.0f; float accdepth = 0.0f; - for (float y = -range; y <= range; y += 1.0f) - for (float x = -range; x <= range; x += 1.0f){ - samples+=1.0f; - accdepth += (texture_depth.SampleCmpLevelZero(sampler_cmp_depth,xSunPos.xy+float2(x,y)/(depthMapSize*xSunPos.z),xSunPos.z).r ) ; + for (float y = -range.y; y <= range.y; y += step.y) + { + for (float x = -range.x; x <= range.x; x += step.x) + { + samples += 1.0f; + // texture_depth is non-linear depth (but it could work for linear too with linear reference value) + // SampleCmpLevelZero also makes a comparison by using a LESS_EQUAL comparison sampler + // It compares the reference value (xSunPos.z) to the depthmap value. + // Returns 0.0 if all samples in a bilinear kernel are greater than reference value + // Returns 1.0 if all samples in a bilinear kernel are less or equal than refernce value + // Can return in between values based on bilinear filtering + accdepth += (texture_depth.SampleCmpLevelZero(sampler_cmp_depth, xSunPos.xy + float2(x, y), xSunPos.z).r); } - accdepth/=samples; - - p1.pos=float4(0,0,0,1); - p1.opa=float4(accdepth,0,0,0); + } + accdepth /= samples; + p1.pos = float4(0, 0, 0, 1); + p1.opa = float4(accdepth, 0, 0, 0); + // Make a new flare if it is at least partially visible: [branch]if( accdepth>0 ) append(triStream,p1,p[0].vid,mods[p[0].vid],flareSize); -} \ No newline at end of file +}