Cube rendered
This commit is contained in:
parent
92603d8faf
commit
6d2a0e4d04
@ -6,42 +6,16 @@ import org.khronos.webgl.Float32Array
|
||||
import org.khronos.webgl.Int32Array
|
||||
import org.khronos.webgl.WebGLRenderingContext
|
||||
import org.w3c.dom.HTMLCanvasElement
|
||||
import ru.landgrafhomyak.bgtu.computer_graphics1.model_builder.Matrix4x4
|
||||
import ru.landgrafhomyak.bgtu.computer_graphics1.model_builder.Point2F
|
||||
import ru.landgrafhomyak.bgtu.computer_graphics1.model_builder.Point3F
|
||||
import ru.landgrafhomyak.bgtu.computer_graphics1.model_builder.Point4F
|
||||
|
||||
fun main() {
|
||||
val canvas = document.getElementById("canvas")!! as HTMLCanvasElement
|
||||
|
||||
val gl: dynamic = canvas.getContext("webgl2")!! /*as WebGLRenderingContext*/
|
||||
|
||||
val modelVertexesBuffer = gl.createBuffer()
|
||||
val textureVertexesBuffer = gl.createBuffer()
|
||||
val textureTypesBuffer = gl.createBuffer()
|
||||
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, modelVertexesBuffer)
|
||||
gl.bufferData(
|
||||
gl.ARRAY_BUFFER,
|
||||
Float32Array(model.modelVertexes.toTypedArray()),
|
||||
gl.STATIC_DRAW
|
||||
)
|
||||
gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 3 * 4, 0)
|
||||
gl.enableVertexAttribArray(0)
|
||||
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, textureVertexesBuffer)
|
||||
gl.bufferData(
|
||||
gl.ARRAY_BUFFER,
|
||||
Float32Array(model.textureVertexes.toTypedArray()),
|
||||
gl.STATIC_DRAW
|
||||
)
|
||||
gl.vertexAttribPointer(1, 2, gl.FLOAT, false, 2 * 4, 0)
|
||||
gl.enableVertexAttribArray(1)
|
||||
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, textureTypesBuffer)
|
||||
gl.bufferData(
|
||||
gl.ARRAY_BUFFER,
|
||||
Int32Array(model.textureTypes.map { t -> t.ordinal }.toTypedArray()),
|
||||
gl.STATIC_DRAW
|
||||
)
|
||||
gl.vertexAttribIPointer(2, 2, gl.INT, false, 1 * 4, 0)
|
||||
gl.enableVertexAttribArray(2)
|
||||
|
||||
val vertexShader = gl.createShader(gl.VERTEX_SHADER);
|
||||
gl.shaderSource(vertexShader, vertexShaderSource)
|
||||
@ -61,26 +35,130 @@ fun main() {
|
||||
gl.attachShader(shaderProgram, fragmentShader)
|
||||
gl.linkProgram(shaderProgram)
|
||||
println("program compilation log: ${gl.getProgramInfoLog(shaderProgram)}")
|
||||
|
||||
gl.useProgram(shaderProgram)
|
||||
val transformLocation = gl.getUniformLocation(shaderProgram, "transform")
|
||||
val projectionLocation = gl.getUniformLocation(shaderProgram, "projection")
|
||||
val screenLocation = gl.getUniformLocation(shaderProgram, "screen_scale")
|
||||
|
||||
|
||||
val modelVertexesBuffer = gl.createBuffer()
|
||||
val textureVertexesBuffer = gl.createBuffer()
|
||||
val textureTypesBuffer = gl.createBuffer()
|
||||
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, modelVertexesBuffer)
|
||||
println(model.modelVertexes.joinToString())
|
||||
gl.bufferData(
|
||||
gl.ARRAY_BUFFER,
|
||||
Float32Array(model.modelVertexes.toTypedArray()),
|
||||
gl.STATIC_DRAW
|
||||
)
|
||||
val vpa = gl.getAttribLocation(shaderProgram, "vertex_pos")
|
||||
gl.vertexAttribPointer(vpa, 3, gl.FLOAT, false, 0, 0)
|
||||
gl.enableVertexAttribArray(vpa)
|
||||
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, textureVertexesBuffer)
|
||||
gl.bufferData(
|
||||
gl.ARRAY_BUFFER,
|
||||
Float32Array(model.textureVertexes.toTypedArray()),
|
||||
gl.STATIC_DRAW
|
||||
)
|
||||
val tpa = gl.getAttribLocation(shaderProgram, "texture_pos")
|
||||
gl.vertexAttribPointer(tpa, 2, gl.FLOAT, false, 2 * 4, 0)
|
||||
gl.enableVertexAttribArray(tpa)
|
||||
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, textureTypesBuffer)
|
||||
gl.bufferData(
|
||||
gl.ARRAY_BUFFER,
|
||||
Int32Array(model.textureTypes.map { t -> t.ordinal }.toTypedArray()),
|
||||
gl.STATIC_DRAW
|
||||
)
|
||||
val tta = gl.getAttribLocation(shaderProgram, "texture_type")
|
||||
gl.vertexAttribIPointer(tta, 2, gl.INT, false, 1 * 4, 0)
|
||||
gl.enableVertexAttribArray(tta)
|
||||
|
||||
gl.enable(gl.DEPTH_TEST)
|
||||
|
||||
var xAngle = 0.0f
|
||||
var yAngle = 0.0f
|
||||
var distance = 0.0f
|
||||
val xAngleStep = 0.1f
|
||||
val yAngleStep = 0.1f
|
||||
val distanceStep = 0.1f
|
||||
|
||||
|
||||
val redraw = {
|
||||
val radius = ((if (canvas.width < canvas.height) canvas.width else canvas.height) * 7f / 16f);
|
||||
gl.viewport(0, 0, canvas.width, canvas.height);
|
||||
gl.clearColor(0f, 0f, 0f, 1f);
|
||||
gl.clear(gl.COLOR_BUFFER_BIT);
|
||||
gl.drawArrays(gl.TRIANGLES, 0, model.textureTypes.size / 3)
|
||||
gl.clear(gl.COLOR_BUFFER_BIT or gl.DEPTH_BUFFER_BIT);
|
||||
val t = Matrix4x4.shift(0f, 0f, distance) * Matrix4x4.rotateY(yAngle) * Matrix4x4.rotateX(xAngle)
|
||||
val po = Matrix4x4.projectionOrtho(-2f, 2f, -2f, 2f, -2f, 2f);
|
||||
val pc = Matrix4x4.projectionCentralInfinite(-2f, 2f, -2f, 2f, 1f) * Matrix4x4.shift(0f, 0f, -3f) * Matrix4x4.scale(3f, 3f, -1f);
|
||||
val s: Point2F
|
||||
if (canvas.width > canvas.height) {
|
||||
s = Point2F(canvas.height.toFloat() / canvas.width.toFloat(), 1f)
|
||||
} else {
|
||||
s = Point2F(1f, canvas.width.toFloat() / canvas.height.toFloat())
|
||||
}
|
||||
gl.uniformMatrix4fv(transformLocation, false, t.toFloatArray())
|
||||
gl.uniformMatrix4fv(projectionLocation, false, pc.toFloatArray())
|
||||
gl.uniform2f(screenLocation, s.x, s.y)
|
||||
gl.drawArrays(gl.TRIANGLES, 0, model.textureTypes.size)
|
||||
gl.flush()
|
||||
}
|
||||
val p = Matrix4x4.projectionCentral(-2f, 2f, -2f, 2f, 2f, 4f);
|
||||
|
||||
println(p * Point4F(-1f, -1f, -2f, 1f))
|
||||
println(p * Point4F(-1f, 1f, -3f, 1f))
|
||||
println(p * Point4F(1f, 1f, -4f, 1f))
|
||||
|
||||
redraw()
|
||||
|
||||
window.onkeydown = { keyEvent ->
|
||||
when (keyEvent.code) {
|
||||
"ArrowDown" -> {
|
||||
|
||||
gl.clearColor(0f, 0f, 0f, 1f);
|
||||
gl.clear(gl.COLOR_BUFFER_BIT);
|
||||
gl.drawArrays(gl.TRIANGLES, 0, model.textureTypes.size / 3)
|
||||
xAngle += xAngleStep;
|
||||
redraw()
|
||||
}
|
||||
|
||||
"ArrowUp" -> {}
|
||||
"ArrowLeft" -> {}
|
||||
"ArrowRight" -> {}
|
||||
"ArrowUp" -> {
|
||||
xAngle -= xAngleStep;
|
||||
redraw()
|
||||
}
|
||||
|
||||
"ArrowLeft" -> {
|
||||
yAngle -= yAngleStep;
|
||||
redraw()
|
||||
}
|
||||
|
||||
"ArrowRight" -> {
|
||||
yAngle += yAngleStep;
|
||||
redraw()
|
||||
}
|
||||
|
||||
"PageUp" -> {
|
||||
distance += distanceStep;
|
||||
redraw()
|
||||
}
|
||||
|
||||
"PageDown" -> {
|
||||
distance -= distanceStep;
|
||||
if (distance < 0) distance = 0f
|
||||
redraw()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
window.onresize = { _ ->
|
||||
canvas.width = document.documentElement!!.clientWidth;
|
||||
canvas.height = document.documentElement!!.clientHeight;
|
||||
redraw()
|
||||
}
|
||||
window.onload = { _ ->
|
||||
canvas.width = document.documentElement!!.clientWidth;
|
||||
canvas.height = document.documentElement!!.clientHeight;
|
||||
redraw()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -24,14 +24,12 @@ val model = ModelTriangles.fromPolygons(
|
||||
Polygon.PolygonVertex(1f, 1f, 0f, rot_n(240, 1)),
|
||||
Polygon.PolygonVertex(1f, 0f, 1f, rot_n(120, 1))
|
||||
),
|
||||
|
||||
Polygon(
|
||||
TextureType.HSV,
|
||||
Polygon.PolygonVertex(-1f, -1f, 1f, rot_n(60, 2)),
|
||||
Polygon.PolygonVertex(-1f, 1f, 1f, rot_n(0, 2)),
|
||||
Polygon.PolygonVertex(0f, 1f, 1f, rot_n(0, 1))
|
||||
),
|
||||
|
||||
Polygon(
|
||||
TextureType.HSV,
|
||||
Polygon.PolygonVertex(-1f, -1f, 1f, rot_n(60, 2)),
|
||||
@ -45,14 +43,12 @@ val model = ModelTriangles.fromPolygons(
|
||||
Polygon.PolygonVertex(1f, 0f, 1f, rot_n(120, 1)),
|
||||
Polygon.PolygonVertex(1f, -1f, 1f, rot_n(120, 1))
|
||||
),
|
||||
|
||||
Polygon(
|
||||
TextureType.HSV,
|
||||
Polygon.PolygonVertex(1f, -1f, -1f, rot_n(180, 2)),
|
||||
Polygon.PolygonVertex(1f, 1f, -1f, rot_n(240, 2)),
|
||||
Polygon.PolygonVertex(1f, 1f, 0f, rot_n(240, 1))
|
||||
),
|
||||
|
||||
Polygon(
|
||||
TextureType.HSV,
|
||||
Polygon.PolygonVertex(1f, -1f, -1f, rot_n(180, 2)),
|
||||
@ -66,14 +62,12 @@ val model = ModelTriangles.fromPolygons(
|
||||
Polygon.PolygonVertex(1f, 0f, 1f, rot_n(120, 1)),
|
||||
Polygon.PolygonVertex(1f, -1f, 1f, rot_n(120, 2))
|
||||
),
|
||||
|
||||
Polygon(
|
||||
TextureType.HSV,
|
||||
Polygon.PolygonVertex(-1f, 1f, -1f, rot_n(300, 2)),
|
||||
Polygon.PolygonVertex(1f, 1f, -1f, rot_n(240, 2)),
|
||||
Polygon.PolygonVertex(1f, 1f, 0f, rot_n(240, 1))
|
||||
),
|
||||
|
||||
Polygon(
|
||||
TextureType.HSV,
|
||||
Polygon.PolygonVertex(-1f, 1f, -1f, rot_n(300, 2)),
|
||||
@ -87,6 +81,7 @@ val model = ModelTriangles.fromPolygons(
|
||||
Polygon.PolygonVertex(0f, 1f, 1f, rot_n(0, 1)),
|
||||
Polygon.PolygonVertex(-1f, 1f, 1f, rot_n(0, 2))
|
||||
),
|
||||
|
||||
Polygon(
|
||||
TextureType.WHITE_TRANSPARENCY,
|
||||
Polygon.PolygonVertex(-1f, -1f, 1f, 0f, 0f),
|
||||
@ -126,5 +121,5 @@ val model = ModelTriangles.fromPolygons(
|
||||
Polygon.PolygonVertex(-1f, -1f, -1f, 1f, 1f),
|
||||
Polygon.PolygonVertex(-1f, -1f, 1f, 0f, 1f),
|
||||
Polygon.PolygonVertex(1f, -1f, -1f, 1f, 0f)
|
||||
),
|
||||
)
|
||||
)
|
@ -0,0 +1,162 @@
|
||||
package ru.landgrafhomyak.bgtu.computer_graphics1.model_builder
|
||||
|
||||
import kotlin.math.cos
|
||||
import kotlin.math.sin
|
||||
|
||||
class Matrix4x4 private constructor(
|
||||
private val v00: Float,
|
||||
private val v01: Float,
|
||||
private val v02: Float,
|
||||
private val v03: Float,
|
||||
private val v10: Float,
|
||||
private val v11: Float,
|
||||
private val v12: Float,
|
||||
private val v13: Float,
|
||||
private val v20: Float,
|
||||
private val v21: Float,
|
||||
private val v22: Float,
|
||||
private val v23: Float,
|
||||
private val v30: Float,
|
||||
private val v31: Float,
|
||||
private val v32: Float,
|
||||
private val v33: Float
|
||||
) {
|
||||
private inline fun _foldMatrix(other: Matrix4x4, operator: (rowIndex: Int, columnIndex: Int, self: Float, other: Float) -> Float): Matrix4x4 = Matrix4x4(
|
||||
operator(0, 0, this.v00, other.v00), operator(0, 1, this.v01, other.v01), operator(0, 2, this.v02, other.v02), operator(0, 3, this.v03, other.v03),
|
||||
operator(1, 0, this.v10, other.v10), operator(1, 1, this.v11, other.v11), operator(1, 2, this.v12, other.v12), operator(1, 3, this.v13, other.v13),
|
||||
operator(2, 0, this.v20, other.v20), operator(2, 1, this.v21, other.v21), operator(2, 2, this.v22, other.v22), operator(2, 3, this.v23, other.v23),
|
||||
operator(3, 0, this.v30, other.v30), operator(3, 1, this.v31, other.v31), operator(3, 2, this.v32, other.v32), operator(3, 3, this.v33, other.v33),
|
||||
)
|
||||
|
||||
operator fun get(row: Int, column: Int) = when (row * 4 + column) {
|
||||
0 -> this.v00
|
||||
1 -> this.v01
|
||||
2 -> this.v02
|
||||
3 -> this.v03
|
||||
4 -> this.v10
|
||||
5 -> this.v11
|
||||
6 -> this.v12
|
||||
7 -> this.v13
|
||||
8 -> this.v20
|
||||
9 -> this.v21
|
||||
10 -> this.v22
|
||||
11 -> this.v23
|
||||
12 -> this.v30
|
||||
13 -> this.v31
|
||||
14 -> this.v32
|
||||
15 -> this.v33
|
||||
else -> throw IllegalArgumentException()
|
||||
}
|
||||
|
||||
operator fun times(other: Matrix4x4): Matrix4x4 =
|
||||
this._foldMatrix(other) { y, x, _, _ ->
|
||||
return@_foldMatrix this[y, 0] * other[0, x] + this[y, 1] * other[1, x] + this[y, 2] * other[2, x] + this[y, 3] * other[3, x];
|
||||
}
|
||||
|
||||
fun toFloatArray() = floatArrayOf(
|
||||
this.v00, this.v01, this.v02, this.v03,
|
||||
this.v10, this.v11, this.v12, this.v13,
|
||||
this.v20, this.v21, this.v22, this.v23,
|
||||
this.v30, this.v31, this.v32, this.v33
|
||||
)
|
||||
|
||||
fun transposed() = Matrix4x4(
|
||||
this.v00, this.v10, this.v20, this.v30,
|
||||
this.v01, this.v11, this.v21, this.v31,
|
||||
this.v02, this.v12, this.v22, this.v32,
|
||||
this.v03, this.v13, this.v23, this.v33,
|
||||
)
|
||||
|
||||
operator fun times(p: Point3F) = Point3F(
|
||||
x = this.v00 * p.x + this.v01 * p.y + this.v02 * p.z + this.v03,
|
||||
y = this.v10 * p.x + this.v11 * p.y + this.v12 * p.z + this.v13,
|
||||
z = this.v20 * p.x + this.v21 * p.y + this.v22 * p.z + this.v23,
|
||||
)
|
||||
|
||||
operator fun times(p: Point4F) = Point4F(
|
||||
x = this.v00 * p.x + this.v01 * p.y + this.v02 * p.z + this.v03,
|
||||
y = this.v10 * p.x + this.v11 * p.y + this.v12 * p.z + this.v13,
|
||||
z = this.v20 * p.x + this.v21 * p.y + this.v22 * p.z + this.v23,
|
||||
w = this.v30 * p.x + this.v31 * p.y + this.v32 * p.z + this.v33,
|
||||
)
|
||||
|
||||
companion object {
|
||||
val I = Matrix4x4(
|
||||
1f, 0f, 0f, 0f,
|
||||
0f, 1f, 0f, 0f,
|
||||
0f, 0f, 1f, 0f,
|
||||
0f, 0f, 0f, 1f
|
||||
)
|
||||
|
||||
fun scale(x: Float, y: Float, z: Float) = Matrix4x4(
|
||||
x, 0f, 0f, 0f,
|
||||
0f, y, 0f, 0f,
|
||||
0f, 0f, z, 0f,
|
||||
0f, 0f, 0f, 1f
|
||||
)
|
||||
|
||||
fun scale(s: Float) = this.scale(s, s, s)
|
||||
|
||||
fun rotateX(rad: Float): Matrix4x4 {
|
||||
val c = cos(rad)
|
||||
val s = sin(rad)
|
||||
return Matrix4x4(
|
||||
1f, 0f, 0f, 0f,
|
||||
0f, c, -s, 0f,
|
||||
0f, s, c, 0f,
|
||||
0f, 0f, 0f, 1f
|
||||
)
|
||||
}
|
||||
|
||||
fun rotateY(rad: Float): Matrix4x4 {
|
||||
val c = cos(rad)
|
||||
val s = sin(rad)
|
||||
return Matrix4x4(
|
||||
c, 0f, s, 0f,
|
||||
0f, 1f, 0f, 0f,
|
||||
-s, 0f, c, 0f,
|
||||
0f, 0f, 0f, 1f
|
||||
)
|
||||
}
|
||||
|
||||
fun rotateZ(rad: Float): Matrix4x4 {
|
||||
val c = cos(rad)
|
||||
val s = sin(rad)
|
||||
return Matrix4x4(
|
||||
c, -s, 0f, 0f,
|
||||
s, c, 0f, 0f,
|
||||
0f, 0f, 1f, 0f,
|
||||
0f, 0f, 0f, 1f
|
||||
)
|
||||
}
|
||||
|
||||
fun shift(x: Float, y: Float, z: Float) = Matrix4x4(
|
||||
1f, 0f, 0f, x,
|
||||
0f, 1f, 0f, y,
|
||||
0f, 0f, 1f, z,
|
||||
0f, 0f, 0f, 1f
|
||||
)
|
||||
|
||||
fun projectionOrtho(l: Float, r: Float, b: Float, t: Float, n: Float, f: Float) = Matrix4x4(
|
||||
2f / (r - l), 0f, 0f, -(r + l) / (r - l),
|
||||
0f, 2f / (t - b), 0f, -(t + b) / (t - b),
|
||||
0f, 0f, 2f / (f - n), -(f + n) / (f - n),
|
||||
0f, 0f, 0f, 1f
|
||||
)
|
||||
|
||||
fun projectionCentral(l: Float, r: Float, b: Float, t: Float, n: Float, f: Float) = Matrix4x4(
|
||||
2f * n / (r - l), 0f, (r + l) / (r - l), 0f,
|
||||
0f, 2f * n / (t - b), (t + b) / (t - b), 0f,
|
||||
0f, 0f, -(f + n) / (f - n), -2f * n * f / (f - n),
|
||||
0f, 0f, -1f, 0f
|
||||
)
|
||||
|
||||
fun projectionCentralInfinite(l: Float, r: Float, b: Float, t: Float, n: Float) = Matrix4x4(
|
||||
2f * n / (r - l), 0f, (r + l) / (r - l), 0f,
|
||||
0f, 2f * n / (t - b), (t + b) / (t - b), 0f,
|
||||
0f, 0f, -1f, -2f * n,
|
||||
0f, 0f, -1f, 0f
|
||||
)
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
package ru.landgrafhomyak.bgtu.computer_graphics1.model_builder
|
||||
|
||||
class Point4F(
|
||||
val x: Float,
|
||||
val y: Float,
|
||||
val z: Float,
|
||||
val w: Float,
|
||||
) {
|
||||
operator fun component1(): Float = this.x
|
||||
operator fun component2(): Float = this.y
|
||||
operator fun component3(): Float = this.z
|
||||
operator fun component4(): Float = this.w
|
||||
|
||||
override fun toString(): String =
|
||||
"<point 4f x=${this.x} y=${this.y} z=${this.z} w=${this.w}>"
|
||||
}
|
@ -6,14 +6,19 @@ internal val vertexShaderSource = """
|
||||
#version 300 es
|
||||
|
||||
uniform mat4 transform;
|
||||
layout(location = 0) in vec3 vertex_pos;
|
||||
layout(location = 1) in vec2 texture_pos;
|
||||
layout(location = 2) in int texture_type;
|
||||
uniform mat4 projection;
|
||||
uniform vec2 screen_scale;
|
||||
in vec3 vertex_pos;
|
||||
in vec2 texture_pos;
|
||||
in int texture_type;
|
||||
out vec2 texture_pos_v2f;
|
||||
flat out int texture_type_v2f;
|
||||
|
||||
void main() {
|
||||
gl_Position = vec4(vertex_pos.xyz, 1) * transform;
|
||||
gl_Position = vec4(vertex_pos, 1.0);
|
||||
gl_Position *= transform;
|
||||
gl_Position *= projection;
|
||||
gl_Position.xy *= screen_scale;
|
||||
texture_pos_v2f = texture_pos;
|
||||
texture_type_v2f = texture_type;
|
||||
}
|
||||
@ -21,27 +26,61 @@ internal val vertexShaderSource = """
|
||||
|
||||
internal val fragmentShaderSource = """
|
||||
#version 300 es
|
||||
#define PI 3.1415926535897932384626433832795
|
||||
|
||||
precision mediump float;
|
||||
in vec2 texture_pos_v2f;
|
||||
flat in int texture_type_v2f;
|
||||
out vec4 color;
|
||||
out vec4 FragColor;
|
||||
|
||||
vec3 hsv2rgb(float, float, float);
|
||||
vec3 hsv_texture(float, float);
|
||||
|
||||
void main() {
|
||||
switch (texture_type_v2f) {
|
||||
case ${TextureType.WHITE_TRANSPARENCY.ordinal}:
|
||||
color = vec4(255, 255, 255, 127);
|
||||
FragColor = vec4(1.0, 1.0, 1.0, 0.5);
|
||||
break;
|
||||
case ${TextureType.CHESS.ordinal}:
|
||||
if (int( round(floor(texture_pos_v2f.x / 0.1)) + round(floor(texture_pos_v2f.y / 0.1)) ) % 2 == 0) {
|
||||
color = vec4(0, 0, 0, 255);
|
||||
FragColor = vec4(0.0, 0.0, 0.0, 1.0);
|
||||
} else {
|
||||
color = vec4(255, 255, 255, 255);
|
||||
FragColor = vec4(1.0, 1.0, 1.0, 1.0);
|
||||
}
|
||||
break;
|
||||
case ${TextureType.HSV.ordinal}:
|
||||
FragColor = vec4(hsv_texture(texture_pos_v2f.x, texture_pos_v2f.y), 1.0);
|
||||
break;
|
||||
default:
|
||||
color = vec4(0, 0, 0, 0);
|
||||
FragColor = vec4(0.0, 0.0, 0.0, 0.0);
|
||||
}
|
||||
}
|
||||
|
||||
vec3 hsv_texture(float x, float y) {
|
||||
float angle = atan(y, x);
|
||||
return hsv2rgb(mod(mod(angle / PI * 180.0, 360.0) + 360.0, 360.0), 1.0, 1.0);
|
||||
}
|
||||
|
||||
vec3 hsv2rgb(float hue, float saturation, float value) {
|
||||
int hi = int(floor(hue / 60.0)) % 6;
|
||||
float f = hue / 60.0 - floor(hue / 60.0);
|
||||
float v = value;
|
||||
float p = value * (1.0 - saturation);
|
||||
float q = value * (1.0 - f * saturation);
|
||||
float t = value * (1.0 - (1.0 - f) * saturation);
|
||||
switch (hi) {
|
||||
case 0:
|
||||
return vec3(v, t, p);
|
||||
case 1:
|
||||
return vec3(q, v, p);
|
||||
case 2:
|
||||
return vec3(p, v, t);
|
||||
case 3:
|
||||
return vec3(p, q, v);
|
||||
case 4:
|
||||
return vec3(t, p, v);
|
||||
default:
|
||||
return vec3(v, p, q);
|
||||
}
|
||||
}
|
||||
""".trimIndent()
|
@ -5,7 +5,7 @@
|
||||
<title>Title</title>
|
||||
</head>
|
||||
<body>
|
||||
<canvas style="left: 0; top: 0; right: 0; bottom:0; position: fixed" id="canvas"></canvas>
|
||||
<canvas style="left: 0; top: 0; right: 0; bottom:0; position: fixed; width: 100%;image-rendering: pixelated;" id="canvas"></canvas>
|
||||
<script src="computer-graphics-1.js"></script>
|
||||
|
||||
</body>
|
||||
|
Loading…
Reference in New Issue
Block a user