精华内容
下载资源
问答
  • <div><p>I reimplemented the variance kernel using Welford's online algorithm to fix catastrophic cancellation: <h2>precision test with random noise: <pre><code> mrconvert image.mif -coord 3 0 - | ...
  • Reduce volume memory usage

    2020-12-03 03:11:45
    <div><p>Reduce memory usage when computing variance normalization on volume files.</p><p>该提问来源于开源项目:Washington-University/HCPpipelines</p></div>
  • Find outlier decision dates

    2020-12-09 13:48:45
    <div><p>We should be able to do a report of likely-incorrect decision dates based on variance. Like if a volume has a bunch of dates between 1658 and 1800, that's fine, but if it has all dates in ...
  • 主题:Shadow Map(SM), Percentage Closer Filtering(PCF), Variance Shadow Map(VSM) 引言  对于3D场景来说,阴影的重要性不言而喻。随着时代的发展,各种各样的阴影绘制技术被提出(如Shadow Volume和Shadow ...

    作者:i_dovelemon

    日期:2019-06-07

    主题:Shadow Map(SM), Percentage Closer Filtering(PCF), Variance Shadow Map(VSM)

     

    引言

      对于3D场景来说,阴影的重要性不言而喻。随着时代的发展,各种各样的阴影绘制技术被提出(如Shadow Volume和Shadow Map)。在之前的博文中,我们讨论过PSSM。这是一种为了解决大场景阴影贴图透视走样方法而提出的算法。它主要是将场景切割,用多张Shadow Map来组织阴影。这个算法核心是多张Shadow Map的组织,而不是Shadow Map本身。

     

    介绍

      一般情况下,我们不做任何特殊处理,产生的Shadow Map,我们称之为Standard Shadow Map(SSM)(参考文献[1])。如果不做任何处理的使用SSM,这样势必会给场景中的阴影带来很多的锯齿,比较难看(如图1种的SSM)。究其原因,是我们在计算一个像素是否被阴影覆盖的时候,只有单纯的覆盖和不覆盖两种情况,而贴图本身是一种离散的数据情况,所以会给阴影产生锯齿。

      所以,针对这种情况,人们想到了不使用覆盖和不覆盖这两种情况进行阴影的表达,而是用这个像素被覆盖的程度(percentage)(参考文献[2])。就像我们对于有锯齿的图形,会在边缘加上一点alpha渐变来解决一样,通过覆盖程度的不同,会给阴影产生一个柔和的边缘(如图1中的PCF)。

      但PCF本身需要通过对Shadow Map进行多次采样求平均值来进行,想要比较好的效果,采样半径需要比较大。这样势必会造成性能损耗。所以在PCF的基础上,人们通过dithering的技术,减少采样次数来实现类似的效果。

      SSM和PCF都需要Shadow Map中存放的是像素对应的深度值。而在进行阴影计算的时候,需要从中获取到对应的深度值。这就导致我们的Shadow Map无法利用硬件提供的mipmapping和linear filtering等手段进行filtering。

      所以,人们想到通过其他的手段来让我们能够对Shadow Map进行filtering。也就是本文将要着重介绍的Variance Shadow Map(VSM)。

     

    Variance Shadow Map

      VSM的技术是由William Donnelly(参考文献[3])等人提出的一种方案。通过他们的方案我们就能够对Shadow Map进行mipmapping和filtering,甚至还可以进行blur。所以这样的方法就能够很好的产生柔和的阴影(如图1中的VSM)。原理部分请参考原始论文和NVIDIA的一篇简述(参考文献[4])。

      VSM的大致步骤如下所示:

      1.创建一个双通道及以上的的RenderTarget(我的Demo为了简单,直接使用的是RGBA四通道的贴图)。VSM对精度要求比较高,所以RenderTarget需要fp16或者fp32的精度(我用的是fp32)。接下来就和SSM一样,从灯光的视角来渲染场景,然后保存两个不同的值:depth,depth*depth。注意depth需要归一化到[0,1]的范围来保持精度。

      2.对产生的Shadow Map进行Blur操作,完毕之后再产生Mipmap链。

      3.在进行阴影计算的时候,根据Shadow Map中存放的depth和depth*depth,使用硬件提供的mipmapping和filtering,自动的计算出一阶动差(平均值)M1和二阶动差M2。

      4.根据当前像素在光源空间中的深度与M1进行比较,如果当前光源深度小于M1,就表示当前像素不在阴影中。

      5.反之,就在阴影里面。那么根据如下几个公式,求出当前像素的覆盖率(percentage):

      $pmax = \frac{\sigma^2}{\sigma^2 + (t - M_1)^2}(t为当前像素深度)$

      $\sigma^2 = M_2 - M_1^2$

      6.然后使用pmax来绘制阴影。

     

    代码

      本文的Demo项目可在这里找到,这里不在给出详细的代码。

      以下是模型绘制阴影时的Shader(sceneGrassSD.vs和glb_sceneGrassVSMSD.fs):

    #version 330
    
    in vec3 glb_attr_Pos;
    in vec3 glb_attr_Normal;
    in vec2 glb_attr_TexCoord;
    
    uniform mat4 glb_unif_ShadowM;
    uniform mat4 glb_unif_WorldM;
    uniform mat4 glb_unif_Trans_Inv_WorldM;
    
    out vec3 vs_Vertex;
    out vec3 vs_Normal;
    out vec2 vs_TexCoord;
    
    uniform float glb_unif_Timer;
    uniform float glb_unif_WindPower;
    uniform float glb_unif_WindSpeed;
    uniform vec3 glb_unif_WindDir;
    uniform float glb_unif_HeightPower;
    
    vec3 calc_wind_animation(vec2 uv, vec3 pos) {
        float height = pow(uv.y, glb_unif_HeightPower);
        float offset = height * glb_unif_WindPower * sin(uv.y * glb_unif_WindSpeed + glb_unif_WindSpeed * glb_unif_Timer);
        return pos + glb_unif_WindDir * offset;
    }
    
    void main() {
    	mat4 shadowM = glb_unif_ShadowM;
    
        vec3 pos = calc_wind_animation(glb_attr_TexCoord, glb_attr_Pos);
    	gl_Position = shadowM * glb_unif_WorldM * vec4(pos, 1.0);
    	vs_Vertex = vec3(gl_Position.xyz) / gl_Position.w;
    	//vs_Normal = (glb_unif_Trans_Inv_WorldM * vec4(glb_attr_Normal, 0.0)).xyz;
    	vs_Normal = vec3(0.0, 1.0, 0.0);
    	vs_TexCoord = glb_attr_TexCoord;
    }
    
    #version 330
    
    // Input attributes
    in vec3 vs_Vertex;
    in vec3 vs_Normal;
    in vec2 vs_TexCoord;
    
    out vec3 oColor;
    
    // Uniform
    uniform vec3 glb_unif_ParallelLight_Dir;
    
    // Constant value
    uniform float glb_unif_MinOffset;
    uniform float glb_unif_MaxOffset;
    
    uniform sampler2D glb_unif_MaskMap;
    
    void main() {
    	vec4 mask = texture(glb_unif_MaskMap, vs_TexCoord, 0);
    	if (mask.w < 0.5 || vs_TexCoord.y > 0.9) discard;
    
    	float depth = vs_Vertex.z;
    	depth = depth + 1.0;
    	depth = depth / 2.0;
    
    	oColor = vec3(depth, depth * depth, 0.0);
    }
    

      

      以下是进行阴影计算时的Shader(floorL.vs和glb_floorVSML.fs):

    #version 330
    
    // Input attributes
    layout (location = 0) in vec3 glb_attr_Pos;
    layout (location = 2) in vec3 glb_attr_Normal;
    layout (location = 3) in vec3 glb_attr_Tangent;
    layout (location = 4) in vec3 glb_attr_Binormal;
    layout (location = 5) in vec2 glb_attr_TexCoord;
    layout (location = 6) in vec2 glb_attr_LightMapTexCoord;
    
    // Output attributes
    out vec4 vs_Vertex;
    out vec3 vs_Normal;
    out vec3 vs_Tangent;
    out vec3 vs_Binormal;
    out vec2 vs_TexCoord;
    out vec2 vs_SecondTexCoord;
    
    uniform mat4 glb_unif_ProjM;
    uniform mat4 glb_unif_ViewM;
    
    uniform mat4 glb_unif_WorldM;
    uniform mat4 glb_unif_Trans_Inv_WorldM;
    
    void main() {
    	gl_Position = glb_unif_ProjM * glb_unif_ViewM * glb_unif_WorldM * vec4(glb_attr_Pos, 1.0);
    	vs_Vertex = (glb_unif_WorldM * vec4(glb_attr_Pos, 1.0));
    
        vs_Normal = (glb_unif_Trans_Inv_WorldM * vec4(glb_attr_Normal, 0.0)).xyz;
        vs_Tangent = (glb_unif_Trans_Inv_WorldM * vec4(glb_attr_Tangent, 0.0)).xyz;
        vs_Binormal = (glb_unif_Trans_Inv_WorldM * vec4(glb_attr_Binormal, 0.0)).xyz;
    
    	vs_TexCoord = glb_attr_TexCoord;
        vs_SecondTexCoord = glb_attr_LightMapTexCoord;
    }
    
    #version 450
    
    // Input attributes
    in vec4 vs_Vertex;
    in vec3 vs_Normal;
    in vec3 vs_Tangent;
    in vec3 vs_Binormal;
    in vec2 vs_TexCoord;
    in vec2 vs_SecondTexCoord;
    
    // Output color
    out vec4 oColor;
    
    // Uniform
    uniform vec3 glb_unif_Albedo;
    uniform float glb_unif_Roughness;
    uniform float glb_unif_Metallic;
    uniform samplerCube glb_unif_DiffusePFC;
    uniform samplerCube glb_unif_SpecularPFC;
    uniform sampler2D glb_unif_AOMap;
    uniform mat4 glb_unif_ShadowM;
    uniform sampler2D glb_unif_ShadowMap;
    
    vec3 calc_view() {
    	vec3 view = vec3(0.0, 0.0, 0.0);
    	view = normalize(glb_unif_EyePos - vs_Vertex.xyz);
    	return view;
    }
    
    vec3 calc_light_dir() {
    	vec3 light_dir = vec3(0.0, 0.0, 0.0);
    	light_dir = -glb_unif_ParallelLight_Dir;
    	return light_dir;
    }
    
    vec3 calc_direct_light_color() {
    	vec3 light = vec3(0.0, 0.0, 0.0);
    	light = light + glb_unif_ParallelLight;
    
    	return light;
    }
    
    float calculateVSMShadowFactor(vec3 pos, vec3 eyePos, vec3 lookAt, mat4 shadowM, sampler2D shadowMap) {
    	float shadowFactor = 1.0;
    
    	vec4 lightSpacePos = shadowM * vec4(pos, 1.0);
    	lightSpacePos.xyz /= lightSpacePos.w;
    	lightSpacePos.xyz /= 2.0;
    	lightSpacePos.xyz += 0.5;
    
    	if (lightSpacePos.x < 0.0 || 
    		lightSpacePos.x > 1.0 ||
    		lightSpacePos.y < 0.0 ||
    		lightSpacePos.y > 1.0) {
    		// Out of shadow
    		shadowFactor = 1.0;
    	} else {
    		vec2 shadowMoments = texture(shadowMap, lightSpacePos.xy).xy;
    		if (lightSpacePos.z < shadowMoments.x) {
    			// Out of shadow
    			shadowFactor = 1.0;
    		} else {
    			float variance = shadowMoments.y - shadowMoments.x * shadowMoments.x;
    			float pmax = variance / (variance + pow(lightSpacePos.z - shadowMoments.x, 2.0));
    			shadowFactor = pmax;
    		}
    	}
    
    	return shadowFactor;
    }
    
    void main() {
    	oColor = vec4(0.0, 0.0, 0.0, 0.0);
    
    	vec3 normalInWorld = vec3(0.0, 0.0, 0.0);
    	vec3 normalInTangent = vec3(0.0, 0.0, 0.0);
        normalInWorld = normalize(vs_Normal);
    
    	vec3 view = calc_view();
    
    	vec3 light = calc_light_dir();
    
    	vec3 h = normalize(view + light);
    
    	vec3 albedo = glb_unif_Albedo;
    	float roughness = glb_unif_Roughness;
    	float metallic = glb_unif_Metallic;
    	vec3 emission = vec3(0.0, 0.0, 0.0);
    	float ao = 1.0;
    
    	vec3 direct_light_color = calc_direct_light_color();
    
    	vec3 direct_color = glbCalculateDirectLightColor(normalInWorld, view, light, h, albedo, roughness, metallic, direct_light_color);
    
    	float shadow_factor = calculateVSMShadowFactor(vs_Vertex.xyz, glb_unif_EyePos, glb_unif_LookAt, glb_unif_ShadowM, glb_unif_ShadowMap);
    
    	oColor.xyz = (direct_color * ao) * shadow_factor + glb_unif_GlobalLight_Ambient * albedo * ao;
    
    	float alpha = 1.0;
    	oColor.w = alpha;
    }

     

    总结

      上面给出了如何实现一个VSM,相对于SSM和PCF,它的效率要差点,但是效果会好很多。除了这个好处之外,我们知道SSM有Shadow Bias的问题,使用VSM可以完全避免掉这个问题。当然VSM也有它自己的缺点,比如精度要求高,容易出现light bleeding等等。除了VSM之外,还有其他的Shadow Map技术,也能够支持对Shadow Map进行Filtering和Blur(如ESM)。这里有一篇文章(参考文献[5])对比了各个算法的优缺点,大家可以参考下。

     

    参考文献

    [1] Tutorial 16: Shadow mapping

    [2] GPU Gems 1 Chapter 11: Shadow map antialiasing

    [3] Variance Shadow map

    [4] Nvidia-Variance Shadow Mapping

    [5] 切换到ESM-KlayGE游戏引擎

    转载于:https://www.cnblogs.com/idovelemon/p/10988985.html

    展开全文
  • Specifically, the gaussian random fields had asymmetric variance when the X and Y dimensions were not symmetrical. This led to rippling type pattern in the gaussian fields. Fixed by upsampling the ...
  • Rewrite throwing

    2021-01-12 00:39:36
    * Volume effects on dispersion rewritten to include the milliliter volume stat * Dodgy critters prevent proper aiming, increasing dispersion when aiming at them * Point-blank and 1 distance throws ...
  • Welford in 1962 and described by Donald Knuth in Art of Computer Programming, Volume 2: Seminumerical Algorithms. (You can also check ...
  • <p>Based on these results, we chose a 2% threshold (∼20–30 voxels per slice) as a reasonable empirical threshold that effectively identified voxels with the highest fractional variance of ...
  • What I mean is storing the mean volume, number of data points, as well as the variance and just updating it depending on the day? This will probably decrease runtime to less than a few seconds. I can...
  • refactor and implement for <code>add_volume</code> as well (<code>add_volume</code> doesn't currently support RGBA plotting - this will come later)</li><li>[x] add examples!</li></ul>该提问来源于...
  • Expected Values and Variance The Monte Carlo Estimator Sampling Random Variables The Inversion Method Example: Power Distribution Example: Exponential Distribution Example: Piecewise-Constant 1D...
  • { MKLDNN_ARG_VARIANCE, variance_memory}, { MKLDNN_ARG_WEIGHTS, weights_memory}}; rand_fill(src_layer.data(), src_layer_md.get_size()); //Warmup (*bn_fwd).execute(s, args_fwd); bench_result ...
  • 11.5.1 Variance 193 11.5.2 Standard deviation 196 CONTENTS 9 11.6 Sampling distribution of the mean 198 11.6.1 Standard error of the mean 199 11.7 Confidence levels and the t-distribution 200 Summary...
  • Source Sampling Improvements

    2020-12-09 02:49:28
    If a particle is sampled in void, it is now resampled within the selected mesh volume element until non-void is encountered or a user-specified limit is met. Before, it would resample the full ...
  • 110, WM_VARIANCE=5 WM_MIN=110, WM_HALF_MIN=110, WM_HALF_MAX=110, WM_MAX=110 preflooding height equal to 15 percent done. Analyze... main basin size= 1602755 voxels, voxel ...
  • s time series over time (instead of each volume's values over components).</li></ul> </li></ol> </li><li>Compute un-normalized weights for each component for <em>demeaned</em> optimally combined ...
  • <div><p>We hope to use <code>wasmi</code> to implement a policy engine for low-volume packet inspection in an embedded setting. Initial CPU profiles using toy policies showed almost 40% CPU time spent...
  • Nov 27 17:36:08 raspberrypi pulseaudio[1014]: [pulseaudio] alsa-mixer.c: Volume element Nov 27 17:36:08 raspberrypi pulseaudio[1014]: [pulseaudio] alsa-mixer.c: Volume element Nov 27 17:36:08 ...
  • LED tutorial

    2021-01-02 17:03:38
    ll need lots of simulations (and/or a long time) to get the spectrum to good accuracy (low variance). </li><li> <p>Better: since the dipoles are uncorrelated, we can just do a sequence of ...
  • A random item has 10 active buy offers between 11m-12m and 5 sell offers at 14m-14.5m you should expect it around a price of 13m with enough variance to not give away exact offers.) 2) Similar to ...
  • OpenGL development cookbook

    2018-08-31 11:29:20
    In addition, shadow mapping techniques are also covered including support of percentage closer filtering (PCF) and variance shadow mapping. In typical applications, more complex mesh models are used...
  • As an indication, it can be noted that this volume of variance is equivalent to 10% of the demand for silver and 1% of the demand for gold. <p>Its low exposure makes it an asset as strong as it is ...
  • It uses the distance sensor measurements and the pose and covariance of the robot to generate an elevation map with variance estimates. Subscribed Topics /points (sensor_msgs/PointCloud2) The ...
  • 'volume': np.random.random(100) } Functions can either be imported directly or instantiated by name: from talib import abstract # directly SMA = abstract.SMA # or by name SMA = abstract.Function('...
  • Plotting volume-series data Calculating the simple daily percentage change in closing price Calculating simple daily cumulative returns of a stock Resampling data from daily to monthly returns ...
  • 110, WM_VARIANCE=0 WM_MIN=109, WM_HALF_MIN=109, WM_HALF_MAX=110, WM_MAX=110 preflooding height equal to 25 percent done. Analyze... main basin size= 2220668 voxels, voxel ...
  • (python:8446): GVFS-RemoteVolumeMonitor-WARNING **: cannot open directory /usr/share/gvfs/remote-volume-monitors: Error opening directory '/usr/share/gvfs/remote-volume-monitors': No such file...
  • Robust Statistics

    热门讨论 2009-03-28 18:05:17
    6.4.1 The minimum volume ellipsoid estimate 187 6.4.2 S-estimates 188 6.4.3 The minimum covariance determinant estimate 189 6.4.4 S-estimates for high dimension 190 6.4.5 One-step reweighting 193 6.5 ...
  • <p>The variance in failure includes on Heroku where AFAIK the starting state is always identical (I don't think their cache is updated unless a push succeeds). <p>Here is one example of a failure:...
  • Volumetric shadows in the fog use Variance Shadow Maps. VSM allows for pre-blurring the shadowmap for very soft shadows with wide penumbra for the cost of just one shadow sample at the stage of ...

空空如也

空空如也

1 2
收藏数 36
精华内容 14
关键字:

variancevolume