particle smoothing function sandbox
This commit is contained in:
parent
5386b8bee9
commit
b198b61bb7
175
flat.js
175
flat.js
@ -1,6 +1,91 @@
|
||||
import { getPath } from "./common.js";
|
||||
|
||||
function test(position)
|
||||
{
|
||||
const x = position[0] * 4 * Math.PI;
|
||||
const y = position[1] * 4 * Math.PI;
|
||||
return Math.cos(y - 3 + Math.sin(x)) * 0.5 + 0.5;
|
||||
}
|
||||
|
||||
function length(vector)
|
||||
{
|
||||
return Math.sqrt(vector[0] * vector[0] + vector[1] * vector[1]);
|
||||
}
|
||||
|
||||
function sub(a, b)
|
||||
{
|
||||
return [
|
||||
a[0] - b[0],
|
||||
a[1] - b[1],
|
||||
];
|
||||
}
|
||||
|
||||
function smoothing(radius, distance)
|
||||
{
|
||||
const volume = Math.PI * Math.pow(radius, 8) / 4;
|
||||
const value = Math.max(0, radius * radius - distance * distance);
|
||||
return value * value * value / volume;
|
||||
}
|
||||
|
||||
class FlatRenderer {
|
||||
createParticles(device)
|
||||
{
|
||||
this.maxDim = 32;
|
||||
this.maxParticles = this.maxDim * this.maxDim;
|
||||
this.particleStride = 4 * 2; // in elements
|
||||
this.particles = new Float32Array(this.maxParticles * this.particleStride);
|
||||
this.particleBuffers = [];
|
||||
this.particleBindGroups = [];
|
||||
|
||||
this.particleConfiguration = new Float32Array(3 * 4);
|
||||
this.particleConfigurationBuffers = [];
|
||||
|
||||
for (let i = 0; i < 2; i++) {
|
||||
const buffer = device.createBuffer({
|
||||
label: `particle buffer ${i}`,
|
||||
size: this.particles.byteLength,
|
||||
usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST,
|
||||
});
|
||||
this.particleBuffers.push(buffer);
|
||||
|
||||
const configBuffer = device.createBuffer({
|
||||
label: `particle configuration buffer ${i}`,
|
||||
size: this.particleConfiguration.byteLength,
|
||||
usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,
|
||||
});
|
||||
this.particleConfigurationBuffers.push(configBuffer);
|
||||
|
||||
const bindGroup = device.createBindGroup({
|
||||
label: `particle buffer bind group ${i}`,
|
||||
layout: this.bindGroupLayout.particle,
|
||||
entries: [{
|
||||
binding: 0,
|
||||
resource: { buffer: configBuffer },
|
||||
}, {
|
||||
binding: 1,
|
||||
resource: { buffer: buffer },
|
||||
}],
|
||||
});
|
||||
this.particleBindGroups.push(bindGroup);
|
||||
}
|
||||
|
||||
for (let y = 0; y < this.maxDim; y++) {
|
||||
for (let x = 0; x < this.maxDim; x++) {
|
||||
const index = y * this.maxDim + x;
|
||||
//this.particles[index * this.particleStride + 0] = (x / this.maxDim) + 0.5 / this.maxDim;
|
||||
//this.particles[index * this.particleStride + 1] = (y / this.maxDim) + 0.5 / this.maxDim;
|
||||
// position
|
||||
const position = [Math.random(), Math.random()];
|
||||
this.particles[index * this.particleStride + 0] = position[0];
|
||||
this.particles[index * this.particleStride + 1] = position[1];
|
||||
this.particles[index * this.particleStride + 2] = 0.0;
|
||||
this.particles[index * this.particleStride + 3] = 1.0;
|
||||
// value.x
|
||||
this.particles[index * this.particleStride + 4] = test(position);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
constructor(device, canvasFormat, viewUniformBuffer, shaderModule)
|
||||
{
|
||||
const label = "flat";
|
||||
@ -29,20 +114,35 @@ class FlatRenderer {
|
||||
// pipeline
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
const bindGroupLayouts = [
|
||||
device.createBindGroupLayout({
|
||||
label: `${label} view matrix bind group layout`,
|
||||
this.bindGroupLayout = {
|
||||
view: device.createBindGroupLayout({
|
||||
label: `${label} bind group layout view`,
|
||||
entries: [{
|
||||
binding: 0,
|
||||
visibility: GPUShaderStage.VERTEX,
|
||||
buffer: { type: "uniform" }
|
||||
}]
|
||||
}),
|
||||
];
|
||||
particle: device.createBindGroupLayout({
|
||||
label: `${label} bind group layout particle`,
|
||||
entries: [{
|
||||
binding: 0,
|
||||
visibility: GPUShaderStage.FRAGMENT,
|
||||
buffer: { type: "uniform" }
|
||||
}, {
|
||||
binding: 1,
|
||||
visibility: GPUShaderStage.FRAGMENT,
|
||||
buffer: { type: "read-only-storage" }
|
||||
}]
|
||||
}),
|
||||
};
|
||||
|
||||
const pipelineLayout = device.createPipelineLayout({
|
||||
label: `${label} pipeline layout`,
|
||||
bindGroupLayouts: bindGroupLayouts,
|
||||
bindGroupLayouts: [
|
||||
this.bindGroupLayout.view,
|
||||
this.bindGroupLayout.particle
|
||||
],
|
||||
});
|
||||
|
||||
this.renderPipeline = device.createRenderPipeline({
|
||||
@ -69,6 +169,12 @@ class FlatRenderer {
|
||||
},
|
||||
});
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// particles
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
this.createParticles(device);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// bind group
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
@ -76,7 +182,7 @@ class FlatRenderer {
|
||||
this.bindGroups = [
|
||||
device.createBindGroup({
|
||||
label: `${label} bind group`,
|
||||
layout: bindGroupLayouts[0],
|
||||
layout: this.bindGroupLayout.view,
|
||||
entries: [{
|
||||
binding: 0,
|
||||
resource: { buffer: viewUniformBuffer },
|
||||
@ -85,11 +191,66 @@ class FlatRenderer {
|
||||
];
|
||||
}
|
||||
|
||||
render(renderPass)
|
||||
positionDensity(position, circleRadius, particleCount)
|
||||
{
|
||||
var density = 0.0;
|
||||
for (var i = 0; i < particleCount; i++) {
|
||||
const particlePosition = [this.particles[i * this.particleStride + 0],
|
||||
this.particles[i * this.particleStride + 1]];
|
||||
const distance = length(sub(position, particlePosition));
|
||||
const influence = smoothing(circleRadius, distance);
|
||||
density += influence;
|
||||
}
|
||||
return density;
|
||||
}
|
||||
|
||||
updateParticles(device, frameNumber, configuration)
|
||||
{
|
||||
for (var i = 0; i < configuration.particleCount; i++) {
|
||||
const position = [this.particles[i * this.particleStride + 0],
|
||||
this.particles[i * this.particleStride + 1]];
|
||||
const density = this.positionDensity(position,
|
||||
configuration.circleRadius,
|
||||
configuration.particleCount);
|
||||
// value.y
|
||||
this.particles[i * this.particleStride + 5] = density;
|
||||
}
|
||||
|
||||
device.queue.writeBuffer(this.particleBuffers[frameNumber], 0,
|
||||
this.particles, 0, this.particles.length);
|
||||
|
||||
const PARTICLE = 0;
|
||||
const CIRCLE = 1;
|
||||
const MOUSE = 2;
|
||||
|
||||
const config = this.particleConfiguration;
|
||||
config[PARTICLE * 4 + 0] = configuration.particleCount;
|
||||
config[PARTICLE * 4 + 1] = configuration.particleSize;
|
||||
config[PARTICLE * 4 + 2] = configuration.particleMass1;
|
||||
config[PARTICLE * 4 + 3] = configuration.particleMass2;
|
||||
|
||||
config[CIRCLE * 4 + 0] = configuration.circleRadius;
|
||||
config[CIRCLE * 4 + 1] = configuration.circleThickness;
|
||||
config[CIRCLE * 4 + 2] = configuration.testIntensity;
|
||||
config[CIRCLE * 4 + 3] = configuration.mass12Mix;
|
||||
|
||||
config[MOUSE * 4 + 0] = configuration.mousePosition[0];
|
||||
config[MOUSE * 4 + 1] = configuration.mousePosition[1];
|
||||
config[MOUSE * 4 + 2] = configuration.mousePosition[2];
|
||||
config[MOUSE * 4 + 3] = configuration.mousePosition[3];
|
||||
|
||||
device.queue.writeBuffer(this.particleConfigurationBuffers[frameNumber], 0,
|
||||
this.particleConfiguration, 0, this.particleConfiguration.length)
|
||||
}
|
||||
|
||||
render(device, renderPass, frameNumber, configuration)
|
||||
{
|
||||
this.updateParticles(device, frameNumber, configuration);
|
||||
|
||||
renderPass.setPipeline(this.renderPipeline);
|
||||
renderPass.setIndexBuffer(this.buffer, "uint16");
|
||||
renderPass.setBindGroup(0, this.bindGroups[0]);
|
||||
renderPass.setBindGroup(1, this.particleBindGroups[frameNumber]);
|
||||
renderPass.drawIndexed(6);
|
||||
}
|
||||
}
|
||||
|
||||
88
flat.wgsl
88
flat.wgsl
@ -5,7 +5,20 @@ struct Configuration {
|
||||
eyePosition: vec4f,
|
||||
};
|
||||
|
||||
struct Particle {
|
||||
position: vec4f,
|
||||
value: vec4f,
|
||||
};
|
||||
|
||||
struct ParticleConfiguration {
|
||||
particle: vec4f,
|
||||
circle: vec4f,
|
||||
mouse: vec4f,
|
||||
};
|
||||
|
||||
@group(0) @binding(0) var<uniform> config: Configuration;
|
||||
@group(1) @binding(0) var<uniform> particleConfiguration: ParticleConfiguration;
|
||||
@group(1) @binding(1) var<storage> particle: array<Particle>;
|
||||
|
||||
struct VertexInput {
|
||||
@builtin(vertex_index) vertex_index: u32,
|
||||
@ -27,16 +40,85 @@ const vertices = array(
|
||||
fn vertexMain(input: VertexInput) -> VertexOutput
|
||||
{
|
||||
let texture = vertices[input.vertex_index];
|
||||
let position = vec4f(texture * 2.0 - 1.0, 0.0, 1.0);
|
||||
|
||||
var output: VertexOutput;
|
||||
output.position = position;
|
||||
output.position = vec4f(texture * 2.0 - 1.0, 0.0, 1.0);
|
||||
output.texture = texture;
|
||||
return output;
|
||||
}
|
||||
|
||||
const pi: f32 = 3.14159274101257324219;
|
||||
|
||||
fn smoothing(radius: f32, distance: f32) -> f32
|
||||
{
|
||||
let volume = pi * pow(radius, 8) / 4;
|
||||
let value = max(0, radius * radius - distance * distance);
|
||||
return value * value * value / volume;
|
||||
}
|
||||
|
||||
fn test(position: vec2f) -> f32
|
||||
{
|
||||
let x = position.x * 4 * pi;
|
||||
let y = position.y * 4 * pi;
|
||||
return cos(y - 3 + sin(x)) * 0.5 + 0.5;
|
||||
}
|
||||
|
||||
fn positionDensity(position: vec2f, circleRadius: f32, particleCount: u32) -> f32
|
||||
{
|
||||
var density: f32 = 0.0;
|
||||
for (var i: u32 = 0; i < u32(particleCount); i++) {
|
||||
let distance = length(position - particle[i].position.xy);
|
||||
let influence = smoothing(circleRadius, distance);
|
||||
density += influence;
|
||||
}
|
||||
return density;
|
||||
}
|
||||
|
||||
@fragment
|
||||
fn fragmentMain(input: VertexOutput) -> @location(0) vec4f
|
||||
{
|
||||
return vec4(input.texture, 0.0, 1.0);
|
||||
var color: vec4f = vec4f(0.0, 0.0, 0.0, 0.0);
|
||||
|
||||
let particleCount = u32(particleConfiguration.particle.x);
|
||||
let particleSize = particleConfiguration.particle.y;
|
||||
let particleMass1 = particleConfiguration.particle.z;
|
||||
let particleMass2 = particleConfiguration.particle.w;
|
||||
|
||||
let circleRadius = particleConfiguration.circle.x;
|
||||
let circleThickness = particleConfiguration.circle.y;
|
||||
let testIntensity = particleConfiguration.circle.z;
|
||||
let mass12Mix = particleConfiguration.circle.w;
|
||||
|
||||
let circlePosition = particleConfiguration.mouse;
|
||||
|
||||
var property: f32 = 0.0;
|
||||
|
||||
for (var i: u32 = 0; i < particleCount; i++) {
|
||||
let distance = length(input.texture.xy - particle[i].position.xy);
|
||||
if (distance < particleSize) {
|
||||
color.x = particle[i].value.x;
|
||||
}
|
||||
//let circleDistance = length(input.texture.xy - circlePosition.xy);
|
||||
let influence = smoothing(circleRadius, distance);
|
||||
//let particleDensity = positionDensity(particle[i].position.xy, circleRadius, particleCount);
|
||||
let particleProperty = particle[i].value.x;
|
||||
let particleDensity = particle[i].value.y;
|
||||
|
||||
let p1 = particleProperty * influence;
|
||||
let p2 = p1 / particleDensity;
|
||||
|
||||
property += mix(p1, p2, mass12Mix);
|
||||
}
|
||||
color.z = property * mix(particleMass1, particleMass2, mass12Mix);
|
||||
|
||||
if (circlePosition.w != 0) {
|
||||
let thickness = abs(length(input.texture.xy - circlePosition.xy) - circleRadius);
|
||||
if (thickness < circleThickness) {
|
||||
//color.y = 1.0;
|
||||
}
|
||||
}
|
||||
|
||||
let testColor = test(input.texture.xy);
|
||||
return vec4(color.xz, testColor * testIntensity, 1.0);
|
||||
//return vec4(color.x, 0, 0, 1.0);
|
||||
}
|
||||
|
||||
29
index.html
29
index.html
@ -11,6 +11,9 @@
|
||||
div, span {
|
||||
font: 0.8rem sans-serif;
|
||||
}
|
||||
span {
|
||||
padding-bottom: 0.1rem;
|
||||
}
|
||||
select, option {
|
||||
font: 0.8rem sans-serif;
|
||||
}
|
||||
@ -23,6 +26,12 @@
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
input[type="range"] {
|
||||
height: 0.9rem;
|
||||
width: 70%;
|
||||
}
|
||||
|
||||
.control-root {
|
||||
position: fixed;
|
||||
left: 0;
|
||||
@ -32,13 +41,13 @@
|
||||
background: #eee;
|
||||
}
|
||||
.control-main {
|
||||
width: 250px;
|
||||
width: 310px;
|
||||
float: right;
|
||||
margin-right: 15px;
|
||||
background: #444;
|
||||
}
|
||||
.label {
|
||||
width: calc(40% - 0.3rem);
|
||||
width: calc(30% - 0.3rem);
|
||||
float: left;
|
||||
clear: left;
|
||||
overflow: hidden;
|
||||
@ -46,7 +55,7 @@
|
||||
margin-top: 0.25rem;
|
||||
}
|
||||
.value {
|
||||
width: calc(60% - 0.2rem);
|
||||
width: calc(70% - 0.2rem);
|
||||
float: left;
|
||||
margin-top: 0.1rem;
|
||||
margin-right: 0.2rem;
|
||||
@ -57,9 +66,9 @@
|
||||
.row {
|
||||
height: 1.5rem;
|
||||
}
|
||||
code {
|
||||
font: 0.95rem monospace;
|
||||
padding-top: 0.1rem;
|
||||
.code, code {
|
||||
font: 0.85rem monospace;
|
||||
padding-top: 0.15rem;
|
||||
}
|
||||
.float3 {
|
||||
width: 30%;
|
||||
@ -71,6 +80,9 @@
|
||||
display: inline-block;
|
||||
text-align: right;
|
||||
}
|
||||
.range-span {
|
||||
float: right;
|
||||
}
|
||||
</style>
|
||||
<script src="index.js" type="module"></script>
|
||||
<!--<script src="index2.js" type="module"></script>-->
|
||||
@ -78,7 +90,7 @@
|
||||
<body>
|
||||
<canvas></canvas>
|
||||
<div class="control-root">
|
||||
<div class="control-main">
|
||||
<div class="control-main" id="control-main">
|
||||
<!--
|
||||
<div class="row">
|
||||
<span class="label">model</span>
|
||||
@ -92,6 +104,7 @@
|
||||
</select>
|
||||
</div>
|
||||
-->
|
||||
<!--
|
||||
<div class="row">
|
||||
<span class="label">eye</span>
|
||||
<div class="value">
|
||||
@ -107,6 +120,7 @@
|
||||
<code class="float2" id="pitch">0.0</code>
|
||||
</div>
|
||||
</div>
|
||||
-->
|
||||
<!--
|
||||
<div class="row">
|
||||
<span class="label">test2</span>
|
||||
@ -115,7 +129,6 @@
|
||||
</select>
|
||||
</div>
|
||||
-->
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
142
index.js
142
index.js
@ -65,9 +65,9 @@ const eyeValueZ = document.getElementById("eye-value-z");
|
||||
const yawValue = document.getElementById("yaw");
|
||||
const pitchValue = document.getElementById("pitch");
|
||||
|
||||
function recreateDepth()
|
||||
function recreateDepth(force)
|
||||
{
|
||||
if (canvas.clientWidth !== canvas.width || canvas.clientWidth !== canvas.height) {
|
||||
if (canvas.clientWidth !== canvas.width || canvas.clientWidth !== canvas.height || force === true) {
|
||||
canvas.width = canvas.clientWidth;
|
||||
canvas.height = canvas.clientHeight;
|
||||
|
||||
@ -190,21 +190,140 @@ function updateView()
|
||||
viewUniformBufferSize);
|
||||
|
||||
const cameraStateF32 = new Float32Array(memory.buffer, cameraStateAddress, cameraStateSize);
|
||||
/*
|
||||
eyeValueX.innerHTML = cameraStateF32[0].toFixed(1);
|
||||
eyeValueY.innerHTML = cameraStateF32[1].toFixed(1);
|
||||
eyeValueZ.innerHTML = cameraStateF32[2].toFixed(1);
|
||||
yawValue.innerHTML = cameraStateF32[9].toFixed(2);
|
||||
pitchValue.innerHTML = cameraStateF32[10].toFixed(2);
|
||||
*/
|
||||
}
|
||||
|
||||
const controlMain = document.getElementById("control-main");
|
||||
|
||||
function remap(low1, high1, low2, high2, value)
|
||||
{
|
||||
return low2 + (value - low1) * (high2 - low2) / (high1 - low1);
|
||||
}
|
||||
|
||||
const sliderDefaults = {
|
||||
"circle radius": 385,
|
||||
"circle thickness": 284,
|
||||
"mass12 mix": 1,
|
||||
"particle count": 360,
|
||||
"particle mass1": 126,
|
||||
"particle mass2": 417,
|
||||
"particle size": 51,
|
||||
"test intensity": 0,
|
||||
};
|
||||
|
||||
class Slider {
|
||||
constructor(label, low, high, max = 1024)
|
||||
{
|
||||
const labelE = document.createElement("span");
|
||||
labelE.className = "label";
|
||||
labelE.innerHTML = label;
|
||||
|
||||
const valueE = document.createElement("div");
|
||||
valueE.className = "value";
|
||||
|
||||
const inputE = document.createElement("input");
|
||||
inputE.className = "range";
|
||||
inputE.min = 0;
|
||||
inputE.max = max;
|
||||
inputE.type = "range";
|
||||
const spanE = document.createElement("span");
|
||||
spanE.className = "range-span code";
|
||||
|
||||
valueE.appendChild(inputE);
|
||||
valueE.appendChild(spanE);
|
||||
|
||||
controlMain.appendChild(labelE);
|
||||
controlMain.appendChild(valueE);
|
||||
|
||||
this.label = label;
|
||||
this.input = inputE;
|
||||
this.span = spanE;
|
||||
this.low = low;
|
||||
this.high = high;
|
||||
this.lastValue = undefined;
|
||||
|
||||
const storageValue = localStorage.getItem(this.label);
|
||||
if (storageValue !== null) {
|
||||
this.input.value = storageValue;
|
||||
} else if (this.label in sliderDefaults) {
|
||||
this.input.value = sliderDefaults[this.label];
|
||||
}
|
||||
this.update();
|
||||
}
|
||||
|
||||
update()
|
||||
{
|
||||
const rawValue = parseInt(this.input.value);
|
||||
const value = remap(this.input.min, this.input.max, this.low, this.high, this.input.value);
|
||||
if (rawValue !== this.lastValue) {
|
||||
this.lastValue = rawValue;
|
||||
localStorage.setItem(this.label, rawValue);
|
||||
}
|
||||
if (this.high > 10) {
|
||||
this.span.innerHTML = value.toFixed(0);
|
||||
} else {
|
||||
this.span.innerHTML = value.toFixed(5);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
const sliders = {
|
||||
particleSize: new Slider("particle size", 0.0, 0.05),
|
||||
particleMass1: new Slider("particle mass1", 0.0, 0.01),
|
||||
particleMass2: new Slider("particle mass2", 0.0, 1.0),
|
||||
particleCount: new Slider("particle count", 0.0, 1024.0),
|
||||
circleRadius: new Slider("circle radius", 0.0, 0.5),
|
||||
circleThickness: new Slider("circle thickness", 0.0, 0.01),
|
||||
testIntensity: new Slider("test intensity", 0.0, 2.0),
|
||||
mass12Mix: new Slider("mass12 mix", 0.0, 1.0, 1),
|
||||
};
|
||||
|
||||
const mousePosition = new Float32Array([0, 0, 0, 0]);
|
||||
|
||||
function updateSliders()
|
||||
{
|
||||
return {
|
||||
mousePosition: mousePosition,
|
||||
particleSize: sliders.particleSize.update(),
|
||||
particleMass1: sliders.particleMass1.update(),
|
||||
particleMass2: sliders.particleMass2.update(),
|
||||
particleCount: sliders.particleCount.update(),
|
||||
circleRadius: sliders.circleRadius.update(),
|
||||
circleThickness: sliders.circleThickness.update(),
|
||||
testIntensity: sliders.testIntensity.update(),
|
||||
mass12Mix: sliders.mass12Mix.update(),
|
||||
};
|
||||
}
|
||||
|
||||
function onClick(e)
|
||||
{
|
||||
mousePosition[0] = e.clientX / canvas.width;
|
||||
mousePosition[1] = 1.0 - (e.clientY / canvas.height);
|
||||
mousePosition[2] = 0;
|
||||
mousePosition[3] = 1;
|
||||
}
|
||||
canvas.addEventListener("click", onClick);
|
||||
|
||||
var canRender = false;
|
||||
var frameNumber = 0;
|
||||
function render2()
|
||||
{
|
||||
recreateDepth();
|
||||
const colorView = context.getCurrentTexture().createView();
|
||||
if (canRender === true) {
|
||||
const configuration = updateSliders();
|
||||
|
||||
updateView();
|
||||
canRender = false;
|
||||
recreateDepth(false);
|
||||
const colorView = context.getCurrentTexture().createView();
|
||||
|
||||
updateView();
|
||||
|
||||
{
|
||||
const encoder = device.createCommandEncoder();
|
||||
const renderPass = encoder.beginRenderPass({
|
||||
colorAttachments: [{
|
||||
@ -223,14 +342,23 @@ function render2()
|
||||
|
||||
//gltfRenderer.render(renderPass);
|
||||
//lightRenderer.render(renderPass);
|
||||
flatRenderer.render(renderPass);
|
||||
flatRenderer.render(device, renderPass, frameNumber, configuration);
|
||||
|
||||
renderPass.end();
|
||||
|
||||
const commandBuffer = encoder.finish();
|
||||
device.queue.submit([commandBuffer]);
|
||||
|
||||
frameNumber = (frameNumber + 1) % 2;
|
||||
}
|
||||
|
||||
requestAnimationFrame(render2);
|
||||
}
|
||||
function setCanRender()
|
||||
{
|
||||
canRender = true;
|
||||
}
|
||||
setInterval(setCanRender, 66.67); // 15 fps
|
||||
|
||||
recreateDepth(true);
|
||||
requestAnimationFrame(render2);
|
||||
|
||||
@ -148,5 +148,6 @@ void camera_view_projection(CameraState * camera_state,
|
||||
XMStoreFloat4x4(&view_state->viewProj, view_projection);
|
||||
XMStoreFloat4x4(&view_state->lightViewProj, light_world * view_projection);
|
||||
XMStoreFloat4(&view_state->lightPosition, light_position);
|
||||
XMStoreFloat4(&view_state->eyePosition, XMLoadFloat3(&camera_state->eye));
|
||||
XMVECTOR eye = XMLoadFloat3(&camera_state->eye);
|
||||
XMStoreFloat4(&view_state->eyePosition, eye);
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user