zoukankan      html  css  js  c++  java
  • Simple Shadow Mapping

      Simple Shadow Mapping 最基本的SM。之前曾经被坑过,后来发现其实原理并不麻烦。就是 绘制深度图 加上 投影纹理映射 以及简单的比较就行了。

      首先要获得深度图·其实要怎么获取·获取什么样的值(W-BUF或者Z-BUF)并没有太重要的关系·只要能有一张把光源当做摄像机所绘制出的深度图并保证比较时是一致的应该就可以了·

    下面是简易的HLSL:

    #pragma pack_matrix( row_major )
    
    cbuffer Transforms{
    	float4x4 cb_WVP;
    };
    
    struct VS_TO_PS{
    	float4 Pos : SV_POSITION;
    	float2 Depth : TEXCOORD0;
    };
    
    VS_TO_PS vs_main(float3 i_Pos : POSITION){
    	VS_TO_PS Out = (VS_TO_PS)0;
    	Out.Pos = mul( float4(i_Pos, 1.0f), cb_WVP );
    	Out.Depth.xy = Out.Pos.zw;
    	return Out;
    }
    
    float4 ps_main( VS_TO_PS i_n ) : SV_Target0{
    	return i_n.Depth.x / i_n.Depth.y;
    }
    

     这里用这样的就够了·

    #pragma pack_matrix( row_major )
    
    cbuffer Transforms{
    	float4x4 cb_WVP;
    	float4x4 cb_LightWVP;
    };
    
    struct VS_TO_PS{
    	float4 Pos 	: SV_POSITION;
    	float4 LightPos	: TEXCOORD0;
    };
    
    VS_TO_PS vs_main( float3 i_Pos : POSITION ){
    	VS_TO_PS Out = (VS_TO_PS)0;
    	
    	Out.Pos = mul( float4( i_Pos, 1.f ), cb_WVP );
    	Out.LightPos = mul( float4( i_Pos, 1.f ), cb_LightWVP );
    	
    	return Out;
    }
    
    Texture2D DepthMap;
    SamplerState DepthMapSampler;
    
    static const float s_Offset = 0.00005f;
    static const float4 s_ShadowColor = float4(0.f, 0.f, 0.f, 0.5f);
    static const float4 s_OutColor = float4(0.f, 0.f, 0.f, 0.f);
    
    float4 ps_main( VS_TO_PS i_n ) : SV_Target0{
    	float3 t_ProjPos = i_n.LightPos.xyz / i_n.LightPos.w;
    
    	t_ProjPos.x = +0.5 * t_ProjPos.x + 0.5f;
    	t_ProjPos.y = -0.5 * t_ProjPos.y + 0.5f;
    
    	float t_DepthMap = DepthMap.Sample( DepthMapSampler, t_ProjPos.xy ).r;
    
    	float t_DepthScene = t_ProjPos.z - s_Offset;
    	float4 t_OutColor = t_DepthMap >= t_DepthScene ? s_OutColor : s_ShadowColor;
    	return t_OutColor;
    }
    

     没什么特别的地方·只是把当前的位置变换到DepthMap的切线空间后与对应的值进行比较就可以了·

    另外这里是用减去Offset值来处理Z-FIGHTING的问题·

    不然就会这样·

  • 相关阅读:
    Linux内核的总结认识
    服务器的基本问题避免
    Linux中多线程信号的处理
    gdb调试
    TCP数据包的封包和拆包
    网络TCp数据的传输设计(黏包处理)
    InputArray和OutputArray
    UTF8转unicode说明
    C++使用标准库的栈和队列
    resize函数有五种插值算法
  • 原文地址:https://www.cnblogs.com/macom/p/3397769.html
Copyright © 2011-2022 走看看