XDGE_RayMarchine 1- 利用Frag Shader绘制图形

Render/RayMarchine/Base 1- 利用Frag绘制图形

@author: 白袍小道-胡言乱语

@Read: 转载说明

前言

1、RayMarching

*光线行进**,从摄像机向屏幕上的每一个像素发射一条光线,光线按照一定步长前进,检测当前光线距离物体表面的距离,并且根据这个距离调整光线的步长,直到抵达物体表面。

2、Frag绘制图形

在片段着色阶段去执行,这里注意一下

//1、片段后还有光栅,光栅的采样会有可能导致1-N 星盘
//2、片段还有机会可以改变SV_Depth

正文

这里强调一下RayMarching,更加关注的如何利用这个原理。是否从屏幕上每个Pixel出发,还是看需求。

RayMarching可以参考:

https://iquilezles.org/www/articles/distfunctions/distfunctions.htm

https://zhuanlan.zhihu.com/p/90245545

目的

获取是否相交,相交的信息,我们就可以对该片元处理

Frag绘制图形

除了纹理和顶点描述,我们还可以有一种手段去做一些简单的图形。

这种手段基础:利用顶点到着色着色进行了线性的插值,然后在片元着色中,我们可以利用这些信息(如UV或者Proj, 坐标转到屏幕坐标),按照图形(求交)搞事情(非标准语言)。

image-20200917165304417

绘制图形

这里因为是测试案例,直接作为特殊后期屏幕Quad绘制。

(偷懒一下,直接作为PostProcess阶段前插入一个RayMachineRCMD来执行。其中RCMD为XDGameEngine封装的一个,Quad为屏幕Mesh)

XDGameEngine_GraphicsUtility.BlitSRT(pPostContext.PostRenderCMD, pPostContext.SrcColorBuffer,BuiltinRenderTextureType.CameraTarget,_EffectMat,0);

其中BlitSRT就是一个向目标(这里由于不需要做DownSample什么的,就直接用了Context内置)绘制,

  public void BlitSRT(CommandBuffer buffer, XDGTexture source, XDGRenderTargetIdentifier destination,
            Material mat, int pass)
        {
            //buffer.SetGlobalTexture(XDGameEngine_GraphicsShaderID._MainTex, source);
            mat.SetTexture(XDGameEngine_GraphicsShaderID._MainTex, source);
            buffer.SetRenderTarget(destination);
            buffer.DrawMesh(mesh, Matrix4x4.identity, mat, 0, pass);
        }

image-20200917174039608

备注:(直接用SV_Target,也可以自己包一个Struct包含SVDepth 后续来做脑洞)

求交

基础求交

直线包含公式:两点之间

float4 XD_Ray_Line2D(float2 pos, float2 point1, float2 point2, float width, float3 color, float antialias)
{
    float k = (point1.y - point2.y)/(point1.x - point2.x);
    float b = point1.y - k * point1.x;
                    
    float d = abs(k * pos.x - pos.y + b) / sqrt(k * k + 1);
    float t = smoothstep(width/2.0, width/2.0 + antialias, d);
    return float4(color, 1.0 - t);                
}

圆形包含公式:距离圆心和半径

float4 XD_Ray_circle(float2 pos, float2 center, float radius, float3 color, float antialias)
{
    float d = length(pos - center) - radius;
    float t = smoothstep(0, antialias, d);
    return float4(color, 1.0 - t);
}

三角形包含公式:三个DOT

float4 XD_Ray_Triangle(float2 p, float2 Pos1, float2 Pos2, float2 Pos3,float3 color)
{
    float2 AB = Pos2-Pos1;
    float2 BC = Pos3-Pos2;
    float2 CA = Pos1-Pos3;
    
    float2 AP = p - Pos1;
    float2 BP = p - Pos2;
    float2 CP = p - Pos3;
    
   float3 cPAB = cross(float3(AP,.0),float3(AB,.0));
    float3 cCAB = cross(float3(-CA,.0),float3(AB,.0));
    bool bPA = dot(cPAB, cCAB) >= .0;
    

    float3 cPAC = cross(float3(CP,.0), float3(CA,.0));
    float3 cBAC = cross(float3(-BC,.0), float3(CA,.0));
    bool bPC = dot(cPAC, cBAC) >= .0;
    
    float3 cPBC = cross(float3(BP,.0), float3(BC,.0));
    float3 cABC = cross(float3(-AB,.0), float3(BC,.0));
    bool bPB = dot(cPBC, cABC) >= .0;
    
    float t = bPC && bPB && bPA? 1:0;
    return float4(color, t); 
}

点和多边形求交

不只是这里有用,这里就不做展开。在Render/Acc(加速),和Render/Math部分会说明。

1、面积和判断

2、奇偶

射线法不仅仅适用于规则的矩形,也适用于多边形。

img

沿着点做多条射线,那么每条射线就会与多边形产生n个交点(0个交点也算)。若某一条射线产生奇数个交点,那么就认定点在多边形范围内。

3、转角累加法

多边形和多边形

1、分离轴定理

凸多边形的碰撞判断方式

2、凹多边形处理

把凹多边形进行分割,拆成凸多边形

3、基于四叉树

https://zhuanlan.zhihu.com/p/83722268)

步进和二分

留作后续继续

人生当苦,笑着看看
原文地址:https://www.cnblogs.com/BaiPao-XD/p/13686608.html