Skip to content

Commit

Permalink
feat(renderer): add ability to render a height map & add camera contr…
Browse files Browse the repository at this point in the history
…ols (#159)
  • Loading branch information
esterTion authored Oct 11, 2023
1 parent 44608fb commit a16b303
Show file tree
Hide file tree
Showing 4 changed files with 113 additions and 3 deletions.
57 changes: 57 additions & 0 deletions src/components/ParametersBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,20 @@ export default function ParametersBar(props: {
ControlDifficulty.Expert,
);

const setParams = props.setParams;
const [renderHeightMap, setRenderHeightMap] = useState(false);
const [isCameraControlMode, setIsCameraControlMode] = useState(false);

useEffect(() => {
setParams((prev) => {
return {
...prev,
renderHeightMap,
isCameraControlMode,
};
});
}, [renderHeightMap, isCameraControlMode, setParams]);

if (isPaneVisible) {
return (
<Container direction="vertical" size={space}>
Expand Down Expand Up @@ -186,6 +200,49 @@ export default function ParametersBar(props: {
{/* add controls to be shown to both here */}
<SimulationColour setParams={props.setParams} />

<Row gutter={16}>
<ParameterLabel title="Rendering mode"></ParameterLabel>
</Row>
<Row gutter={16}>
<Col className="gutter-row" span={12}>
<ParameterButton
label="Flat surface"
onClick={() => {
setIsCameraControlMode(false);
setRenderHeightMap(false);
}}
/>
</Col>
<Col className="gutter-row" span={12}>
<ParameterButton
label="Height map"
onClick={() => {
setRenderHeightMap(true);
}}
/>
</Col>
</Row>
<Row gutter={16} style={renderHeightMap ? {} : { display: 'none' }}>
<ParameterLabel title="Current Control"></ParameterLabel>
</Row>
<Row gutter={16} style={renderHeightMap ? {} : { display: 'none' }}>
<Col className="gutter-row" span={12}>
<ParameterButton
label="Apply force"
onClick={() => {
setIsCameraControlMode(false);
}}
/>
</Col>
<Col className="gutter-row" span={12}>
<ParameterButton
label="Spin camera"
onClick={() => {
setIsCameraControlMode(true);
}}
/>
</Col>
</Row>
{/* choose initial model */}
<Dropdown menu={{ items, onClick }}>
<DropdownMenu
Expand Down
23 changes: 21 additions & 2 deletions src/components/Simulation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
import type React from 'react';
import { useEffect, useMemo, useRef } from 'react';
import vertexShader from '../shaders/vert.glsl';
import vertexShaderForHeightMap from '../shaders/vert_height.glsl';
import fragmentShader from '../shaders/frag.glsl';

// WebGPU imports
Expand All @@ -17,6 +18,9 @@ class SimulationParams {
// render options
densityLowColour: t.Color = new t.Color('blue');
densityHighColour: t.Color = new t.Color('red');

renderHeightMap: boolean = false;
isCameraControlMode: boolean = false;
}

// we will store the parameters in an interface explicitly so
Expand Down Expand Up @@ -79,8 +83,15 @@ function DiffusionPlane(
// create the shader
const shaderMat = useMemo(() => {
const shaderMat = new t.ShaderMaterial();
shaderMat.vertexShader = applyConfigToShader(vertexShader as string);
if (props.params.renderHeightMap) {
shaderMat.vertexShader = applyConfigToShader(
vertexShaderForHeightMap as string,
);
} else {
shaderMat.vertexShader = applyConfigToShader(vertexShader as string);
}
shaderMat.fragmentShader = applyConfigToShader(fragmentShader as string);
shaderMat.side = t.DoubleSide;

// provide a dummy density field first

Expand All @@ -103,13 +114,19 @@ function DiffusionPlane(
};

return shaderMat;
}, [props.params.densityHighColour, props.params.densityLowColour]);
}, [
props.params.densityHighColour,
props.params.densityLowColour,
props.params.renderHeightMap,
]);

// HOOKS

useFrame((state) => {
if (disableInteraction) return;
// potential performance issue?
state.camera.setRotationFromAxisAngle(new t.Vector3(1, 0, 0), -Math.PI / 2);
state.camera.position.set(0, 10, 0);
ref.current.lookAt(0, 99, 0);
});

Expand All @@ -125,6 +142,8 @@ function DiffusionPlane(
// update the density uniforms every time
// output is received
function output(data: Float32Array): void {
// create a copy to prevent modifying original data
data = data.slice(0);
const param: Record<string, number> = {
densityRangeHigh: parseFloat(renderConfig.densityRangeHigh),
densityRangeLow: parseFloat(renderConfig.densityRangeLow),
Expand Down
7 changes: 6 additions & 1 deletion src/pages/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
type OutgoingMessage,
} from '../workers/modelWorkerMessage';
import { type ModelSave } from '../services/model/modelService';
import { OrbitControls } from '@react-three/drei';
import RestorePopup from '../components/RestoreComponents/restorePopUp';

const SimulatorContainer = styled.div`
Expand Down Expand Up @@ -113,8 +114,12 @@ export default function Home(props: IndexProp): React.ReactElement {
}}
>
<ambientLight />
<OrbitControls
target={[0, 0, 0]}
enabled={simulationParams.isCameraControlMode}
></OrbitControls>
<DiffusionPlane
disableInteraction={false}
disableInteraction={simulationParams.isCameraControlMode}
position={[0, 0, 0]}
params={simulationParams}
worker={worker}
Expand Down
29 changes: 29 additions & 0 deletions src/shaders/vert_height.glsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// VERTEX SHADER
varying lowp vec4 vColor;

uniform sampler2D density;
uniform vec3 hiCol;
uniform vec3 lowCol;

vec4 getColourFromDensity(float density)
{
return vec4(mix(lowCol, hiCol, density), 1.0);
}

vec2 getCoordFromPoint(vec3 pos)
{
float x = ((pos.x + (${width} / 2.0)) / ${width});
float y = ((-pos.y + (${height} / 2.0)) / ${height});
return vec2(x, y);
}

void main(void)
{
highp vec2 vTextureCoord = getCoordFromPoint(position);
vColor = getColourFromDensity(texture2D(density, vTextureCoord).r);

vec3 changedPosition = position;
changedPosition.z = texture2D(density, vTextureCoord).r;

gl_Position = projectionMatrix * modelViewMatrix * vec4( changedPosition, 1.0 );
}

0 comments on commit a16b303

Please sign in to comment.