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

posted @ 2020-10-29 21:59  白袍小道  阅读(98)  评论(0编辑  收藏  举报

白袍小道 DaoZhang_XDZ@163.com - 创建于 8012

窥探道理