3d gpu
This commit is contained in:
BIN
hlsl/shadercross
BIN
hlsl/shadercross
Binary file not shown.
@@ -1,40 +0,0 @@
|
||||
// Constant Buffer for Transformation Matrices
|
||||
cbuffer TransformBuffer : register(b0)
|
||||
{
|
||||
float4x4 WorldMatrix; // World transformation matrix
|
||||
float4x4 ViewProjectionMatrix; // Combined view and projection matrix
|
||||
}
|
||||
|
||||
// Input structure for the vertex shader
|
||||
struct VertexInput
|
||||
{
|
||||
float3 Position : POSITION; // Vertex position (model space)
|
||||
float2 UV : TEXCOORD0; // Texture coordinates
|
||||
float4 Color : COLOR0; // Vertex color
|
||||
};
|
||||
|
||||
// Output structure from the vertex shader to the pixel shader
|
||||
struct VertexOutput
|
||||
{
|
||||
float4 Position : SV_Position; // Clip-space position
|
||||
float2 UV : TEXCOORD0; // Texture coordinates
|
||||
float4 Color : COLOR0; // Interpolated vertex color
|
||||
};
|
||||
|
||||
// Vertex shader
|
||||
VertexOutput main(VertexInput input)
|
||||
{
|
||||
VertexOutput output;
|
||||
|
||||
// Transform the vertex position from model space to world space
|
||||
float4 worldPosition = mul(WorldMatrix, float4(input.Position, 1.0f));
|
||||
|
||||
// Transform the position to clip space using the view-projection matrix
|
||||
output.Position = mul(ViewProjectionMatrix, worldPosition);
|
||||
|
||||
// Pass through texture coordinates and vertex color
|
||||
output.UV = input.UV;
|
||||
output.Color = input.Color;
|
||||
|
||||
return output;
|
||||
}
|
||||
@@ -73,7 +73,7 @@ deps += dependency('qjs-layout',static:true)
|
||||
deps += dependency('qjs-nota',static:true)
|
||||
deps += dependency('qjs-miniz',static:true)
|
||||
deps += dependency('qjs-soloud',static:true)
|
||||
|
||||
deps += dependency('assimp')
|
||||
deps += dependency('physfs')
|
||||
|
||||
#deps += dependency('opencv4')
|
||||
|
||||
@@ -43,6 +43,8 @@ var unit_transform = os.make_transform();
|
||||
},
|
||||
*/
|
||||
|
||||
var sprite_mesh = {};
|
||||
|
||||
render.doc = {
|
||||
doc: "Functions for rendering modes.",
|
||||
normal: "Final render with all lighting.",
|
||||
@@ -54,6 +56,8 @@ cur.images = [];
|
||||
cur.samplers = [];
|
||||
|
||||
var base_pipeline = {
|
||||
vertex: "sprite.vert",
|
||||
frag: "sprite.frag",
|
||||
primitive: "triangle", // point, line, linestrip, triangle, trianglestrip
|
||||
fill: true, // false for lines
|
||||
depth: {
|
||||
@@ -101,64 +105,13 @@ var base_pipeline = {
|
||||
},
|
||||
label: "scripted pipeline"
|
||||
}
|
||||
render.base_pipeline = base_pipeline;
|
||||
|
||||
var pipe_shaders = new WeakMap();
|
||||
var pipeline_3d = Object.create(base_pipeline);
|
||||
|
||||
// Uses the shader with the specified pipeline. If none specified, uses the base pipeline
|
||||
render.use_shader = function use_shader(shader, pipeline = base_pipeline) {
|
||||
if (typeof shader === "string") shader = make_shader(shader);
|
||||
if (cur.shader === shader) return;
|
||||
|
||||
if (!pipe_shaders.has(shader)) pipe_shaders.set(shader, new WeakMap());
|
||||
var shader_pipelines = pipe_shaders.get(shader);
|
||||
if (!shader_pipelines.has(pipeline)) {
|
||||
var new_pipeline = render.make_pipeline(shader,pipeline);
|
||||
shader_pipelines.set(pipeline, new_pipeline);
|
||||
}
|
||||
|
||||
var use_pipeline = shader_pipelines.get(pipeline);
|
||||
if (cur.shader === shader && cur.pipeline === use_pipeline) return;
|
||||
|
||||
cur.shader = shader;
|
||||
cur.bind = undefined;
|
||||
cur.mesh = undefined;
|
||||
cur.ssbo = undefined;
|
||||
cur.images = [];
|
||||
cur.pipeline = use_pipeline;
|
||||
|
||||
// Grab or create a pipeline obj that utilizes the specific shader and pipeline
|
||||
render.setpipeline(use_pipeline);
|
||||
shader_globals(cur.shader);
|
||||
};
|
||||
|
||||
render.use_pipeline = function use_pipeline(pipeline) {
|
||||
|
||||
}
|
||||
|
||||
render.use_mat = function use_mat(mat) {
|
||||
if (!cur.shader) return;
|
||||
if (cur.mat === mat) return;
|
||||
|
||||
shader_apply_material(cur.shader, mat, cur.mat);
|
||||
|
||||
cur.mat = mat;
|
||||
|
||||
cur.images.length = 0;
|
||||
cur.samplers.length = 0;
|
||||
if (!cur.shader.fs.images) return;
|
||||
for (var img of cur.shader.fs.images) {
|
||||
if (mat[img.name]) cur.images.push(mat[img.name]);
|
||||
else cur.images.push(game.texture("no_tex.gif"));
|
||||
}
|
||||
for (var smp of cur.shader.fs.samplers) {
|
||||
var std = smp.sampler_type === "nonfiltering";
|
||||
cur.samplers.push(std);
|
||||
}
|
||||
};
|
||||
|
||||
function set_model(t) {
|
||||
if (cur.shader.vs.unimap.model) render.setunim4(0, cur.shader.vs.unimap.model.slot, t);
|
||||
function use_pipeline(pipeline) {
|
||||
if (!pipeline.gpu)
|
||||
pipeline.gpu = gpu.make_pipeline(pipeline);
|
||||
render._main.set_pipeline(pipeline);
|
||||
}
|
||||
|
||||
render.poly_prim = function poly_prim(verts) {
|
||||
@@ -181,25 +134,6 @@ render.poly_prim = function poly_prim(verts) {
|
||||
};
|
||||
};
|
||||
|
||||
var uni_globals = {
|
||||
time(stage, slot) {
|
||||
render.setuniv(stage, slot, profile.secs(profile.now()));
|
||||
},
|
||||
projection(stage, slot) {
|
||||
render.setuniproj(stage, slot);
|
||||
},
|
||||
view(stage, slot) {
|
||||
render.setuniview(stage, slot);
|
||||
},
|
||||
vp(stage, slot) {
|
||||
render.setunivp(stage, slot);
|
||||
},
|
||||
};
|
||||
|
||||
function set_global_uni(uni, stage) {
|
||||
uni_globals[uni.name]?.(stage, uni.slot);
|
||||
}
|
||||
|
||||
var shader_cache = {};
|
||||
var shader_times = {};
|
||||
|
||||
@@ -221,153 +155,13 @@ render.hotreload = function shader_hotreload() {
|
||||
}
|
||||
};
|
||||
|
||||
function create_shader_obj(file) {
|
||||
var driver = os.gpu_driver();
|
||||
switch(driver) {
|
||||
}
|
||||
var files = [file];
|
||||
var out = ".prosperon/tmp.shader";
|
||||
var shader = io.slurp(file);
|
||||
|
||||
var incs = shader.match(/#include <.*>/g);
|
||||
if (incs)
|
||||
for (var inc of incs) {
|
||||
var filez = inc.match(/#include <(.*)>/)[1];
|
||||
var macro = io.slurp(filez);
|
||||
if (!macro) {
|
||||
filez = `${filez}`;
|
||||
macro = io.slurp(filez);
|
||||
}
|
||||
shader = shader.replace(inc, macro);
|
||||
files.push(filez);
|
||||
}
|
||||
|
||||
shader = shader.replace(/uniform\s+(\w+)\s+(\w+);/g, "uniform _$2 { $1 $2; };");
|
||||
shader = shader.replace(/(texture2D|sampler) /g, "uniform $1 ");
|
||||
|
||||
io.slurpwrite(out, shader);
|
||||
|
||||
var compiled = {};
|
||||
|
||||
// shader file is created, now cross compile to all targets
|
||||
for (var platform in shaderlang) {
|
||||
var backend = shaderlang[platform];
|
||||
var ret = os.system(`sokol-shdc -f bare_yaml --slang=${backend} -i ${out} -o ${out}`);
|
||||
if (ret) {
|
||||
console.error(`error compiling shader ${file}. No compilation found for ${platform}:${backend}, and no cross compiler available.`);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Take YAML and create the shader object */
|
||||
var yamlfile = `${out}_reflection.yaml`;
|
||||
var jjson = yaml.tojson(io.slurp(yamlfile));
|
||||
var obj = json.decode(jjson);
|
||||
io.rm(yamlfile);
|
||||
|
||||
obj = obj.shaders[0].programs[0];
|
||||
function add_code(stage) {
|
||||
stage.code = io.slurp(stage.path);
|
||||
|
||||
io.rm(stage.path);
|
||||
delete stage.path;
|
||||
}
|
||||
|
||||
add_code(obj.vs);
|
||||
if (!obj.fs && obj.vs.fs) {
|
||||
obj.fs = obj.vs.fs;
|
||||
delete obj.vs.fs;
|
||||
}
|
||||
|
||||
add_code(obj.fs);
|
||||
|
||||
obj.indexed = true;
|
||||
|
||||
if (obj.vs.inputs)
|
||||
for (var i of obj.vs.inputs) {
|
||||
if (!(i.name in attr_map)) i.mat = -1;
|
||||
else i.mat = attr_map[i.name];
|
||||
}
|
||||
|
||||
function make_unimap(stage) {
|
||||
if (!stage.uniform_blocks) return {};
|
||||
var unimap = {};
|
||||
for (var uni of stage.uniform_blocks) {
|
||||
var uniname = uni.struct_name[0] == "_" ? uni.struct_name.slice(1) : uni.struct_name;
|
||||
|
||||
unimap[uniname] = {
|
||||
name: uniname,
|
||||
slot: Number(uni.slot),
|
||||
size: Number(uni.size),
|
||||
};
|
||||
}
|
||||
|
||||
return unimap;
|
||||
}
|
||||
|
||||
obj.vs.unimap = make_unimap(obj.vs);
|
||||
obj.fs.unimap = make_unimap(obj.fs);
|
||||
|
||||
obj.name = file;
|
||||
|
||||
strip_shader_inputs(obj);
|
||||
|
||||
compiled[platform] = obj;
|
||||
}
|
||||
|
||||
compiled.files = files;
|
||||
compiled.source = shader;
|
||||
|
||||
return compiled;
|
||||
}
|
||||
|
||||
function make_shader(shader, pipe) {
|
||||
if (shader_cache[shader]) return shader_cache[shader];
|
||||
|
||||
var file = shader;
|
||||
shader = io.slurp(file);
|
||||
if (!shader)
|
||||
shader = io.slurp(`${file}`);
|
||||
|
||||
var writejson = `.prosperon/${file.name()}.shader.json`;
|
||||
|
||||
breakme: if (io.exists(writejson)) {
|
||||
var data = json.decode(io.slurp(writejson));
|
||||
var filemod = io.mod(writejson);
|
||||
if (!data.files) break breakme;
|
||||
for (var i of data.files) {
|
||||
if (io.mod(i) > filemod) {
|
||||
break breakme;
|
||||
}
|
||||
}
|
||||
|
||||
var shaderobj = json.decode(io.slurp(writejson));
|
||||
var obj = shaderobj[os.sys()];
|
||||
|
||||
shader_cache[file] = obj;
|
||||
shader_times[file] = io.mod(file);
|
||||
return obj;
|
||||
}
|
||||
|
||||
var compiled = create_shader_obj(file);
|
||||
io.slurpwrite(writejson, json.encode(compiled));
|
||||
var obj = compiled[os.sys()];
|
||||
|
||||
shader_cache[file] = obj;
|
||||
shader_times[file] = io.mod(file);
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
var shader_unisize = {
|
||||
4: render.setuniv,
|
||||
8: render.setuniv2,
|
||||
12: render.setuniv3,
|
||||
16: render.setuniv4,
|
||||
};
|
||||
|
||||
function shader_globals(shader) {
|
||||
for (var p in shader.vs.unimap) set_global_uni(shader.vs.unimap[p], 0);
|
||||
for (var p in shader.fs.unimap) set_global_uni(shader.fs.unimap[p], 1);
|
||||
function make_shader(shader, ...args) {
|
||||
var file = `shaders/spirv/${shader}.spv`;
|
||||
if (shader_cache[file]) return shader_cache[file];
|
||||
shader = io.slurpbytes(file);
|
||||
shader = render._main.make_shader(shader, ...args);
|
||||
shader_cache[file] = shader;
|
||||
return shader;
|
||||
}
|
||||
|
||||
function shader_apply_material(shader, material = {}, old = {}) {
|
||||
@@ -491,41 +285,96 @@ render.device = {
|
||||
gamegear: [160, 144, 3.2],
|
||||
};
|
||||
|
||||
render.device.doc = `Device resolutions given as [x,y,inches diagonal].`;
|
||||
var sprite_stack = [];
|
||||
|
||||
var textshader;
|
||||
var circleshader;
|
||||
var polyshader;
|
||||
var slice9shader;
|
||||
var parshader;
|
||||
var spritessboshader;
|
||||
var polyssboshader;
|
||||
var sprite_ssbo;
|
||||
render.device.doc = `Device resolutions given as [x,y,inches diagonal].`;
|
||||
var std_sampler;
|
||||
|
||||
function upload_model(model)
|
||||
{
|
||||
var bufs = [];
|
||||
for (var i in model) {
|
||||
if (typeof model[i] !== 'object') continue;
|
||||
if (i === 'indices') model[i].index = true;
|
||||
bufs.push(model[i]);
|
||||
}
|
||||
render._main.upload(bufs);
|
||||
}
|
||||
|
||||
var campos = [0,0,500];
|
||||
|
||||
function gpupresent()
|
||||
{
|
||||
var myimg = game.texture("pockle");
|
||||
myimg.sampler = std_sampler;
|
||||
var spritemesh = render._main.make_sprite_mesh(sprite_stack);
|
||||
upload_model(spritemesh);
|
||||
|
||||
sprite_stack.length = 0;
|
||||
|
||||
var cmds = render._main.acquire_cmd_buffer();
|
||||
var pass = cmds.render_pass();
|
||||
try{
|
||||
pass.bind_pipeline(base_pipeline.gpu);
|
||||
pass.bind_model(spritemesh);
|
||||
pass.bind_mat({diffuse:myimg});
|
||||
cmds.camera(prosperon.camera.transform);
|
||||
pass.draw(spritemesh.count,1,0,0,0);
|
||||
prosperon.camera.transform.pos = campos;
|
||||
campos.y -= 0.1;
|
||||
campos.z += 0.1;
|
||||
prosperon.camera.fov = 60;
|
||||
prosperon.camera.near = 0.1;
|
||||
prosperon.camera.far = 100000;
|
||||
cmds.camera_perspective(prosperon.camera);
|
||||
pass.bind_pipeline(pipeline_model.gpu);
|
||||
pass.bind_model(ducky);
|
||||
pass.draw(ducky.count,1,0,0,0);
|
||||
cmds.camera(prosperon.camera.transform, true);
|
||||
pass.bind_pipeline(base_pipeline.gpu);
|
||||
pass.draw(spritemesh.count,1,0,0,0);
|
||||
} catch(e) { console.log(e); } finally {
|
||||
pass.end();
|
||||
cmds.submit();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
var ducky;
|
||||
var pipeline_model;
|
||||
|
||||
render.init = function () {
|
||||
return;
|
||||
textshader = make_shader("text_base.cg");
|
||||
render.spriteshader = make_shader("sprite.cg");
|
||||
spritessboshader = make_shader("sprite_ssbo.cg");
|
||||
var postpipe = Object.create(base_pipeline);
|
||||
postpipe.cull = cull_map.none;
|
||||
postpipe.primitive = primitive_map.triangle;
|
||||
render.postshader = make_shader("simplepost.cg", postpipe);
|
||||
slice9shader = make_shader("9slice.cg");
|
||||
circleshader = make_shader("circle.cg");
|
||||
polyshader = make_shader("poly.cg");
|
||||
parshader = make_shader("baseparticle.cg");
|
||||
polyssboshader = make_shader("poly_ssbo.cg");
|
||||
poly_ssbo = render.make_textssbo();
|
||||
sprite_ssbo = render.make_textssbo();
|
||||
|
||||
render.textshader = textshader;
|
||||
io.mount("core");
|
||||
render._main.present = gpupresent;
|
||||
ducky = os.model_buffer("Duck.glb");
|
||||
upload_model(ducky);
|
||||
for (var i in ducky) console.log(`ducky has ${i}`)
|
||||
console.log(ducky.count)
|
||||
var sprite_vert = make_shader("sprite.vert", true,0,0,0,1);
|
||||
var sprite_frag = make_shader("sprite.frag", false,1,0,0,0);
|
||||
base_pipeline.vertex = sprite_vert;
|
||||
base_pipeline.fragment = sprite_frag;
|
||||
base_pipeline.gpu = render._main.make_pipeline(base_pipeline);
|
||||
var model_vert = make_shader("model.vert", true, 0,0,0,1);
|
||||
var model_frag = make_shader("model.frag", false, 0,0,0,0);
|
||||
pipeline_model = Object.create(base_pipeline);
|
||||
pipeline_model.vertex = model_vert;
|
||||
pipeline_model.fragment = model_frag;
|
||||
pipeline_model.gpu = render._main.make_pipeline(pipeline_model);
|
||||
|
||||
std_sampler = render._main.make_sampler({
|
||||
min_filter: "nearest",
|
||||
mag_filter: "nearest",
|
||||
mipmap_mode: "nearest",
|
||||
address_mode_u: "clamp_edge",
|
||||
address_mode_v: "clamp_edge",
|
||||
address_mode_w: "clamp_edge"
|
||||
});
|
||||
|
||||
/* os.make_circle2d().draw = function () {
|
||||
render.circle(this.body().transform().pos, this.radius, [1, 1, 0, 1]);
|
||||
};
|
||||
|
||||
|
||||
var disabled = [148 / 255, 148 / 255, 148 / 255, 1];
|
||||
var sleep = [1, 140 / 255, 228 / 255, 1];
|
||||
var dynamic = [1, 70 / 255, 46 / 255, 1];
|
||||
@@ -617,7 +466,7 @@ function draw_sprites()
|
||||
for (var img in layer) {
|
||||
var sparray = layer[img];
|
||||
if (sparray.length === 0) continue;
|
||||
var geometry = os.make_sprite_mesh(sparray);
|
||||
var geometry = render._main.make_sprite_mesh(sparray);
|
||||
render.geometry(sparray[0], geometry);
|
||||
}
|
||||
}
|
||||
@@ -702,7 +551,7 @@ function flush_poly() {
|
||||
poly_idx = 0;
|
||||
}
|
||||
|
||||
render.line = function render_line(points, color = Color.white, thickness = 1, shader = polyssboshader, pipe = base_pipeline) {
|
||||
render.line = function render_line(points, color = Color.white, thickness = 1, pipe = base_pipeline) {
|
||||
render._main.line(points, color);
|
||||
};
|
||||
|
||||
@@ -711,14 +560,14 @@ render.point = function (pos, size, color = Color.blue) {
|
||||
render._main.point(pos,color);
|
||||
};
|
||||
|
||||
render.cross = function render_cross(pos, size, color = Color.red, thickness = 1) {
|
||||
render.cross = function render_cross(pos, size, color = Color.red, thickness = 1, pipe = base_pipeline) {
|
||||
var a = [pos.add([0, size]), pos.add([0, -size])];
|
||||
var b = [pos.add([size, 0]), pos.add([-size, 0])];
|
||||
render.line(a, color, thickness);
|
||||
render.line(b, color, thickness);
|
||||
};
|
||||
|
||||
render.arrow = function render_arrow(start, end, color = Color.red, wingspan = 4, wingangle = 10) {
|
||||
render.arrow = function render_arrow(start, end, color = Color.red, wingspan = 4, wingangle = 10, pipe = base_pipeline) {
|
||||
var dir = end.sub(start).normalized();
|
||||
var wing1 = [Vector.rotate(dir, wingangle).scale(wingspan).add(end), end];
|
||||
var wing2 = [Vector.rotate(dir, -wingangle).scale(wingspan).add(end), end];
|
||||
@@ -734,11 +583,11 @@ render.coordinate = function render_coordinate(pos, size, color) {
|
||||
|
||||
var queued_shader;
|
||||
var queued_pipe;
|
||||
render.rectangle = function render_rectangle(rect, color = Color.white, shader = polyssboshader, pipe = base_pipeline) {
|
||||
render.rectangle = function render_rectangle(rect, color = Color.white, pipe = base_pipeline) {
|
||||
render._main.fillrect(rect,color);
|
||||
};
|
||||
|
||||
render.text = function text(str, rect, font = cur_font, size = 0, color = Color.white, wrap = 0) {
|
||||
render.text = function text(str, rect, font = cur_font, size = 0, color = Color.white, wrap = 0, pipe = base_pipeline) {
|
||||
if (typeof font === 'string')
|
||||
font = render.get_font(font)
|
||||
var mesh = os.make_text_buffer(str, rect, 0, color, wrap, font);
|
||||
@@ -924,8 +773,14 @@ render.image = function image(image, rect = [0,0], rotation = 0, color = Color.w
|
||||
|
||||
rect.width ??= image.texture.width;
|
||||
rect.height ??= image.texture.height;
|
||||
|
||||
render._main.texture(image.texture, rect, image.rect, color);
|
||||
var T = os.make_transform();
|
||||
T.rect(rect);
|
||||
sprite_stack.push({
|
||||
transform: T,
|
||||
color: color,
|
||||
image:image
|
||||
});
|
||||
// render._main.texture(image.texture, rect, image.rect, color);
|
||||
};
|
||||
|
||||
render.images = function images(image, rects)
|
||||
@@ -1163,13 +1018,14 @@ prosperon.make_camera = function make_camera() {
|
||||
cam.zoom = 1; // the "scale factor" this camera demonstrates
|
||||
// camera renders draw calls, and then hud
|
||||
cam.render = function() {
|
||||
render._main.camera(this.transform,true);
|
||||
render._main.scale([this.zoom, this.zoom]);
|
||||
prosperon.draw();
|
||||
draw_sprites();
|
||||
render._main.camera(this.transform,true);
|
||||
render._main.scale([this.zoom, this.zoom]);
|
||||
prosperon.hud();
|
||||
render._main.scale([1,1]);
|
||||
render._main.camera(unit_transform,false);
|
||||
prosperon.hud();
|
||||
|
||||
}
|
||||
return cam;
|
||||
};
|
||||
@@ -1296,7 +1152,6 @@ var imgui_fn = function imgui_fn() {
|
||||
prosperon.window_render(basesize.scale(mult));
|
||||
*/
|
||||
|
||||
var present_thread = undefined;
|
||||
var clearcolor = [100,149,237,255].scale(1/255);
|
||||
prosperon.render = function prosperon_render() {
|
||||
try{
|
||||
@@ -1311,8 +1166,7 @@ if (debug.show) try { imgui_fn(); } catch(e) { console.error(e) }
|
||||
} catch(e) {
|
||||
console.error(e)
|
||||
} finally {
|
||||
if (present_thread) present_thread.wait();
|
||||
present_thread = render._main.present();
|
||||
render._main.present();
|
||||
tracy.end_frame();
|
||||
}
|
||||
};
|
||||
|
||||
1161
scripts/sdl_gpu.js
Normal file
1161
scripts/sdl_gpu.js
Normal file
File diff suppressed because it is too large
Load Diff
@@ -247,9 +247,9 @@ Cmdline.register_order(
|
||||
else console.warn("No config.js file found. Starting with default parameters.");
|
||||
|
||||
prosperon.window = game.engine_start(prosperon);
|
||||
// var renderer = prosperon.window.make_renderer("gpu");
|
||||
// render._main = renderer;
|
||||
render._main = prosperon.window.make_gpu();
|
||||
render._main.window = prosperon.window;
|
||||
render._main.claim_window(prosperon.window);
|
||||
var tt = game.texture('moon');
|
||||
tt.texture.__proto__.toString = function() { return os.value_id(this); }
|
||||
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
@block vert
|
||||
uniform vec4 rect; // uv rect
|
||||
|
||||
void vert()
|
||||
{
|
||||
uv = (uv*rect.zw)+rect.xy;
|
||||
}
|
||||
@end
|
||||
|
||||
@block frag
|
||||
uniform vec4 border; // border given as [left,down,right,top], in uv coordinates of texture, so (pixel)border.x/texture.x, etc
|
||||
uniform vec2 win_tex_scale; // size of the drawing area over the size of the tex
|
||||
uniform vec4 shade;
|
||||
uniform vec4 frag_rect;
|
||||
|
||||
float map(float value, float originalMin, float originalMax, float newMin, float newMax) {
|
||||
return (value - originalMin) / (originalMax - originalMin) * (newMax - newMin) + newMin;
|
||||
}
|
||||
|
||||
vec2 uv9slice(vec2 uv, vec2 s, vec4 b)
|
||||
{
|
||||
vec2 t = clamp((s * uv - b.xy) / (s - b.xy - b.zw), 0., 1.);
|
||||
return mix(uv * s, 1. - s * (1. - uv), t);
|
||||
}
|
||||
|
||||
void frag()
|
||||
{
|
||||
vec2 guv;
|
||||
guv.x = map(uv.x, frag_rect.x, frag_rect.x+frag_rect.z, 0, 1);
|
||||
guv.y = map(uv.y, frag_rect.y, frag_rect.y+frag_rect.w, 0, 1);
|
||||
vec2 nuv = uv9slice(guv, win_tex_scale, border);
|
||||
nuv.x = map(nuv.x, 0, 1, frag_rect.x, frag_rect.x+frag_rect.z);
|
||||
nuv.y = map(nuv.y, 0, 1, frag_rect.y, frag_rect.y+frag_rect.w);
|
||||
|
||||
color = texture(sampler2D(diffuse,smp), nuv);
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
#include <base.cg>
|
||||
@@ -1,47 +0,0 @@
|
||||
@vs vs
|
||||
in vec3 a_pos;
|
||||
in vec2 a_uv;
|
||||
|
||||
out vec2 uv;
|
||||
|
||||
#define PI 3.141592
|
||||
|
||||
vec3 pos;
|
||||
|
||||
uniform mat4 projection;
|
||||
uniform mat4 view;
|
||||
uniform mat4 vp;
|
||||
uniform mat4 model;
|
||||
|
||||
@include_block vert
|
||||
|
||||
void main()
|
||||
{
|
||||
pos = a_pos;
|
||||
uv = a_uv;
|
||||
vert();
|
||||
gl_Position = vp * model * vec4(pos, 1.0);
|
||||
}
|
||||
@end
|
||||
|
||||
@fs fs
|
||||
|
||||
in vec2 uv;
|
||||
|
||||
out vec4 color;
|
||||
|
||||
#define PI 3.141592
|
||||
|
||||
texture2D diffuse;
|
||||
@sampler_type smp nonfiltering
|
||||
sampler smp;
|
||||
|
||||
@include_block frag
|
||||
|
||||
void main()
|
||||
{
|
||||
frag();
|
||||
}
|
||||
@end
|
||||
|
||||
@program sprite vs fs
|
||||
@@ -1,48 +0,0 @@
|
||||
@vs vs
|
||||
in vec2 a_pos;
|
||||
in vec2 a_uv;
|
||||
|
||||
uniform vec2 diffuse_size;
|
||||
|
||||
struct particle {
|
||||
mat4 model;
|
||||
vec4 color;
|
||||
};
|
||||
|
||||
readonly buffer ssbo {
|
||||
particle par[];
|
||||
};
|
||||
|
||||
out vec2 uv;
|
||||
out vec4 color0;
|
||||
|
||||
uniform mat4 vp;
|
||||
uniform float baseinstance;
|
||||
|
||||
void main()
|
||||
{
|
||||
particle p = par[int(baseinstance)+gl_InstanceIndex];
|
||||
gl_Position = vp * p.model * vec4(a_pos, 0.0, 1.0);
|
||||
uv = a_uv;
|
||||
color0 = p.color;
|
||||
}
|
||||
@end
|
||||
|
||||
@fs fs
|
||||
in vec2 uv;
|
||||
|
||||
in vec4 color0;
|
||||
out vec4 color;
|
||||
|
||||
texture2D diffuse;
|
||||
@sampler_type smp nonfiltering
|
||||
sampler smp;
|
||||
|
||||
void main()
|
||||
{
|
||||
color = texture(sampler2D(diffuse,smp),uv);
|
||||
color *= color0;
|
||||
}
|
||||
@end
|
||||
|
||||
@program text vs fs
|
||||
@@ -1,61 +0,0 @@
|
||||
@vs vs
|
||||
in vec2 a_pos;
|
||||
in vec2 a_uv;
|
||||
|
||||
struct letter {
|
||||
vec2 pos;
|
||||
vec2 wh;
|
||||
vec2 uv;
|
||||
vec2 uv_size;
|
||||
vec4 color;
|
||||
};
|
||||
|
||||
readonly buffer ssbo {
|
||||
letter ls[];
|
||||
};
|
||||
|
||||
out vec2 uv; // Normalized UV, from 0 to 1 on the letter, for special effects
|
||||
out vec2 fuv; // This is the UV given to get the correct letter from the texture
|
||||
out vec4 color0;
|
||||
|
||||
vec2 pos;
|
||||
|
||||
uniform mat4 vp;
|
||||
|
||||
@include_block vert
|
||||
|
||||
void main()
|
||||
{
|
||||
letter charData = ls[gl_InstanceIndex];
|
||||
fuv = charData.uv + a_pos*charData.uv_size;
|
||||
uv = a_uv;
|
||||
color0 = charData.color;
|
||||
pos = charData.pos+(a_pos*charData.wh);
|
||||
vert();
|
||||
gl_Position = vp * vec4(pos, 0.0, 1.0);
|
||||
}
|
||||
@end
|
||||
|
||||
@fs fs
|
||||
in vec2 uv;
|
||||
in vec2 fuv;
|
||||
in vec4 color0;
|
||||
|
||||
out vec4 color;
|
||||
|
||||
texture2D text;
|
||||
|
||||
@sampler_type smp nonfiltering
|
||||
sampler smp;
|
||||
|
||||
@include_block frag
|
||||
|
||||
void main()
|
||||
{
|
||||
float lettera = texture(sampler2D(text,smp),fuv).r;
|
||||
frag();
|
||||
color.a *= lettera;
|
||||
}
|
||||
@end
|
||||
|
||||
@program text vs fs
|
||||
@@ -1,41 +0,0 @@
|
||||
@vs vert
|
||||
in vec3 a_pos;
|
||||
|
||||
uniform float radius;
|
||||
uniform vec2 coord;
|
||||
uniform mat4 vp;
|
||||
out vec2 coords;
|
||||
out float rad;
|
||||
void main() {
|
||||
vec3 pos = a_pos;
|
||||
pos.xy -= 0.5;
|
||||
pos.xy *= 2;
|
||||
coords = pos.xy;
|
||||
pos *= radius;
|
||||
pos.xy += coord;
|
||||
rad = radius;
|
||||
gl_Position = vp * vec4(pos,1);
|
||||
}
|
||||
@end
|
||||
|
||||
@fs frag
|
||||
in vec2 coords;
|
||||
in float rad;
|
||||
uniform vec4 shade;
|
||||
uniform float inner_r;
|
||||
out vec4 color;
|
||||
void main() {
|
||||
float px = 1/rad;
|
||||
float blur = 1.0+px;
|
||||
float R = 1;
|
||||
float R2 = 1-inner_r;
|
||||
float dist = distance(vec2(0,0),coords);
|
||||
float sm = 1 - smoothstep(R-px,R*blur,dist);
|
||||
float sm2 = smoothstep(R2-px,R2*blur,dist);
|
||||
|
||||
float alpha = sm*sm2;
|
||||
color = vec4(shade.xyz, alpha*shade.a);
|
||||
}
|
||||
@end
|
||||
|
||||
@program circle vert frag
|
||||
15
shaders/common.hlsl
Normal file
15
shaders/common.hlsl
Normal file
@@ -0,0 +1,15 @@
|
||||
// Constant Buffer for Transformation Matrices
|
||||
cbuffer TransformBuffer : register(b0, space1)
|
||||
{
|
||||
float4x4 vp;
|
||||
float4x4 view;
|
||||
float time; // time in seconds since app start
|
||||
}
|
||||
|
||||
struct VSInput
|
||||
{
|
||||
float3 pos : POSITION;
|
||||
float2 uv : TEXCOORD0;
|
||||
float4 color : COLOR0;
|
||||
float3 normal : NORMAL;
|
||||
};
|
||||
27
shaders/compile.sh
Executable file
27
shaders/compile.sh
Executable file
@@ -0,0 +1,27 @@
|
||||
# Requires shadercross CLI installed from SDL_shadercross
|
||||
for filename in *.vert.hlsl; do
|
||||
if [ -f "$filename" ]; then
|
||||
echo "compiling ${filename}"
|
||||
shadercross "$filename" -o "spirv/${filename/.hlsl/.spv}"
|
||||
shadercross "$filename" -o "msl/${filename/.hlsl/.msl}"
|
||||
shadercross "$filename" -o "dxil/${filename/.hlsl/.dxil}"
|
||||
fi
|
||||
done
|
||||
|
||||
for filename in *.frag.hlsl; do
|
||||
if [ -f "$filename" ]; then
|
||||
echo "compiling ${filename}"
|
||||
shadercross "$filename" -o "spirv/${filename/.hlsl/.spv}"
|
||||
shadercross "$filename" -o "msl/${filename/.hlsl/.msl}"
|
||||
shadercross "$filename" -o "dxil/${filename/.hlsl/.dxil}"
|
||||
fi
|
||||
done
|
||||
|
||||
for filename in *.comp.hlsl; do
|
||||
if [ -f "$filename" ]; then
|
||||
echo "compiling ${filename}"
|
||||
shadercross "$filename" -o "spirv/${filename/.hlsl/.spv}"
|
||||
shadercross "$filename" -o "msl/${filename/.hlsl/.msl}"
|
||||
shadercross "$filename" -o "dxil/${filename/.hlsl/.dxil}"
|
||||
fi
|
||||
done
|
||||
@@ -1,21 +0,0 @@
|
||||
@block vert
|
||||
uniform vec4 rect;
|
||||
|
||||
void vert()
|
||||
{
|
||||
pos *= vec3(rect.zw,1);
|
||||
uv = (uv*rect.zw)+rect.xy;
|
||||
}
|
||||
@end
|
||||
|
||||
@block frag
|
||||
uniform vec4 shade;
|
||||
void frag()
|
||||
{
|
||||
color = texture(sampler2D(diffuse,smp), uv);
|
||||
if (color.a == 0.0) discard;
|
||||
color = vec4(0.0);
|
||||
}
|
||||
@end
|
||||
|
||||
#include <base.cg>
|
||||
15
shaders/model.frag.hlsl
Normal file
15
shaders/model.frag.hlsl
Normal file
@@ -0,0 +1,15 @@
|
||||
// If using a texture instead, define:
|
||||
Texture2D diffuse : register(t0, space2);
|
||||
SamplerState smp : register(s0, space2);
|
||||
|
||||
struct PSInput
|
||||
{
|
||||
float4 pos : SV_POSITION;
|
||||
float2 uv : TEXCOORD0;
|
||||
float3 normal : NORMAL;
|
||||
};
|
||||
|
||||
float4 main(PSInput input) : SV_TARGET
|
||||
{
|
||||
return float4(input.uv,1,1);
|
||||
}
|
||||
17
shaders/model.vert.hlsl
Normal file
17
shaders/model.vert.hlsl
Normal file
@@ -0,0 +1,17 @@
|
||||
#include "common.hlsl"
|
||||
|
||||
struct VSOutput
|
||||
{
|
||||
float4 pos : SV_POSITION;
|
||||
float2 uv : TEXCOORD0;
|
||||
float3 normal : NORMAL; // Might be unused in no-light case, but we'll pass it anyway.
|
||||
};
|
||||
|
||||
VSOutput main(VSInput input)
|
||||
{
|
||||
VSOutput output;
|
||||
output.pos = mul(vp, float4(input.pos, 1.0));
|
||||
output.uv = input.uv;
|
||||
output.normal = input.normal; // World space normal if needed
|
||||
return output;
|
||||
}
|
||||
40
shaders/model_lit.frag.hlsl
Normal file
40
shaders/model_lit.frag.hlsl
Normal file
@@ -0,0 +1,40 @@
|
||||
cbuffer LightBuffer : register(b2, space1)
|
||||
{
|
||||
float4 uDiffuseColor; // base diffuse color
|
||||
float3 uLightDirection; // direction of the incoming light, normalized
|
||||
float4 uLightColor; // color of the light, e.g., (1,1,1,1)
|
||||
};
|
||||
|
||||
// Example hard-coded values (if not using cbuffer, you can directly hardcode in code):
|
||||
// float3 uLightDirection = normalize(float3(0.0, -1.0, -1.0));
|
||||
// float4 uLightColor = float4(1.0, 1.0, 1.0, 1.0);
|
||||
|
||||
// You can also still use a texture:
|
||||
Texture2D uDiffuseTexture : register(t0);
|
||||
SamplerState samplerState : register(s0);
|
||||
|
||||
struct PSInput
|
||||
{
|
||||
float4 pos : SV_POSITION;
|
||||
float2 uv : TEXCOORD0;
|
||||
float3 normal : NORMAL;
|
||||
};
|
||||
|
||||
float4 main(PSInput input) : SV_TARGET
|
||||
{
|
||||
// Sample base color
|
||||
float4 baseColor = uDiffuseTexture.Sample(samplerState, input.uv);
|
||||
// If no texture, just use uDiffuseColor:
|
||||
// float4 baseColor = uDiffuseColor;
|
||||
|
||||
// Compute diffuse lighting
|
||||
// Ensure normal is normalized
|
||||
float3 N = normalize(input.normal);
|
||||
// Light direction is assumed normalized. Make sure uLightDirection is a direction from fragment to light.
|
||||
// If the direction is from the light to the fragment, invert it: float3 L = -uLightDirection;
|
||||
float NdotL = saturate(dot(N, -uLightDirection));
|
||||
|
||||
float4 shadedColor = baseColor * (uLightColor * NdotL);
|
||||
|
||||
return shadedColor;
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
@vs vs
|
||||
in vec3 a_pos;
|
||||
uniform mat4 vp;
|
||||
uniform mat4 model;
|
||||
|
||||
void main() {
|
||||
gl_Position = vp * model * vec4(a_pos, 1);
|
||||
}
|
||||
@end
|
||||
|
||||
@fs fs
|
||||
uniform vec4 shade;
|
||||
out vec4 color;
|
||||
|
||||
void main() {
|
||||
color = shade;
|
||||
}
|
||||
@end
|
||||
|
||||
@program sprite vs fs
|
||||
@@ -1,34 +0,0 @@
|
||||
@vs vs
|
||||
in vec3 a_pos;
|
||||
uniform mat4 vp;
|
||||
out vec4 shade;
|
||||
|
||||
struct poly {
|
||||
mat4 model;
|
||||
vec4 color;
|
||||
};
|
||||
|
||||
readonly buffer ssbo {
|
||||
poly polys[];
|
||||
};
|
||||
|
||||
uniform float baseinstance;
|
||||
|
||||
void main() {
|
||||
poly p = polys[int(baseinstance)+gl_InstanceIndex];
|
||||
gl_Position = vp * p.model * vec4(a_pos, 1);
|
||||
shade = p.color;
|
||||
}
|
||||
@end
|
||||
|
||||
@fs fs
|
||||
|
||||
in vec4 shade;
|
||||
out vec4 color;
|
||||
|
||||
void main() {
|
||||
color = shade;
|
||||
}
|
||||
@end
|
||||
|
||||
@program sprite vs fs
|
||||
@@ -1,40 +0,0 @@
|
||||
@vs vs
|
||||
in vec3 a_pos;
|
||||
in vec2 a_uv;
|
||||
|
||||
out vec2 uv;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec3 pos = a_pos;
|
||||
pos -= 0.5;
|
||||
pos *= 2;
|
||||
uv = a_uv;
|
||||
gl_Position = vec4(pos.xy, 0, 1.0);
|
||||
}
|
||||
@end
|
||||
|
||||
@fs fs
|
||||
in vec2 uv;
|
||||
|
||||
out vec4 color;
|
||||
|
||||
#define PI 3.141592
|
||||
|
||||
texture2D diffuse;
|
||||
|
||||
@sampler_type smp filtering
|
||||
sampler smp;
|
||||
|
||||
uniform vec2 mouse;
|
||||
uniform float time;
|
||||
|
||||
@include_block frag
|
||||
|
||||
void main()
|
||||
{
|
||||
frag();
|
||||
}
|
||||
@end
|
||||
|
||||
@program p vs fs
|
||||
@@ -1,38 +0,0 @@
|
||||
@block frag
|
||||
|
||||
uniform float offset_amt;
|
||||
|
||||
// Sharpen kernel
|
||||
float kernel[9] = float[](
|
||||
-1, -1, -1,
|
||||
-1, 9, -1,
|
||||
-1, -1, -1
|
||||
);
|
||||
|
||||
void frag()
|
||||
{
|
||||
vec2 offset = vec2(1/offset_amt, 1/offset_amt);
|
||||
vec2 offsets[9] = vec2[](
|
||||
vec2(-offset.x, offset.y), // top-left
|
||||
vec2(0.0, offset.y), // top-center
|
||||
vec2(offset.x, offset.y), // top-right
|
||||
vec2(-offset.x, 0.0), // center-left
|
||||
vec2(0.0, 0.0), // center-center (current pixel)
|
||||
vec2(offset.x, 0.0), // center-right
|
||||
vec2(-offset.x, -offset.y), // bottom-left
|
||||
vec2(0.0, -offset.y), // bottom-center
|
||||
vec2(offset.x, -offset.y) // bottom-right
|
||||
);
|
||||
|
||||
color = vec4(0.0);
|
||||
|
||||
// Apply the kernel to the current pixel and its neighbors
|
||||
for (int i = 0; i < 9; i++) {
|
||||
vec3 samp = texture(sampler2D(diffuse,smp),uv+offsets[i]).rgb;
|
||||
color.rgb += samp * kernel[i];
|
||||
}
|
||||
color.a = 1.0;
|
||||
}
|
||||
@end
|
||||
|
||||
#include <postbase.cg>
|
||||
@@ -1,22 +0,0 @@
|
||||
@vs vs
|
||||
in vec3 a_pos;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec3 pos = a_pos;
|
||||
pos -= 0.5;
|
||||
pos *= 2;
|
||||
gl_Position = vec4(pos.xy, 0, 1.0);
|
||||
}
|
||||
@end
|
||||
|
||||
@fs fs
|
||||
out vec4 color;
|
||||
|
||||
void main()
|
||||
{
|
||||
color = vec4(1.0);
|
||||
}
|
||||
@end
|
||||
|
||||
@program p vs fs
|
||||
@@ -1,8 +0,0 @@
|
||||
@block frag
|
||||
void frag()
|
||||
{
|
||||
color = texture(sampler2D(diffuse,smp),uv);
|
||||
}
|
||||
@end
|
||||
|
||||
#include <postbase.cg>
|
||||
@@ -1,20 +0,0 @@
|
||||
@block vert
|
||||
uniform vec4 rect;
|
||||
uniform vec2 diffuse_size;
|
||||
void vert()
|
||||
{
|
||||
pos *= vec3(diffuse_size * rect.zw,1);
|
||||
uv = (uv*rect.zw)+rect.xy;
|
||||
}
|
||||
@end
|
||||
|
||||
@block frag
|
||||
|
||||
void frag()
|
||||
{
|
||||
color = texture(sampler2D(diffuse,smp), uv);
|
||||
if (color.a == 0) discard;
|
||||
}
|
||||
@end
|
||||
|
||||
#include <base.cg>
|
||||
21
shaders/sprite.frag.hlsl
Normal file
21
shaders/sprite.frag.hlsl
Normal file
@@ -0,0 +1,21 @@
|
||||
Texture2D diffuse : register(t0, space2);
|
||||
SamplerState smp : register(s0, space2);
|
||||
|
||||
// Structure for pixel shader input (from vertex shader output).
|
||||
struct PSInput
|
||||
{
|
||||
float2 uv : TEXCOORD0;
|
||||
float4 color : COLOR0;
|
||||
};
|
||||
|
||||
// Pixel shader main function
|
||||
float4 main(PSInput input) : SV_TARGET
|
||||
{
|
||||
float4 color = diffuse.Sample(smp, input.uv);
|
||||
color *= input.color;
|
||||
|
||||
if (color.a == 0.0f)
|
||||
clip(-1);
|
||||
|
||||
return color;
|
||||
}
|
||||
21
shaders/sprite.vert.hlsl
Normal file
21
shaders/sprite.vert.hlsl
Normal file
@@ -0,0 +1,21 @@
|
||||
#include "common.hlsl"
|
||||
|
||||
// Output structure from the vertex shader to the pixel shader
|
||||
struct VertexOutput
|
||||
{
|
||||
float4 pos : SV_Position; // Clip-space position
|
||||
float2 uv : TEXCOORD0; // Texture coordinates
|
||||
float4 color : COLOR0; // Interpolated vertex color
|
||||
};
|
||||
|
||||
// Vertex shader
|
||||
VertexOutput main(VSInput input)
|
||||
{
|
||||
VertexOutput output;
|
||||
output.pos = mul(vp, float4(input.pos,1.0));
|
||||
output.uv = input.uv;
|
||||
output.color = input.color;
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
@@ -1,58 +0,0 @@
|
||||
@vs vs
|
||||
in vec3 a_pos;
|
||||
in vec2 a_uv;
|
||||
out vec2 uv;
|
||||
out vec4 shade;
|
||||
|
||||
vec3 pos;
|
||||
|
||||
struct sprite {
|
||||
mat4 model;
|
||||
vec4 rect;
|
||||
vec4 shade;
|
||||
};
|
||||
|
||||
readonly buffer ssbo {
|
||||
sprite sprites[];
|
||||
};
|
||||
|
||||
uniform mat4 vp;
|
||||
uniform float baseinstance;
|
||||
|
||||
void main()
|
||||
{
|
||||
sprite s = sprites[int(baseinstance)+gl_InstanceIndex];
|
||||
pos = a_pos;
|
||||
uv = a_uv;
|
||||
uv = (uv*s.rect.zw)+s.rect.xy;
|
||||
gl_Position = vp * s.model * vec4(pos, 1.0);
|
||||
shade = s.shade;
|
||||
}
|
||||
@end
|
||||
|
||||
@fs fs
|
||||
|
||||
in vec2 uv;
|
||||
in vec4 shade;
|
||||
|
||||
out vec4 color;
|
||||
|
||||
texture2D diffuse;
|
||||
|
||||
@sampler_type smp nonfiltering
|
||||
sampler smp;
|
||||
|
||||
void frag()
|
||||
{
|
||||
color = texture(sampler2D(diffuse,smp), uv);
|
||||
color *= shade;
|
||||
if (color.a == 0.0) discard;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
frag();
|
||||
}
|
||||
@end
|
||||
|
||||
@program sprite vs fs
|
||||
@@ -1,3 +0,0 @@
|
||||
@block vert
|
||||
void vert(){}
|
||||
@end
|
||||
@@ -1,10 +0,0 @@
|
||||
#include <stdvert.cg>
|
||||
|
||||
@block frag
|
||||
void frag()
|
||||
{
|
||||
color = color0;
|
||||
}
|
||||
@end
|
||||
|
||||
#include <basetext.cg>
|
||||
6
shaders/wind.hlsl
Normal file
6
shaders/wind.hlsl
Normal file
@@ -0,0 +1,6 @@
|
||||
#define WIND
|
||||
|
||||
struct Wind
|
||||
{
|
||||
float3 windy : TEXCOORD1;
|
||||
};
|
||||
1918
source/jsffi.c
1918
source/jsffi.c
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user