Article

Published 3 months ago
41
0

3D引擎如在处理几何的时候一般都是使用三角面。所有物体，都是由基础三角形构成的。也有物体不能由三角形构成，那就是体积渲染，利用光线追踪技术，然后使用几何公式来绘制图形。本文将从最简单的体积渲染例子开始体积渲染之旅。

struct v2f {
float4 pos : SV_POSITION;	// Clip space
float3 wPos : TEXCOORD1;	// World position
};

// Vertex function
v2f vert (appdata_full v)
{
v2f o;
o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
o.wPos = mul(_Object2World, v.vertex).xyz;
return o;
}

// Fragment function
fixed4 frag (v2f i) : SV_Target
{
float3 worldPosition = i.wPos;
float3 viewDirection = normalize(i.wPos - _WorldSpaceCameraPos);
return raymarch (worldPosition, viewDirection);
}

fixed4 raymarch (float3 position, float3 direction)
{
for (int i = 0; i < STEPS; i++)
{
if ( sphereHit(position) )
return fixed4(1,0,0,1); // Red

position += direction * STEP_SIZE;
}

return fixed4(0,0,0,1); // White
}

//几何形状函数
bool sphereHit (float3 p)
{
//unity_ObjectToWorld._14_24_34 为物体的中心点
}

Shader "Raymarch/VolumetricRendering1"{
Properties{
}
Tags { "RenderType"="Opaque" }
LOD 100

Pass{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"

#define STEPS 128
#define STEP_SIZE 0.01

struct appdata{
float4 vertex : POSITION;
};

struct v2f{
float4 vertex : SV_POSITION;
float3 wPos : TEXCOORD0;
};

v2f vert (appdata v){
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.wPos = mul(unity_ObjectToWorld, v.vertex).xyz;
return o;
}

bool sphereHit (float3 p){
}

fixed4 raymarch (float3 position, float3 direction){
for (int i = 0; i < STEPS; i++){
if(sphereHit(position))  return return fixed4(1,0,0,1);
position += direction * STEP_SIZE;
}
return fixed4(0,0,0,1);
}

fixed4 frag (v2f i) : SV_Target{
float3 worldPosition = i.wPos;
float3 viewDirection = normalize(worldPosition - _WorldSpaceCameraPos);
return raymarch (worldPosition, viewDirection);
}
ENDCG
}
}
}



1