• 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)

    步进和二分

    留作后续继续

    人生当苦,笑着看看
  • 相关阅读:
    Tomcat性能优化总结
    shell 服务器监控 cpu 和 java 占用 CPU 脚本
    编写shell时,遇到let: not found错误及解决办法
    Studio 3T 破解 mogodb
    nginx/iptables动态IP黑白名单实现方案
    创业公司这两年
    致所有的开发者们
    如何成为一名全栈开发工程师
    谈谈在创业公司的几点感触
    推荐阅读《赢在下班后》
  • 原文地址:https://www.cnblogs.com/BaiPao-XD/p/13686608.html
Copyright © 2020-2023  润新知