canvas+webgl实现三维神庙教堂内效果代码

代码语言:html

所属分类:三维

代码描述:canvas+webgl实现三维神庙教堂内效果代码

代码标签: canvas webgl 三维 神庙 教堂

下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开

<!DOCTYPE html>
<html lang="en" >

<head>
  <meta charset="UTF-8">
  


  
  
<style>
body { margin: 0; overflow: hidden; }
</style>


  
</head>

<body translate="no">
  <canvas id="myCanvas"></canvas>
  
      <script >
const canvas = document.getElementById('myCanvas');
const gl = canvas.getContext('webgl2');

const vertexShaderSource = `#version 300 es

in vec2 a_position;

void main() {
    gl_Position = vec4(a_position, 0.0, 1.0);
}
`;

const fragmentShaderSource = `#version 300 es

precision highp float;

uniform vec2 iResolution; // Declare as vec2 (canvas width and height)
uniform vec2 iMouse;
uniform float iTime;

out vec4 fragColor;

// Shadertoy code here

#define PI 3.14159265359
#define RES iResolution
#define PT iMouse
#define smin smoothmin
#define smax smoothmax

float d0 = 120.;

// Signed distance function for a plane
float sdPlane(vec3 p, vec3 n, float h) {
  return dot(p, n) + h;
}

float sdCylinder(vec3 p, in float r, in float h, in int hAxis) {
  vec2 aR, aH;

  if (hAxis == 0) { // x-axis
    aR = p.yz, aH = vec2(p.x, 0.0);
  } else if (hAxis == 1) { // y-axis
    aR = p.xz, aH = vec2(p.y, 0.0);
  } else { // z-axis
    aR = p.xy, aH = vec2(p.z, 0.0);
  }

  vec2 d = vec2(length(aR) - r, abs(aH.x) - h / 2.0);

  // Return the distance to the cylinder
  return min(max(d.x, d.y), 0.0) + length(max(d, 0.0));
}

float sdCuboid(vec3 p, vec2 a, float h) {
  vec3 d = abs(p) - vec3(a.x, h, a.y);
  return length(max(d, 0.0)) + min(max(d.x, max(d.y, d.z)), 0.0);
}

float sdSphere(vec3 p, float r) {
  return length(p) - r;
}

float smoothmin(float d1, float d2, float k) {
  float h = max(k - abs(d1 - d2), 0.) / k;
  return min(d1, d2) - h * h * k * (1. / 4.);
}

float smoothmax(float d1, float d2, float k) {
    float h = max(k - abs(d1 - d2), 0.) / k;
    return max(d1, d2) + h * h * k * (1. / 4.);
}

float noise(vec2 p) {
  float random = dot(p,vec2(12.235,78.37283));
  random = sin(random);
  random *= 4358.4346;
  random += fract(iTime);
  random = fract(random);
  return 1.5 - random*4.5;
}

int partID = 1; // identifier for surfaces to apply specific color to

float map(vec3 p) {

  float m = 5.; // mod width
  vec3 p0 = p; // pre-mod state

  float ceilY = 8.; // ceiling,
  p.y-=ceilY;
  float ceiling = -p.y;

  p = p0; // reset to pre-mod base

  p.xz = mod(p.xz - m,2.*m) - m;
  
  vec3 p1 = p; // baseline for mods placed at the center of the columns (with mods in place)

  float column = sdCylinder(p, .5, 9., 1); // the round columns

  float flutes = 1.;
  float fTimes = 24.;

  for (float i = 0.; i < fTimes; i++) {
    float fAngle = 2.*PI/fTimes*i;
    p.z+= .5*cos(fAngle);
    p.x+= .5*sin(fAngle);
    float f = sdCylinder(p, 0., 7.7, 1) - .04;
    
    flutes = min(flutes, f);
    p = p1; // reset to column baseline (with mods applied)
  }

  column = max(column,-flutes); // round column with etched flutes

  p.y+=4.05;
  float cRing = sdCylinder(p, .5, 0., 1) - .05;
  column = min(column, cRing); // column with added ring around its circumference at the bottom

  float bA = .5;
  float bR = .15;
  float baseH = 2.;
  p.y += baseH + 2.*bR;
  vec2 a = vec2(.5);
  float base = sdCuboid(p, a, baseH) - bR; // tall cuboid base for the round column

  float bd = bA+bR;
  p.xz+=bd;
  float bFlutes = 1.;

  for (float i=0.;i<4.;i++) {
    if (i == 1.) { p.x -=2.*bd; }
    else if (i == 2.) { p.z -=2.*bd; }
    else if (i == 3.) { p.x +=2.*bd; }

    float bF = sdCuboid(p,vec2(0.),3.) - .35;
    bFlutes = min(bFlutes, bF);

  }

  p = p1;
  base = max(-bFlutes, base); // cuboid base with round flutes running down each vertical edge

  p.y+=6.5;
  float antiBev = sdCuboid(p,vec2(.55),2.2);
  base = min(base, antiBev); // an extra cuboid sticking out of the flutes

  column = smin(column,base, bR); // column is smoothly melted into the base

  float floor = sdPlane(p, vec3(0.0, 1.0, 0.0), 2.2); // blank floor

  float tiles = floor; // extra surface identical to the floor that colorful patterms will be cut out of 

  float pattern1 = min( // said pattern
                    min(max(length(p.xz) - m - .125, 1. - length(p.xz) + m*2./3.),
                    min(
                      mix(abs(p.x),abs(p.z),.5) - m/3.5,
                      max(abs(p.x),abs(p.z)) - m/2.5
                      )
                    ),
                    -max(
                      mix(abs(p.x), abs(p.z),.25),
                      mix(abs(p.x), abs(p.z),.75)
                    ) + 4.6
                   );

  tiles = max(tiles, pattern1); // the pattern is cut out

  p = p1; // reset to column baseline

  p.y-=6.2;

  float cBase = sdCuboid(p, a, baseH+10.); // a cuboid at the top of the cylindrical column, similar to the one forming the base

  p.y+=1.3;

  p.y-=21.;
  p.y/=25.;

  float r = 1.;
  float ovoid = sdSphere(p, r);
  
  cBase = max(cBase,ovoid); // an ellyptical spheroid is cut out of the cuboid

  p = p1;

  p.y-=4.;

  float cRing2 = sdCylinder(p, .5, 0., 1) - .05; // another ring around the column's circumference is added at its top
  cBase = min(cBase,cRing2); // the ring is m.........完整代码请登录后点击上方下载按钮下载查看

网友评论0