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

    人生当苦,笑着看看
  • 相关阅读:
    31天重构学习笔记18. 使用条件判断代替异常
    31天重构学习笔记12. 分解依赖
    31天重构学习笔记2. 移动方法
    .NET 技术社区谈之中文篇
    31天重构学习笔记10. 提取方法
    31天重构学习笔记14. 分离职责
    31天重构学习笔记20. 提取子类
    31天重构学习笔记16. 封装条件
    31天重构学习笔记17. 提取父类
    .NET 技术社区谈之英文篇
  • 原文地址:https://www.cnblogs.com/BaiPao-XD/p/13899522.html
Copyright © 2011-2022 走看看