zoukankan      html  css  js  c++  java
  • XDRender_Volumn_ImageRenderPass RayMarchine -1

    XDRender_Volumn_ImageRenderPass RayMarchine -1

    @Author:白袍小道

    image-20201029213311219

    image-20201029214051110

    前言


    作为体积渲染,RayMachine是一种不错的选择,这里我们先用RayMachine来画一个球.

    这里实现是作为ImageRenderPass的可选项

    正文

    理论


    后续补上来

    RayMachine定义

    RayMarching:光线行进,从摄像机向屏幕上的每一个像素发射一条光线,光线按照一定步长前进,检测当前光线距离物体表面的距离(这里我们可以定义为距离形状函数或者有向距离场SDF),并且根据这个距离调整光线的步长,直到抵达物体表面.同时搞事情(填充部分)

    RayMachine特性

    不错的原因是由于可以处理一些

    1、对于形状不固定,且比较离散

    2、由于是动态计算出的形状,你可以理解为矢量边缘.

    3、利用步进函数来确定形状或者结合其他

    RayMachine的基础步骤

    略:后面再补上

    实现


    1、确定处理阶段(Pass)

    这里我是放在ImageRenderPass的FeaturePass部分, 因为不想和后处理冲突.且按照定义,作为基于图像的绘制. 毕竟Raymarchine的主实现还是像画家一样去描绘.

    2、加入到对应的节点

    3、加入对应的HLSL, 代码、Shader

    顶点着色

    XDArt_ImageRender.hlsl

    ImageRender_Varyings ImageRenderPassVert(appdata v)
    {
        ImageRender_Varyings o;
        float4 clipVec = UnityObjectToClipPos(v.vertex);
        o.vertex = clipVec;
        float3 viewPosition = mul(unity_CameraInvProjection, clipVec.xyzz).xyz;
        // 这里深度为0
        // float depth = UNITY_SAMPLE_DEPTH(tex2Dproj(_CameraDepthTexture, i.screenPos));
        // float3 viewPos = viewPosition * Linear01Depth(depth);
        float3 worldPos = mul(UNITY_MATRIX_I_V, float4(viewPosition, 1.0)).xyz;
        o.worldPos = worldPos;
        o.uv = v.uv;
        return o;
    }
    
    片段

    其中

    mainColor + raymarch (_WorldSpaceCameraPos.xyz,viewDirection,lightDirection);是为了叠加原来的处理结果. 故而主函数判断若不在范围范围0.0

    float4 fragRay (ImageRender_Varyings i ) : SV_TARGET
            {
                half4 mainColor = tex2D (_MainTex, i.uv);
                float3 worldPosition = i.worldPos;
                float3 viewDirection = normalize(i.worldPos - _WorldSpaceCameraPos.xyz);
                float3 lightDirection = normalize(UnityWorldSpaceLightDir(i.worldPos).xyz);
                return mainColor + raymarch (_WorldSpaceCameraPos.xyz,viewDirection,lightDirection);
            }
    
    主函数
    float4 raymarch (float3 rayOrigin, float3 rayDirection,float3 lightDir)
            {
                for (int i=0; i<256; i++)
                {
                    float ray = DistanceFunction(rayOrigin);
                    if(_Limit != 0)
                    {
                        if (distance(rayOrigin,ray*rayDirection)>250) 
                        break;
                    }
                    if (ray < _MinDistance) 
                    return float4 (lighting(rayOrigin,lightDir,rayDirection),1.0); 
                    else 
                    rayOrigin+=ray*rayDirection; 
                }
                return float4 (0.0,0.0,0.0,0.0);
            }
    
    形状函数--有向距离场SDF
    ///
            //距离函数-用来确定形状
            ///
            float DistanceFunction (float3 p)
            {
                return length(p)-_Radius;
            }
    
    光照(颜色处理)
    ///
            //光照函数-用来绘制
            ///
            float3 lighting (float3 rayOrigin,float3 lightDir,float3 viewDir)
            {
                return lerp(0.2,1.0,dot(lightDir,viewDir)) * _Color.xyz;
            }
    

    数据

    HLSLINCLUDE
    #include "Packages/com.xdgameengine.unity/EngineResource/ShaderLibrary/CoreExtends/XDArt_ImageRender.hlsl"
            float _Limit;
            float _MinDistance;
            float _Radius;
            float4 _Color;
    

    总结

    还没想好如何表达感慨, 但确实很好就对了

    备注

    1、参考大全:ShaderToy

    人生当苦,笑着看看
  • 相关阅读:
    web.py利用模板的详细步骤
    Arduino入门笔记(9):蓝牙模块及第一辆蓝牙遥控小车
    Python常用模块之sys
    使用Supervisor管理Linux进程
    Python socket聊天室程序
    Ubuntu 文件文件夹查看权限和设置权限
    python遍历目录
    linux tail命令的使用方法详解
    Python使用openpyxl读写excel文件
    python中enumerate()的用法
  • 原文地址:https://www.cnblogs.com/BaiPao-XD/p/13899522.html
Copyright © 2011-2022 走看看