-
-
Save mirichi/d1b4d8d706596a11cacf2c09242dc024 to your computer and use it in GitHub Desktop.
レイマーチングテスト
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'dxruby' | |
hlsl = <<EOS | |
float4x4 g_proj, g_view; | |
struct VS_INPUT // 頂点シェーダの入力フォーマット | |
{ | |
float4 vPosition : POSITION0; | |
float2 vTexCoord : TEXCOORD0; | |
}; | |
struct VS_OUTPUT // 頂点シェーダの出力フォーマット | |
{ | |
float4 vPosition : POSITION0; | |
float2 vTexCoord : TEXCOORD0; | |
}; | |
VS_OUTPUT VS(VS_INPUT v) // 頂点シェーダ | |
{ | |
VS_OUTPUT output; | |
output.vPosition = mul(mul(v.vPosition, g_view), g_proj); | |
output.vTexCoord = v.vTexCoord; | |
return output; | |
} | |
struct PS_INPUT | |
{ | |
float2 vTexCoord : TEXCOORD0; | |
}; | |
struct PS_OUTPUT | |
{ | |
float4 vColor : COLOR0; | |
}; | |
float3 mod(float3 a, float b) { return a-b*floor(a/b); } | |
float DistanceFunction(float3 pos) | |
{ | |
float c = 8.0; | |
return length(mod(pos, c) - 0.5 * c) - 1.0; | |
} | |
float3 getNormal(float3 p) | |
{ | |
float d = 0.0001; | |
return normalize(float3( DistanceFunction(p+float3(d,0.0,0.0))-DistanceFunction(p+float3(-d,0.0,0.0)), | |
DistanceFunction(p+float3(0.0,d,0.0))-DistanceFunction(p+float3(0.0,-d,0.0)), | |
DistanceFunction(p+float3(0.0,0.0,d))-DistanceFunction(p+float3(0.0,0.0,-d)))); | |
} | |
PS_OUTPUT PS(PS_INPUT p) | |
{ | |
PS_OUTPUT output; | |
float2 pos = (p.vTexCoord * 2.0 - 1.0) * float2(640.0 / 480.0, -1.0); | |
float3 light = float3(1, 1, -1); | |
float3 camPos = float3(0.0, 0.0, -3.0); | |
float3 camDir = float3(0.0, 0.0, 1.0); | |
float3 camUp = float3(0.0, 1.0, 0.0); | |
float3 camSide = cross(camUp, camDir); | |
float focus = 1.8; | |
float3 rayDir = normalize(camSide*pos.x + camUp*pos.y + camDir*focus); | |
float t = 0.0, d; | |
float3 posOnRay = camPos; | |
for(int i=0; i<32; ++i) | |
{ | |
d = DistanceFunction(posOnRay); | |
t += d; | |
posOnRay = camPos + t*rayDir; | |
} | |
if(abs(d) < 0.001) | |
{ | |
float3 normal = getNormal(posOnRay); | |
output.vColor = float4(float3(1,1,1) * max(dot(normal, light), 0.2),1); | |
} | |
else | |
{ | |
output.vColor = float4(0,0,0,0); | |
} | |
return output; | |
} | |
technique | |
{ | |
pass | |
{ | |
VertexShader = compile vs_3_0 VS(); | |
PixelShader = compile ps_3_0 PS(); | |
} | |
} | |
EOS | |
width = 640 | |
height = 480 | |
core = Shader::Core.new(hlsl, | |
g_view: :float, | |
g_proj: :float) | |
shader = Shader.new(core) | |
# 2D用ビュー行列 | |
shader.g_view = [ 1, 0, 0, 0, | |
0, -1, 0, 0, | |
0, 0, 1, 0, | |
-width/2, height/2, 0, 1] | |
# 2D用透視変換(?)行列 | |
shader.g_proj = [2.0 / width, 0, 0, 0, | |
0, 2.0 / height, 0, 0, | |
0, 0, 0, 0, | |
0, 0, 1, 1] | |
image = Image.new(640, 480) | |
Window.loop do | |
Window.draw_shader(0, 0, image, shader) | |
break if Input.key_push?(K_ESCAPE) | |
end | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment